Recinerive Chains


11

Steiner Chains เป็นกลุ่มของ N วงกลมที่แต่ละวงสัมผัสกับวงกลมที่ไม่มีการตัดกัน 2 วงรวมถึงวงกลมก่อนหน้าและถัดไปของโซ่ดังที่เห็นในภาพด้านล่าง:

คำสั่งซื้อ 3 คำสั่ง 5 คำสั่ง 7

ในการท้าทายนี้คุณจะเขียนโปรแกรม / ฟังก์ชั่นที่ดึงโซ่ Steiner วนซ้ำนั่นคือวงกลมของห่วงโซ่ที่กำหนดจะเป็นวงกลมฐานของโซ่ที่ซ้ำอีกครั้ง:

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

ท้าทาย

เขียนโปรแกรม / ฟังก์ชั่นที่ยอมรับขนาดภาพและรายการจำนวนเต็มเพื่อแสดงระดับของวงกลมในแต่ละการวนซ้ำที่ต่อเนื่องของโซ่และเอาท์พุทของภาพด้วยโซ่ Steiner แบบเรียกซ้ำ

อินพุต

โปรแกรม / ฟังก์ชั่นของคุณจะยอมรับ 2 ข้อโต้แย้ง:

  • s - ความกว้างและความสูงของภาพ
  • ls - รายการจำนวนเต็มบวกแสดงถึงจำนวนของวงกลมที่มีอยู่ในการวนซ้ำของโซ่ต่อเนื่องซึ่งเรียงลำดับจากเชนบนสุดไปยังเชนล่างสุด

เอาท์พุต

โปรแกรม / ฟังก์ชั่นของคุณจะแสดงภาพขนาดsx sแสดงห่วงโซ่สทิเนอร์

  • วงกลมฐานระดับบนสุดจะมีขนาดใหญ่เท่ากับภาพที่มีเส้นผ่านศูนย์กลางsอยู่กึ่งกลางภาพ
  • เพื่อทำให้สิ่งต่าง ๆ ง่ายขึ้น 2 ฐานวงกลมของห่วงโซ่สทิเนอร์จะเป็นศูนย์กลางกล่าวคือจุดศูนย์กลางของวงกลมพื้นฐาน 2 วงจะเหมือนกัน
  • กำหนดรัศมีภายนอกRและจำนวนวงกลมในห่วงโซ่NสูตรสำหรับรัศมีภายในR'คือR' = (R-R*sin(pi/N))/(sin(pi/N)+1)
  • วงกลมของโซ่เช่นเดียวกับวงกลมฐานด้านในจะเป็นวงกลมฐานด้านนอกของการทำซ้ำของโซ่ต่อไป
  • ในขณะที่วนรอบวงกลมซ้ำคำสั่งของห่วงโซ่ถัดไปควรสอดคล้องกับค่าถัดไป ls
  • ในขณะที่วนซ้ำผ่านวงในของห่วงโซ่การเรียงลำดับควรจะเหมือนกับลำดับของผู้ปกครอง (ตัวอย่าง [5,2]):
  • คำสั่ง 5.2
  • โซ่ทั้งหมดควรสิ้นสุดการเรียกซ้ำที่ความลึกของความยาว ls
  • การหมุนของโซ่ไม่สำคัญ:
  • การหมุน 1 การหมุน 2
  • อย่างไรก็ตามการหมุนของสายวนซ้ำที่สัมพันธ์กับจุดศูนย์กลางของพ่อแม่ควรจะเหมือนกัน:
  • คำสั่ง 5.2 คำสั่งซื้อไม่ถูกต้อง 5.2
  • วงกลมทั้งหมดควรวาดด้วยโครงร่างหรือการเติมที่มั่นคง
  • ตัวเลือกสีจะถูกนำไปใช้งาน, ประหยัดช่องโหว่ (ตัวอย่างเช่นเติมทุกอย่างด้วยสีเดียวกัน)

ตัวอย่างรัน

(depth of the recursion)^4ในตัวอย่างต่อไปสีจะถูกกำหนดโดย

คุณสามารถหาแหล่งที่มาที่นี่

chain(600,[5,4,3])

5.4.3

chain(600,[11,1,1,1,1,1,1])

11.1.1.1.1.1.1

chain(600,[5,6,7,8,9])

5.6.7.8.9


คำตอบ:


4

Javascript ES6, 379 ไบต์

โซลูชันนี้ใช้เพื่อสร้างตัวอย่างการทำงานในคำถาม

f=(s,ls)=>{with(V=document.createElement`canvas`)with(getContext`2d`)with(Math)return(width=height=s,translate(s/=2,s),(S=(o,d=0,n=ls[d],i=(o-o*sin(PI/n))/(sin(PI/n)+1),r=0)=>{fillStyle=`rgba(0,0,0,${pow(d/ls.length,4)})`;beginPath(),arc(0,0,o,-PI,PI),fill();if(d++<ls.length){S(i,d,n);for(;r<n;++r){save();translate(0,(o+i)/2);S((o-i)/2,d);restore();rotate((2*PI)/n);}}})(s),V)}

Ungolfed:

f=(s,ls)=>{                                        // define function that accepts image dimensions and a list of orders
 with(V=document.createElement`canvas`)            // create canvas to draw on, bring its functions into current scope chain
 with(getContext`2d`)                              // bring graphics functions into current scope chain
 with(Math)return(                                 // bring Math functions into current scope chain
  width=height=s,                                  // set width and height of image
  translate(s/=2,s),                               // center the transform on image
   (S=(o,d=0,                                      // define recursive function that accepts outer radius, depth, and optionally order
       n=ls[d],                                    // default chain order to corresponding order in input list
       i=(o-o*sin(PI/n))/(sin(PI/n)+1),            // calculate inner base circle radius
       r=0)=>{                                     // initialize for loop var
    fillStyle=`rgba(0,0,0,${pow(d/ls.length,4)})`; // fill based on depth
    beginPath(),arc(0,0,o,-PI,PI),fill();          // draw circle
    if(d++<ls.length){                             // if within recursion limit
     S(i,d,n);                                     //   recurse on inner circle
     for(;r<n;++r){                                //   loop through all circles of the chain
      save();                                      //   save transform
      translate(0,(o+i)/2);                        //   translate origin to middle of the 2 base circles
      S((o-i)/2,d);                                //   recurse on chain circle
      restore();                                   //   restore transform
      rotate((2*PI)/n);                            //   rotate transform to next circle in chain
   }}})(s),                                        // begin the recursion
 V)}                                               // return the canvas

หมายเหตุ: fส่งคืนผ้าใบ

ตัวอย่างการรัน (สมมติว่ามีการ<body>ต่อท้าย):

document.body.appendChild(f(600,[13,7,11,5,3]))

ควรถ่ายโอนรูปภาพต่อไปนี้ไปยังหน้า:

เอาท์พุต

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