day(08): add solution
Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
parent
1275d5b738
commit
88d06b99ec
3 changed files with 144 additions and 0 deletions
5
samples/day08_1.txt
Normal file
5
samples/day08_1.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
LLR
|
||||||
|
|
||||||
|
AAA = (BBB, BBB)
|
||||||
|
BBB = (AAA, ZZZ)
|
||||||
|
ZZZ = (ZZZ, ZZZ)
|
10
samples/day08_2.txt
Normal file
10
samples/day08_2.txt
Normal 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
129
src/bin/day08.rs
Normal 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);
|
Loading…
Reference in a new issue