วาดเกล็ดหิมะ


18

โจอาศัยอยู่ที่บาฮามาส ฤดูหนาว. ลูก ๆ ของเขารู้สึกผิดหวังที่ไม่มีหิมะตก โจต้องทำหิมะให้ลูก โชคดีที่เขามีเครื่องพิมพ์ 3 มิติ เขาวางแผนที่จะทำเกล็ดหิมะด้วย น่าเสียดายที่เขาไม่รู้ว่าเกล็ดหิมะจะมีลักษณะอย่างไร จริงๆแล้วเขาไม่เคยเห็นเกล็ดหิมะเลย! ให้เราช่วยเขาด้วยการสร้างโปรแกรมที่สร้างภาพ 2d ของเกล็ดหิมะให้เขาโดยอัตโนมัติ

อินพุต

เส้นผ่านศูนย์กลางของภาพ (เป็นพิกเซล), อัตราร้อยละของภาพที่เป็นเกล็ดหิมะ

เอาท์พุต

รูปภาพของเกล็ดหิมะที่มีเส้นผ่านศูนย์กลางที่ต้องการ สามารถบันทึกเป็นไฟล์หรือแสดงต่อผู้ใช้

ข้อมูลจำเพาะ

สร้างลิ่มที่มีมุม 30 องศา สร้างต้นไม้บราวเนียนด้วยเมล็ดเริ่มต้นที่จุดลิ่ม สะท้อนลิ่มรอบจุดศูนย์กลางของภาพ 12 ครั้งเพื่อสร้างภาพที่เหลือ เกล็ดหิมะมีสีขาว พื้นหลังมีสีดำ

เกณฑ์การให้คะแนน

เนื่องจากมีหลายวิธีในการสร้างผังต้นไม้ Brownian คะแนนคือ 10 * จำนวน upvotes - คะแนนกอล์ฟ

คะแนนกอล์ฟถูกกำหนดให้เป็นจำนวนไบต์ในโปรแกรมด้วยโบนัสต่อไปนี้:

-20% สามารถระบุสมมาตรของเกล็ดหิมะโดยพลการ

-50% สามารถระบุรูปร่างของเกล็ดหิมะ (โดยสามารถระบุอัตราส่วนของความยาวของด้านข้างของลิ่มได้)

คะแนนสูงสุดชนะ

นี่คือภาพที่รูปร่างของลิ่มจะมีอัตราส่วนประมาณ 2:

ลิ่ม

สกอร์:

Martin Buttner: 10 * 14 - 409 = -269

นิ: 10 * 1 - 733 * .5 = -356.5

เครื่องมือเพิ่มประสิทธิภาพ: 10 * 5 - 648 = -598

ผู้ชนะคือ Martin ที่มีคะแนน -269!



9
ฉันไม่เข้าใจว่าทำไมถ้าเราถูกกล่าวหาว่าช่วยเหลือใครบางคนที่ไม่เคยเห็นเกล็ดหิมะรู้ว่าพวกเขามีลักษณะอย่างไรเราควรที่จะทำให้พวกเขามีความสมมาตรในการหมุนของระเบียบ 4 เราควรจะหลอกผู้ชายที่น่าสงสารหรือไม่
Peter Taylor

1
@Conor "คะแนนคือ 10 * จำนวน upvotes - golfscore" โปรแกรมนั้นจะมีคะแนน -300000000 นั่นต่ำมาก
TheNumberOne

1
เวดจ์ 6x60deg! การปรับปรุงสิ่งที่พูดในเวลาที่ความคิดเห็นของ @PeterTaylor แต่จริงๆแล้วคุณต้องการเว็ดจ์ 12x30deg .. 6 สำหรับด้านขวามือของแต่ละจุด 6 จุดและ 6 อันสะท้อนด้านซ้ายของแต่ละจุด BTW ฉันไม่เข้าใจโบนัสที่สอง
Level River St

2
@Optimizer Done ควรชัดเจนขึ้นแล้ว
TheNumberOne

คำตอบ:


16

Mathematica, 409 ไบต์

{n,p}=Input[];m=999;Clear@f;_~f~_=0;0~f~0=1;r=RandomInteger;For[i=0,i<m,++i,For[x=m;y=0,f[x+1,y]+f[x-1,y]+f[x,y+1]+f[x,y-1]<1,a=b=-m;While[x+a<0||y+b<0||(y+b)/(x+a)>Tan[Pi/6],a=-r@1;b=r@2-1];x+=a;y+=b];x~f~y=1];Graphics[{White,g=Point/@Join@@{c=Cases[Join@@Table[{i,j}-1,{i,m},{j,m}],{i_,j_}/;i~f~j>0],c.{{1,0},{0,-1}}},Array[Rotate[g,Pi#/3,{0,0}]&,6]},Background->Black,ImageSize->n*p,ImageMargins->n(1-p)/2]

Ungolfed:

{n,p}=Input[];
m = 999;
ClearAll@f;
_~f~_ = 0;
0~f~0 = 1;
r = RandomInteger;
For[i = 0, i < m, ++i,
  For[x = m; y = 0, 
   f[x + 1, y] + f[x - 1, y] + f[x, y + 1] + f[x, y - 1] < 1,
   a = b = -m;
   While[x + a < 0 || y + b < 0 || (y + b)/(x + a) > Tan[Pi/6],
    a = -r@1;
    b = r@2 - 1
    ];
   x += a;
   y += b
   ];
  x~f~y = 1
  ];
Graphics[
 {White, g = 
   Point /@ 
    Join @@ {c = 
       Cases[Join @@ Table[{i, j} - 1, {i, m}, {j, m}], {i_, j_} /;
          i~f~j > 0], c.{{1, 0}, {0, -1}}}, 
  Array[Rotate[g, Pi #/3, {0, 0}] &, 6]},
 Background -> Black,
 ImageSize -> n*p,
 ImageMargins -> n (1 - p)/2
 ]

สิ่งนี้คาดว่าจะป้อนรูปแบบ{n,p}ที่nขนาดภาพเป็นพิกเซลและpเป็นเปอร์เซ็นต์ของภาพที่จะปกคลุมด้วยเกล็ดหิมะ

ใช้เวลาประมาณครึ่งนาทีในการสร้างเกล็ดหิมะด้วยพารามิเตอร์ที่กำหนด คุณสามารถเร่งความเร็วได้โดยเปลี่ยนค่าmจาก999เป็น99เป็น แต่ผลลัพธ์จะดูเบาบางเล็กน้อย ในทำนองเดียวกันคุณสามารถยกระดับคุณภาพโดยใช้ตัวเลขที่มากขึ้น แต่จากนั้นจะใช้เวลานานมาก

ฉันกำลังสร้างต้นไม้บราวเนียนบนตาข่ายจำนวนเต็มวางอนุภาคใหม่ที่{999, 0}และย้ายแบบสุ่มไปทางซ้ายและขึ้นหรือลง (ไม่ไปทางขวา) จนกว่าพวกเขาจะตีอนุภาคที่มีอยู่ ฉันยัง จำกัด การเคลื่อนไหวของลิ่มระหว่าง 0 ถึง 30 องศา ในที่สุดฉันก็สะท้อนลิ่มนั้นบนแกน x และแสดงผลด้วยการหมุน 5 ครั้ง

นี่คือผลการค้นหาบางส่วน (คลิกเพื่อรุ่นที่ใหญ่กว่า):

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

และนี่คือภาพเคลื่อนไหวสองภาพของการเติบโตของต้นไม้ Brownian (10 อนุภาคต่อลิ่มต่อเฟรม):

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


2
ว้าวฉันชอบ ... ทุกคนจริง ผลลัพธ์เป็นสิ่งที่ดี!
Sp3000

6

JavaScript, ES6, 799 740 695 658 648

ฉันแค่นับแท็กผ้าใบสองรายการเท่านั้นและฟังก์ชั่นfจากตัวอย่างด้านล่างเป็นส่วนหนึ่งของจำนวนไบต์ สิ่งที่เหลือสำหรับการสาธิตสด

หากต้องการดูในเชิงปฏิบัติเพียงแค่เรียกใช้ตัวอย่างด้านล่างใน Firefox ล่าสุดที่มีขนาดและอัตราส่วนผ่านช่องป้อนข้อมูล

โปรดทราบว่าคุณจะต้องซ่อนผลลัพธ์จากนั้นแสดงอีกครั้งก่อนเกล็ดหิมะติดต่อกัน

f=(N,P)=>{E.width=E.height=D.width=D.height=N
E.style.background="#000"
C=D.getContext("2d"),F=E.getContext("2d")
C.strokeStyle='#fff'
M=Math,r=M.random,I=0,n=N/2
C.beginPath()
C.rect(n,n,2,2)
C.fill()
B=_=>{x=n*P/100,y=0,w=[]
do{w.push([x,y])
do{X=2*((r()*2)|0)
Y=2*(((r()*3)|0)-1)
}while(x-X<0||y-Y<0||(y-Y)/(x-X)>.577)
x-=X,y-=Y}while(!C.isPointInPath(n+x,n+y))
I++
w=w.slice(-4)
x=w[0]
C.moveTo(x[0]+n,x[1]+n)
w.map(x=>C.lineTo(n+x[0],n+x[1]))
C.stroke()
E.width=E.height=N
for(i=0;i<12;i++){F.translate(n,n)
i||F.rotate(M.PI/6)
i-6?F.rotate(M.PI/3):F.scale(1,-1)
F.translate(-n,-n)
F.drawImage(D,0,0)}
I<(n*n*P*.22/100)&&setTimeout(B,15)}
B()}
<input placeholder="Input N" id=X /><input placeholder="Input percentage" id=Y /><button onclick="f(~~X.value,~~Y.value)">Create snowflake</button><br>
<canvas id=E><canvas id=D>

นี่คือตัวอย่างบางส่วนที่มีขนาดและเปอร์เซ็นต์แตกต่างกัน หนึ่งที่ดีที่สุดเรียกว่าSkullFlake (ครั้งแรกในรายการ) คลิกที่ภาพเพื่อดูความละเอียดเต็ม

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

ความช่วยเหลือและข้อมูลจาก Martin และ githubphagocyte มากมาย


การดำเนินการนี้จะไม่นำเปอร์เซ็นต์ของรูปภาพที่เต็มไปเป็นอินพุต
TheNumberOne

@TheBestOne คิดเป็นเปอร์เซ็นต์ในบัญชีทันที โปรดทราบว่าเนื่องจากนี่เป็นเกล็ดหิมะจากต้นไม้ Brownian ทั้งเปอร์เซ็นต์และอัตราส่วนสำหรับความยาวของลิ่มจึงแม่นยำในขณะที่บทบาทของการสุ่มอยู่ในการเล่น
เครื่องมือเพิ่มประสิทธิภาพ

สิ่งนี้มีคุณสมบัติเหมาะสมแล้ว
TheNumberOne

1

Haskell, 781 733 Bytes

โปรแกรมมีคุณสมบัติ„ ระบุอัตราส่วนของความยาวด้านข้างของตัวเลือกลิ่ม "ดังนั้นคุณต้องเรียกมันด้วยอาร์กิวเมนต์บรรทัดคำสั่งสามตัว:

./sf 150 50 40

อาร์กิวเมนต์ # 1 คือขนาดของรูปภาพ, # 2% ของพิกเซลในลิ่มและ # 3 ความยาว (เป็น%) ของด้านที่สั้นกว่าของลิ่ม รูปภาพจะถูกบันทึกในไฟล์ชื่อ„ o.png“

150-50-40: 150-50-40

โปรแกรมของฉันสร้างเกล็ดหิมะที่มีหนามแหลมถูกตัดออกเนื่องจากพิกเซลใหม่เริ่มต้นที่แกนกลางของลิ่ม (จุดสีเขียว, ดูด้านล่าง) และมีแนวโน้มที่จะอยู่ที่นั่นเพราะพวกมันเคลื่อนที่แบบสุ่มไปทางซ้ายขึ้นหรือลงอย่างเท่าเทียมกัน เมื่อพิกเซลที่อยู่นอกลิ่มถูกทิ้งเส้นตรงจะปรากฏขึ้นบนขอบเขตของลิ่ม (ลูกศรสีเขียว) ฉันขี้เกียจเกินไปที่จะลองเส้นทางอื่นสำหรับพิกเซล

150-50-40: 150-40-40e

เมื่อลิ่มมีขนาดใหญ่พอ (ข้อโต้แย้งที่ 3 100) แหลมบนแกนกลางสามารถเติบโตได้แล้วมี 12 แห่ง

150-40-100: 150-40-100

พิกเซลน้อยทำให้มีรูปร่างกลม (ซ้าย: 150-5-20; ขวา 150-20-90)

150-5-20 150-20-90

โปรแกรม:

import System.Environment;import System.Random;import Graphics.GD
d=round;e=fromIntegral;h=concatMap;q=0.2588
j a(x,y)=[(x,y),(d$c*e x-s*e y,d$s*e x+c*e y)] where c=cos$pi/a;s=sin$pi/a
go s f w p@(x,y)((m,n):o)|x<1=go s f w(s,0)o|abs(e$y+n)>q*e x=go s f w p o|elem(x-m,y+n)f&&(v*z-z)*(b-q*z)-(-v*q*z-q*z)*(a-z)<0=p:go s(p:f)w(s,0)o|1<2=go s f w(x-m,y+n)o where z=e s;a=e x;b=e y;v=e w/100
main = do 
 k<-getArgs;g<-getStdGen;let(s:p:w:_)=map read k
 i<-newImage(2*s,2*s);let t=h(j 3)$h(\(x,y)->[(x,y),(d$0.866*e x+0.5*e y,d$0.5*e x-0.866*e y)])$take(s*d(q*e s)*p`div`100)$go s[(0,0)]w(s,0)$map(\r->((1+r)`mod`2,r))(randomRs(-1,1)g)
 mapM(\(x,y)->setPixel(x+s,y+s)(rgb 255 255 255)i)((h(j(-3/2))t)++(h(j(3/2))t));savePngFile "o.png" i

@Optimizer: สไปค์อยู่บนแกนกลางของลิ่ม ลิ่มเลื่อนขึ้นและลง 15 องศาไปยังแกน x ใน*-*-100ภาพทั้งสองด้านนั้นจะไปถึงขอบด้านซ้ายของภาพ (ดูภาพที่สองสำหรับตำแหน่งของลิ่ม) มีพิกเซลประมาณครึ่งหนึ่งของด้านข้าง - อีกครึ่งหนึ่งว่างเปล่า
nimi

1
การใช้ตัวนับนี้โปรแกรมของคุณมีความยาว 841 ไบต์
TheNumberOne

@TheBestOne: แท็บกับช่องว่างเมื่อเยื้อง ผมเคยผสมพวกเขาขึ้นเมื่อมีการเพิ่มการเพิ่ม 4 code styleช่องว่างสำหรับ ฉันแก้ไขโพสต์และตั้งค่าแท็บแล้ว แต่ก็ยังคงปรากฏเป็นช่องว่าง ไม่มีใครรู้วิธีการแก้ไขหรือไม่
nimi

@nimi บนเว็บไซต์ TheBestOne ที่เชื่อมโยงมี#ลิงค์แฮชเล็กน้อยซึ่งคุณสามารถคลิกได้ คุณสามารถวางรหัสแบบแท็บของคุณและเชื่อมโยงได้
Sp3000

คุณอาจสร้างลิงก์ไปยังรหัสที่อื่นได้ คุณสามารถใช้ช่องว่างแทนแท็บเยื้อง คุณสามารถรับcode styleโดยการเยื้องช่องว่างทุกบรรทัด 4
TheNumberOne

0

กำลังดำเนินการ 2 - 575 ตัวอักษร

รับไฟล์ f ซึ่งบรรทัดแรกคือขนาดรูปภาพและที่สองคือรัศมีภาพ ทุกครั้งที่มีจุดใหม่จะถูกหมุนรอบจุดศูนย์กลาง 12 ครั้ง สิ่งนี้จะสร้างเอฟเฟกต์ที่คล้ายกันมากเป็นลิ่มหมุน แต่ไม่เหมือนกันทั้งหมด

  int d,w,h,k,l,o,p,x,y;
  String n[] = loadStrings("f.txt");
  d=Integer.parseInt(n[0]);
  h=Integer.parseInt(n[1]);
  size(d,d);
  w=d/2;
  k=l=(int)random(d); 
  background(0);
  loadPixels();
  o=p=0;
  pixels[w*w*2+w]=color(255);
  while(true)
  {
    o=k+(int)random(-2,2);
    p=l+(int)random(-2,2);
    if(p*d+o>d*d-1 || p*d+o<0 || o<0 || o>d){
      k=l=(int)random(d);
    }
    else
    {
      if(pixels[p*d+o]==color(255))
      {
        p=l-w;
        o=k-w;
        if(o*o+p*p>h*h){break;}
        float s,c;
        for(int j=0;j<12;j++)
        {
          s=sin(PI*j/6);
          c=cos(PI*j/6);         
          x=(int)((o*c)-(p*s));
          y=(int)(((p*c)+(o*s)));
          pixels[(int)(d*y+x+w+(w*d))]=color(255);
        }
        k=l=(int)random(d);  
      }
      else
      {
        k=o;
        l=p;
      }
    }
  }
  updatePixels(); 

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

คุณสามารถประมวลผลได้ที่นี่


3
สิ่งนี้ค่อนข้างไม่พอดีกับข้อกำหนด สิ่งนี้จะมีคุณสมบัติถ้าคุณสะท้อนจุดรอบ ๆ ศูนย์แทนที่จะหมุน
TheNumberOne

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