10 void debug(const char *fmt
, ...) {
12 if (getenv("DEBUG")) {
14 vfprintf(stderr
, fmt
, ap
);
23 static void dump(int g
, bool *a
) {
24 for (int i
= 0; i
< size
; i
++)
25 debug("%c", a
[i
] ? '#' : '.');
29 static void gen(int g
, bool *a
, bool *b
) {
33 debug("beginning generation %d\n", g
);
34 assert(!(a
[0] | a
[1] | a
[size
- 2] | a
[size
- 1]));
35 for (i
= 0; i
< size
- 2; i
++) {
36 act
= ((act
<< 1) & 0x1f) | a
[i
+ 2];
41 static int sum(int offset
, bool *a
) {
44 for (i
= 0; i
< size
; i
++)
50 int main(int argc
, char **argv
) {
51 size_t len
= 0, count
= 0;
59 /* Part 1 - read in initial line */
61 generations
= atoi(argv
[2]);
62 if (argc
> 1 && !(stdin
= freopen(argv
[1], "r", stdin
))) {
67 if (getline(&line
, &len
, stdin
) < 0 || getchar() != '\n') {
68 fprintf(stderr
, "bad input\n");
71 p
= strchr(line
, ':');
73 fprintf(stderr
, "bad input\n");
78 size
= strchr(p
, '\n') - p
+ 2 * offset
;
79 state
[0] = calloc(size
, sizeof(bool));
80 state
[1] = calloc(size
, sizeof(bool));
83 state
[0][count
++] = *p
++ == '#';
85 /* Part 2 - read in rules */
87 while (getline(&line
, &len
, stdin
) >= 0) {
90 for (i
= 0; i
< 5; i
++)
91 idx
= (idx
<< 1) | (line
[i
] == '#');
92 next
[idx
] = line
[9] == '#';
94 printf("Read %zu lines\n", count
);
95 assert(!(next
[0] | next
[1] | next
[16])); /* Otherwise offset is too small */
96 debug("%*c\n", offset
, '0');
99 /* Part 3 - determine output */
100 int s
= sum(offset
, state
[0]);
103 for (i
= 1; i
<= LIMIT
; i
++) {
105 gen(i
, state
[(i
+ 1) % 2], state
[i
% 2]);
106 dump(i
, state
[i
% 2]);
107 s2
= sum(offset
, state
[i
% 2]);
108 if (generations
== i
)
109 printf("sum at generation %d is %d\n", i
, s2
);
118 printf("pattern locked at diff of %d for last %zu iterations of %d\n",
120 printf("sum(%d) is %d, projection is %" PRId64
"\n", LIMIT
, s
,
121 diff
* (UINT64_C(50000000000) - LIMIT
) + s
);