Код Гольф: рисовать ascii арт-звезды
Поскольку на этой неделе никто не опубликовал код-гольф-вызов, я попробую. Я делаю это, чтобы вы могли делать что-то еще, кроме игры с мечами во время этих долгих циклов компиляции.
Задача:
Нарисуйте звезды ASCII art, заданные тремя числами на стандартном входе (количество спайков, тип звезды (Звезда рисуется путем соединения вершин, которые разделены n вершинами), и диаметр звезды). Примеры:
Input: Input: Input:
5 2 20 7 2 20 7 3 20
Output: Output: Output:
x x x
xx xx x
xx x xx xx xx x
x x x xxxx x xx xx
xx x x xxxxx x x x x xxx
xxxx x x xxxx x x x x x x
x xxx x xx x xx xxx x x x
x x xxxx x x xx x xxxxx xx x
x x xxx x x x x xx xxxxxx
x x x xxx x x x x x xx xxxxxx
x x xx x x x x x x xxx
x x x xxx x x x x xx xxxxxx
x x xxx x x x x xx xxxxxx
x x xxxx x x xx x xxxxx xx x
x xxx x xx x xx xxx x x x
xxxx x x xxxx x x x x x x
xx x x xxxxx x x x x xxx
x x x xxxx x xx xx
xx x xx xx xx x
xx x x x
x x x
Так как растеризация правильно строк может быть Пита для кода-гольф вызов, я оставлю некоторую свободу действий, но не слишком много. Другие примеры:
Достаточно хорошо:
x x x x
xx xx x x
x x x x
x xx xx x x x
x x x
x x x
xxx xxx x x
x x xxxxxxxxxxxxxxxxxxxxx
x x xx x x xx
xx x x xx xx x x xx
x x xxx xxx
xxxxxxxxxxxxxxxxxxxxx xxxxx
x x x xx xx x
x xx xx x
xxx xxx
x x xx x x xx
x
x
Не режет его:
x xx xx
xx x x
xx x x
x x xx xx
xx x x x x
xxxx x x x xx xx x
x xxxx x x
x xxxx x x x
x x xxx xxx xxx
xx x xxxxxx x x
xx x xxxxxx x x
xx xxx xx x x xx
x x xxx x x x
x xxx x xxxxxxxxxxxxxxxxxxxxx
xxx x x x x
xx x x
x x
x x x x
x x
xx
x
Lack of precission Lack of clipping
Веселитесь!
6 ответов:
Рубин -
323 276 304297a,b,c=gets.split.map &:to_i o=(0..c).map{' '*c} m=(1..a).map{|i|r=2*h=Math::PI*i/a [(1+Math.sin(r))*c/2+0.5,(1+Math.cos(r))*c/2]} a.times{|n|j,i,x,y=*m[n],*m[n-b] j,x,i,y=i,y,j,x if k=((i-y)/(j-x))**2>1 s,z=[x,j].sort s.to_i.upto(z){|m|t=i+(m-j)*(i-y)/(j-x) k ?(o[t][m]='x'):(o[m][t]='x')}} puts o x xx x xx x x x x x x xx x x xx xx x x x x x x xxxx x xx xx xxxxxxxxxxxxxxxx xxx x x xxxxx xx x x x xx x x x x x xxx x x xxxxx x x x x x x x x x x x x xxx x xx x xx xxxx x xxx x x x xx x x xxxx x x x x xxxxxx x xx x x x xxx x x xxx x x xxxxx x xx x x x xxx xx x x x xx x xxxxx xx x x xx x xx xx x x xx x xxxx x x x xx x xxx xx x x x xx x xxxx xx x x x x xxx xx xxx x x xxxxx x xx x x xxxx x x x x xxxxxxx x xx x x xxx x xx x xx xxxx x xxx x x x xx x xxx x x xxxxx x x x x x xx x x x x xxx x x x xxxx xx x x x xx x x x x x x x xxxx x x x x xxxxxxxxxxxxxxxx x x x x xx xx x x x xx x x xx x x x xx x x
С# :
555428 символы
using System.Drawing;class P{static void Main(string[]a){int p=int.Parse(a[0]),i=int.Parse(a[1]),l=int.Parse(a[2]),n;var o=System.Console.Out;var b=new Bitmap(l*4/3,l*4/3);var g=Graphics.FromImage(b);g.TranslateTransform(l/8,l/3);for(n=0;n<p;n++){g.DrawLine(Pens.Red,0,0,l,0);g.TranslateTransform(l,0);g.RotateTransform(360*i/p);}for(i=0;i<b.Height;i++,o.WriteLine())for(p=0;p<b.Width;p++)o.Write(b.GetPixel(p,i).A>0?"#":" ");}}
Звезды 5 2 20
# # # # # # # # # # # ##################### ## # # ## # # # # # # # # ## ## ## ## # # # # # ### # # # # # # ## ## # # # # # ## ## # #
OCaml, 659 символов (wc-c).
Использует классический алгоритм Бресенхема для рисования линий, сделанный рекурсивным для развлечения. Сохранить как
stars.ml
и запустить с помощьюecho 5 2 20 | ocaml stars.ml
.let pl b x y=b.(x).[y]<-'x' let ln b x0 y0 x1 y1 = let rec h p x0 y0 x1 y1 = if x0>x1 then h p x1 y1 x0 y0 else( let dx,dy,ys=x1-x0,abs(y1-y0),if y0<y1 then 1 else -1 in let rec k x y e= if x<=x1 then( p y x; if e<dy then k(x+1)(y+ys)(e-dy+dx) else k(x+1)y(e-dy) )in k x0 y0(dx/2) )in if abs(y1-y0)>abs(x1-x0)then h(fun x y->pl b y x)y0 x0 y1 x1 else h(pl b)x0 y0 x1 y1 let f=float let g n s d= let b=Array.init d(fun _->String.make d ' ')in let r=f(d/2)-.0.1 in let k h i=int_of_float(r+.r*.h(6.2831853*.(f(i mod n)/.(f n))))in let x,y=k cos,k sin in for i=0 to n do ln b(x i)(y i)(x(i+s))(y(i+s))done;Array.iter print_endline b let()=Scanf.scanf"%d %d %d"g
Выходы
x x x xx xxx xx xx x x xxx xx x x x x xxxxx x x x x xx x x xxxxxx xx x x x xxx xxxxx x x xxx x x x xxx x x x x x xxxx x x x xx xxxxxxx xx x x x xxx x x xx x xxxxx x x x x xxxx x x x x x xx xxxxxx x x xx xx x x xxx x xxx x x xxx x x x xxx x xxxx x x xxx xx xx x xx xxxx x x xxxx x x xx x xxxxxx x x xxx x x x x x xxxxx x xx x xxxx x x xxx x x x xx x x x x xx x x xxxxxx x x x x xxx x x x xxxxx x x x x xx x xx xxx xx x xx x x xx x x x
Моя первая попытка кодового гольфа...
Python -
550533507484451437 charsСохранить как
k.py
. Выполнить какpython k.py 5 2 20
import sys,math as m A=abs;R=range;X=round p,t,w=map(int,sys.argv[1:]) G=[[' ']*-~w for i in R(w+1)] def L(a,b,c,d): s=A(d-b)>A(c-a) if s:a,b,c,d=b,a,d,c if a>c:a,b,c,d=c,d,a,b f=c-a;e=f/2;y=int(X(b));x=int(X(a)) while x<X(c): e-=A(d-b);p,q=((x,y),(y,x))[s];G[p][q]='x';x+=1 if e<0:y+=(-1,1)[y<d];e+=f r=w/2;k=m.pi*2/p s=[(m.sin(k*i)*r+r,m.cos(k*i)*r+r)for i in R(p+t)] for i in R(p):L(*(s[i]+s[i+t])) for i in G:print''.join(i)
(потенциально можно сохранить еще 2 символа, заменив отступ 2-го уровня вкладками...)
Расширенная версия доступна здесь: http://gist.github.com/591485
Пример вывода:
x x x xx xx x xx x xx x xx x x x x xxxxx xx xx xx x x x xxxx x x x x xxx xxxx x x xxxx x x x x x x x xxx x xxx x xx xxx x x x x x xxxx x x xx x xxxxx xx x x x xxx x x x x xx xxxxxx x x xxx x x x x x xx xxxxx x x x x x x x xx xxx x x x xxx x x x x xx xxxxx x x xxx x x x x xx xxxx x x xxxxx x x xx x xxxxx xx x x xxx x xxx x xx xxx x xx x x xxx x x xxxx x x x x x x xx x x x xxxx x x xx xx x x x x xxxxx xx xx xx x xx x x x x x x
VBScript,
584 511482 байтыЯ также использовал алгоритм Bresenham на линии.
g=Split(WScript.StdIn.ReadAll):t=g(1):d=g(2):ReDim r(d*d) For i=0 To d*d:r(i)=" ":Next c=1.57:u=(d-1)/2:b=c*4/g(0):For i=1 To g(0) Z n:x=g:Z n+c:y=g:Z n-b*t:f=g:Z n-b*t+c:n=n+b s=Abs(g-y)>Abs(f-x):If s Then W x,y:W f,g If x>f Then W x,f:W y,g p=f-x:q=Abs(g-y):h=p\2:v=(y>g)*2+1 For x=x To f:r((s+1)*(y*d+x)-s*(x*d+y))="x" h=h-q:If h<0 Then y=y+v:h=h+p Next:Next:For i=0 To d:WScript.Echo Mid(Join(r,""),i*d+1,d):Next Sub W(a,b):e=a:a=b:b=e:End Sub Sub Z(e):g=Int(u*Cos(e)+u):End Sub
Вывод:
x x x xx xx x xx x xx xxx xx x x x x xxxx x xx xx xx x x xxxxx x x x x xx xxxx x x xxx x x x xx x x xx x x xxx x x x xx xxxxxx x x x x xxx x x xx x xxxx x x x xxx x x x x xx xx xxx xx x xxx x x x xx xx xxxx xx x xx x x x xx xx xxx x x x xxxx x x x x xx xx xxxxxx x x xxx x x xxx x xxxxxxx x xxx x x x x x xxxx x x xxxxx x x xxx x xx xxx x x xx x xx x x xxxxx xx x x x xx x x x xxxx x xx xx xx x x xxx xx x xx xxx x x x x
Расширенный код:
Dim PI, args, output, i PI = 4 * Atn(1) args = Split(WScript.StdIn.ReadAll, " ") output = Join(Star(args(0), args(1), args(2)), vbNullString) For i = 1 To Len(output) Step args(2) WScript.Echo Mid(output, i, args(2)) Next Function Star(spikes, star_type, diameter) Dim result(), i, vertexes(), angle, radius, p1, p2 ReDim result(diameter * diameter - 1) ReDim vertexes(spikes - 1) For i = 0 To UBound(result) result(i) = " " Next radius = (diameter - 1) / 2 For i = 0 To UBound(vertexes) vertexes(i) = Array(CLng(radius * Cos(angle) + radius), _ CLng(radius * Sin(angle) + radius)) angle = angle - (2 * PI / spikes) Next For i = 0 To UBound(vertexes) p1 = vertexes(i) p2 = vertexes((i + star_type) Mod spikes) DrawLine p1(0), p2(0), p1(1), p2(1), result, diameter Next Star = result End Function Sub DrawLine(ByVal x0, ByVal x1, ByVal y0, ByVal y1, arr, diameter) Dim steep, deltax, deltay, error, ystep steep = Abs(y1 - y0) > Abs(x1 - x0) If steep Then Swap x0, y0 Swap x1, y1 End If If x0 > x1 Then Swap x0, x1 Swap y0, y1 End If deltax = x1 - x0 deltay = Abs(y1 - y0) error = deltax \ 2 If y0 < y1 Then ystep = 1 Else ystep = -1 For x0 = x0 To x1 If steep Then arr(x0 * diameter + y0) = "x" Else arr(y0 * diameter + x0) = "x" End If error = error - deltay If error < 0 Then y0 = y0 + ystep error = error + deltax End If Next End Sub Function Swap(a, b) Dim temp temp = a a = b b = temp End Function
Javascript (на основе решения Isc на python),
598591586559 байты (используется с оболочкой rhino: сохранить как ' звезды.js', беги со звездами носорога.js 7 2 20'):for(var a=Math,b=parseInt,c=a.floor,d=a.abs,e=arguments,f=b(e[0]),g=b(e[1]),h=b(e[2]),i=[],j=0;j<(h+1)*h;j++)i.push((j+1)%(h+1)?" ":"\n");function k(w,x){i[x*(h+1)+w]="x"}var l=(h-1)/2,m=[];for(j=0;j<f;j++)m.push([c(l*a.cos(a.PI*2/f*j)+h/2),c(l*a.sin(a.PI*2/f*j)+h/2)]); for(j=0;j<f;j++){var n=m[j][0],o=m[j][1],p=m[(j+g)%f][0],q=m[(j+g)%f][1],r=void 0,s=void 0;if(r=d(q-o)>d(p-n)){s=n;n=o;o=s;s=p;p=q;q=s}if(n>p){s=n;n=p;p=s;s=o;o=q;q=s}for(var t=p-n,u=0,v=d(q-o)/t,y=o<q?1:-1,z=o,A=n;A<=p;A++){r?k(z,A):k(A,z);u+=v;if(u>=0.5){z+=y;u-=1}}}print(i.join(""));
Вывод:
x xx xx x x xx x x xxxx x x x xxx x x x xxx x x xxx xx x xxx xx x xx x x x xxxx x x xxx x xxx x xxxxx x x xx x x x x xx xx x x xx x x xxx x xxxx x xxxxx x x xxx x x x x x xx x x x x x xxx x x x x x x x x x xx x x xx x x x xxx x xxx xxxxx x x x xxxx x x xx xxx xx x x x xx x xx xx x x xx xx x x xx x xxxxxx x x x xxxx x xx xx xxxx xx xx xxxx xx xx xxx xx xx xxxxxx x xxxxxxx x xxxx x x xxx x x xx x x x xx xx xx xx x x xРасширенный код:
var p = parseInt(arguments[0]), t = parseInt(arguments[1]), w = parseInt(arguments[2]); var g = []; for(var i = 0; i < (w + 1) * w; i++) g.push((i + 1) % (w + 1) ? ' ' : '\n'); function plot(x, y) { g[y * (w + 1) + x] = 'x';} function line(x0, y0, x1, y1) { var steep = Math.abs(y1 - y0) > Math.abs(x1 - x0), temp; if(steep) { temp = x0; x0 = y0; y0 = temp; temp = x1; x1 = y1; y1 = temp; } if(x0 > x1) { temp = x0; x0 = x1; x1 = temp; temp = y0; y0 = y1; y1 = temp; } var deltax = x1 - x0; var deltay = Math.abs(y1 - y0); var error = 0; var deltaerr = deltay / deltax; var ystep var y = y0; if(y0 < y1) ystep = 1; else ystep = -1; for(var x = x0; x <= x1; x++) { if(steep) plot(y,x); else plot(x,y); error = error + deltaerr; if(error >= 0.5) { y = y + ystep; error = error - 1.0; } } } var r = (w-1)/2, points = []; for(var i = 0; i < p; i++) { points.push([ Math.floor(r * Math.cos(Math.PI * 2 / p * i) + w/2), Math.floor(r * Math.sin(Math.PI * 2 / p * i) + w/2) ]); } for(var i = 0; i < p; i++) { line(points[i][0], points[i][1], points[((i + t) % p)][0], points[((i + t) % p)][1]); } print(g.join(''));