การแทนแบบกราฟิกของ Koch สโนว์เฟลค


13

สร้างเกล็ดหิมะโคช์ส

เกล็ดหิมะ Koch เป็นสามเหลี่ยมที่แต่ละnจุดมีการเพิ่มจุดอีกด้านหนึ่งไว้ตรงกลางของแต่ละด้าน: http://en.wikipedia.org/wiki/Koch_snowflake#Properties

แล้วเรามี ท้าทายโคช์สโนว์เฟลn=4สำหรับ ความท้าทายใหม่คือการวาดเกล็ดหิมะ Koch กับใด ๆnระหว่างและ110

กฎระเบียบ

เกล็ดหิมะอาจไม่ฮาร์โค้ดในโปรแกรมหรือในไฟล์ - มันจะต้องสร้างโดยโปรแกรมของคุณ

โปรแกรมของคุณต้องรองรับทุกขนาดnตั้งแต่ 1 ถึง 10

จำนวนด้านต้องถูกป้อนโดยผู้ใช้ผ่าน std-in

คุณต้องพิมพ์ภาพกราฟิกเกล็ดหิมะลงบนหน้าจอ

ตัวอย่างเกล็ดหิมะ Koch ที่มีค่าnเท่ากับ 1, 2, 3 และ 4 (เส้นสีเขียวเพื่อความชัดเจนเท่านั้นอย่าทำซ้ำ):

เกล็ดหิมะโคช์ส

ในกรณีที่มีเบรกเกอร์โปรแกรมที่มีจำนวน upvotes มากที่สุดชนะ (การประกวดป๊อป)


ฉันไม่เข้าใจเรื่องนี้: "คุณต้องใช้ฟังก์ชั่นในการคำนวณตำแหน่งที่จะวางพิกเซลถ้าโปรแกรมของคุณไม่มีฟังก์ชั่นในตัวสำหรับจุดประสงค์นี้คุณอาจหักค่าใช้จ่ายจากการใช้หนึ่งคะแนน " พิกเซลอะไร
xnor

@xnor เดิมทีมันหมายถึงการคำนวณวิธีการวาดเกล็ดหิมะบนพื้นฐานต่อพิกเซล / ตัวละคร (ความท้าทายเดิมเป็นความท้าทาย ASCII-art เช่นกัน) คนส่วนใหญ่อาจจะแค่ใช้เส้นดังนั้นฉันจะลบมัน

สามารถวาดเกล็ดหิมะทั้งหมดที่เต็มไปด้วย?
xnor

แน่นอน. ความคิดเห็นนี้จะต้องนานกว่านี้

นอกจากn=7นี้คุณไม่สามารถเห็นสามเหลี่ยมที่เพิ่มเข้ามาใหม่ในเกล็ดหิมะบนหน้าจอคอมพิวเตอร์ "ความพยายามที่ดีที่สุด" ที่นี่ตกลงไหม? มีความละเอียดขั้นต่ำสำหรับวิธีแก้ปัญหาแบบพิกเซลหรือไม่?
xnor

คำตอบ:


7

Mathematica 72

Region@Line@AnglePath[Nest[Join@@({#,1,4,1}&/@#)&,{4,4,4},Input[]-1]π/3]

n = 3

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

ขอบคุณสำหรับ alephalpha


งานที่ดี. เล่นกอล์ฟโดยตัวละครสองตัวและคุณจะชนะ!

@ Hosch250 อัปเดตขอบคุณ
chyanog

คุณสามารถใช้AnglePathใน Mathematica 10.1
alephalpha

@chyaongGraphics@Line@AnglePath[Nest[Join@@({-1,2,-1,#}&/@#)&,{2,2,2},Input[]-1]Pi/3]
alephalpha

1
@alephalpha 73 ตัวอักษร:ListLinePlot@AnglePath[Nest[Join@@({#,1,4,1}&/@#)&,{4,4,4},Input[]-1]π/3]
chyanog

15

MATLAB, 119 115

ในเหตุการณ์ที่ผิดปกติฉันพบว่าโปรแกรมนี้ใช้งานได้ดีกว่าเมื่อฉันเล่นกอล์ฟ ครั้งแรกมันกลายเป็นเร็วขึ้นมากเนื่องจาก vectorization ตอนนี้มันแสดงข้อความ~n:~แจ้งเตือนที่เป็นประโยชน์เพื่อเตือนผู้ใช้ว่าต้องป้อนปริมาณใด!

บรรทัดใหม่ไม่ได้เป็นส่วนหนึ่งของโปรแกรม

x=exp(i*pi/3);
o='~n:~';
P=x.^o;
for l=2:input(o);
P=[kron(P(1:end-1),~~o)+kron(diff(P)/3,[0 1 1+1/x 2]) 1];
end;
plot(P)

n = 9: n = 9

oเป็นสตริงโดยพลการซึ่งเท่ากับ[0 2 4 0]โมดูโล 6. e iπ / 3ยกกำลังเหล่านี้ให้จุดยอดของสามเหลี่ยมด้านเท่าในระนาบเชิงซ้อน ครั้งแรกที่kronใช้ในการทำสำเนาของรายการคะแนนกับแต่ละทำซ้ำ 4 ครั้ง ~~oเป็นวิธีที่สะดวกในการหาเวกเตอร์ 4 ตัว ประการที่สองdiff(P)ค้นหาเวกเตอร์ระหว่างแต่ละจุดที่ต่อเนื่องกัน ทวีคูณของเวกเตอร์นี้ (0, 1/3, (1 + e -iπ / 3 ) / 3 และ 2/3) ถูกเพิ่มเข้าไปในแต่ละจุดเก่า


อืมคุณช่วยอธิบายเพิ่มเติมได้อย่างไรว่ารหัสนี้ทำงานอย่างไร ฉันคิดว่าฉันรู้ Matlab บางอย่าง แต่นี่คือ ... วิกลจริต ?? =)
ข้อบกพร่อง

@flawr ฉันเพิ่มบันทึกย่อไปสองสามข้อนั่นช่วยได้บ้างไหม?
feersum

ขอบคุณมาก! ฉันจะเก็บเคล็ดลับการล่วงละเมิดทางสายนั้นไว้ในใจ =)
ข้อผิดพลาด

9

T-SQL: 686 (ไม่รวมการจัดรูปแบบ)

สำหรับ SQL Server 2012+

ถึงแม้ว่าสิ่งนี้จะไม่เป็นคู่แข่ง แต่ฉันต้องดูว่าฉันสามารถทำได้ใน T-SQL หรือไม่ หายไปสำหรับวิธีการเริ่มต้นด้วยสามขอบเริ่มต้นจากนั้นเรียกซ้ำผ่านแต่ละขอบและแทนที่ด้วย 4 ขอบสำหรับแต่ละระดับ ในที่สุดการรวมกันทั้งหมดเป็นเรขาคณิตเดียวสำหรับระดับที่ระบุสำหรับ @i

DECLARE @i INT=8,@ FLOAT=0,@l FLOAT=9;
WITH R AS(
    SELECT sX,sY,eX,eY,@l l,B,1i
    FROM(VALUES(@,@,@l,@,0),(@l,@,@l/2,SQRT(@l*@l-(@l/2)*(@l/2)),-120),(@l/2,SQRT(@l*@l-(@l/2)*(@l/2)),@,@,-240))a(sX,sY,eX,eY,B)
    UNION ALL
    SELECT a.sX,a.sY,a.eX,a.eY,l/3,a.B,i+1
    FROM R 
        CROSS APPLY(VALUES(sX,sY,sX+(eX-sX)/3,sY+(eY-sY)/3,sX+((eX-sX)/3)*2,sY+((eY-sY)/3)*2))x(x1,y1,x2,y2,x3,y3)
        CROSS APPLY(VALUES(x2+((l/3)*SIN(RADIANS(B-210.))),y2+((l/3)*COS(RADIANS(B-210.)))))n(x4,y4)
        CROSS APPLY(VALUES(x1,y1,x2,y2,B),
            (x3,y3,eX,eY,B),
            (x2,y2,x4,y4,B+60),
            (x4,y4,x3,y3,B-60)
        )a(sX,sY,eX,eY,B)
WHERE @i>i)
SELECT Geometry::UnionAggregate(Geometry::Parse(CONCAT('LINESTRING(',sX,' ',sY,',',eX,' ',eY,')')))
FROM R 
WHERE i=@i

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


ฉันไม่ทราบเลยว่าพ่อมดแม่มดสามารถทำได้ด้วย T-SQL!
Harry Mustoe-Playfair

9

โลโก้: 95

to w:c ifelse:c=1[fd 2 lt 60][w:c-1 w:c-1 lt 180 w:c-1 w:c-1]end
to k:c repeat 3[w:c rt 180]end

กำหนดฟังก์ชั่นkด้วยพารามิเตอร์ระดับเดียว

แก้ไข

ในการแก้ไขออนไลน์นี้http://www.calormen.com/jslogo/คุณสามารถเพิ่มk readwordการใช้พรอมต์สำหรับการป้อนข้อมูล rwแต่ด้วยเหตุผลบางคำสั่งนี้ไม่สนับสนุนมาตรฐานการย่อ

โซลูชัน 102 ตัวอักษรด้านล่างใช้งานได้ใน USBLogo พร้อมอินพุตมาตรฐานตามที่ระบุในคำถาม อย่างไรก็ตามรหัสต้องการการเปลี่ยนแปลงเล็กน้อยเนื่องจาก UCBLogo มีตัวแยกวิเคราะห์แปลก ๆ มันต้องการtoและendอยู่ในบรรทัดที่แยกต่างหากและพื้นที่ก่อน:จำเป็น แต่ในทางกลับกัน:เป็นทางเลือก

to w c
ifelse c=1[fd 2 lt 60][w c-1 w c-1 lt 180 w c-1 w c-1]
end
to k c
repeat 3[w c rt 180]
end
k rw

คุณเรียกใช้โลโก้ได้อย่างไร
Beta Decay

@BetaDecay ฉันใช้สิ่งนี้: logo.twentygototen.orgแต่นี่เป็นครั้งแรกที่ฉันค้นพบ: calormen.com/jslogoนอกจากนี้คุณยังสามารถติดตั้ง USBLogo ได้
Nutki

8

BBC BASIC, 179

REV 1

INPUTn
z=FNt(500,470,0,0,3^n/9)END
DEFFNt(x,y,i,j,a)
LINEx-36*a,y-21*a,x+36*a,y-a*21PLOT85,x,y+a*42IFa FORj=-1TO1FORi=-1TO1z=FNt(x+24*a*i,y+j*14*a*(i*i*3-2),i,j,-j*a/3)NEXTNEXT
=0

เหมือนเมื่อก่อน แต่เป็นขาวดำในรุ่น ungolfed (แต่คล่องตัว) และรุ่น golfed ไม่ใช่ผู้ชนะแม้จะมีความจริงที่ว่าการทำอย่างนี้จะช่วยหลีกเลี่ยงความจำเป็นในการใช้ treament แบบพิเศษสำหรับ n = 1

  INPUTn
        REM call function and throw return value away to z
  z=FNt(500,470,0,0,3^n/9)
  END

        REM x,y=centre of triangle. a=scale.
        REM loop variables i,j are only passed in order to make them local, not global.
  DEFFNt(x,y,i,j,a)

        REM first draw a line at the bottom of the triangle. PLOT85 then draws a filled triangle,
        REM using the specified point (top of the triangle) and the last two points visited (those used to draw the line.)
  LINEx-36*a,y-21*a,x+36*a,y-21*a
  PLOT85,x,y+42*a

        REM if the absolute magnitude of a is sufficient to be truthy, recurse to the next level.
        REM j determines if the triangle will be upright, inverted or (if j=0) infinitely small.
        REM i loops through the three triangles of each orientation, from left to right.
  IFa FORj=-1TO1 FORi=-1TO1:z=FNt(x+24*a*i,y+j*14*a*(i*i*3-2),i,j,-j*a/3):NEXT:NEXT

        REM return 0
  =0

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

REV 0

ตามคำตอบของ OP ต่อ @xnor เกล็ดหิมะตกลง คำตอบนี้ได้แรงบันดาลใจจากความคิดเห็นของ xnor สีเป็นเพียงเพื่อความสนุกสนานและเพื่อแสดงวิธีการสร้าง ใช้สามเหลี่ยม (สีม่วงแดงในกรณีนี้) และ overplot ด้วย 6 สามเหลี่ยม 1/3 ของฐาน

  INPUTn
  z=FNt(500,470,n,1,0,0)
  END

  DEFFNt(x,y,n,o,i,a)
  a=3^n/22
  GCOLn
  MOVEx-36*a,y-o*21*a
  MOVEx+36*a,y-o*21*a
  PLOT85,x,y+o*42*a
  IFn>1FORi=-1TO1:z=FNt(x+24*a*i,y+14*a*(i*i*3-2),n-1,-1,i,a):z=FNt(x+24*a*i,y-14*a*(i*i*3-2),n-1,1,i,a)NEXT
  =0

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


1
ฉันชอบที่ดูเหมือนว่า 7 คนจะรวมเข้าด้วยกัน

@ hosch250 ที่จริงฉันดูเหมือนจะมี "คิดค้น" เศษส่วนใหม่ที่มีเงาเกิดขึ้นเป็นเกล็ดหิมะ Koch และถ้าคุณลบส่วนสีม่วงแดงที่คุณเหลืออยู่ด้วยเกล็ดหิมะ Koch ขนาดเล็ก 6 ตัว รุ่น golfed จะเป็นเพียงเงาดำธรรมดา แต่ฉันจะปล่อยให้ภาพนี้ขึ้นเช่นกัน
เลเวลริเวอร์เซนต์

คุณเขียน BBC Basic หรือ BBC BASIC หรือไม่ ฉันไปที่หลัง แต่ฉันไม่รู้ว่ามันถูกต้องหรือไม่
Beta Decay

2
@BetaDecay BASIC เป็นตัวย่อสำหรับรหัสการเรียนการสอนมาตรฐาน / สัญลักษณ์อเนกประสงค์ บิต "มาตรฐาน" เป็นที่ถกเถียงกันเนื่องจากมีหลายรุ่น en.wikipedia.org/wiki/BASIC BASIC ส่วนใหญ่ต้องการเวอร์ชั่นที่เป็นตัวพิมพ์ใหญ่ แต่ตามหน้า Wikipedia แล้ว Visual Basic ต้องการตัวพิมพ์เล็ก ฉันคิดว่า BBC BASIC เนื่องจากการจัดส่งเป็นตัวพิมพ์ใหญ่ ผมใช้รุ่นที่bbcbasic.co.uk/bbcwin/bbcwin.html มันเป็นตัวพิมพ์ใหญ่ในเว็บไซต์และ IDE ดังนั้นฉันว่ารุ่นตัวพิมพ์ใหญ่นั้นถูกต้องมากกว่า แต่ฉันไม่คิดว่ามันสำคัญมาก
เลเวลริเวอร์เซนต์

อ่าโอเคฉันจะดำเนินการต่อกับเวอร์ชันตัวพิมพ์ใหญ่
Beta Decay

8

Mathematica - 177

r[x_, y_] := Sequence[x, RotationTransform[π/3, x]@y, y]
Graphics@Polygon@Nest[
 ReplaceList[#, {___, x_, y_, ___}  Sequence[x,r[2 x/3 + y/3, 2 y/3 + x/3], y]
  ] &, {{0, 0}, {.5, √3/2}, {1, 0}, {0, 0}}, Input[]]

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

โบนัสคลิปของการเปลี่ยนมุมของชิ้นกลาง

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


6

Python 3 - 139

ใช้ไลบรารีกราฟิกเต่า

from turtle import*
b=int(input())
a=eval(("FR"*3)+".replace('F','FLFRFLF')"*~-b)
for j in a:fd(9/b*("G">j));rt(60*(2-3*("Q">j))*("K"<j))])

เย็น. ฉันชอบวิธีการตามสตริงของคุณในการค้นหารูปร่างที่มีโค้ดไม่เกินสองบรรทัด! แต่คุณไม่สามารถตรวจสอบ"G">j, "Q"<jและใช้fd(9/b)ในการบันทึก 3 ไบต์? นอกจากนี้คุณสามารถหลีกเลี่ยงifงบคูณเช่น("G">j)มีการโต้แย้งและนำพวกเขาทั้งหมดในสายหลังหนึ่ง9/b forOh! จากนั้นคุณสามารถรวมrtและltใช้งานได้120*(...)-60*(...)
Falko

ปรากฏขึ้นเพื่อแสดงอินพุต Koch เกล็ดหิมะ + 1 อินพุต 1 ควรเป็นรูปสามเหลี่ยมเหมือนภาพด้านบนแสดง

@Falko ขอบคุณสำหรับความช่วยเหลือทั้งหมด!
Beta Decay

@ hosch250 แก้ไข
เบต้าผุ

ตอนนี้มันไม่ได้วาดอะไรเลยและอินพุต 1 สร้างการหารด้วย 0 ข้อผิดพลาด

4

Python 3, 117 ไบต์

from turtle import*
ht();n=int(input())-1
for c in eval("'101'.join("*n+"'0'*4"+")"*n):rt(60+180*(c<'1'));fd(99/3**n)

วิธี:

  • วิธีการแก้ปัญหาใช้กราฟิกเต่า Python
  • n คือ input - 1
  • เริ่มต้นจากสตริงที่0000เราเข้าร่วมทุกตัวละครกับ101 nเวลาซ้ำกับเคล็ดลับ eval (ขอบคุณ @xnor สำหรับที่)
  • สำหรับตัวละครในสตริงสุดท้ายทุกครั้งที่เราเปิด 60 องศาไปทางขวาหรือซ้าย 120 องศาขึ้นอยู่กับค่าตัวอักษร ( 1หรือ0) แล้วก้าวไปข้างหน้าความยาว ( 99/3^n) ซึ่งรับประกันขนาดใกล้เคียงกันสำหรับทุกnท่าน
  • สุดท้าย0ในสตริงจะไร้ประโยชน์ แต่มันก็แค่วาดเส้นเดิมที่0วาดครั้งแรก

ตัวอย่างผลลัพธ์สำหรับinput = 3:

Koch


2

R: 240 175

เพราะฉันพยายามเอาหัวไปรอบ ๆ R นี่เป็นอีกเวอร์ชั่นหนึ่ง มีแนวโน้มที่จะมีวิธีที่ดีกว่าในการทำเช่นนี้และฉันยินดีที่จะรับพอยน์เตอร์ สิ่งที่ฉันทำดูเหมือนจะซับซ้อนมาก

n=readline();d=c(0,-120,-240);c=1;while(c<n){c=c+1;e=c();for(i in 1:length(d)){e=c(e,d[i],d[i]+60,d[i]-60,d[i])};d=e};f=pi/180;plot(cumsum(sin(d*f)),cumsum(cos(d*f)),type="l")

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


2

ปรีชาญาณ fwom youw gwave ...

ฉันรู้ว่าฉันต้องการลองใช้สิ่งนี้ใน Befunge-98 โดยใช้ TURT แต่ฉันไม่สามารถรู้ได้ว่าจะทำยังไงและฉันก็นั่งอยู่เป็นเวลาหลายเดือน ตอนนี้เมื่อไม่นานมานี้ฉันคิดหาวิธีที่จะทำได้โดยไม่ต้องดัดแปลงตัวเอง! และดังนั้น ...

Befunge-98 ด้วย TURT ลายนิ้วมือ 103

;v;"TRUT"4(02-&:0\:0\1P>:3+:4`!*;
>j$;space makes me cry;^
^>1-:01-\:0\:01-\:0
0>I@
^>6a*L
^>ca*R
^>fF

มาดูรายละเอียดการใช้งานกันก่อน:

  • ฉันทดสอบสิ่งนี้โดยใช้CCBI 2.1ซึ่งมีการนำ TURT (ลายนิ้วมือกราฟิกเต่า) ทำให้I"พิมพ์" ภาพไปยังไฟล์ SVG หากคุณรันสิ่งนี้ใน CCBI โดยไม่มีคำสั่งอาร์กิวเมนต์--turt-line=PATHมันจะออกมาเป็นไฟล์ชื่อ CCBI_TURT.svg โดยค่าเริ่มต้น นี่คือสิ่งที่ใกล้เคียงที่สุดที่ฉันสามารถหาได้"พิมพ์ภาพกราฟิกของเกล็ดหิมะบนหน้าจอ"ด้วยล่าม Funge ที่ฉันหาได้ บางทีสักวันหนึ่งอาจมีล่ามที่ดีกว่าที่มีจอแสดงผลกราฟิกสำหรับเต่า แต่ตอนนี้ ...
  • จะต้องมีการขึ้นบรรทัดใหม่ในตอนท้ายเพื่อให้ CCBI รันได้โดยไม่ต้องหยุดสาย (รวมอยู่ในจำนวนอักขระ) ฉันรู้ใช่มั้ย

โดยพื้นฐานแล้วสิ่งนี้จะทำงานได้โดยใช้ stack เป็นระบบ L-makeshift และขยายได้ทันที ในแต่ละรอบถ้าหมายเลขบนสุดของสแต็กคือ:

  • -2 จากนั้นจะพิมพ์และหยุด
  • -1 เต่าหมุนทวนเข็มนาฬิกา 60 องศา
  • 0 มันหมุนตามเข็มนาฬิกา 120 องศา;
  • 1 มันไปข้างหน้า (15 พิกเซลที่นี่ แต่คุณสามารถเปลี่ยนได้โดยการแก้ไขfในบรรทัดสุดท้าย);
  • บางหมายเลขnที่ 2 n-1, -1, n-1, 0, n-1, -1, n-1หรือมากกว่านั้นก็จะขยายตัวในกองไป

สำหรับn = 10กระบวนการนี้ใช้เวลานานมาก (สองสามนาทีในระบบของฉัน) และ SVG ที่ได้คือขนาด ~ 10MB และมองไม่เห็นเมื่อดูในเบราว์เซอร์เนื่องจากคุณไม่สามารถปรับขนาดของแปรงโดยใช้ TURT ดูเหมือนว่า IrfanView จะทำงานได้ดีถ้าคุณมีปลั๊กอินที่ถูกต้อง ฉันไม่คุ้นเคยกับ SVG มากนักดังนั้นฉันจึงไม่ทราบว่าวิธีที่ต้องการใช้สำหรับดูไฟล์เหล่านั้นคืออะไร (โดยเฉพาะเมื่อพวกเขาใหญ่มาก)

เฮ้อย่างน้อยก็ใช้งานได้ - ซึ่งเมื่อพิจารณาว่าเป็น Befunge เป็นสิ่งที่ต้องขอบคุณสำหรับตัวมันเอง


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