programing

코드 골프 : 새해 불꽃 놀이

nasanasas 2020. 11. 25. 08:02
반응형

코드 골프 : 새해 불꽃 놀이


2009 년이 다가오고 있으며 경제와 모든면에서 우리는 돈을 절약하고 값 비싼 불꽃 놀이 대신 올해 ASCII 예술로 축하 할 것입니다.

도전

불꽃 놀이와 시간이 주어지면 그 순간의 불꽃 놀이 사진을 찍어 콘솔에 그립니다.

섣달 그믐 (UTC) 자정 이전에 입력 된 최상의 솔루션은 500 회 현상금을 받게됩니다. 이것은 코드 골프이므로 문자 수는 매우 중요합니다. 그러나 커뮤니티 투표도 마찬가지이며, 무엇이 최고 / 가장 멋진 지 / 가장 창의적인지 등에 대한 최종 결정권을 가지고 있습니다.

입력 데이터

좌표계는 왼쪽에서 오른쪽, 아래쪽에서 위쪽이므로 모든 불꽃 놀이는 y0 (영) 좌표 에서 발사됩니다 .

입력 데이터는 다음 형식의 불꽃 놀이로 구성됩니다.

(x, speed_x, speed_y, launch_time, detonation_time)

어디

  • x 불꽃이 발사되는 위치 (열)입니다.
  • speed_xspeed_y, 발사시 불꽃의 수평 및 수직 속도입니다
  • launch_time 이 불꽃 놀이가 시작되는 시점입니다.
  • detonation_time 이 불꽃이 터질 시점입니다.

불꽃 놀이 데이터는 문자 수에 포함되지 않고 5 개의 튜플 (또는 해당 언어에 해당하는 것) 목록으로 프로그램에서 하드 코딩 될 수 있습니다. 그러나이 데이터를 변경하는 것은 쉬워야합니다.

다음과 같은 가정을 할 수 있습니다.

  • 적절한 양의 불꽃 놀이가 있습니다 (예 : 100 개 미만)
  • 각 불꽃 놀이에 대해 5 개의 숫자는 모두 합리적인 범위 내의 정수입니다 (예 : 각각에 대해 16 비트이면 충분 함).
  • -20 <= x <= 820
  • -20 <= speed_x <= 20
  • 0 < speed_y <= 20
  • launch_time >= 0
  • launch_time < detonation_time < launch_time + 50

하나의 추가 입력 데이터는 렌더링되어야하는 시점입니다. 이것은 표준 입력 또는 명령 줄 인수 (선택한 항목)를 통해 제공되는 음이 아닌 정수입니다.

아이디어는 (당신의 프로그램이라는 파이썬 스크립트라고 가정하면 firework.py)이 bash 스크립트는 멋진 불꽃 놀이 애니메이션을 제공한다는 것입니다.

#!/bin/bash
I=0
while (( 1 )) ; do
    python firework.py $I
    I=$(( $I + 1 ))
done

(여기에 동등한 .BAT 파일을 자유롭게 넣으십시오).

불꽃 놀이의 삶

불꽃 놀이의 수명은 다음과 같습니다.

  • 시작 시간 전에는 무시할 수 있습니다.
  • 발사시 로켓은 위치 (x, 0)와 속도 벡터를 가지고 (speed_x, speed_y)있습니다.
  • 각 시간 단계에 대해 속도 벡터가 위치에 추가됩니다. 뉴턴의 법칙에 약간의 스트레칭을 적용하면 속도가 일정하다고 가정합니다.
  • 폭발 시간에 로켓은 9 개의 불꽃으로 폭발합니다. 9 개의 스파크는 모두이 시점에서 동일한 위치 (로켓이 폭발하지 않았 더라면 로켓이 가질 위치)가 동일하지만 속도는 다릅니다. 각 속도는 로켓의 속도를 기반으로하며 -20, 0 또는 20이에 추가 speed_x되고 -10, 0 또는 10이에 추가됩니다 speed_y. 9 가지 가능한 조합입니다.
  • 폭발 시간이 지나면 중력이 당겨지기 시작합니다. 각 시간 단계에서 발생하는 중력 상수 (2)가 모든 스파크에서 뺍니다 speed_y. 수평 speed_x은 일정하게 유지됩니다.
  • 폭발 시간 이후의 각 시간 단계에 대해 먼저 위치에 속도 벡터를 더한 다음 에서 2 뺍니다 speed_y.
  • 스파크의 y위치가 0 아래로 떨어지면 잊어 버릴 수 있습니다.

산출

우리가 원하는 것은 주어진 시점을 바라 보는 불꽃 놀이 사진입니다. 우리는 프레임 만보고 0 <= x <= 7890 <= y <= 23979x24 문자 출력에 매핑.

따라서 로켓이나 스파크의 위치가 (247, 130)이면 24 열 (0부터 시작하므로 25 번째 열), 13 행 (0부터 시작하고 맨 아래부터 계산하므로 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)있고에 1 개가 있다고 가정하면 속도에 관계없이 (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)]

시간 33에서의 출력 :






       \ | /                                                   


                                                      / \    

       -| /                                                   




       -| -                                                   


                                                      / \    





시간 77에서 출력 :













                                            \                                  






                                                \                              
                      엑스                                                        


                      \                                                        

시간 93에서 출력 :




              \ | /                                                        

              \ / /                                                        

              ---\                                         




       \                                                                       







  / \ \            



업데이트 : 0에서 99까지 예상 출력을 firework.ü-wie-geek.de / NUMBER.html에 업로드했습니다 . 여기서 NUMBER는 시간입니다. 디버그 정보가 포함됩니다. 입자를 클릭하면 현재 위치, 속도 등을 볼 수 있습니다. 예, 움라우트 도메인입니다. 브라우저가이를 처리 할 수없는 경우 (분명히 Stack Overflow도 마찬가지이므로) firework.xn---wie-geek-p9a.de를 사용해보십시오 .

또 다른 업데이트 : 아래 댓글에서 알 수 있듯이 이제 YouTube 에서 더 긴 불꽃 놀이를 볼 수 있습니다 . MizardX '항목 의 수정 된 버전으로 만들어졌으며 총 불꽃 수는 170 개입니다 (예, 요청한 사양보다 많지만 프로그램에서 정상적으로 처리했습니다). 색상, 음악 및 최종 화면을 제외하고이 코드 골프에 대한 모든 항목으로 애니메이션을 재현 할 수 있습니다. 따라서 ASCII 예술 불꽃 놀이를 즐길 수있을만큼 괴짜라면 (당신은 알고 있습니다) : 재미있게 보내세요. 모두에게 새해 복 많이 받으세요!


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)

표준 입력에서 시간이 걸리며 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),

이제 우승자 가 선택되었으므로 – 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))

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

파이썬 :

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)

초기 불꽃 놀이 선언을 제거하고 변수 이름을 단일 문자로 압축하고 공백을 최소로 압축하면 590자를 얻을 수 있습니다.


씨:

불필요한 공백을 모두 제거한 상태에서 (불꽃 놀이 선언을 제외한 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);}}

그리고 다음은 가독성을 위해 공백이 추가 된 똑같은 코드입니다.

#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);
    }
}

Python의 경우 @MizardX의 솔루션은 훌륭하지만 코드 골프에 최적화되지 않은 것은 분명합니다. 접두어의 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

(마지막 주석은 모든 가능한 이름을 기계적으로 1-char 만드는 내 작은 codegolf-aux 스크립트에 대한 도우미입니다 .- 어떤 이름을 축소하지 말아야하는지 알려줘야합니다 .-), 압착하여 해결할 수있는 가장 짧은 방법 공백은 592 자입니다 (590 @MizardX 클레임에 충분히 가깝습니다).

모든 중지 (codegolf 분위기에서 코드를 "리팩토링")하면 접두사 뒤에 나타납니다 (수동으로 도입하거나 대체 할 단일 문자 이름에는 소문자를 사용하고 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)

460 자로 측정됩니다. 즉, 130 개가 감소했습니다. 즉, 130/590 = 22 %입니다.

1 문자 이름과 공백을 최소화하는 명백한 방법 외에도 핵심 아이디어는 다음과 같습니다. /나누기 용 단일 ( //Python 2. *의 int에 대한 더 좋은 방법과 동일 ), 중첩 루프가 아닌 genexp if/else를 사용하는 if/elif/else구문 대신 표현식 extendwith 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)

여전히 동일한 출력이지만 이제는 360 자입니다.이 답변의 첫 번째 부분으로 남겨 두었던 이전 솔루션보다 정확히 100자가 적습니다 (아직도 OP는 320보다 훨씬 더 많이 있습니다!-).

나는 입력 시간 값이 stdin에서 오도록 허용하는 자유도를 이용하고 ( input가져 sys오고 사용하는 것보다 훨씬 빡빡합니다 sys.argv[1]!), 중간 목록 (확장 호출 및 최종 루프 포함)을 제거했습니다. g직접 호출되고 K를 업데이트 하는 새로운 함수 선호 하고, 일부 공통성을 찾아서 제거하고, 중첩 된 if / else 표현식을 중첩 된 목록의 복잡한 (그러나 더 간결한 ;-) 빌드 및 인덱싱으로 리팩토링하고, v>2.9*w보다 간결합니다 w==0 or v/w>2(고려할 값 범위에서 항상 동일한 결과를 제공함).

편집 : K ( "화면 이미지")를 1D 목록으로 만들면 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),

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

남은 코드

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

"예쁜"코드 :

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

새롭고 향상된 로직으로 완전히 도난당한 재 작성. 이것은 내가 파이썬에 도달 할 수있는 한 가깝습니다. 여기에서 임시 스크립팅에 맞지 않는 F #의 약점을 볼 수 있습니다. 여기서 V와 W를 float로 명시 적으로 변환하고, 명령 줄 인수를 얻기 위해 추악한 속성을 사용하여 주 함수를 선언해야합니다. .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

Haskell

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

f=…선언 을 제거하면 1068 자로 나오는 MizardX만큼 인상적 이지는 않지만 지옥, 재미있었습니다. 하스켈과 함께 플레이 할 기회를 얻은 지 오래되었습니다.

(약간) 더 예쁜 버전 도 있습니다 .

편집 : Ack. 다시 읽어 보면 사양에 맞지 않습니다.이 버전은 키를 누를 때마다 새 불꽃 놀이 화면을 인쇄하고 ^C종료 해야 합니다. 명령 줄 인수를 사용하지 않고 관련 화면을 인쇄합니다.


Perl

불꽃 놀이 데이터가 다음과 같이 정의된다고 가정합니다.

@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]
);

$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

압축, 433 자로 제공됩니다. (역사 편집 참조)

이것은 여러 이전 답변 (주로 MizardX)의 조각을 기반으로하며 확실히 개선 될 수 있습니다. 다른 일과 관련된 일을 미루는 죄책감은 당장 포기해야한다는 것을 의미합니다.


편집을 용서하십시오-내가 아는 모든 트릭을 꺼내면 356 문자로 압축 될 수 있습니다.

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

$=특별한 펄 변수는 (함께입니다 $%, $-그리고 $?유일한 정수 값을 취할 수). 그것을 사용하면 int기능 을 사용할 필요가 없습니다 .


포트란 77

선사 시대 언어 부서에서 내 항목이 FORTRAN 77에 있습니다.

초기화, 소수의 공백 및 불필요한 공백을 포함하여 2570 자이지만 간결성을 위해 이길 것 같지 않습니다. 특히 각 줄에 6 개의 선행 공백이 필수이기 때문에.

이 파일을 Linux 시스템에서 fireworks.ftn컴파일했습니다 gfortran.

  implicit integer(a-z)
  parameter (n=10)
  integer fw(5,n) / 
 + 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
 + /
  integer p(6, 1000) / 6000 * -1 / 
  character*79 s(0:23)
  character z
c Transform input
      do 10 r=1,n
         p(1, r) = 0
         do 10 c=1,5
   10       p(c+1, r) = fw(c, r)
c Input end time
      read *, t9
c Iterate from 1 to end time
      do 62 t=1,t9
         do 61 q=1,1000
            if (p(1,q) .lt. 0 .or. t .lt. p(5,q)) goto 61
            if (p(6,q).gt.0.and.t.gt.p(5,q) .or. t.gt.abs(p(6,q))) then
               p(1,q) = p(1,q) + p(4,q)
               p(2,q) = p(2,q) + p(3,q)
            endif
            if (t .lt. abs(p(6,q))) goto 61
            if (t .gt. abs(p(6,q))) then
               p(4,q) = p(4,q) - 2
            elseif (t .eq. p(6,q)) then
c Detonation: Build 9 sparks            
               do 52 m=-1,1
                  do 51 k=-1,1
c Find a free entry in p and fill it with a spark
                     do 40 f=1,1000
                        if (p(1,f) .lt. 0) then
                           do 20 j=1,6
   20                      p(j,f) = p(j,q)
                           p(3,f) = p(3,q) + 20 * m
                           p(4,f) = p(4,q) + 10 * k
                           p(6,f) = -p(6,q)
                           goto 51
                        endif
   40                continue
   51             continue
   52          continue
c Delete the original firework
               p(1,q) = -1
            endif
   61    continue
   62 continue
c Prepare output
      do 70 r=0,23
   70 s(r) = ' '
      do 80 q=1,1000
         if (p(1,q) .lt. 0) goto 80
         if (p(5,q) .gt. t9) goto 80
         y = p(1,q) / 10
         if (y .lt. 0 .or. y .gt. 23) goto 80
         x = p(2,q) / 10
         if (x .lt. 0 .or. x .gt. 79) goto 80
         if (s(y)(x+1:x+1) .ne. ' ') then
            z = 'X'
         elseif ((p(4,q) .eq. 0) .or. abs(p(3,q) / p(4,q)) .gt. 2) then
            z = '-'
         elseif ((p(3,q) .eq. 0) .or. abs(p(4,q) / p(3,q)) .gt. 2) then
            z = '|'
         elseif (sign(1, p(3,q)) .eq. sign(1, p(4,q))) then
            z = '/'
         else
            z = '\'
         endif
         s(y)(x+1:x+1) = z
   80 continue
c Output
      do 90 r=23,0,-1
   90 print *, s(r)
      end

다음은 더 작은 Haskell 구현입니다. 911 자입니다. 불꽃 놀이 정의를 빼면 732 자입니다.

import System
z=789
w=239
r=replicate
i=foldl
main=do{a<-getArgs;p(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)](read(a!!0)::Int));}
p[]=return()
p(f:g)=do{putStrLn f;p g}
f s t=i(a t)(r 24(r 79' '))s
a t f(x,s,y,l,d)=if t<l then f else if t<d then c f((x+s*u,y*u),(s,y))else i c f(map(v(t-d)(o(d-l)(x,0)(s,y)))[(g s,h y)|g<-[id,(subtract 20),(+20)],h<-[id,(subtract 10),(+10)]])where u=t-l
v 0(x,y)(vx,vy)=((x,y),(vx,vy))
v t(x,y)(vx,vy)=v(t-1)(x+vx,y+vy)(vx,vy-2)
o t(x,y)(vx,vy)=(x+(vx*t),y+(vy*t))
c f((x,y),(vx,vy))=if x<0||x>=z||y<0||y>=w then f else(take m f)++[(take n r)++[if d/=' 'then 'x'else if vy==0||abs(vx`div`vy)>2 then '-'else if vx==0||abs(vy`div`vx)>2 then '|'else if vx*vy>=0 then '/'else '\\']++(drop(n+1)r)]++(drop(m+1)f)where{s=w-y;n=x`div`10;m=s`div`10;r=f!!m;d=r!!n}

다음은 호기심을위한 비 압축 버전입니다.

import System

sizeX = 789
sizeY = 239

main = do
    args <- getArgs
    printFrame (frame fireworks (read (args !! 0) :: Int))
    where 
        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)]

printFrame :: [String] -> IO ()
printFrame [] = return ()
printFrame (f:fs) = do
    putStrLn f
    printFrame fs

frame :: [(Int,Int,Int,Int,Int)] -> Int -> [String]
frame specs time = 
    foldl (applyFirework time) 
        (replicate 24 (replicate 79 ' ')) specs

applyFirework :: Int -> [String] -> (Int,Int,Int,Int,Int) -> [String]
applyFirework time frame (x,sx,sy,lt,dt) =
    if time < lt then frame
    else if time < dt then 
        drawChar frame 
            ((x + sx * timeSinceLaunch, sy * timeSinceLaunch), (sx,sy))
    else
        foldl drawChar frame 
            (
                map 
                    (
                        posVelOverTime (time - dt) 
                        (posOverTime (dt - lt) (x,0) (sx, sy))
                    ) 
                    [ 
                        (fx sx, fy sy) | 
                            fx <- [id,(subtract 20),(+20)],  
                            fy <- [id,(subtract 10),(+10)]
                    ]
            )
    where timeSinceLaunch = time - lt

posVelOverTime :: Int -> (Int,Int) -> (Int,Int) -> ((Int,Int),(Int,Int))
posVelOverTime 0 (x,y) (vx,vy) = ((x,y),(vx,vy))
posVelOverTime time (x,y) (vx,vy) = 
    posVelOverTime (time - 1) (x+vx, y+vy) (vx, vy - 2)

posOverTime :: Int -> (Int,Int) -> (Int,Int) -> (Int,Int)
posOverTime time (x,y) (vx, vy) = (x + (vx * time), y + (vy * time))

drawChar :: [String] -> ((Int,Int),(Int,Int)) -> [String]
drawChar frame ((x,y),(vx,vy)) =
    if x < 0 || x >= sizeX || y < 0 || y >= sizeY then frame
    else 
        (take mappedY frame) 
        ++ 
            [
                (take mappedX row) 
                ++ 
                    [
                        if char /= ' '                           then 'x'
                        else if vy == 0 || abs (vx `div` vy) > 2 then '-'
                        else if vx == 0 || abs (vy `div` vx) > 2 then '|'
                        else if vx * vy >= 0                     then '/'
                        else                                          '\\'
                    ]
                ++ (drop (mappedX + 1) row) 
            ] 
        ++ (drop (mappedY + 1) frame)
    where 
        reversedY = sizeY - y
        mappedX = x `div` 10
        mappedY = reversedY `div` 10
        row = frame !! mappedY
        char = row !! mappedX

불꽃 놀이 정의를 제외한 Tcl8.5 913 바이트의 초안 :

set 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
}

namespace import tcl::mathop::*
proc @ {a args} {interp alias {} $a {} {*}$args}
@ : proc
@ = set
@ D d p
@ up upvar 1
@ < append out
@ _ foreach
@ e info exists
@ ? if
: P {s d t l} {+ $s [* $d [- $t $l]]}
: > x {= x}
: d {P x X y Y} {up $P p
= x [/ $x 10]
= y [/ $y 10]
= p($x,$y) [? [e p($x,$y)] {> X} elseif {
$Y==0||abs($X)/abs($Y)>2} {> -} elseif {
$X==0||abs($Y)/abs($X)>2} {> |} elseif {
$X*$Y<0} {> \\} {> /}]}
: r {P} {up $P p
= out ""
for {= y 23} {$y >= 0} {incr y -1} {
for {= x 0} {$x < 79} {incr x} {? {[e p($x,$y)]} {< $p($x,$y)} {< " "}}
< "\n"}
puts $out}
: s {F t} {array set p {}
_ {x X Y l d} $F {? {$t >= $l} {? {$t < $d} {= x [P $x $X $t $l]
= y [P 0 $Y $t $l]
D $x $X $y $Y} {= x [P $x $X $d $l]
= y [P 0 $Y $d $l]
= v [- $t $d]
_ dx {-20 0 20} {_ dy {-10 0 10} {= A [+ $X $dx]
= B [- [+ $Y $dy] [* 2 $v]]
= xx [P $x $A $v 0]
= yy [P $y $B $v 0]
D $xx $A $yy $B}}}}}
r p}
s $F [lindex $argv 0]

읽을 수없는 지점에 최적화되었습니다. 여전히 개선 할 여지를 찾고 있습니다. 대부분의 압축은 기본적으로 명령 이름을 단일 문자로 대체하는 명령 별칭을 사용합니다. 예를 들어 함수 정의는 Forth-like : 구문을 사용하여 수행됩니다.

압축되지 않은 버전은 다음과 같습니다.

namespace import tcl::mathop::*

set 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
}

proc position {start speed time launch} {
    + $start [* $speed [- $time $launch]]
}

proc give {x} {return $x}

proc draw {particles x speedX y speedY} {
    upvar 1 $particles p
    set x [/ $x 10]
    set y [/ $y 10]
    set p($x,$y) [if [info exists p($x,$y)] {
            give X
        } elseif {$speedY == 0 || abs(double($speedX))/abs($speedY) > 2} {
            give -
        } elseif {$speedX == 0 || abs(double($speedY))/abs($speedX) > 2} {
            give |
        } elseif {$speedX * $speedY < 0} {
            give \\
        } else {
            give /
        }
    ]
}

proc render {particles} {
    upvar 1 $particles p
    set out ""
    for {set y 23} {$y >= 0} {incr y -1} {
        for {set x 0} {$x < 79} {incr x} {
            if {[info exists p($x,$y)]} {
                append out $p($x,$y)
            } else {
                append out " "
            }
        }
        append out "\n"
    }
    puts $out
}

proc show {fireworks time} {
    array set particles {}
    foreach {x speedX speedY launch detonate} $fireworks {
        if {$time >= $launch} {
            if {$time < $detonate} {
                set x [position $x $speedX $time $launch]
                set y [position 0 $speedY $time $launch]
                draw particles $x $speedX $y $speedY
            } else {
                set x [position $x $speedX $detonate $launch]
                set y [position 0 $speedY $detonate $launch]
                set travel [- $time $detonate]
                foreach dx {-20 0 20} {
                    foreach dy {-10 0 10} {
                        set speedXX [+ $speedX $dx]
                        set speedYY [- [+ $speedY $dy] [* 2 $travel]]
                        set xx [position $x $speedXX $travel 0]
                        set yy [position $y $speedYY $travel 0]
                        draw particles $xx $speedXX $yy $speedYY
                    }
                }
            }
        }
    }
    render particles
}
show $fireworks [lindex $argv 0]

첫 번째 게시물 hahaha http://zipts.com/position.php?s=0 내 최종 제출물은 아니지만 저항 할 수 없음

Btw : 문자 937은 공백을 계산하지 않습니다 (공백을 계산합니까?).


내 대답은 http://www.starenterprise.se/fireworks.html에 있습니다. 그리고 나는 그것을 짧게 만들려고 신경 쓰지 않았고 단지 내가 할 수 있는지보고 싶었습니다.


클로저

들여 쓰기없이, 입력 출력과 불필요한 공백없이 640 자에 이르게됩니다. 정확히 가장 좋은 값의 두 배입니다. :( 따라서 간결하게 이기기 위해 "공백 최적화"버전을 제공하지 않습니다.

(def fw [
[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]
])
(defn rr [x y u v dt g] (if (<= dt 0) [x y u v] (recur (+ x u) (+ y v) u (+ v g) (dec dt) g)))

(defn pp [t f]
  (let [y 0 [x u v a d] f r1 (rr x y u v (- (min t d) a) 0)]
    (if (< t a)
      '()
      (if (< t d)
        (list r1)
        (for [m '(-20 0 20) n '(-10 0 10)]
          (let [[x y u v] r1]
            (rr x y (+ u m) (+ v n) (- t d) -2)))))))

(defn at [x y t]
  (filter #(and (= x (quot (first %) 10)) (= y (quot (second %) 10))) (apply concat (map #(pp t %) fw))))

(defn g [h]
  (if (empty? h) \space
    (if (next h) \X
      (let [[x y u v] (first h)]
        (cond
          (or (zero? v) (> (* (/ u v) (/ u v)) 4)) \-
          (or (zero? u) (> (* (/ v u) (/ v u)) 4)) \|
          (= (neg? u) (neg? v)) \/
          :else \\
        )))))

(defn q [t]
  (doseq [r (range 23 -1 -1)]
    (doseq [c (range 0 80)]
      (print (g (at c r t))))
    (println)))

(q 93)

참고 URL : https://stackoverflow.com/questions/1947031/code-golf-new-years-fireworks

반응형