9 static int do_debug
= -1;
10 void debug(const char *fmt
, ...) {
13 do_debug
= !!getenv("DEBUG");
16 vfprintf(stderr
, fmt
, ap
);
35 struct react list
[LIMIT
] = { { .out
= "ORE", .produce
= 1,
36 .avail
= 1000000000000LL, }, };
39 static long long produced
;
41 static int __attribute__((noreturn
))
42 die(const char *fmt
, ...)
53 find(const char *name
, int *idx
) {
58 for (i
= 0; i
<= count
; i
++)
59 if (!strcmp(list
[i
].out
, name
))
61 die("missing rule for %s", name
);
65 produce(int idx
, long long amt
) {
67 long long need
= amt
- list
[idx
].avail
;
68 long long mult
= need
> 0 ? (need
+ list
[idx
].produce
69 - 1) / list
[idx
].produce
: 0;
71 debug("want %lld of %s, have %lld, needs %lld more batches\n", amt
,
72 list
[idx
].out
, list
[idx
].avail
, mult
);
75 for (i
= 0; i
< list
[idx
].n_in
; i
++)
76 if (!produce(find(list
[idx
].in
[i
].in
, &list
[idx
].in
[i
].idx
),
77 mult
* list
[idx
].in
[i
].consume
))
79 list
[idx
].avail
+= mult
* list
[idx
].produce
- amt
;
85 int main(int argc
, char **argv
) {
90 if (!(stdin
= freopen(argv
[1], "r", stdin
))) {
95 while ((ch
= getchar()) != EOF
) {
98 die("recompile with larger LIMIT");
102 if (scanf(" %d %5[A-Z]", &list
[count
].in
[i
].consume
,
103 list
[count
].in
[i
].in
) != 2)
104 die("parse failure at line %d", count
- 1);
105 list
[count
].in
[i
].idx
= -1;
107 die("recompile with larger MAXIN");
108 } while (getchar() != ' ');
109 list
[count
].n_in
= i
;
110 if (scanf("=> %d %5[A-Z]\n", &list
[count
].produce
, list
[count
].out
) != 2)
111 die("parse failure at line %d", count
- 1);
112 if (!strcmp(list
[count
].out
, "FUEL"))
114 debug("parsed instructions for %d %s from %d inputs\n",
115 list
[count
].produce
, list
[count
].out
, list
[count
].n_in
);
117 printf("scanned %d formulas, fuel at line %d\n", count
, fuel_idx
- 1);
119 if (!produce(fuel_idx
, 1))
120 die("unable to produce 1 fuel");
121 min
= 1000000000000LL - list
[0].avail
;
122 printf("1 fuel requires %lld ore\n", min
);
123 while (list
[0].avail
> min
) {
124 printf("producing %lld more...\n", list
[0].avail
/ min
);
125 if (!produce(fuel_idx
, list
[0].avail
/ min
))
126 die("unexpected failure in bulk production");
128 while (produce(fuel_idx
, 1))
129 printf("at %lld, used up spares for 1 more...\n", produced
);
130 printf("produced %lld total\n", produced
);