Skip to content

Commit 1514705

Browse files
committed
2018
1 parent a7f0923 commit 1514705

File tree

3 files changed

+160
-1
lines changed

3 files changed

+160
-1
lines changed

2018/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
![AoC2018](https://img.shields.io/badge/Advent_of_Code-2018-8A2BE2)
44
![Stars: 43](https://img.shields.io/badge/Stars-43⭐-blue)
5-
![Rust: 22](https://img.shields.io/badge/Rust-22-cyan?logo=Rust)
5+
![Rust: 23](https://img.shields.io/badge/Rust-23-cyan?logo=Rust)
66
![Python: 4](https://img.shields.io/badge/Python-4-cyan?logo=Python)
77

88
## 2018 ([Calendar](https://adventofcode.com/2018)) ([Solutions](../2018/)) : 43⭐

2018/day20/Cargo.toml

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

2018/day20/day20.rs

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
//! [Day 20: A Regular Map](https://adventofcode.com/2018/day/20)
2+
3+
use std::collections::{HashMap, HashSet, VecDeque};
4+
5+
struct Puzzle {
6+
edges: HashMap<(i32, i32), HashSet<(i32, i32)>>,
7+
8+
max_steps: u32,
9+
thousand_doors: u32,
10+
}
11+
12+
impl Puzzle {
13+
fn new() -> Puzzle {
14+
Puzzle {
15+
edges: HashMap::new(),
16+
max_steps: 0,
17+
thousand_doors: 0,
18+
}
19+
}
20+
21+
/// Get the puzzle input.
22+
fn configure(&mut self, path: &str) {
23+
let data = std::fs::read_to_string(path).unwrap();
24+
25+
self.parse(data.trim());
26+
}
27+
28+
fn parse(&mut self, input: &str) {
29+
let mut branchs = vec![];
30+
31+
let mut x = 0;
32+
let mut y = 0;
33+
34+
for c in input.chars() {
35+
match c {
36+
'^' | '$' => (),
37+
'(' => branchs.push((x, y)),
38+
')' => {
39+
(x, y) = branchs.pop().unwrap();
40+
}
41+
'|' => {
42+
(x, y) = *branchs.last().unwrap();
43+
}
44+
_ => {
45+
let (dx, dy) = match c {
46+
'N' => (0, -1),
47+
'E' => (1, 0),
48+
'S' => (0, 1),
49+
'W' => (-1, 0),
50+
_ => panic!("unknown char '{c}"),
51+
};
52+
(*self.edges.entry((x, y)).or_default()).insert((dx, dy));
53+
54+
x += dx;
55+
y += dy;
56+
}
57+
}
58+
}
59+
}
60+
61+
fn solve(&mut self) {
62+
let mut q = VecDeque::new();
63+
let mut seen = HashSet::new();
64+
65+
self.max_steps = 0;
66+
self.thousand_doors = 0;
67+
68+
q.push_back((0, 0, 0));
69+
seen.insert((0, 0));
70+
71+
while let Some((steps, x, y)) = q.pop_front() {
72+
self.max_steps = self.max_steps.max(steps);
73+
74+
if steps >= 1000 {
75+
self.thousand_doors += 1;
76+
}
77+
78+
if let Some(neighbors) = self.edges.get(&(x, y)) {
79+
for (dx, dy) in neighbors {
80+
let nx = x + dx;
81+
let ny = y + dy;
82+
83+
if !seen.contains(&(nx, ny)) {
84+
seen.insert((nx, ny));
85+
q.push_back((steps + 1, nx, ny));
86+
}
87+
}
88+
}
89+
}
90+
}
91+
92+
/// Solve part one.
93+
fn part1(&self) -> u32 {
94+
self.max_steps
95+
}
96+
97+
/// Solve part two.
98+
fn part2(&self) -> u32 {
99+
self.thousand_doors
100+
}
101+
}
102+
103+
fn main() {
104+
let args = aoc::parse_args();
105+
let mut puzzle = Puzzle::new();
106+
puzzle.configure(args.path.as_str());
107+
puzzle.solve();
108+
println!("{}", puzzle.part1());
109+
println!("{}", puzzle.part2());
110+
}
111+
112+
/// Test from puzzle input
113+
#[cfg(test)]
114+
mod test {
115+
use super::*;
116+
117+
#[test]
118+
fn test01() {
119+
let mut puzzle = Puzzle::new();
120+
puzzle.parse("^ENWWW(NEEE|SSE(EE|N))$");
121+
puzzle.solve();
122+
assert_eq!(puzzle.part1(), 10);
123+
}
124+
125+
#[test]
126+
fn test02() {
127+
let mut puzzle = Puzzle::new();
128+
puzzle.parse("^ENNWSWW(NEWS|)SSSEEN(WNSE|)EE(SWEN|)NNN$");
129+
puzzle.solve();
130+
assert_eq!(puzzle.part1(), 18);
131+
}
132+
133+
#[test]
134+
fn test03() {
135+
let mut puzzle = Puzzle::new();
136+
puzzle.parse("^ESSWWN(E|NNENN(EESS(WNSE|)SSS|WWWSSSSE(SW|NNNE)))$");
137+
puzzle.solve();
138+
assert_eq!(puzzle.part1(), 23);
139+
}
140+
141+
#[test]
142+
fn test04() {
143+
let mut puzzle = Puzzle::new();
144+
puzzle.parse("^WSSEESWWWNW(S|NENNEEEENN(ESSSSW(NWSW|SSEN)|WSWWN(E|WWS(E|SS))))$");
145+
puzzle.solve();
146+
assert_eq!(puzzle.part1(), 31);
147+
}
148+
}

0 commit comments

Comments
 (0)