Skip to content

Commit 309ec7f

Browse files
committed
more Rust
1 parent 71633b3 commit 309ec7f

File tree

17 files changed

+528
-40
lines changed

17 files changed

+528
-40
lines changed

2017/day8/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ edition = "2021"
55

66
[dependencies]
77
aoc = { path = "../../aoc" }
8-
pest = "2"
9-
pest_derive = "2"
8+
pest = { version = "2", default-features = false }
9+
pest_derive = { version = "2", default-features = true }
1010
rustc-hash = "2.1.0"
1111

1212
[[bin]]

2017/day8/day8.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
use rustc_hash::FxHashMap;
44

55
use pest::Parser;
6-
use pest_derive::Parser as PestParser;
6+
use pest_derive::Parser;
77

8-
#[derive(PestParser, Debug)]
8+
#[derive(Parser)]
99
#[grammar = "day8.pest"]
1010
struct MyParser;
1111

2019/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# https://adventofcode.com/2018
1+
# https://adventofcode.com/2019
22

33
[workspace]
44
members = [
@@ -10,8 +10,10 @@ members = [
1010
"day8",
1111
"day10",
1212
"day12",
13+
"day14",
1314
"day16",
1415
"day18",
16+
"day20",
1517
"day22",
1618
"day24",
1719
]

2019/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
![AoC2019](https://img.shields.io/badge/Advent_of_Code-2019-8A2BE2)
44
![Stars: 50](https://img.shields.io/badge/Stars-50⭐-blue)
5-
![Rust: 12](https://img.shields.io/badge/Rust-12-cyan?logo=Rust)
5+
![Rust: 14](https://img.shields.io/badge/Rust-14-cyan?logo=Rust)
66
![Python: 23](https://img.shields.io/badge/Python-23-cyan?logo=Python)
77

88
## 2019 ([Calendar](https://adventofcode.com/2019)) ([Solutions](../2019/)) : 50⭐
@@ -22,13 +22,13 @@ Puzzle
2222
[Day 11: Space Police](https://adventofcode.com/2019/day/11) | ⭐⭐ | [![Python](../scripts/assets/python.png)](../2019/day11/day11.py)
2323
[Day 12: The N-Body Problem](https://adventofcode.com/2019/day/12) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2019/day12/day12.rs) [![Python](../scripts/assets/python.png)](../2019/day12/day12.py)
2424
[Day 13: Care Package](https://adventofcode.com/2019/day/13) | ⭐⭐ | [![Python](../scripts/assets/python.png)](../2019/day13/day13.py) [🎁](../2019/day13/README.md)
25-
[Day 14: Space Stoichiometry](https://adventofcode.com/2019/day/14) | ⭐⭐ | [![Python](../scripts/assets/python.png)](../2019/day14/day14.py)
25+
[Day 14: Space Stoichiometry](https://adventofcode.com/2019/day/14) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2019/day14/day14.rs) [![Python](../scripts/assets/python.png)](../2019/day14/day14.py)
2626
[Day 15: Oxygen System](https://adventofcode.com/2019/day/15) | ⭐⭐ | [![Python](../scripts/assets/python.png)](../2019/day15/day15.py) [🎁](../2019/day15/README.md)
2727
[Day 16: Flawed Frequency Transmission](https://adventofcode.com/2019/day/16) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2019/day16/day16.rs) [![Python](../scripts/assets/python.png)](../2019/day16/day16.py) [![C](../scripts/assets/c.png)](../2019/day16/day16.c)
2828
[Day 17: Set and Forget](https://adventofcode.com/2019/day/17) | ⭐⭐ | [![Python](../scripts/assets/python.png)](../2019/day17/day17.py)
2929
[Day 18: Many-Worlds Interpretation](https://adventofcode.com/2019/day/18) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2019/day18/src/main.rs)
3030
[Day 19: Tractor Beam](https://adventofcode.com/2019/day/19) | ⭐⭐ | [![Python](../scripts/assets/python.png)](../2019/day19/day19.py)
31-
[Day 20: Donut Maze](https://adventofcode.com/2019/day/20) | ⭐⭐ | [![Python](../scripts/assets/python.png)](../2019/day20/day20.py)
31+
[Day 20: Donut Maze](https://adventofcode.com/2019/day/20) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2019/day20/day20.rs) [![Python](../scripts/assets/python.png)](../2019/day20/day20.py)
3232
[Day 21: Springdroid Adventure](https://adventofcode.com/2019/day/21) | ⭐⭐ | [![Python](../scripts/assets/python.png)](../2019/day21/day21.py)
3333
[Day 22: Slam Shuffle](https://adventofcode.com/2019/day/22) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2019/day22/day22.rs)
3434
[Day 23: Category Six](https://adventofcode.com/2019/day/23) | ⭐⭐ | [![Python](../scripts/assets/python.png)](../2019/day23/day23.py)

2019/day14/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
name = "day14"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
aoc = { path = "../../aoc" }
8+
rustc-hash = "2.1.0"
9+
10+
[[bin]]
11+
name = "day14"
12+
path = "day14.rs"

2019/day14/day14.rs

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
//! [Day 14: Space Stoichiometry](https://adventofcode.com/2019/day/14)
2+
3+
use rustc_hash::FxHashMap;
4+
5+
type Formulae<'a> = FxHashMap<&'a str, (i64, Vec<(i64, &'a str)>)>;
6+
7+
struct Reaction<'a> {
8+
excess: FxHashMap<&'a str, i64>,
9+
formulae: &'a Formulae<'a>,
10+
}
11+
12+
impl<'a> Reaction<'a> {
13+
fn calc(&mut self, mut amount: i64, chemical: &'a str) -> i64 {
14+
if chemical == "FUEL" {
15+
self.excess.clear();
16+
}
17+
18+
if chemical == "ORE" {
19+
return amount;
20+
}
21+
22+
let v_chemical = self.excess.entry(chemical).or_insert(0);
23+
if amount <= *v_chemical {
24+
*v_chemical -= amount;
25+
return 0;
26+
}
27+
28+
amount -= *v_chemical;
29+
self.excess.insert(chemical, 0);
30+
31+
let (produced, reagents) = self.formulae[chemical].clone();
32+
33+
let nb_reactions = (produced - 1 + amount) / produced;
34+
35+
*self.excess.entry(chemical).or_default() += nb_reactions * produced - amount;
36+
37+
reagents
38+
.iter()
39+
.map(|i| self.calc(nb_reactions * i.0, i.1))
40+
.sum()
41+
}
42+
}
43+
44+
struct Puzzle<'a> {
45+
formulae: Formulae<'a>,
46+
}
47+
48+
impl<'a> Puzzle<'a> {
49+
/// Initialize from the puzzle input.
50+
fn new(data: &'a str) -> Self {
51+
let mut formulae = FxHashMap::default();
52+
53+
for formula in data.lines() {
54+
let (input, output) = formula.split_once(" => ").unwrap();
55+
56+
let (output_quantity, output_cheminal) = output.split_once(' ').unwrap();
57+
58+
let mut reagents = Vec::new();
59+
60+
for reagent in input.split(", ") {
61+
let (quantity_reagent, chemical_reagent) = reagent.split_once(' ').unwrap();
62+
reagents.push((quantity_reagent.parse().unwrap(), chemical_reagent));
63+
}
64+
65+
formulae.insert(
66+
output_cheminal,
67+
(output_quantity.parse().unwrap(), reagents),
68+
);
69+
}
70+
71+
Self { formulae }
72+
}
73+
74+
/// Solve part one.
75+
fn part1(&self) -> i64 {
76+
let mut c = Reaction {
77+
excess: FxHashMap::default(),
78+
formulae: &self.formulae,
79+
};
80+
81+
c.calc(1, "FUEL")
82+
}
83+
84+
/// Solve part two.
85+
fn part2(&self) -> i64 {
86+
let mut c = Reaction {
87+
excess: FxHashMap::default(),
88+
formulae: &self.formulae,
89+
};
90+
91+
let ore = 1_000_000_000_000;
92+
93+
let mut a = 1;
94+
let mut b = ore;
95+
96+
while b - a > 1 {
97+
let m = (a + b) / 2;
98+
let c = c.calc(m, "FUEL");
99+
if c > ore {
100+
b = m;
101+
} else {
102+
a = m;
103+
}
104+
}
105+
106+
a
107+
}
108+
}
109+
110+
fn main() {
111+
let args = aoc::parse_args();
112+
let puzzle = Puzzle::new(&args.input);
113+
println!("{}", puzzle.part1());
114+
println!("{}", puzzle.part2());
115+
}
116+
117+
/// Test from puzzle input
118+
#[cfg(test)]
119+
mod test {
120+
use super::*;
121+
122+
#[test]
123+
fn test1() {
124+
let data = aoc::load_input_data("sample_1.txt");
125+
let puzzle = Puzzle::new(&data);
126+
assert_eq!(puzzle.part1(), 31);
127+
}
128+
129+
#[test]
130+
fn test2() {
131+
let data = aoc::load_input_data("sample_2.txt");
132+
let puzzle = Puzzle::new(&data);
133+
assert_eq!(puzzle.part1(), 165);
134+
}
135+
136+
#[test]
137+
fn test3() {
138+
let data = aoc::load_input_data("sample_3.txt");
139+
let puzzle = Puzzle::new(&data);
140+
assert_eq!(puzzle.part1(), 13312);
141+
assert_eq!(puzzle.part2(), 82892753);
142+
}
143+
144+
#[test]
145+
fn test4() {
146+
let data = aoc::load_input_data("sample_4.txt");
147+
let puzzle = Puzzle::new(&data);
148+
assert_eq!(puzzle.part1(), 180697);
149+
assert_eq!(puzzle.part2(), 5586022);
150+
}
151+
#[test]
152+
fn test5() {
153+
let data = aoc::load_input_data("sample_5.txt");
154+
let puzzle = Puzzle::new(&data);
155+
assert_eq!(puzzle.part1(), 2210736);
156+
assert_eq!(puzzle.part2(), 460664);
157+
}
158+
}

2019/day14/sample_1.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
10 ORE => 10 A
2+
1 ORE => 1 B
3+
7 A, 1 B => 1 C
4+
7 A, 1 C => 1 D
5+
7 A, 1 D => 1 E
6+
7 A, 1 E => 1 FUEL

2019/day14/sample_2.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
9 ORE => 2 A
2+
8 ORE => 3 B
3+
7 ORE => 5 C
4+
3 A, 4 B => 1 AB
5+
5 B, 7 C => 1 BC
6+
4 C, 1 A => 1 CA
7+
2 AB, 3 BC, 4 CA => 1 FUEL

2019/day14/sample_3.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
157 ORE => 5 NZVS
2+
165 ORE => 6 DCFZ
3+
44 XJWVT, 5 KHKGT, 1 QDVJ, 29 NZVS, 9 GPVTF, 48 HKGWZ => 1 FUEL
4+
12 HKGWZ, 1 GPVTF, 8 PSHF => 9 QDVJ
5+
179 ORE => 7 PSHF
6+
177 ORE => 5 HKGWZ
7+
7 DCFZ, 7 PSHF => 2 XJWVT
8+
165 ORE => 2 GPVTF
9+
3 DCFZ, 7 NZVS, 5 HKGWZ, 10 PSHF => 8 KHKGT

2019/day14/sample_4.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2 VPVL, 7 FWMGM, 2 CXFTF, 11 MNCFX => 1 STKFG
2+
17 NVRVD, 3 JNWZP => 8 VPVL
3+
53 STKFG, 6 MNCFX, 46 VJHF, 81 HVMC, 68 CXFTF, 25 GNMV => 1 FUEL
4+
22 VJHF, 37 MNCFX => 5 FWMGM
5+
139 ORE => 4 NVRVD
6+
144 ORE => 7 JNWZP
7+
5 MNCFX, 7 RFSQX, 2 FWMGM, 2 VPVL, 19 CXFTF => 3 HVMC
8+
5 VJHF, 7 MNCFX, 9 VPVL, 37 CXFTF => 6 GNMV
9+
145 ORE => 6 MNCFX
10+
1 NVRVD => 8 CXFTF
11+
1 VJHF, 6 MNCFX => 4 RFSQX
12+
176 ORE => 6 VJHF

0 commit comments

Comments
 (0)