Language agnostic 代码高尔夫:画ascii艺术明星
由于本周没有人发布代码高尔夫挑战赛,我将试一试。我这样做是为了让你在漫长的编译周期中除了玩剑之外还能做些别的事情 挑战: 绘制ASCII艺术星星,在标准输入上给出三个数字(尖峰数、星星类型(通过连接相隔n个顶点的顶点绘制星星)和星星直径)。示例:Language agnostic 代码高尔夫:画ascii艺术明星,language-agnostic,code-golf,rosetta-stone,Language Agnostic,Code Golf,Rosetta Stone,由于本周没有人发布代码高尔夫挑战赛,我将试一试。我这样做是为了让你在漫长的编译周期中除了玩剑之外还能做些别的事情 挑战: 绘制ASCII艺术星星,在标准输入上给出三个数字(尖峰数、星星类型(通过连接相隔n个顶点的顶点绘制星星)和星星直径)。示例: Input: Input: Input: 5 2 20 7 2 20
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
由于正确地光栅化线条对于代码高尔夫挑战来说是一个PITA,我会留下一些余地,但不会太多。更多示例:
很好:
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
玩得开心 OCaml,659个字符(wc-c) 使用经典的Bresenham算法绘制线条,使其具有递归的乐趣。 另存为
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
我第一次尝试代码高尔夫 Python-550 533 507 484 451 437个字符 另存为
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)
VBScript,584 511 482字节
我还对线条使用了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
扩展代码:
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
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(''));
Dim PI,args,输出,i
PI=4*Atn(1)
args=Split(WScript.StdIn.ReadAll,“”)
输出=连接(星形(args(0)、args(1)、args(2)),vbNullString)
对于i=1到Len(输出)步骤args(2)
Echo Mid(输出,i,参数(2))
下一个
功能星形(尖峰、星形、直径)
尺寸结果(),i,顶点(),角度,半径,p1,p2
重读结果(直径*直径-1)
重读顶点(尖峰-1)
对于i=0到UBound(结果)
结果(i)=“
下一个
半径=(直径-1)/2
对于i=0到UBound(顶点)
顶点(i)=阵列(CLng(半径*Cos(角度)+半径)_
CLng(半径*Sin(角度)+半径))
角度=角度-(2*PI/尖峰)
下一个
对于i=0到UBound(顶点)
p1=顶点(i)
p2=顶点((i+星型)Mod尖峰)
抽绳p1(0),p2(0),p1(1),p2(1),结果,直径
下一个
星=结果
端函数
副抽绳(ByVal x0、ByVal x1、ByVal y0、ByVal y1、arr、直径)
暗陡坡、三角洲、三角洲、错误、ystep
陡峭=Abs(y1-y0)>Abs(x1-x0)
如果陡峭的话
互换x0,y0
交换x1,y1
如果结束
如果x0>x1,则
交换x0,x1
互换y0,y1
如果结束
deltax=x1-x0
deltay=Abs(y1-y0)
错误=deltax\2
如果y0
Ruby-323276304297
Javascript(基于Isc的python解决方案),598 591 586 559字节(与rhino shell一起使用:另存为'stars.js',与'rhino stars.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;jx1){
温度=x0;x0=x1;x1=温度;
温度=y0;y0=y1;y1=温度;
}
增值税=x1-x0;
var deltay=数学绝对值(y1-y0);
var误差=0;
var deltaerr=三角洲/三角洲税;
var ystep
var y=y0;
如果(y0
C#:555 428个字符
使用系统图;类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.frommage(b);g.TranslateTransform(l/8,l/3);for(n=0;允许使用像6220这样的星星吗?是的,那是大卫的星星。示例输出中的星星直径似乎是21而不是20?@lsc:oops,似乎我的星星有点偏了。捕捉得好!很好,尽管它需要对8220进行一个小的修复。真的很好,我喜欢在更大的星星上的结果,比如301290hm,真的,8220在我的solu上失败了(注)我在想…看起来像是为了让星星好看,寻找任何参数都太难解决了(可能是+100个字符)@纳基隆:我觉得你的8220星看起来还不错。@ninjalj,带+0.5
它看起来差不多不错,但是顶部出现了一颗无用的x
。那些星的直径不是也是21吗?@Nakilon:你应该从stdin@Chubas不幸的是,Yui Naruse说,这不是一个bug,而是1.9特性。我想这会解决光栅化I苏伊,是的。我喜欢这个。很好!这一个有一些关于如何绘制ascii艺术星星的有趣的扭曲,不幸的是,它不适用于6 2 20、8 2 20等。ninjalj是的,我知道,几何也有点幼稚…星星的直径是错误的,它使用直径参数作为线条的长度,而不是圣ar…我将修复。有趣。如果y0,我将替换
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
a,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
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(''));
#
# #
# #
# #
# #
# #
#####################
## # # ##
# # # #
# # # #
## ##
## ##
# # # #
# ### #
# # # #
# ## ## #
# # # #
## ##
# #