bal*_*pha 63 language-agnostic
2009年即将结束,随着经济和所有,我们将节省我们的钱,而不是购买昂贵的烟花,我们将在今年的ASCII艺术庆祝.
给定一组烟花和时间,在那个时刻拍摄烟花的照片并将其绘制到控制台.
在新年前夜(UTC)午夜之前输入的最佳解决方案将获得500代表的赏金.这是代码高尔夫,因此字符数量很大; 然而,社区投票也是如此,我保留最佳/最酷/最有创意/等等的最终决定.
请注意,我们的坐标系是从左到右,从下到上,所以所有的烟花都是在y-coordinate为0(零)时启动的.
输入数据由表单的烟花组成
(x, speed_x, speed_y, launch_time, detonation_time)
Run Code Online (Sandbox Code Playgroud)
哪里
x 是烟花发射的位置(列),speed_x并且speed_y是发射时烟花的水平和垂直速度,launch_time 是这个烟花发射的时间点,detonation_time 是这个烟花爆炸的时间点.烟花数据可以在您的程序中硬编码为5元组(或您的语言中的等效元素)列表,不计入您的字符数.但是,必须很容易更改此数据.
您可以做出以下假设:
-20 <= x <= 820-20 <= speed_x <= 200 < speed_y <= 20launch_time >= 0launch_time < detonation_time < launch_time + 50单个附加输入数据是应该呈现的时间点.这是一个非负整数,通过标准输入或命令行参数(无论您选择哪个)给出.
这个想法是(假设您的程序是一个名为python的脚本firework.py),这个bash脚本为您提供了一个漂亮的烟火动画:
#!/bin/bash
I=0
while (( 1 )) ; do
python firework.py $I
I=$(( $I + 1 ))
done
Run Code Online (Sandbox Code Playgroud)
(随意把等效的.BAT文件放在这里).
烟花的生命如下:
(x, 0)和速度矢量(speed_x, speed_y).speed_x并添加了-10,0或10 speed_y.这是九种可能的组合.speed_y.水平speed_x保持不变.speed_y.y位置低于零时,你可能会忘记它.我们想要的是烟花的图片,它看起来在给定的时间点.我们只能看看框架0 <= x <= 789和0 <= y <= 239,它映射到79x24字符输出.
因此,如果火箭或火花具有位置(247,130),我们在第24列(从零开始,因此它是第25列),第13行(从零开始并从底部开始计数)中绘制一个字符,因此它是第23行 - 13 = 10,输出的第11行).
绘制哪个角色取决于火箭/火花的当前速度:
speed_y == 0 or abs(speed_x) / abs(speed_y) > 2字符是" -".speed_x == 0 or abs(speed_y) / abs(speed_x) > 2字符是" |".\"或" /"(你猜对了).X改为" ".因此,假设你有一个火花(536, 119)和一个火花(531, 115),你绘制一个" X",无论它们的速度如何.*更新:这些是整数除法,因此斜率必须分别至少为3,或最多为1/3
输出(写入标准输出)是24行,每行以换行符结束.尾随空格被忽略,因此您可以(但不需要)填充宽度为79.这些行不得超过79个字符(不包括换行符).所有内部空间必须是空格字符(ASCII 32).
烟花:
fireworks = [(628, 6, 6, 3, 33),
(586, 7, 11, 11, 23),
(185, -1, 17, 24, 28),
(189, 14, 10, 50, 83),
(180, 7, 5, 70, 77),
(538, -7, 7, 70, 105),
(510, -11, 19, 71, 106),
(220, -9, 7, 77, 100),
(136, 4, 14, 80, 91),
(337, -13, 20, 106, 128)]
Run Code Online (Sandbox Code Playgroud)
时间33的输出:
\ | /
/ \
- | /
- | -
/ \
时间77的输出:
\
\
X
\
93时的输出:
\ | /
\ / /
- - - \
\
/ \ \
更新:我已将0到99的预期输出上传到firework.ü-wie-geek.de/NUMBER.html,其中NUMBER是时间.它包括调试信息; 点击一个粒子来查看它的当前位置,速度等等.是的,它是一个变音域.如果您的浏览器无法处理(显然Stack Overflow都不能),请尝试firework.xn---wie-geek-p9a.de.
另一个更新:正如下面的评论中暗示的那样,YouTube现在可以提供更长的烟火.它是使用MizardX条目的修改版本创建的,总烟花数量为170(是的,这超出了规范的要求,但程序优雅地处理了它).除了颜色,音乐和结束屏幕之外,可以通过此代码高尔夫的任何条目重新创建动画.所以,如果你非常讨厌享受ASCII艺术烟火(你知道的话):玩得开心,祝大家新年快乐!
Jua*_*uan 12
继承我的Python解决方案:
c = [(628, 6, 6, 3, 33),
(586, 7, 11, 11, 23),
(185, -1, 17, 24, 28),
(189, 14, 10, 50, 83),
(180, 7, 5, 70, 77),
(538, -7, 7, 70, 105),
(510, -11, 19, 71, 106),
(220, -9, 7, 77, 100),
(136, 4, 14, 80, 91),
(337, -13, 20, 106, 128)]
t=input()
z=' '
s=([z]*79+['\n'])*23+[z]*79
def p(x,y,i,j):
if 0<=x<790 and 0<=y<240:p=x/10+(23-y/10)*80;I=abs(i);J=abs(j);s[p]='X-|\\/'[[s[p]!=z,I>=3*J,J>=3*I,i*j<0,1].index(1)]
for x,i,j,l,d in c:
T=t-l;x+=i*T
if t>=d:e=t-d;[p(x+X*e,j*T+e*(Y-e+1),i+X,j+Y-2*e)for X in -20,0,20 for Y in -10,0,10]
elif t>=l:p(x,j*T,i,j)
print ''.join(s)
Run Code Online (Sandbox Code Playgroud)
从stdin获取时间,它有342个字符的漂亮数字.我还在想象OP如何获得320:P
编辑:这是我能得到的最好的,根据wc的322个字符
t=input()
s=([' ']*79+['\n'])*24
def p(x,y,i,j):
if 790>x>-1<y<240:p=x/10+(23-y/10)*80;I=abs(i);J=abs(j);s[p]='X-|\\/'[[s[p]>' ',I>=3*J,J>=3*I,i*j<0,1].index(1)]
for x,i,j,l,d in c:
T=t-l;x+=i*T;e=t-d
if t>=d:[p(x+X*e,j*T+e*(Y-e+1),i+X,j+Y-2*e)for X in-20,0,20for Y in-10,0,10]
elif t>=l:p(x,j*T,i,j)
print''.join(s),
Run Code Online (Sandbox Code Playgroud)
既然选择了胜利者 - 祝贺Juan - 这是我自己的解决方案,Python中有304个字符:
t=input()
Q=range
for y in Q(24):print"".join((["\\/|-"[3*(h*h>=9*v*v)or(v*v>=9*h*h)*2or h*v>0]for X,H,V,L,D in F for s,Z,K,P,u in[(t-D,t>D,t-L,G%3*20-20,G/3*10-10)for G in[Q(9),[4]][t<D]]for h,v in[[P+H,u+V-2*s*Z]]if((X+H*K+P*s)/10,23-(V*K-s*(Z*s-Z-u))/10)==(x,y)][:2]+[" ","X"])[::3][-1]for x in Q(79))
Run Code Online (Sandbox Code Playgroud)
这并不是很快,因为对于79x24显示器中的每个点,它会遍历所有烟花以查看此时是否有任何烟花可见.
这是一个试图解释发生了什么的版本:
t=input()
Q=range
for y in Q(24):
line = ""
for x in Q(79):
chars = [] # will hold all characters that should be drawn at (x, y)
for X,H,V,L,D in F: # loop through the fireworks
s = t - D
Z = t > D
K = t - L
# if t < D, i.e. the rocket hasn't exploded yet, this is just [(0, 0)];
# otherwise it's all combinations of (-20, 0, 20) for x and (-10, 0, 10)
speed_deltas = [(G % 3 * 20 - 20, G / 3 * 10 -10) for G in [Q(9), [4]][t < D]]
for P, u in speed_deltas:
if x == (X + H*K + P*s)/10 and y == 23 - (V*K - s*(Z*s - Z - u))/10:
# the current horizontal and vertical speed of the particle
h = P + H
v = u + V - 2*s*Z
# this is identical to (but shorter than) abs(h) >= 3 * abs(v)
is_horizontal = h*h >= 9*v*v
is_vertical = v*v >= 9*h*h
is_northeast_southwest = h*v > 0
# a shorter way of saying
# char_index = (3 if is_horizontal else 2 if is_vertical else 1
# if is_northeast_southwest else 0)
char_index = 3 * is_horizontal or 2 * is_vertical or is_northeast_southwest
chars.append("\\/|-"[char_index])
# chars now contains all characters to be drawn to this point. So we have
# three possibilities: If chars is empty, we draw a space. If chars has
# one element, that's what we draw. And if chars has more than one element,
# we draw an "X".
actual_char = (chars[:2] + [" ", "X"])[::3][-1] # Yes, this does the trick.
line += actual_char
print line
Run Code Online (Sandbox Code Playgroud)
蟒蛇:
fireworks = [(628, 6, 6, 3, 33),
(586, 7, 11, 11, 23),
(185, -1, 17, 24, 28),
(189, 14, 10, 50, 83),
(180, 7, 5, 70, 77),
(538, -7, 7, 70, 105),
(510, -11, 19, 71, 106),
(220, -9, 7, 77, 100),
(136, 4, 14, 80, 91),
(337, -13, 20, 106, 128)]
import sys
t = int(sys.argv[1])
particles = []
for x, speed_x, speed_y, launch_time, detonation_time in fireworks:
if t < launch_time:
pass
elif t < detonation_time:
x += speed_x * (t - launch_time)
y = speed_y * (t - launch_time)
particles.append((x, y, speed_x, speed_y))
else:
travel_time = t - detonation_time
x += (t - launch_time) * speed_x
y = (t - launch_time) * speed_y - travel_time * (travel_time - 1)
for dx in (-20, 0, 20):
for dy in (-10, 0, 10):
x1 = x + dx * travel_time
y1 = y + dy * travel_time
speed_x_1 = speed_x + dx
speed_y_1 = speed_y + dy - 2 * travel_time
particles.append((x1, y1, speed_x_1, speed_y_1))
rows = [[' '] * 79 for y in xrange(24)]
for x, y, speed_x, speed_y in particles:
x, y = x // 10, y // 10
if 0 <= x < 79 and 0 <= y < 24:
row = rows[23 - y]
if row[x] != ' ': row[x] = 'X'
elif speed_y == 0 or abs(speed_x) // abs(speed_y) > 2: row[x] = '-'
elif speed_x == 0 or abs(speed_y) // abs(speed_x) > 2: row[x] = '|'
elif speed_x * speed_y < 0: row[x] = '\\'
else: row[x] = '/'
print '\n'.join(''.join(row) for row in rows)
Run Code Online (Sandbox Code Playgroud)
如果删除初始烟花声明,将变量名压缩为单个字符,将空格压缩到最小,则可以获得590个字符.
C:
删除所有不必要的空格(不包括烟花声明的632字节):
#define N 10
int F[][5]={628,6,6,3,33,586,7,11,11,23,185,-1,17,24,28,189,14,10,50,83,180,7,5,70,77,538,-7,7,70,105,510,-11,19,71,106,220,-9,7,77,100,136,4,14,80,91,337,-13,20,106,128};
#define G F[i]
#define R P[p]
g(x,y){if(y==0||abs(x)/abs(y)>2)return 45;if(x==0||abs(y)/abs(x)>2)return'|';if(x*y<0)return 92;return 47;}main(int A,char**B){int a,b,c,C[24][79]={},d,i,j,p=0,P[N*9][3],Q,t=atoi(B[1]),x,y;for(i=0;i<N;i++){if(t>=G[3]){a=t-G[3];x=G[0]+G[1]*a;y=G[2]*a;if(t<G[4]){R[0]=x;R[1]=y;R[2]=g(G[1],G[2]);p++;}else{b=t-G[4];y-=b*(b-1);for(c=-20;c<=20;c+=20){for(d=-10;d<=10;d+=10){R[0]=x+c*b;R[1]=y+d*b;R[2]=g(G[1]+c,G[2]+d-2*b);p++;}}}}}Q=p;for(p=0;p<Q;p++){x=R[0]/10;y=R[1]/10;if(R[0]>=0&&x<79&&R[1]>=0&&y<24)C[y][x]=C[y][x]?88:R[2];}for(i=23;i>=0;i--){for(j=0;j<79;j++)putchar(C[i][j]?C[i][j]:32);putchar(10);}}
Run Code Online (Sandbox Code Playgroud)
这里是完全相同的代码,添加了空白以便于阅读:
#define N 10
int F[][5] = {
628, 6, 6, 3, 33,
586, 7, 11, 11, 23,
185, -1, 17, 24, 28,
189, 14, 10, 50, 83,
180, 7, 5, 70, 77,
538, -7, 7, 70, 105,
510, -11, 19, 71, 106,
220, -9, 7, 77, 100,
136, 4, 14, 80, 91,
337, -13, 20, 106, 128
};
#define G F[i]
#define R P[p]
g(x, y) {
if(y == 0 || abs(x)/abs(y) > 2)
return 45;
if(x == 0 || abs(y)/abs(x) > 2)
return '|';
if(x*y < 0)
return 92;
return 47;
}
main(int A, char**B){
int a, b, c, C[24][79] = {}, d, i, j, p = 0, P[N*9][3], Q, t = atoi(B[1]), x, y;
for(i = 0; i < N; i++) {
if(t >= G[3]) {
a = t - G[3];
x = G[0] + G[1]*a;
y = G[2]*a;
if(t < G[4]) {
R[0] = x;
R[1] = y;
R[2] = g(G[1], G[2]);
p++;
} else {
b = t - G[4];
y -= b*(b-1);
for(c = -20; c <= 20; c += 20) {
for(d =- 10; d <= 10; d += 10) {
R[0] = x + c*b;
R[1] = y + d*b;
R[2] = g(G[1] + c, G[2] + d - 2*b);
p++;
}
}
}
}
}
Q = p;
for(p = 0; p < Q; p++) {
x = R[0]/10;
y = R[1]/10;
if(R[0] >= 0 && x < 79 && R[1] >= 0 && y < 24)
C[y][x] = C[y][x] ? 88 : R[2];
}
for(i = 23; i >= 0; i--) {
for(j = 0; j < 79; j++)
putchar(C[i][j] ? C[i][j] : 32);
putchar(10);
}
}
Run Code Online (Sandbox Code Playgroud)
对于Python,@ MizardX的解决方案很好,但显然不是codegolf优化 - 除了"不要真正计算"前缀的333个字符,即:
fireworks = [(628, 6, 6, 3, 33),
(586, 7, 11, 11, 23),
(185, -1, 17, 24, 28),
(189, 14, 10, 50, 83),
(180, 7, 5, 70, 77),
(538, -7, 7, 70, 105),
(510, -11, 19, 71, 106),
(220, -9, 7, 77, 100),
(136, 4, 14, 80, 91),
(337, -13, 20, 106, 128)]
f = fireworks
### int sys argv append abs join f xrange
Run Code Online (Sandbox Code Playgroud)
(最后一条评论是我的一个小的codegolf-aux脚本的帮助器,它使所有可行的名称1-char机械 - 它需要被告知什么名字不能缩小;-),最短的我可以通过挤压来解决这个问题空格是592个字符(足够接近590 @MizardX声明).
拉出所有的句点("重构"代码高尔夫的心情),我得到,在前缀后面(我用单字符名称的小写我手动介绍或替换,大写我的codegolf-aux脚本自动替换):
import sys
Z=int(sys.argv[1])
Y=[]
e=Y.extend
for X,W,V,U,T in f:
if Z>=U:
z=Z-U;X+=W*z
if Z<T:e(((X,V*z,W,V),))
else:R=Z-T;e((X+Q*R,z*V-R*(R-1)+P*R,W+Q,V+P-2*R)for Q in(-20,0,20)for P in(-10,0,10))
K=[79*[' ']for S in range(24)]
for X,S,W,V in Y:
X,S=X/10,S/10
if(0<=X<79)&(0<=S<24):
J=K[23-S];v=abs(V);w=abs(W)
J[X]='X'if J[X]!=' 'else'-'if V==0 or w/v>2 else'|'if W==0 or v/w>2 else '\\'if W*V<0 else'/'
print '\n'.join(''.join(J)for J in K)
Run Code Online (Sandbox Code Playgroud)
测量为460个字符 - 减少130,即130/590 = 22%.
超出1个字符的名称和明显的方式以最小化间距,关键想法包括:单/除法(相同更好//为在Python 2.*整数),一个if/else代替一个的表达if/elif/else语句,extend用genexp而不是嵌套循环with append(允许删除一些空格和标点符号),不绑定到只出现一次的名称子表达式,绑定到名称子表达式,否则将重复(包括.extend属性查找),分号而不是换行符(如果可行)单独的行必须缩进,否则,将换行计为1个字符,没有保存).
是的,可读性受到了一些影响,但这在代码高尔夫中并不令人惊讶;-).
编辑:经过更多紧缩后,我现在有一个较小的程序(相同的前缀):
Z=input()
K=[79*[' ']for S in range(24)];a=-10,0,10
def g(X,S,W,V):
X/=10;S/=10
if(0<=X<79)&(0<=S<24):J=K[23-S];v=abs(V);w=abs(W);J[X]=[[['/\\'[W*V<0],'|'][v>2.9*w],'-'][w>2.9*v],'X'][J[X]!=' ']
for X,W,V,U,T in f:
if Z>=U:
z=Z-U;X+=W*z
if Z<T:g(X,V*z,W,V)
else:R=Z-T;[g(X+Q*2*R,z*V-R*(R-1)+P*R,W+Q*2,V+P-2*R)for Q in a for P in a]
print'\n'.join(''.join(J)for J in K)
Run Code Online (Sandbox Code Playgroud)
仍然是相同的输出,但现在是360个字符 - 比我以前的解决方案少了100个,我已经离开了这个答案的第一部分(仍然远远高于OP说他有的320,但是! - ).
我已经采取了自由允许输入时间值来从标准输入程度的优势(input比进口更严格sys和使用sys.argv[1]- !),消除了中间列表(瓦特/延长通话和它的最终循环)在支持g直接调用的新函数并在我们去的时候更新K,找到并删除了一些共性,将嵌套的if/else表达式重构为一个复杂的(但更简洁;-)构建和嵌套列表的索引,使用了这样一个事实:v>2.9*w更简洁w==0 or v/w>2(并且总是在要考虑的值范围内给出相同的结果).
编辑:将K("屏幕图像")放入1-D列表中再保存26个字符,将以下解决方案缩小到334(仍然在OP之上14,但是关闭......! - ):
Z=input()
K=list(24*(' '*79+'\n'))
a=-10,0,10
def g(X,S,W,V):
if(0<=X<790)&(0<=S<240):j=80*(23-S/10)+X/10;v=abs(V);w=abs(W);K[j]=[[['/\\'[W*V<0],'|'][v>2.9*w],'-'][w>2.9*v],'X'][K[j]!=' ']
for X,W,V,U,T in f:
if Z>=U:
z=Z-U;X+=W*z
if Z<T:g(X,V*z,W,V)
else:R=Z-T;[g(X+Q*2*R,z*V-R*(R-1)+P*R,W+Q*2,V+P-2*R)for Q in a for P in a]
print ''.join(K),
Run Code Online (Sandbox Code Playgroud)
在F#中用957*字符完成,它就像罪恶一样难看:
一系列烟花:
let F = [(628,6,6,3,33);(586,7,11,11,23);(185,-1,17,24,28);(189,14,10,50,83);(180,7,5,70,77);(538,-7,7,70,105);(510,-11,19,71,106);(220,-9,7,77,100);(136,4,14,80,91);(337,-13,20,106,128)]
Run Code Online (Sandbox Code Playgroud)
剩下的代码
let M=List.map
let C=List.concat
let P=List.partition
let L t f r=(let s=P(fun(_,_,_,u,_)->not(t=u))f
(fst s, r@(M(fun(x,v,w,_,t)->x,0,v,w,t)(snd s))))
let X d e (x,y,v,w)=C(M(fun(x,y,v,w)->[x,y,v-d,w;x,y,v,w;x,y,v+d,w])[x,y,v,w-e;x,y,v,w;x,y,v,w+e])
let D t r s=(let P=P(fun(_,_,_,_,u)->not(t=u))r
(fst P,s@C(M(fun(x,y,v,w,_)->(X 20 10(x,y,v,w)))(snd P))))
let rec E t l f r s=(
let(a,m)=L t f (M(fun(x,y,v,w,t)->x+v,y+w,v,w,t)r)
let(b,c)=D t m (M(fun(x,y,v,w)->x+v,y+w,v,w-2)s)
if(t=l)then(a,b,c)else E(t+1)l a b c)
let N=printf
let G t=(
let(f,r,s)=E 0 t F [] []
let os=s@(M(fun(x,y,v,w,_)->(x,y,v,w))r)
for y=23 downto 0 do (
for x=0 to 79 do (
let o=List.filter(fun(v,w,_,_)->((v/10)=x)&&((w/10)=y))os
let l=o.Length
if l=0 then N" "
elif l=1 then
let(_,_,x,y)=o.Head
N(
if y=0||abs(x)/abs(y)>2 then"-"
elif x=0||abs(y)/abs(x)>2 then"|"
elif y*x>0 then"/"
else"\\")
elif o.Length>1 then N"X")
N"\n"))
[<EntryPointAttribute>]
let Z a=
G (int(a.[0]))
0
Run Code Online (Sandbox Code Playgroud)
"漂亮"代码:
let fxs = [(628,6,6,3,33);(586,7,11,11,23);(185,-1,17,24,28);(189,14,10,50,83);(180,7,5,70,77);(538,-7,7,70,105);(510,-11,19,71,106);(220,-9,7,77,100);(136,4,14,80,91);(337,-13,20,106,128)]
let movs xs =
List.map (fun (x, y, vx, vy) -> (x + vx, y + vy, vx, vy-2)) xs
let movr xs =
List.map (fun (x, y, vx, vy, dt) -> (x + vx, y + vy, vx, vy, dt)) xs
let launch t fs rs =
let split = List.partition(fun (lx, sx, sy, lt, dt) -> not (t = lt)) fs
(fst split, rs @ (List.map(fun (lx, sx, sy, lt, dt) -> (lx, 0, sx, sy, dt)) (snd split)))
let split dx dy (x,y,sx,sy) =
List.concat (List.map (fun (x,y,sx,sy)->[(x,y,sx-dx,sy);(x,y,sx,sy);(x,y,sx+dx,sy)]) [(x,y,sx,sy-dy);(x,y,sx,sy);(x,y,sx,sy+dy)])
let detonate t rs ss =
let tmp = List.partition (fun (x, y, sx, sy, dt) -> not (t = dt)) rs
(fst tmp, ss @ List.concat (List.map(fun (x, y, sx, sy, dt) -> (split 20 10 (x, y, sx, sy))) (snd tmp)))
let rec simulate t l fs rs ss =
let (nfs, trs) = launch t fs (movr rs)
let (nrs, nss) = detonate t trs (movs ss)
if (t = l) then (nfs,nrs,nss)
else
simulate (t+1) l nfs nrs nss
let screen t =
let (fs, rs, ss) = simulate 0 t fxs [] []
let os = ss @ (List.map(fun (x, y, sx, sy,_) -> (x, y, sx, sy)) rs)
for y = 23 downto 0 do
for x = 0 to 79 do
let o = List.filter(fun (px,py,_,_)->((px/10)=x) && ((py/10)=y)) os
if o.Length = 0 then printf " "
elif o.Length = 1 then
let (_,_,sx,sy) = o.Head
printf (
if sy = 0 || abs(sx) / abs(sy) > 2 then "-"
elif sx = 0 || abs(sy) / abs(sx) > 2 then "|"
elif sy * sx > 0 then "/"
else"\\"
)
elif o.Length > 1 then printf "X"
printfn ""
[<EntryPointAttribute>]
let main args =
screen (int(args.[0]))
0
Run Code Online (Sandbox Code Playgroud)
完全被盗用新的和改进的逻辑重写.这和Python一样接近.你可以看到F#不向这里特设的脚本,在这里我要V和W的显式转换为浮动齿轮的弱点,声明主要功能有一个丑陋的属性来获取命令行参数,我不得不引用.NET System.Console.Write获得漂亮的输出.
哦,好好练习学习一门语言.
这是新代码,544字节:
let Q p t f=if p then t else f
let K=[|for i in 1..1920->Q(i%80>0)' ''\n'|]
let g(X,S,W,V)=
if(X>=0&&X<790&&S>=0&&S<240)then(
let (j,v,w)=(80*(23-S/10)+X/10,abs(float V),abs(float W))
Array.set K j (Q(K.[j]=' ')(Q(w>2.9*v)'-'(Q(v>2.9*w)'|'(Q(W*V>0)'/''\\')))'X'))
let a=[-10;0;10]
[<EntryPointAttribute>]
let m s=
let Z=int s.[0]
for (X,W,V,U,T) in F do(
if Z>=U then
let z,R=Z-U,Z-T
let x=X+W*z
if(Z<T)then(g(x,V*z,W,V))else(for e in[|for i in a do for j in a->(x+j*2*R,z*V-R*(R-1)+i*R,W+j*2,V+i-2*R)|]do g e))
System.Console.Write K
0
Run Code Online (Sandbox Code Playgroud)
import Data.List
f=[(628,6,6,3,33),(586,7,11,11,23),(185,-1,17,24,28),(189,14,10,50,83),(180,7,5,70,77),(538,-7,7,70,105),(510,-11,19,71,106),(220,-9,7,77,100),(136,4,14,80,91),(337,-13,20,106,128)]
c=filter
d=True
e=map
a(_,_,_,t,_)=t
b(_,_,_,_,t)=t
aa(_,y,_,_)=y
ab(x,t,y,_,u)=(x,0,t,y,u)
ac(x,y,t,u,_)=[(x,y,t+20,u+10),(x,y,t,u+10),(x,y,t-20,u+10),(x,y,t+20,u),(x,y,t,u),(x,y,t-20,u),(x,y,t+20,u-10),(x,y,t,u-10),(x,y,t-20,u-10)]
g(x,y,t,u,v)=(x+t,y+u,t,u,v)
h(x,y,t,u)=(x+t,y+u,t,u-2)
i=(1,f,[],[])
j s 0=s
j(t,u,v,w)i=j(t+1,c((/=t).a)u,c((> t).b)x++(e ab.c((==t).a))u,c((>0).aa)(e h w)++(concat.e ac.c((==t).b))x)(i-1)
where x=e g v
k x y
|x==0='|'
|3*abs y<=abs x='-'
|3*abs x<=abs y='|'
|(y<0&&x>0)||(y>0&&x<0)='\\'
|d='/'
l(x,y,t,u,_)=m(x,y,t,u)
m(x,y,t,u)=(div x 10,23-div y 10,k t u)
n(x,y,_)(u,v,_)
|z==EQ=compare x u
|d=z
where z=compare y v
o((x,y,t):(u,v,w):z)
|x==u&&y==v=o((x,y,'X'):z)
|d=(x,y,t):(o((u,v,w):z))
o x=x
q _ y []
|y==23=""
|d='\n':(q 0(y+1)[])
q v u((x,y,z):t)
|u>22=""
|v>78='\n':(q 0(u+1)((x,y,z):t))
|u/=y='\n':(q 0(u+1)((x,y,z):t))
|v/=x=' ':(q(v+1)u((x,y,z):t))
|d = z:(q(v+1)u t)
p(_,_,v,w)=q 0 0((c z.o.sortBy n)((e l v)++(e m w)))
where z(x,y,_)=x>=0&&x<79&&y>=0
r x=do{z <- getChar;(putStr.p)x}
s=e(r.j i)[1..]
main=foldr(>>)(return())s
Run Code Online (Sandbox Code Playgroud)
不像MizardX那么令人印象深刻,如果你删除f=…声明,它会以1068个字符进入,但是地狱,它很有趣.已经有一段时间了,因为我有机会和Haskell一起玩.
(稍微)更漂亮的版本也可用.
编辑:Ack.重读,我不太符合规范:这个版本每按一次键就会打印一个新的烟火显示屏,需要^C退出; 它不需要命令行参数并打印出相关的屏幕.
假设烟花数据定义为:
@f = (
[628, 6, 6, 3, 33],
[586, 7, 11, 11, 23],
[185, -1, 17, 24, 28],
[189, 14, 10, 50, 83],
[180, 7, 5, 70, 77],
[538, -7, 7, 70, 105],
[510, -11, 19, 71, 106],
[220, -9, 7, 77, 100],
[136, 4, 14, 80, 91],
[337, -13, 20, 106, 128]
);
Run Code Online (Sandbox Code Playgroud)
$t=shift;
for(@f){
($x,$c,$d,$l,$e)=@$_;
$u=$t-$l;
next if$u<0;
$x+=$c*$u;
$h=$t-$e;
push@p,$t<$e?[$x,$d*$u,$c,$d]:map{$f=$_;map{[$x+$f*$h,($u*$d-$h*($h-1))+$_*$h,$c+$f,$d+$_-2*$h]}(-10,0,10)}(-20,0,20)
}
push@r,[($")x79]for(1..24);
for(@p){
($x,$y,$c,$d)=@$_;
if (0 <= $x && ($x=int$x/10) < 79 && 0 <= $y && ($y=int$y/10) < 24) {
@$_[$x]=@$_[$x]ne$"?'X':!$d||abs int$c/$d>2?'-':!$c||abs int$d/$c>2?'|':$c*$d<0?'\\':'/'for$r[23 - $y]
}
}
$"='';
print$.,map{"@$_\n"}@r
Run Code Online (Sandbox Code Playgroud)
压缩,有433个字符.(见历史编辑)
这是基于多个先前的答案(主要是MizardX的),并且肯定可以改进.拖延其他与工作有关的任务的罪恶意味着我现在必须放弃.
原谅编辑 - 取出我所知道的所有技巧,这可以压缩到356 char:
sub p{
($X,$=,$C,$D)=@_;
if(0<=$X&($X/=10)<79&0<=$=&($=/=10)<24){
@$_[$X]=@$_[$X]ne$"?X:$D&&abs$C/$D<3?$C&&abs$D/$C<3?
$C*$D<0?'\\':'/':'|':'-'for$r[23-$=]
}
}
@r=map[($")x79],1..24;
$t=pop;
for(@f){
($x,$c,$d,$u,$e)=@$_;
$x-=$c*($u-=$t);
$u>0?1:($h=$t-$e)<0
?p$x,-$d*$u,$c,$d
:map{for$g(-10,0,10){p$x+$_*$h,$h*(1-$h+$g)-$u*$d,$c+$_,$d+$g-2*$h}}-20,0,20
}
print@$_,$/for@r
Run Code Online (Sandbox Code Playgroud)
$=是一种特殊的Perl变量(以沿$%,$-和$?)只能取整数值.使用它消除了使用该int功能的需要.