ตัวเลขเป็นกราฟิกวงกลม


36

ก่อนอื่นศึกษาปริศนานี้เพื่อทำความเข้าใจกับสิ่งที่คุณกำลังจะทำ

ความท้าทายของคุณคือการเขียนโปรแกรมหรือฟังก์ชั่นที่จะส่งออกกราฟิกแบบวงกลมเช่นเดียวกับตัวต่อจากปริศนาที่ให้หมายเลข (ฐาน 10) ระหว่าง 1 ถึง 100 (รวม) สิ่งนี้คล้ายกับความท้าทายนี้ยกเว้นว่าคุณจะสร้างกราฟิกแทนที่จะเป็นตัวเลขโรมัน วงกลมต่อไปนี้แทนตัวเลข 1-10 จากซ้ายไปขวา:

รูปแบบวงกลม

ในฐานะที่เป็นคำตอบของปริศนาภาพกราฟิกของคุณควรอ่านเหมือนตัวเลขโรมันจากด้านในซึ่งความหนาของเส้นแสดงถึงสัญลักษณ์ตัวเลขโรมันและกราฟิกทั้งหมดแสดงถึงจำนวน สำหรับการอ้างอิงของคุณนี่คือความหนาของเส้นที่คุณต้องการ แต่ละบรรทัดควรมีช่องว่างภายใน 3px ระหว่างบรรทัดกับบรรทัดถัดไป

Number  Roman Numeral   Line Width
1       I               1px
5       V               3px
10      X               5px
50      L               7px
100     C               9px

กรุณาโพสต์ตัวอย่างหรือสองของผลลัพธ์ของคุณ สมมติว่าอินพุตถูกต้องช่องโหว่มาตรฐานฯลฯ และอื่น ๆ นี่คือรหัสกอล์ฟดังนั้นจำนวนไบต์ที่น้อยที่สุดจึงชนะ ในกรณีที่เสมอคะแนนโหวตมากที่สุดชนะ โชคดี!


3
จำเป็นต้องใช้ขนาดที่แน่นอนของรูปภาพหรือไม่หรือมีขนาดที่เพียงพอสำหรับการมีขนาดที่เหมาะสม
David Zhang Zhang

@ DavidZhang ใช่โปรดยึดขนาดและขนาดของแพ็ดดิงที่ฉันได้ระบุไว้เพื่อความเป็นธรรม
Rip Leeb

คำตอบ:


15

Mathematica - 166 181 ไบต์

ค่อนข้างกระชับมากกว่าคำตอบ Mathematica อื่น ๆ ขอบคุณส่วนหนึ่งจากรูปแบบที่ไม่มีจุดมากขึ้น

c = Characters; r = Riffle;
Graphics[r[{0, 0}~Disk~# & /@ Reverse@Accumulate[
    l = {3} ~Join~ r[2 Position[c@"IVXLC", #][[1, 1]] - 1 & /@ 
        c@IntegerString[#, "Roman"], 3]], {White, Black}],
    ImageSize -> 2 Total@l] &

ช่องว่างทั้งหมดมีไว้เพื่อความชัดเจนเท่านั้น ฟังก์ชันนี้กำหนดฟังก์ชันที่ไม่ระบุตัวตนซึ่งจะส่งคืนกราฟิกที่ต้องการ

นิเมชั่น

วงกลมเคลื่อนไหว

การสร้างภาพเคลื่อนไหว GIF ของวงกลมหมายเลขนั้นเป็นเรื่องเล็กน้อยใน Mathematica ซึ่งมีฟังก์ชั่นในตัวสำหรับการสร้างภาพเคลื่อนไหวและส่งออกลำดับของวัตถุที่กำหนดเอง สมมติว่าโค้ดด้านบนเพิ่งถูกเรียกใช้งาน

Table[Show[%@n, PlotRange -> {{-100, 100}, {-100, 100}}, 
    ImageSize -> 200], {n, 1, 399, 1}];
Export["animcircles.gif", %]

ตัวอย่างผลลัพธ์

ตัวอย่างผลลัพธ์


กรุณาโพสต์ผลลัพธ์ไม่กี่ ขออภัยที่ไม่ได้ถามที่นี่เป็นที่แรก ฉันได้เปลี่ยนคำถามเพื่อยอมรับฟังก์ชั่น
Rip Leeb

ขอบคุณสำหรับคำแนะนำ @ MartinBüttner รหัสได้รับการแก้ไขแล้วเพื่อให้ได้ภาพที่มีขนาดที่ถูกต้องและมีการเพิ่มตัวอย่างเอาต์พุต
เดวิดจาง

3
ภาพเคลื่อนไหวของคุณเลื้อย ไม่ว่าฉันจะทำได้ดีกว่า
corsiKa

อืมคุณพูดถูก ฉันไม่แน่ใจจริงๆว่าทำไมถึงเป็นเช่นนั้นเมื่อพิจารณาว่าฉันระบุช่วงพล็อตไว้อย่างชัดเจนสำหรับ Mathematica
David Zhang Zhang

อาจเกี่ยวข้องกับการ wiggling: mathematica.stackexchange.com/q/134272
coredump

15

เสียงกระเพื่อมสามัญ - 376 331 304 ไบต์

(use-package(car(ql:quickload'vecto)))(lambda(n o &aux(r 3)l p)(map()(lambda(c)(setf l(position c" I V X L C D M")p(append`((set-line-width,l)(centered-circle-path 0 0,(+(/ l 2)r))(stroke))p)r(+ r l 3)))(format()"~@R"n))(with-canvas(:width(* 2 r):height(* 2 r))(translate r r)(map()'eval p)(save-png o)))

ตัวอย่าง

ป้อนคำอธิบายรูปภาพที่นี่(1) ป้อนคำอธิบายรูปภาพที่นี่(24)

ป้อนคำอธิบายรูปภาพที่นี่(104) ป้อนคำอธิบายรูปภาพที่นี่(1903) ป้อนคำอธิบายรูปภาพที่นี่(3999)

นิเมชั่น

สำหรับตัวเลขตั้งแต่ 1 ถึง 400:

ใหม่

หมายเหตุ:สำหรับบันทึกภาพเคลื่อนไหวนี้ทำได้ดังนี้:

ฉันมีรหัสเวอร์ชันที่แก้ไขringsซึ่งตั้งชื่อแล้วซึ่งจะส่งกลับความกว้างของภาพที่สร้างขึ้น ดังนั้นผลลัพธ์ของลูปต่อไปนี้คือขนาดสูงสุดที่นี่182 :

 (loop for x from 1 to 400
       maximize (rings x (format nil "/tmp/rings/ring~3,'0d.png" x)))

วนรอบทั้งหมดใช้เวลา 9.573 วินาที ที่ให้ประมาณ 24ms สำหรับแต่ละจำนวนเต็ม จากนั้นในเปลือก:

 convert -delay 5 -loop 0 -gravity center -extent 182x182 ring*png anim.gif

Ungolfed

(ql:quickload :vecto)
(use-package :vecto)

(lambda (n o)
  (loop with r = 3
        for c across (format nil "~@R" n)
        for l = (1+ (* 2(position c"IVXLCDM")))
        for h = (/ l 2)
        collect `(,(incf r h),l) into p
        do (incf r (+ h 3))
        finally (with-canvas(:width (* 2 r) :height (* 2 r))
                  (loop for (x y) in p
                        do (set-line-width y)
                           (centered-circle-path r r x)
                           (stroke))
                  (save-png o))))

คำอธิบาย

  • ฟังก์ชั่นใช้จำนวนเต็มNตั้งแต่ 1 ถึง 3999 และชื่อไฟล์

  • ฉันใช้(format nil "~@R" N)ในการแปลงจากทศนิยมเป็นโรมัน ตัวอย่างเช่น:

     (format nil "~@R" 34) => "XXXIV"
    

    ~@R สตริงควบคุมรูปแบบที่ระบุไว้ในการทำงานสำหรับจำนวนเต็มระหว่าง 1 และ 3999. นั่นเป็นเหตุผลที่มีข้อ จำกัด สำหรับช่วงของปัจจัยการผลิตที่ได้รับอนุญาต

  • ฉันวนซ้ำสตริงที่สร้างรายการPที่มี(radius width)คู่รักสำหรับแต่ละเลข C

    • ความกว้างคือการจับคู่เชิงเส้นอย่างง่าย: ฉันใช้สตริงคงที่ "IVXLCDM" เพื่อคำนวณตำแหน่งของ C ในนั้น คูณด้วยสองและบวกหนึ่งเราได้ค่าที่ต้องการ:

             (1+ (* 2 (position c "IVXLCDM")))
      

      อย่างไรก็ตามเรื่องนี้ทำแตกต่างกันเล็กน้อยในรุ่น golfed:

             (position c " I V X L C D M")
      
    • การคำนวณรัศมีแต่ละครั้งนั้นคำนึงถึงความกว้างของแต่ละวงแหวนเช่นเดียวกับช่องว่างระหว่างวงแหวน หากไม่มีการปรับความเร็วให้เหมาะสมการคำนวณยังคงแม่นยำเพราะไม่ได้อิงกับการลอย แต่เป็นจำนวนตรรกยะ

      แก้ไข : ฉันเปลี่ยนพารามิเตอร์เพื่อให้สอดคล้องกับกฎการขยาย

  • เมื่อเสร็จแล้วฉันก็รู้ขนาดที่ต้องการของผืนผ้าใบที่เกิดขึ้น (รัศมีการคำนวณล่าสุดสองเท่า)

  • ในที่สุดฉันวาดวงกลมสำหรับแต่ละองค์ประกอบPและบันทึกผืนผ้าใบ

1
"รหัสนี้รองรับตัวเลขโรมัน (IVXLCDM) ทั้งหมด" หมายความว่าโปรแกรมของคุณใช้ตัวเลขโรมันเป็นอินพุตหรือไม่ นั่นไม่ใช่สิ่งที่ฉันตั้งใจ แต่เจ๋งมาก อุปกรณ์ประกอบฉากสำหรับแอนิเมชันเช่นกัน
Rip Leeb

1
ไม่ไม่ขอโทษถ้ามันไม่ชัดเจน: มันทำงานได้กับจำนวนเต็มใด ๆ ระหว่าง 1 ถึง 3999 ในคำถามของคุณคุณต้องการเพียงอินพุตจาก 1 ถึง 100 และตารางของคุณไม่ได้พูดถึง D หรือ M ... ฉันจะแก้ไขสิ่งนั้น ส่วนหนึ่ง
coredump

8

HTML + JQuery, 288

HTML

<canvas>

JS

    r=3;w=9;c=$('canvas').get(0).getContext('2d')
    for(i=prompt(),e=100;e-.1;e/=10){
    if((x=Math.floor(i/e)%10)==4)d(w)+d(w+2)
    else if(x==9)d(w)+d(w+4)
    else{if(x>4)d(w+2)
    for(j=x%5;j;j--)d(w)}
    w-=4}
    function d(R){c.lineWidth=R
    c.beginPath()
    c.arc(150,75,r+=R/2,0,7)
    c.stroke()
    r+=R/2+3}

ซอ


ไม่มีส่วนย่อยหรือไม่
เครื่องมือเพิ่มประสิทธิภาพ

@Optimizer ลืมไปแล้วว่าตอนนี้เรามีแล้ว
TwiNight

5

Java, 565

import java.awt.*;class Z{public static void main(String[]s){int i=new Byte(s[0]),j=i/10,k=i%10;String t="",u;if(j>8)t="59";if(j>9)t="9";if(j==4)t="57";else if(j<9){t=j>4?"7":"";j-=j>4?5:0;if(j>0)t+="5";if(j>1)t+="5";if(j>2)t+="5";}if(k>8)t+="15";if(k==4)t+="13";else if(k<9){t+=k>4?"3":"";k-=k>4?5:0;if(k>0)t+="1";if(k>1)t+="1";if(k>2)t+="1";}u=t;Frame f=new Frame(){public void paint(Graphics g){g.setColor(Color.BLACK);int x=0;for(char c:u.toCharArray()){int z=c-48,q=x;for(;x<q+z;)g.drawOval(99-x,99-x,x*2,x++*2);x+=3;}}};f.setSize(200,200);f.setVisible(1>0);}}

ตัวอย่าง

15

15

84

84

93

93

รูปแบบที่ดี:

import java.awt.*;    
class Z {    
    public static void main(String[] s) {
        int i = new Byte(s[0]), j = i / 10, k = i % 10;
        String t = "", u;
        if (j > 8)
            t = "59";
        if (j > 9)
            t = "9";
        if (j == 4) {
            t = "57";
        } else if (j < 9) {
            t = j > 4 ? "7" : "";
            j -= j > 4 ? 5 : 0;
            if (j > 0)
                t += "5";
            if (j > 1)
                t += "5";
            if (j > 2)
                t += "5";
        }
        if (k > 8)
            t += "15";
        if (k == 4) {
            t += "13";
        } else if (k < 9) {
            t += k > 4 ? "3" : "";
            k -= k > 4 ? 5 : 0;
            if (k > 0)
                t += "1";
            if (k > 1)
                t += "1";
            if (k > 2)
                t += "1";
        }
        u = t;
        Frame f = new Frame() {
            public void paint(Graphics g) {
                g.setColor(Color.BLACK);
                int x = 0;
                for (char c : u.toCharArray()) {
                    int z = c - 48, q = x;
                    for (; x < q + z;) {
                        g.drawOval(99 - x, 99 - x, x * 2, x++ * 2);
                    }
                    x += 3;
                }
            }
        };
        f.setSize(200, 200);
        f.setVisible(1 > 0);
    }
}

กรุณาโพสต์ผลลัพธ์ไม่กี่ ขออภัยที่ไม่ได้ถามที่นี่เป็นที่แรก
Rip Leeb

3

Mathematica 9 - 301 249 ไบต์

: D มันให้ความรู้สึกโกงที่จะใช้ตัวแปลงเป็นตัวเลขโรมัน แต่ในตัว

l=Length;k=Characters;r@n_:=(w=Flatten[Position[k@"IVXLC",#]*2-1&/@k@IntegerString[n,"Roman"]];Show[Table[Graphics@{AbsoluteThickness@w[[i]],Circle[{0,0},(Join[{0},Accumulate[3+w]]+3)[[i]]+w[[i]]/2]},{i,Range@l@w}],ImageSize->{(Total@w+(l@w)*3)*2}])

(เมื่อฉันทำเมื่อคืนนี้ฉันไม่มีเวลามากนัก แต่ฉันก็รู้ว่ามันอาจจะลงเล่นกอล์ฟได้มากขึ้นและฉันก็เอาคำแนะนำจาก David Zhang ... : D ขอบคุณ!)

ชัดเจนขึ้นอีกเล็กน้อย:

l=Length;
k=Characters;
r@n_:=
    (
    w=Flatten[Position[k@"IVXLC",#]*2-1&/@k@IntegerString[n,"Roman"]];
    Show[Table[Graphics@{AbsoluteThickness@w[[i]],Circle[{0,0},(Join[{0},Accumulate[3+w]]+3)[[i]]+w[[i]]/2]},{i,Range@l@w}],ImageSize->{(Total@w+(l@w)*3)*2}]
    )

นี่คือฟังก์ชั่นที่คุณสามารถเรียกได้ว่า:

r[144]

ป้อนคำอธิบายรูปภาพที่นี่

หรือคุณสามารถแสดงผลลัพธ์จากค่าaถึงbด้วย:Table[r[i],{i,a,b}]

หมายเหตุ : ใช้งานได้กับค่าสูงสุด 399 เท่านั้น


1

Python 2, 322 296

สคริปต์จะอ่านตัวเลขที่จะถูกแปลงจาก stdin และส่งภาพเป็นมาร์กอัป SVG

.. ฉันใช้ 'แดง' แทน 'ดำ' เพราะมันช่วยประหยัด 2 ตัวอักษร :)

นี่คือตัวอย่างบางส่วน: สำหรับ 23: http://jsfiddle.net/39xmpq49/ สำหรับ 42: http://jsfiddle.net/7Ls24q9e/1/

i=input();r=9
def R(n,p):
 global r,i;i-=n;print '<circle r="{0}" stroke-width="{1}"/>'.format(r,p);r+=p+3
print '<svg viewBox="-50 -50 99 99" fill="none" stroke="red">',[[R(n,int(p)) for p in s*int(i/n)] for n,s in zip([100,90,50,40,10,9,5,4,1],'9/59/7/57/5/15/3/13/1'.split('/'))]and'','</svg>'

1

JavaScript 342 334 308

function R(n){var v=document,o=[],x=1,c=v.body.appendChild(v.createElement('canvas')).getContext('2d')
while(n)v=n%10,y=x+2,o=[[],[x],[x,x],[x,x,x],[x,y],[y],[y,x],[y,x,x],[y,x,x,x],[x,x+=4]][v].concat(o),n=(n-v)/10
v=3
while(x=o.shift())c.lineWidth=x,c.beginPath(),c.arc(150,75,v+x/2,0,7),c.stroke(),v+=x+3}

for (var i = 1; i <= 100; i++) {
  R(i);
}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.