Skip to content

Commit 9b018c2

Browse files
committed
2025: days 10 and 11
1 parent 7ef2b78 commit 9b018c2

File tree

8 files changed

+342
-8
lines changed

8 files changed

+342
-8
lines changed

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# [Advent of Code](https://adventofcode.com) in Rust 🦀
22

3-
![Stars: 518](https://img.shields.io/badge/Stars-518⭐-blue)
4-
![Rust: 259](https://img.shields.io/badge/Rust-259-cyan?logo=Rust)
3+
![Stars: 522](https://img.shields.io/badge/Stars-522⭐-blue)
4+
![Rust: 261](https://img.shields.io/badge/Rust-261-cyan?logo=Rust)
55
![Python: 127](https://img.shields.io/badge/Python-127-cyan?logo=Python)
66

77
<img src="./scripts/assets/christmas_ferris_2015_2024.png" alt="Christmas Ferris" width="164" />
@@ -10,7 +10,7 @@
1010

1111
Made for fun 😎 and to practice Rust. Many thanks to [Eric Wastl](https://twitter.com/ericwastl).
1212

13-
## 2025 (current event) ([Calendar](https://adventofcode.com/2025)) ([Solutions](src/year2025/)) : 18
13+
## 2025 (current event) ([Calendar](https://adventofcode.com/2025)) ([Solutions](src/year2025/)) : 22
1414

1515
Puzzle | Stars | Languages
1616
----------------------------------------------------------------- | ----- | -----------
@@ -23,12 +23,14 @@ Puzzle | Stars | Lang
2323
[Day 7: Laboratories](https://adventofcode.com/2025/day/7) | ⭐⭐ | [![Rust](./scripts/assets/rust.png)](src/year2025/day7/day7.rs) [![Go](./scripts/assets/go.png)](src/year2025/day7/day7.go) [🎁](src/year2025/day7/README.md)
2424
[Day 8: Playground](https://adventofcode.com/2025/day/8) | ⭐⭐ | [![Rust](./scripts/assets/rust.png)](src/year2025/day8/day8.rs)
2525
[Day 9: Movie Theater](https://adventofcode.com/2025/day/9) | ⭐⭐ | [![Rust](./scripts/assets/rust.png)](src/year2025/day9/day9.rs) [![Rust](./scripts/assets/rust.png)](src/year2025/day9/day9_geo.rs) [![Python](./scripts/assets/python.png)](src/year2025/day9/day9_img.py) [🎁](src/year2025/day9/README.md)
26+
[Day 10: Factory](https://adventofcode.com/2025/day/10) | ⭐⭐ | [![Rust](./scripts/assets/rust.png)](src/year2025/day10/day10.rs)
27+
[Day 11: Reactor](https://adventofcode.com/2025/day/11) | ⭐⭐ | [![Rust](./scripts/assets/rust.png)](src/year2025/day11/day11.rs)
2628

2729
## All years
2830

2931
Calendar | Solutions | Stars | Rust | Python | 🎁
3032
-------- | --------- | ----- | ---- | ------ | --
31-
[Advent of Code 2025](https://adventofcode.com/2025) | [Solutions](src/year2025/README.md) | 18⭐ | 9 | 5 | 2
33+
[Advent of Code 2025](https://adventofcode.com/2025) | [Solutions](src/year2025/README.md) | 22⭐ | 11 | 5 | 2
3234
[Advent of Code 2024](https://adventofcode.com/2024) | [Solutions](src/year2024/README.md) | 50⭐ | 25 | 11 | 3
3335
[Advent of Code 2023](https://adventofcode.com/2023) | [Solutions](src/year2023/README.md) | 50⭐ | 25 | 10 | 2
3436
[Advent of Code 2022](https://adventofcode.com/2022) | [Solutions](src/year2022/README.md) | 50⭐ | 25 | 18 | 1

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,5 +127,5 @@ make_year!(year2024
127127
);
128128

129129
make_year!(year2025
130-
day1,day2,day3,day4,day5,day6,day7,day8,day9
130+
day1,day2,day3,day4,day5,day6,day7,day8,day9,day10,day11
131131
);

src/year2025/README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# Advent of Code in Rust 🦀
22

33
![AoC2025](https://img.shields.io/badge/Advent_of_Code-2025-8A2BE2)
4-
![Stars: 18](https://img.shields.io/badge/Stars-18⭐-blue)
5-
![Rust: 11](https://img.shields.io/badge/Rust-11-cyan?logo=Rust)
4+
![Stars: 22](https://img.shields.io/badge/Stars-22⭐-blue)
5+
![Rust: 13](https://img.shields.io/badge/Rust-13-cyan?logo=Rust)
66
![Python: 6](https://img.shields.io/badge/Python-6-cyan?logo=Python)
77

8-
## 2025 ([Calendar](https://adventofcode.com/2025)) ([Solutions](./)) : 18
8+
## 2025 ([Calendar](https://adventofcode.com/2025)) ([Solutions](./)) : 22
99

1010
Puzzle | Stars | Languages
1111
----------------------------------------------------------------- | ----- | -----------
@@ -18,3 +18,5 @@ Puzzle | Stars | Lang
1818
[Day 7: Laboratories](https://adventofcode.com/2025/day/7) | ⭐⭐ | [![Rust](../../scripts/assets/rust.png)](day7/day7.rs) [![Go](../../scripts/assets/go.png)](day7/day7.go) [🎁](day7/README.md)
1919
[Day 8: Playground](https://adventofcode.com/2025/day/8) | ⭐⭐ | [![Rust](../../scripts/assets/rust.png)](day8/day8.rs)
2020
[Day 9: Movie Theater](https://adventofcode.com/2025/day/9) | ⭐⭐ | [![Rust](../../scripts/assets/rust.png)](day9/day9.rs) [![Rust](../../scripts/assets/rust.png)](day9/day9_geo.rs) [![Python](../../scripts/assets/python.png)](day9/day9_img.py) [🎁](day9/README.md)
21+
[Day 10: Factory](https://adventofcode.com/2025/day/10) | ⭐⭐ | [![Rust](../../scripts/assets/rust.png)](day10/day10.rs)
22+
[Day 11: Reactor](https://adventofcode.com/2025/day/11) | ⭐⭐ | [![Rust](../../scripts/assets/rust.png)](day11/day11.rs)

src/year2025/day10/day10.rs

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
//! [Day 10: Factory](https://adventofcode.com/2025/day/10)
2+
3+
use z3::ast::Int;
4+
5+
struct Machine {
6+
lights: u32,
7+
wirings: Vec<u32>,
8+
joltages: Vec<u32>,
9+
}
10+
11+
impl Machine {
12+
/// Returns fewest required presses to correctly configure the indicator lights of the machine.
13+
fn score(&self) -> Option<usize> {
14+
(0..(1u32 << self.wirings.len()))
15+
.filter_map(|k| {
16+
let mut result = 0;
17+
let mut k_score = 0;
18+
19+
for (i, wiring) in self.wirings.iter().enumerate() {
20+
if k & (1 << i) != 0 {
21+
// press button, xor toggles the lights
22+
result ^= wiring;
23+
k_score += 1;
24+
}
25+
}
26+
27+
if result == self.lights {
28+
Some(k_score)
29+
} else {
30+
None
31+
}
32+
})
33+
.min()
34+
}
35+
36+
/// Return the fewest button presses required to correctly configure the joltage level counters .
37+
fn optimize(&self) -> u64 {
38+
let solver = z3::Optimize::new();
39+
40+
let vars: Vec<_> = (0..self.wirings.len())
41+
.map(|i| Int::new_const(format!("w{i}")))
42+
.collect();
43+
44+
for v in &vars {
45+
solver.assert(&v.ge(Int::from_u64(0)));
46+
}
47+
48+
for (i, &target) in self.joltages.iter().enumerate() {
49+
let mut terms = Vec::new();
50+
for (j, w) in self.wirings.iter().enumerate() {
51+
if w & (1 << i) != 0 {
52+
terms.push(vars[j].clone());
53+
}
54+
}
55+
56+
let sum = if terms.is_empty() {
57+
Int::from_u64(0)
58+
} else {
59+
Int::add(&terms.iter().collect::<Vec<_>>())
60+
};
61+
solver.assert(&sum.eq(Int::from_u64(target.into())));
62+
}
63+
64+
let sum_vars = z3::ast::Int::add(&vars.iter().collect::<Vec<_>>());
65+
solver.minimize(&sum_vars);
66+
67+
match solver.check(&[]) {
68+
z3::SatResult::Sat => {
69+
let model = solver.get_model().unwrap();
70+
vars.iter()
71+
.filter_map(|v| {
72+
let val = model.get_const_interp(v).unwrap();
73+
val.as_u64()
74+
})
75+
.sum()
76+
}
77+
_ => 0,
78+
}
79+
}
80+
}
81+
82+
struct Puzzle {
83+
machines: Vec<Machine>,
84+
}
85+
86+
impl Puzzle {
87+
/// Initialize from the puzzle input.
88+
fn new(data: &str) -> Self {
89+
let mut machines = vec![];
90+
for line in data.lines() {
91+
let p: Vec<_> = line.split_ascii_whitespace().collect();
92+
93+
// parse the indicator lights
94+
let mut lights = 0;
95+
for (k, light) in p[0]
96+
.strip_prefix('[')
97+
.unwrap()
98+
.strip_suffix(']')
99+
.unwrap()
100+
.chars()
101+
.enumerate()
102+
{
103+
if light == '#' {
104+
lights += 1 << k;
105+
}
106+
}
107+
108+
// parse the button wiring schematics
109+
let mut wirings = vec![];
110+
for w in &p[1..p.len() - 1] {
111+
wirings.push(
112+
w.strip_prefix('(')
113+
.unwrap()
114+
.strip_suffix(')')
115+
.unwrap()
116+
.split(',')
117+
.map(|s: &str| 1u32 << s.parse::<u32>().unwrap())
118+
.sum(),
119+
);
120+
}
121+
122+
// parse the joltage requirements
123+
let joltages = p
124+
.last()
125+
.unwrap()
126+
.strip_prefix('{')
127+
.unwrap()
128+
.strip_suffix('}')
129+
.unwrap()
130+
.split(',')
131+
.map(|s: &str| s.parse::<u32>().unwrap())
132+
.collect();
133+
134+
machines.push(Machine {
135+
lights,
136+
wirings,
137+
joltages,
138+
});
139+
}
140+
Self { machines }
141+
}
142+
143+
/// Solve part one.
144+
fn part1(&self) -> usize {
145+
self.machines.iter().filter_map(Machine::score).sum()
146+
}
147+
148+
/// Solve part two.
149+
fn part2(&self) -> u64 {
150+
self.machines.iter().map(Machine::optimize).sum()
151+
}
152+
}
153+
154+
/// # Panics
155+
#[must_use]
156+
pub fn solve(data: &str) -> (usize, u64) {
157+
let puzzle = Puzzle::new(data);
158+
(puzzle.part1(), puzzle.part2())
159+
}
160+
161+
pub fn main() {
162+
let args = aoc::parse_args();
163+
args.run(solve);
164+
}
165+
166+
#[cfg(test)]
167+
mod test {
168+
use super::*;
169+
170+
const TEST_INPUT: &str = include_str!("test.txt");
171+
172+
#[test]
173+
fn part1() {
174+
let puzzle = Puzzle::new(TEST_INPUT);
175+
assert_eq!(puzzle.part1(), 7);
176+
}
177+
178+
#[test]
179+
fn part2() {
180+
let puzzle = Puzzle::new(TEST_INPUT);
181+
assert_eq!(puzzle.part2(), 33);
182+
}
183+
}

src/year2025/day10/test.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7}
2+
[...#.] (0,2,3,4) (2,3) (0,4) (0,1,2) (1,2,3,4) {7,5,12,7,2}
3+
[.###.#] (0,1,2,3,4) (0,3,4) (0,1,2,4,5) (1,2) {10,11,11,5,10,5}

src/year2025/day11/day11.rs

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
//! [Day 11: Reactor](https://adventofcode.com/2025/day/11)
2+
3+
use rustc_hash::FxHashMap;
4+
5+
struct Puzzle<'a> {
6+
outputs: FxHashMap<&'a str, Vec<&'a str>>,
7+
}
8+
9+
impl<'a> Puzzle<'a> {
10+
/// Initialize from the puzzle input.
11+
fn new(data: &'a str) -> Self {
12+
Self {
13+
outputs: data
14+
.lines()
15+
.map(|line| {
16+
let (device, s) = line.split_once(": ").unwrap();
17+
18+
(device, s.split_ascii_whitespace().collect())
19+
})
20+
.collect(),
21+
}
22+
}
23+
24+
/// Solve part one.
25+
fn part1(&self) -> u64 {
26+
fn count<'b>(
27+
key: &'b str,
28+
f: &FxHashMap<&'b str, Vec<&'b str>>,
29+
memo: &mut FxHashMap<&'b str, u64>,
30+
) -> u64 {
31+
if let Some(&v) = memo.get(key) {
32+
return v;
33+
}
34+
if key == "out" {
35+
return 1;
36+
}
37+
let sum = f[key].iter().map(|child| count(child, f, memo)).sum();
38+
memo.insert(key, sum);
39+
sum
40+
}
41+
42+
let mut memo = FxHashMap::default();
43+
count("you", &self.outputs, &mut memo)
44+
}
45+
46+
/// Solve part two.
47+
fn part2(&self) -> u64 {
48+
fn count<'b>(
49+
key: &'b str,
50+
f: &FxHashMap<&'b str, Vec<&'b str>>,
51+
vdac: bool,
52+
vfft: bool,
53+
memo: &mut FxHashMap<(&'b str, bool, bool), u64>,
54+
) -> u64 {
55+
let memo_key = (key, vdac, vfft);
56+
57+
if let Some(&v) = memo.get(&memo_key) {
58+
return v;
59+
}
60+
61+
if key == "out" {
62+
let v = u64::from(vdac && vfft);
63+
memo.insert(memo_key, v);
64+
return v;
65+
}
66+
67+
let mut new_vdac = vdac;
68+
let mut new_vfft = vfft;
69+
70+
if key == "dac" {
71+
new_vdac = true;
72+
}
73+
if key == "fft" {
74+
new_vfft = true;
75+
}
76+
77+
let sum = f[key]
78+
.iter()
79+
.map(|child| count(child, f, new_vdac, new_vfft, memo))
80+
.sum();
81+
82+
memo.insert(memo_key, sum);
83+
sum
84+
}
85+
86+
let mut memo = FxHashMap::default();
87+
count("svr", &self.outputs, false, false, &mut memo)
88+
}
89+
}
90+
91+
/// # Panics
92+
#[must_use]
93+
pub fn solve(data: &str) -> (u64, u64) {
94+
let puzzle = Puzzle::new(data);
95+
(puzzle.part1(), puzzle.part2())
96+
}
97+
98+
pub fn main() {
99+
let args = aoc::parse_args();
100+
args.run(solve);
101+
}
102+
103+
#[cfg(test)]
104+
mod test {
105+
use super::*;
106+
107+
const SAMPLE_1: &str = include_str!("sample_1.txt");
108+
const SAMPLE_2: &str = include_str!("sample_2.txt");
109+
110+
#[test]
111+
fn part1() {
112+
let puzzle = Puzzle::new(SAMPLE_1);
113+
assert_eq!(puzzle.part1(), 5);
114+
}
115+
116+
#[test]
117+
fn part2() {
118+
let puzzle = Puzzle::new(SAMPLE_2);
119+
assert_eq!(puzzle.part2(), 2);
120+
}
121+
}

src/year2025/day11/sample_1.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
aaa: you hhh
2+
you: bbb ccc
3+
bbb: ddd eee
4+
ccc: ddd eee fff
5+
ddd: ggg
6+
eee: out
7+
fff: out
8+
ggg: out
9+
hhh: ccc fff iii
10+
iii: out

src/year2025/day11/sample_2.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
svr: aaa bbb
2+
aaa: fft
3+
fft: ccc
4+
bbb: tty
5+
tty: ccc
6+
ccc: ddd eee
7+
ddd: hub
8+
hub: fff
9+
eee: dac
10+
dac: fff
11+
fff: ggg hhh
12+
ggg: out
13+
hhh: out

0 commit comments

Comments
 (0)