9 #if 0 // sample problem
11 char initial
[] = "1.11.23";
12 // "hydrogen", "lithium",
14 #elif 0 // day11.input, part 1
16 char initial
[] = "1.13333.12222";
17 // "promethium", "cobalt", "Curium", "ruthenium", "Plutonium",
19 #else // day11.input, part 2
21 char initial
[] = "1.1333311.1222211";
22 // "promethium", "cobalt", "Curium", "ruthenium", "Plutonium", "elerium",
27 typedef struct state state
;
35 char items
[PAIRS
* 2];
39 char cache
[1 << ((PAIRS
* 2 + 1) * 2 - 3)];
43 int h
= s
->elevator
- 1;
44 for (int i
= 0; i
< PAIRS
* 2; i
++)
45 h
= (h
<< 2) + s
->items
[i
] - 1;
52 if (s
->elevator
< 1 || s
->elevator
> 4)
54 for (int i
= 0; i
< PAIRS
; i
++) {
55 if (s
->chips
[i
] == s
->gens
[i
]) // A chip with own generator is safe
57 for (int j
= 0; j
< PAIRS
; j
++) {
60 if (s
->chips
[i
] == s
->gens
[j
]) // A chip with any other generator fails
64 // No point revisiting a configuration already seen
66 if (cache
[h
>> 3] & (1 << (h
& 3)))
68 cache
[h
>> 3] |= 1 << (h
& 3);
75 for (int i
= 0; i
< PAIRS
* 2; i
++)
82 parse (const char *str
)
84 state
*s
= malloc (sizeof *s
);
86 s
->elevator
= *p
++ - '0';
89 for (int i
= 0; i
< PAIRS
; i
++)
90 s
->chips
[i
] = *p
++ - '0';
93 for (int i
= 0; i
< PAIRS
; i
++)
94 s
->gens
[i
] = *p
++ - '0';
101 out (state
*s
, FILE *f
)
103 putc (s
->elevator
+ '0', f
);
105 for (int i
= 0; i
< PAIRS
; i
++)
106 putc (s
->chips
[i
] + '0', f
);
108 for (int i
= 0; i
< PAIRS
; i
++)
109 putc (s
->gens
[i
] + '0', f
);
115 generate (state
*s
, FILE *f
)
121 for (i
= 0; i
< PAIRS
* 2; i
++)
122 if (e
== s
->items
[i
])
124 if (getenv ("DEBUG"))
125 printf ("%d items to choose from, producing up to %d states\n", count
,
126 count
* (count
+ 1));
128 for (i
= 0; i
< PAIRS
* 2; i
++) {
129 if (e
== s
->items
[i
]) {
133 for (j
= i
+ 1; j
< PAIRS
* 2; j
++)
134 if (e
== s
->items
[j
]) {
144 for (i
= 0; i
< PAIRS
* 2; i
++) {
145 if (e
== s
->items
[i
]) {
149 for (j
= i
+ 1; j
< PAIRS
* 2; j
++)
150 if (e
== s
->items
[j
]) {
163 int main(int argc
, char **argv
)
166 char *str1
= initial
, *str2
= NULL
;
167 size_t size1
= strlen (str1
), size2
= 0;
171 printf (" starting generation %d\n", ++generations
);
174 f
= open_memstream (&str2
, &size2
);
176 char *q
= strchrnul (p
, '\n');
177 state
*s
= parse (p
);
178 if (getenv ("DEBUG"))
185 } while (p
< str1
+ size1
- 1);
186 printf (" generation %d visited %d states\n", generations
, seen
);
195 printf ("found solution in %d generations\n", generations
);