12 static int debug_level
= -1;
16 debug_level
= atoi(getenv("DEBUG") ?: "0");
19 static void __attribute__((format(printf
, 2, 3)))
20 debug_raw(int level
, const char *fmt
, ...) {
23 debug_level
= atoi(getenv("DEBUG") ?: "0");
24 if (debug_level
>= level
) {
26 vfprintf(stderr
, fmt
, ap
);
30 #define debug(...) debug_raw(1, __VA_ARGS__)
32 static int __attribute__((noreturn
)) __attribute__((format(printf
, 1, 2)))
33 die(const char *fmt
, ...)
44 static bool seen
[1<<25];
45 static int chain
[2][LIMIT
+ 3];
48 dump(int gen
, int val
) {
51 debug("at generation/level %d 0x%x:\n", gen
, val
);
52 for (i
= 0; i
< 25; i
++) {
53 debug("%c", ".#"[!!(val
& (1 << i
))]);
60 generation1(int val
) {
61 unsigned long long l
= 0;
64 for (i
= 0; i
< 5; i
++)
65 l
|= (val
& (0x1fULL
<< (5 * i
))) << (8 + 2 * i
);
66 for (val
= i
= 0; i
< 25; i
++) {
67 m
= i
/ 5 * 7 + i
% 5;
68 t
= __builtin_popcountll(l
& (0x8382ULL
<< m
));
69 val
|= (t
== 2 || t
== 2 - !(l
& (1ULL << (m
+ 8)))) << i
;
75 generation2_one(int *p
) {
78 if (!(p
[-1] | p
[0] | p
[1]))
81 /* 1: [-1]12, [-1]8, [0]2, [0]6 */
82 t
= 4 - (!(p
[-1] & (1 << 11)) + !(p
[-1] & (1 << 7)) +
83 !(p
[0] & (1 << 1)) + !(p
[0] & (1 << 5)));
84 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 0))) << 0;
86 /* 2: [0]1, [-1]8, [0]3, [0]7 */
87 t
= 4 - (!(p
[0] & (1 << 0)) + !(p
[-1] & (1 << 7)) +
88 !(p
[0] & (1 << 2)) + !(p
[0] & (1 << 6)));
89 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 1))) << 1;
91 /* 3: [0]2, [-1]8, [0]4, [0]8 */
92 t
= 4 - (!(p
[0] & (1 << 1)) + !(p
[-1] & (1 << 7)) +
93 !(p
[0] & (1 << 3)) + !(p
[0] & (1 << 7)));
94 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 2))) << 2;
96 /* 4: [0]3, [-1]8, [0]5, [0]9 */
97 t
= 4 - (!(p
[0] & (1 << 2)) + !(p
[-1] & (1 << 7)) +
98 !(p
[0] & (1 << 4)) + !(p
[0] & (1 << 8)));
99 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 3))) << 3;
101 /* 5: [0]4, [-1]8, [-1]14, [0]10 */
102 t
= 4 - (!(p
[0] & (1 << 3)) + !(p
[-1] & (1 << 7)) +
103 !(p
[-1] & (1 << 13)) + !(p
[0] & (1 << 9)));
104 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 4))) << 4;
106 /* 6: [-1]12, [0]1, [0]7, [0]11 */
107 t
= 4 - (!(p
[-1] & (1 << 11)) + !(p
[0] & (1 << 0)) +
108 !(p
[0] & (1 << 6)) + !(p
[0] & (1 << 10)));
109 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 5))) << 5;
111 /* 7: [0]6, [0]2, [0]8, [0]12 */
112 t
= 4 - (!(p
[0] & (1 << 5)) + !(p
[0] & (1 << 1)) +
113 !(p
[0] & (1 << 7)) + !(p
[0] & (1 << 11)));
114 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 6))) << 6;
116 /* 8: [0]7, [0]3, [0]9, [1]1, [1]2, [1]3, [1]4, [1]5 */
117 t
= 8 - (!(p
[0] & (1 << 6)) + !(p
[0] & (1 << 2)) +
118 !(p
[0] & (1 << 8)) + !(p
[1] & (1 << 0)) +
119 !(p
[1] & (1 << 1)) + !(p
[1] & (1 << 2)) +
120 !(p
[1] & (1 << 3)) + !(p
[1] & (1 << 4)));
121 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 7))) << 7;
123 /* 9: [0]8, [0]4, [0]10, [0]14 */
124 t
= 4 - (!(p
[0] & (1 << 7)) + !(p
[0] & (1 << 3)) +
125 !(p
[0] & (1 << 9)) + !(p
[0] & (1 << 13)));
126 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 8))) << 8;
128 /* 10: [0]9, [0]5, [-1]14, [0]15 */
129 t
= 4 - (!(p
[0] & (1 << 8)) + !(p
[0] & (1 << 4)) +
130 !(p
[-1] & (1 << 13)) + !(p
[0] & (1 << 14)));
131 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 9))) << 9;
133 /* 11: [-1]12, [0]6, [0]12, [0]16 */
134 t
= 4 - (!(p
[-1] & (1 << 11)) + !(p
[0] & (1 << 5)) +
135 !(p
[0] & (1 << 11)) + !(p
[0] & (1 << 15)));
136 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 10))) << 10;
138 /* 12: [0]11, [0]7, [1]1, [1]6, [1]11, [1]16, [1]21, [0]17 */
139 t
= 8 - (!(p
[0] & (1 << 10)) + !(p
[0] & (1 << 6)) +
140 !(p
[1] & (1 << 0)) + !(p
[1] & (1 << 5)) +
141 !(p
[1] & (1 << 10)) + !(p
[1] & (1 << 15)) +
142 !(p
[1] & (1 << 20)) + !(p
[0] & (1 << 16)));
143 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 11))) << 11;
145 /* 14: [1]5, [1]10, [1]15, [1]20, [1]25, [0]9, [0]15, [0]19 */
146 t
= 8 - (!(p
[1] & (1 << 4)) + !(p
[1] & (1 << 9)) +
147 !(p
[1] & (1 << 14)) + !(p
[1] & (1 << 19)) +
148 !(p
[1] & (1 << 24)) + !(p
[0] & (1 << 8)) +
149 !(p
[0] & (1 << 14)) + !(p
[0] & (1 << 18)));
150 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 13))) << 13;
152 /* 15: [0]14, [0]10, [-1]14, [0]20 */
153 t
= 4 - (!(p
[0] & (1 << 13)) + !(p
[0] & (1 << 9)) +
154 !(p
[-1] & (1 << 13)) + !(p
[0] & (1 << 19)));
155 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 14))) << 14;
157 /* 16: [-1]12, [0]11, [0]17, [0]21 */
158 t
= 4 - (!(p
[-1] & (1 << 11)) + !(p
[0] & (1 << 10)) +
159 !(p
[0] & (1 << 16)) + !(p
[0] & (1 << 20)));
160 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 15))) << 15;
162 /* 17: [0]16, [0]12, [0]18, [0]22 */
163 t
= 4 - (!(p
[0] & (1 << 15)) + !(p
[0] & (1 << 11)) +
164 !(p
[0] & (1 << 17)) + !(p
[0] & (1 << 21)));
165 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 16))) << 16;
167 /* 18: [0]17, [1]21, [1]22, [1]23, [1]24, [1]25, [0]19, [0]23 */
168 t
= 8 - (!(p
[0] & (1 << 16)) + !(p
[1] & (1 << 20)) +
169 !(p
[1] & (1 << 21)) + !(p
[1] & (1 << 22)) +
170 !(p
[1] & (1 << 23)) + !(p
[1] & (1 << 24)) +
171 !(p
[0] & (1 << 18)) + !(p
[0] & (1 << 22)));
172 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 17))) << 17;
174 /* 19: [0]18, [0]14, [0]20, [0]24 */
175 t
= 4 - (!(p
[0] & (1 << 17)) + !(p
[0] & (1 << 13)) +
176 !(p
[0] & (1 << 19)) + !(p
[0] & (1 << 23)));
177 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 18))) << 18;
179 /* 20: [0]19, [0]15, [-1]14, [0]25 */
180 t
= 4 - (!(p
[0] & (1 << 18)) + !(p
[0] & (1 << 14)) +
181 !(p
[-1] & (1 << 13)) + !(p
[0] & (1 << 24)));
182 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 19))) << 19;
184 /* 21: [-1]12, [0]16, [0]22, [-1]18 */
185 t
= 4 - (!(p
[-1] & (1 << 11)) + !(p
[0] & (1 << 15)) +
186 !(p
[0] & (1 << 21)) + !(p
[-1] & (1 << 17)));
187 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 20))) << 20;
189 /* 22: [0]21, [0]17, [0]23, [-1]18 */
190 t
= 4 - (!(p
[0] & (1 << 20)) + !(p
[0] & (1 << 16)) +
191 !(p
[0] & (1 << 22)) + !(p
[-1] & (1 << 17)));
192 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 21))) << 21;
194 /* 23: [0]22, [0]18, [0]24, [-1]18 */
195 t
= 4 - (!(p
[0] & (1 << 21)) + !(p
[0] & (1 << 17)) +
196 !(p
[0] & (1 << 23)) + !(p
[-1] & (1 << 17)));
197 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 22))) << 22;
199 /* 24: [0]23, [0]19, [0]25, [-1]18 */
200 t
= 4 - (!(p
[0] & (1 << 22)) + !(p
[0] & (1 << 18)) +
201 !(p
[0] & (1 << 24)) + !(p
[-1] & (1 << 17)));
202 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 23))) << 23;
204 /* 25: [0]24, [0]20, [-1]14, [-1]18 */
205 t
= 4 - (!(p
[0] & (1 << 23)) + !(p
[0] & (1 << 19)) +
206 !(p
[-1] & (1 << 13)) + !(p
[-1] & (1 << 17)));
207 r
|= (t
== 1 || t
== 1 + !(p
[0] & (1 << 24))) << 24;
217 for (i
= 1; i
<= LIMIT
+ 1; i
++)
218 t
+= __builtin_popcount(chain
[1 - g
% 2][i
] =
219 generation2_one(&chain
[g
% 2][i
]));
224 main(int argc
, char **argv
) {
225 int ch
, i
= 0, val
= 0;
229 if (argc
> 1 && strcmp(argv
[1], "-"))
230 if (!(stdin
= freopen(argv
[1], "r", stdin
))) {
235 limit
= atoi(argv
[2]);
236 if (limit
% 2 || limit
> LIMIT
)
237 die("need even limit less than %d", LIMIT
);
240 while ((ch
= getchar()) != EOF
) {
243 val
|= (ch
== '#') << i
++;
246 die("incorrect input");
247 chain
[0][limit
/ 2 + 1] = val
;
250 for (i
= 0; i
< limit
; i
++) {
252 val
= generation1(val
);
258 // die("recompile with larger LIMIT");
259 printf("part1: first repeating generation %d has score %d\n", i
, val
);
261 dump(-1, chain
[0][limit
/ 2]);
262 dump(0, chain
[0][limit
/ 2 + 1]);
263 dump(1, chain
[0][limit
/ 2 + 2]);
264 for (i
= 0; i
< limit
; i
++) {
265 val
= generation2(i
);
266 dump(-1, chain
[1 - i
% 2][limit
/ 2]);
267 dump(0, chain
[1 - i
% 2][limit
/ 2 + 1]);
268 dump(1, chain
[1 - i
% 2][limit
/ 2 + 2]);
270 printf("part2: after %d generations, there are %d bugs\n", i
, val
);