Вызов Кода - Нарисуй Снежинку

  • Автор темы Gomaalogs
  • Обновлено
  • 22, Oct 2024
  • #1

Джо живет на Багамах. Сейчас зима. Его дети разочарованы отсутствием снега. Джо нужно сделать снег для своих детей. К счастью, у него есть 3D-принтер. Он планирует сделать из него снежинки. К сожалению, он понятия не имеет, как будет выглядеть снежинка. На самом деле он никогда не видел снежинки! Давайте поможем ему, создав программу, которая автоматически генерирует для него 2d-изображение снежинки.

Вход

Диаметр изображения (в пикселях), процент изображения, которое на самом деле является снежинкой.

Выход

Изображение снежинки необходимого диаметра. Его можно сохранить в файл или отобразить пользователю.

Технические характеристики

Создайте клин с углом 30 градусов. Создайте Броуновское дерево с начальным семенем в острие клина. Отразите клин вокруг центра изображения 12 раз, чтобы создать остальную часть изображения. Снежинка имеет белый цвет. Фон имеет черный цвет.

Подсчет очков

Поскольку существуют разные способы создания броуновского дерева, оценка равна 10 * количество голосов «за» — оценка в гольфе.

Счет в гольфе определяется как количество байтов в программе со следующими бонусами:

-20% Можно произвольно указать симметрию снежинки.

-50% Можно указать форму снежинки. (Благодаря возможности указать соотношение длин сторон клина.)

Побеждает наибольшее количество очков.

Вот изображение того, какой будет форма клина при соотношении примерно 2:

вызов кода - Нарисуй снежинку

Табло:

Мартин Баттнер: 10 * 14 – 409 = -269

Ними: 10 * 1 — 733 * .5 = -356,5

Оптимизатор: 10 * 5 – 648 = -598

Победителем стал Мартин со счетом -269!

#code-challenge #graphical-output #geometry

Gomaalogs


Рег
16 Jan, 2008

Тем
69

Постов
193

Баллов
568
  • 26, Oct 2024
  • #2

Математика, 409 байт

 
 
 
 
 
 
   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(); 
 

Негольфед:

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

Это ожидает ввода формы ./sf 150 50 40 where <input placeholder="Вход N" id=X /><input placeholder="Процент ввода" id=Y /><button onclick="f(~~X.value,~~Y.value)">Create snowflake</button><br> <canvas id=E><canvas id=D> — размер изображения в пикселях, а 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()} is the percentage of the image to be covered by the snowflake.

Генерация снежинки с заданными параметрами занимает где-то полминуты. Вы можете ускорить его, изменив значение f from {999, 0} к 99 , but then the result looks a bit sparse. Likewise, you can crank up the quality by using larger numbers, but then it'll take very long.

Я формирую броуновское дерево на целочисленной решетке, помещая новые частицы в 999 , and moving the randomly to the left and up or down (not to the right), until they hit the existing particles. I'm also constraining the motion to the wedge between 0 and 30 degrees. Finally, I reflect that wedge on the x-axis, and display it with its 5 rotations.

Вот некоторые результаты (нажмите, чтобы увеличить версию):

А вот две анимации роста броуновского дерева (по 10 частиц на клин в кадре):

 

Dauk


Рег
06 May, 2005

Тем
95

Постов
211

Баллов
686
  • 26, Oct 2024
  • #3

JavaScript, ES6, 799 740 695 658 648

Я считаю только два тега холста и функцию m from the snippet below as part of the byte count. Остальное предназначено для живой демонстрации.

Чтобы увидеть это в действии, просто запустите приведенный ниже фрагмент в последней версии Firefox, указав размер и соотношение через поля ввода.

Обратите внимание, что вам придется скрыть результат, а затем показать его снова перед следующей снежинкой.

p n

Вот несколько примеров рендеров с разным размером и процентами. Самый лучший называется ЧерепЧешуйка (первый в списке). Нажмите на изображения, чтобы увидеть их в полном разрешении.

Большая помощь и вклад от Мартина и githubphagocyte.

 

Ivan_Petrov


Рег
16 Oct, 2011

Тем
73

Постов
186

Баллов
601
  • 26, Oct 2024
  • #4

Хаскелл, 781 733 байт

В программе есть опция «указать соотношение длин сторон клина», поэтому вызывать ее нужно с тремя аргументами командной строки:

{n,p}

Аргумент №1 — это размер изображения, №2 — процент пикселей в сегменте и №3 — длина (в %) более короткой стороны сегмента. Изображение сохраняется в файле с именем «o.png».

150-50-40:

Моя программа создает снежинки с обрезанными шипами, потому что новые пиксели начинаются на средней оси клина (зеленая точка, см. ниже) и имеют тенденцию оставаться там, потому что они одинаково случайно движутся влево, вверх или вниз. Когда пиксели за пределами сегмента отбрасываются, на границе сегмента появляются прямые линии (зеленая стрелка). Мне было лень пробовать другие пути для пикселей.

150-50-40:

Когда клин достаточно велик (3-й аргумент 100), шипы на средней оси могут вырасти, и тогда их станет 12.

150-40-100:

Несколько пикселей образуют круглые формы (слева: 150-5-20; справа 150-20-90).

Программа:

{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 ] ||answer||

Обработка 2–575 символов

Принимает файл f, первая строка которого — размер изображения, а вторая — радиус чешуек.

{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]

Каждый раз, когда размещается новая точка, она вращается вокруг центра 12 раз. Это создает очень похожий эффект на вращающийся клин, но не совсем такой же. вы можете получить обработку

 

Gorpheus


Рег
16 Mar, 2011

Тем
60

Постов
198

Баллов
538
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно