Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code Golf: New Year's Fireworks [closed]

Heres my solution in 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)

Takes the time from the stdin and it has the nice number of 342 characters. I'm still trying to imagine how the OP got 320 :P

Edit: This is the best I could get, 322 chars acording to wc

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

Now that the winner is chosen – congratulations to Juan – here is my own solution, 304 characters in Python:

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

This is not really fast, because for each point in the 79x24 display, it loops through all fireworks to see if any of them is visible at this point.

Here is a version that tries to explain what's going on:

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

Python:

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)

If you remove the initial fireworks declaration, compress variable-names to single characters, and whitespace to a minimum, you can get 590 characters.


C:

With all unnecessary whitespace removed (632 bytes excluding the fireworks declaration):

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

And here's the exact same code with whitespace added for readability:

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