1
0
Fork 0

day(08): add solution

Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
Matej Focko 2023-12-08 11:55:22 +01:00
parent 1275d5b738
commit 88d06b99ec
Signed by: mfocko
GPG key ID: 7C47D46246790496
3 changed files with 144 additions and 0 deletions

5
samples/day08_1.txt Normal file
View file

@ -0,0 +1,5 @@
LLR
AAA = (BBB, BBB)
BBB = (AAA, ZZZ)
ZZZ = (ZZZ, ZZZ)

10
samples/day08_2.txt Normal file
View file

@ -0,0 +1,10 @@
LR
11A = (11B, XXX)
11B = (XXX, 11Z)
11Z = (11B, XXX)
22A = (22B, XXX)
22B = (22C, 22C)
22C = (22Z, 22Z)
22Z = (22B, 22B)
XXX = (XXX, XXX)

129
src/bin/day08.rs Normal file
View file

@ -0,0 +1,129 @@
use std::collections::HashMap;
use aoc_2023::*;
type Output1 = u64;
type Output2 = Output1;
#[derive(Debug, Clone, Copy)]
enum Direction {
Left,
Right,
}
impl Direction {
fn get<'a>(&self, options: &'a (String, String)) -> &'a str {
match self {
Direction::Left => &options.0,
Direction::Right => &options.1,
}
}
}
fn gcd(mut x: u64, mut y: u64) -> u64 {
while y != 0 {
(x, y) = (y, x % y);
}
x
}
fn lcm(x: u64, y: u64) -> u64 {
x / gcd(x, y) * y
}
struct Day08 {
instructions: Vec<Direction>,
graph: HashMap<String, (String, String)>,
}
impl Solution<Output1, Output2> for Day08 {
fn new<P: AsRef<Path>>(pathname: P) -> Self {
let lines: Vec<String> = file_to_lines(pathname);
let mut graph = HashMap::new();
for line in lines.iter().skip(2) {
let mut parts = line.split(" = ");
let u = parts.next().unwrap();
let right = parts.next().unwrap();
let next = right
.strip_prefix('(')
.unwrap()
.strip_suffix(')')
.unwrap()
.split(", ")
.collect_vec();
graph.insert(u.to_string(), (next[0].to_string(), next[1].to_string()));
}
Self {
instructions: lines[0]
.chars()
.map(|i| match i {
'L' => Direction::Left,
'R' => Direction::Right,
_ => unreachable!("unknown direction"),
})
.collect_vec(),
graph,
}
}
fn part_1(&mut self) -> Output1 {
let mut instructions = self.instructions.iter().cycle();
let mut counter = 0;
let mut vertex = "AAA";
while vertex != "ZZZ" {
let instruction = instructions.next().unwrap();
vertex = instruction.get(&self.graph[vertex]);
counter += 1;
}
counter
}
fn part_2(&mut self) -> Output2 {
let mut instructions = self.instructions.iter().cycle();
let mut vertices: Vec<&str> = self
.graph
.keys()
.filter_map(|u| {
if u.ends_with('A') {
Some(u.as_str())
} else {
None
}
})
.collect();
let mut counters = vec![0; vertices.len()];
while vertices.iter().any(|v| !v.ends_with('Z')) {
let instruction = instructions.next().unwrap();
for u in 0..vertices.len() {
if vertices[u].ends_with('Z') {
continue;
}
vertices[u] = instruction.get(&self.graph[vertices[u]]);
counters[u] += 1;
}
}
debug!("Instruction length: {}", self.instructions.len());
debug!("Counters: {:?}", &counters);
counters.into_iter().fold(1, lcm)
}
}
fn main() -> Result<()> {
Day08::main()
}
test_sample!(day_08, Day08, 6, 6);