Skip to content

Commit 84eec7e

Browse files
committed
Add solution for 2019/day14/part2
1 parent 5cfc5ec commit 84eec7e

File tree

4 files changed

+133
-107
lines changed

4 files changed

+133
-107
lines changed

.readme/solutions.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
"intcode.py", "intcode.py",
6868
"gravity.go", null,
6969
"runner.php", null,
70-
"one-fuel.php", null,
70+
"ore-to-fuel.php", "ore-to-fuel.php",
7171
null, null,
7272
"fft.go", null,
7373
null, null,

2019/day14/one-fuel.php

-104
This file was deleted.

2019/day14/ore-to-fuel.php

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#!/usr/bin/php
2+
<?php
3+
4+
function parse_input() {
5+
$recipes = [];
6+
while(($line = fgets(STDIN)) !== false) {
7+
$line = trim($line);
8+
if($line === '') continue;
9+
10+
[$input, $output] = explode('=>', $line);
11+
[$out_count, $out_name] = str_to_ingredient($output);
12+
13+
$inputs = [];
14+
foreach(explode(',', $input) as $i) {
15+
[$count, $name] = str_to_ingredient($i);
16+
$inputs[$name] = $count;
17+
}
18+
19+
$recipes[$out_name] = [
20+
'count' => $out_count,
21+
'input' => $inputs,
22+
];
23+
}
24+
return $recipes;
25+
}
26+
27+
function str_to_ingredient($str) {
28+
$result = explode(' ', trim($str));
29+
$result[0] = (int)$result[0];
30+
return $result;
31+
}
32+
33+
function print_list($header, $list) {
34+
$fmt = [];
35+
foreach($list as $name => $count) {
36+
if($count > 0) {
37+
$fmt[] = $count . ' ' . $name;
38+
}
39+
}
40+
41+
if(count($fmt) > 0) {
42+
echo $header, ': ', implode(', ', $fmt), "\n";
43+
} else {
44+
echo $header, ": (nothing)\n";
45+
}
46+
}
47+
48+
function use_recipe($recipes, $name, &$need, &$have) {
49+
if($name === 'ORE') return false;
50+
51+
$count = $need[$name];
52+
if($count === 0) return false;
53+
54+
$reactions = ceil($count / $recipes[$name]['count']);
55+
foreach($recipes[$name]['input'] as $in_name => $in_count) {
56+
$in_need = $reactions * $in_count;
57+
if(isset($have[$in_name])) {
58+
if($have[$in_name] >= $in_need) {
59+
$have[$in_name] -= $in_need;
60+
$in_need = 0;
61+
} else {
62+
$in_need -= $have[$in_name];
63+
$have[$in_name] = 0;
64+
}
65+
}
66+
67+
if($in_need > 0) {
68+
if(!isset($need[$in_name])) {
69+
$need[$in_name] = 0;
70+
}
71+
$need[$in_name] += $in_need;
72+
}
73+
}
74+
75+
if(!isset($have[$name])) {
76+
$have[$name] = 0;
77+
}
78+
$have[$name] += ($reactions * $recipes[$name]['count']) - $count;
79+
$need[$name] = 0;
80+
81+
return true;
82+
}
83+
84+
function calc_ore_for_fuel($recipes, $fuel_count, $print = false) {
85+
$need = ['FUEL' => $fuel_count];
86+
$have = [];
87+
88+
while(true) {
89+
if($print) {
90+
print_list('Need', $need);
91+
print_list('Have', $have);
92+
}
93+
94+
$changed = false;
95+
foreach($need as $name => $_) {
96+
$changed = $changed || use_recipe($recipes, $name, $need, $have);
97+
}
98+
if(!$changed) break;
99+
}
100+
return $need['ORE'];
101+
}
102+
103+
# -- part 1
104+
105+
$recipes = parse_input();
106+
$ore = calc_ore_for_fuel($recipes, 1, true);
107+
echo '=> Part 1: need ', $ore, " ORE to produce 1 FUEL\n";
108+
109+
# -- part 2
110+
# the "ore cost for X units of fuel" calculation is quite cheap,
111+
# so just binary-search for the answer
112+
113+
const TRILLION = 1000000000000;
114+
115+
$min_fuel = (int)floor(TRILLION / $ore); // Naive answer
116+
$max_fuel = $min_fuel * 2; // Gotta guess somehow
117+
118+
while($min_fuel !== $max_fuel) {
119+
$mid_fuel = (int)ceil(($min_fuel + $max_fuel) / 2); // Round up because we want to prefer lowering max over raising min
120+
$mid_cost = calc_ore_for_fuel($recipes, $mid_fuel);
121+
122+
printf('Checking fuel cost for range %d - %d: need %13d ORE for %d FUEL%s', $min_fuel, $max_fuel, $mid_cost, $mid_fuel, "\n");
123+
if($mid_cost <= TRILLION) {
124+
$min_fuel = $mid_fuel;
125+
} else {
126+
$max_fuel = $mid_fuel - 1;
127+
}
128+
}
129+
echo '=> Part 2: need ', calc_ore_for_fuel($recipes, $min_fuel), ' ORE to produce ', $min_fuel, " FUEL\n";
130+

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ be broken, as in "it worked with my input" – but might fail with yours.
3939
| **12½** | | [![Awful](https://github.com/suve/advent-of-code/raw/master/.readme/yuk.png)](2020/day12/waypoint.yuk) | | [![Bash](https://github.com/suve/advent-of-code/raw/master/.readme/sh.png)](2018/day12/ancient-plants.sh) | [![Pascal](https://github.com/suve/advent-of-code/raw/master/.readme/pas.png)](2017/day12/pipes.pas) |
4040
| **13** | | [![JavaScript](https://github.com/suve/advent-of-code/raw/master/.readme/js.png)](2020/day13/buses.js) | [![PHP](https://github.com/suve/advent-of-code/raw/master/.readme/php.png)](2019/day13/runner.php) | [![C](https://github.com/suve/advent-of-code/raw/master/.readme/c.png)](2018/day13/carts.c) | [![Awful](https://github.com/suve/advent-of-code/raw/master/.readme/yuk.png)](2017/day13/firewall.yuk) |
4141
| **13½** | | [![PHP](https://github.com/suve/advent-of-code/raw/master/.readme/php.png)](2020/day13/timestamp.php) | | [![C](https://github.com/suve/advent-of-code/raw/master/.readme/c.png)](2018/day13/carts.c) | [![Awful](https://github.com/suve/advent-of-code/raw/master/.readme/yuk.png)](2017/day13/firewall.yuk) |
42-
| **14** | | [![Rust](https://github.com/suve/advent-of-code/raw/master/.readme/rs.png)](2020/day14/bitmask.rs) | [![PHP](https://github.com/suve/advent-of-code/raw/master/.readme/php.png)](2019/day14/one-fuel.php) | [![C](https://github.com/suve/advent-of-code/raw/master/.readme/c.png)](2018/day14/recipes.c) | [![C](https://github.com/suve/advent-of-code/raw/master/.readme/c.png)](2017/day14/knot-again.c) |
43-
| **14½** | | [![Rust](https://github.com/suve/advent-of-code/raw/master/.readme/rs.png)](2020/day14/bitmask2.rs) | | [![C](https://github.com/suve/advent-of-code/raw/master/.readme/c.png)](2018/day14/recipes.c) | [![C](https://github.com/suve/advent-of-code/raw/master/.readme/c.png)](2017/day14/knot-again.c) |
42+
| **14** | | [![Rust](https://github.com/suve/advent-of-code/raw/master/.readme/rs.png)](2020/day14/bitmask.rs) | [![PHP](https://github.com/suve/advent-of-code/raw/master/.readme/php.png)](2019/day14/ore-to-fuel.php) | [![C](https://github.com/suve/advent-of-code/raw/master/.readme/c.png)](2018/day14/recipes.c) | [![C](https://github.com/suve/advent-of-code/raw/master/.readme/c.png)](2017/day14/knot-again.c) |
43+
| **14½** | | [![Rust](https://github.com/suve/advent-of-code/raw/master/.readme/rs.png)](2020/day14/bitmask2.rs) | [![PHP](https://github.com/suve/advent-of-code/raw/master/.readme/php.png)](2019/day14/ore-to-fuel.php) | [![C](https://github.com/suve/advent-of-code/raw/master/.readme/c.png)](2018/day14/recipes.c) | [![C](https://github.com/suve/advent-of-code/raw/master/.readme/c.png)](2017/day14/knot-again.c) |
4444
| **15** | | [![Rust](https://github.com/suve/advent-of-code/raw/master/.readme/rs.png)](2020/day15/numbers.rs) | | | [![C](https://github.com/suve/advent-of-code/raw/master/.readme/c.png)](2017/day15/generators.c) |
4545
| **15½** | | [![Rust](https://github.com/suve/advent-of-code/raw/master/.readme/rs.png)](2020/day15/numbers.rs) | | | [![C](https://github.com/suve/advent-of-code/raw/master/.readme/c.png)](2017/day15/generators.c) |
4646
| **16** | | [![PHP](https://github.com/suve/advent-of-code/raw/master/.readme/php.png)](2020/day16/tickets.php) | [![Go](https://github.com/suve/advent-of-code/raw/master/.readme/go.png)](2019/day16/fft.go) | [![C](https://github.com/suve/advent-of-code/raw/master/.readme/c.png)](2018/day16/opcodes.c) | [![Awful](https://github.com/suve/advent-of-code/raw/master/.readme/yuk.png)](2017/day16/dance.yuk) |

0 commit comments

Comments
 (0)