10 static int debug_level
= -1;
11 static void __attribute__((unused
))
12 debug_raw(int level
, const char *fmt
, ...) {
15 debug_level
= atoi(getenv("DEBUG") ?: "0");
16 if (debug_level
>= level
) {
18 vfprintf(stderr
, fmt
, ap
);
22 #define debug(...) debug_raw(1, __VA_ARGS__)
28 static struct point a
[4], orig
[4];
29 static int perx
, pery
, perz
;
35 printf("After %d steps:\n", step
);
36 for (i
= 0; i
< 4; i
++)
37 printf("pos=<x=%3d, y=%3d, z=%3d>, vel=<x=%3d, y=%3d, z=%3d>\n",
38 a
[i
].px
, a
[i
].py
, a
[i
].pz
, a
[i
].vx
, a
[i
].vy
, a
[i
].vz
);
42 gravity_one(int one
, int two
) {
43 if (a
[one
].px
< a
[two
].px
) {
46 } else if (a
[one
].px
> a
[two
].px
) {
50 if (a
[one
].py
< a
[two
].py
) {
53 } else if (a
[one
].py
> a
[two
].py
) {
57 if (a
[one
].pz
< a
[two
].pz
) {
60 } else if (a
[one
].pz
> a
[two
].pz
) {
80 for (i
= 0; i
< 4; i
++) {
91 printf("after %d steps, ", i
);
92 for (i
= 0; i
< 4; i
++)
93 t
+= (abs(a
[i
].px
) + abs(a
[i
].py
) + abs(a
[i
].pz
)) *
94 (abs(a
[i
].vx
) + abs(a
[i
].vy
) + abs(a
[i
].vz
));
95 printf("energy is %d\n", t
);
98 static struct collision
{
110 static void check_collide(struct point
*p1
, struct point
*p2
,
111 struct collision
*c
, int i
) {
112 if (!perx
&& p1
->px
== p2
->px
&& i
% 6 == 5) {
120 if (!pery
&& p1
->py
== p2
->py
&& i
% 6 == 5) {
128 if (!perz
&& p1
->pz
== p2
->pz
&& i
% 6 == 5) {
136 if (p1
->px
== p2
->px
&& p1
->py
== p2
->py
&& p1
->pz
== p2
->pz
) {
137 printf("collision occurred!");
144 check_collide(&a
[0], &a
[1], &collide
[0], i
);
145 check_collide(&a
[0], &a
[2], &collide
[1], i
);
146 check_collide(&a
[0], &a
[3], &collide
[2], i
);
147 check_collide(&a
[1], &a
[2], &collide
[3], i
);
148 check_collide(&a
[1], &a
[3], &collide
[4], i
);
149 check_collide(&a
[2], &a
[3], &collide
[5], i
);
150 if (!perx
&& !(a
[0].vx
| a
[1].vx
| a
[2].vx
| a
[3].vx
) &&
151 a
[0].px
== orig
[0].px
&& a
[1].px
== orig
[1].px
&&
152 a
[2].px
== orig
[2].px
&& a
[3].px
== orig
[3].px
) {
155 if (!pery
&& !(a
[0].vy
| a
[1].vy
| a
[2].vy
| a
[3].vy
) &&
156 a
[0].py
== orig
[0].py
&& a
[1].py
== orig
[1].py
&&
157 a
[2].py
== orig
[2].py
&& a
[3].py
== orig
[3].py
) {
160 if (!perz
&& !(a
[0].vz
| a
[1].vz
| a
[2].vz
| a
[3].vz
) &&
161 a
[0].pz
== orig
[0].pz
&& a
[1].pz
== orig
[1].pz
&&
162 a
[2].pz
== orig
[2].pz
&& a
[3].pz
== orig
[3].pz
) {
165 return perx
&& pery
&& perz
;
169 gcd(long long one
, long long two
) {
173 return gcd(one
- two
, two
);
174 return gcd(one
, two
- one
);
177 int main(int argc
, char **argv
) {
178 int i
, limit
= 1000000, progress
;
181 if (argc
> 1 && strcmp(argv
[1], "-"))
182 if (!(stdin
= freopen(argv
[1], "r", stdin
))) {
188 limit
= atoi(argv
[2]);
190 progress
= atoi(argv
[3]);
192 progress
= limit
/ 10;
194 for (i
= 0; i
< 4; i
++)
195 if (scanf("<x=%d, y=%d, z=%d>\n", &a
[i
].px
, &a
[i
].py
, &a
[i
].pz
) != 3) {
196 printf("unexpected input\n");
199 memcpy(orig
, a
, sizeof a
);
200 for (i
= 0; i
< limit
; i
++) {
204 } else if (i
== 1000)
215 if (perx
&& pery
&& perz
) {
217 printf("cycles at %d %d %d\n", perx
, pery
, perz
);
218 tmp
= perx
/ gcd(perx
, pery
) * pery
;
219 printf("overall at %lld\n", tmp
/ gcd(tmp
, perz
) * perz
);
221 printf("must run longer to find cycles\n");
223 for (i
= 0; i
< 6; i
++)
224 if (collide
[i
].x
&& collide
[i
].y
&& collide
[i
].z
)
225 debug("potential collision in pair %d? %d(+%d)@%d, %d(+%d)@%d, "
227 collide
[i
].x
, collide
[i
].nx
, collide
[i
].px
,
228 collide
[i
].y
, collide
[i
].ny
, collide
[i
].py
,
229 collide
[i
].z
, collide
[i
].nz
, collide
[i
].pz
);