Skip to content

Commit

Permalink
day 8 part 2 efficient
Browse files Browse the repository at this point in the history
  • Loading branch information
asmello committed Dec 14, 2023
1 parent 679e0ce commit 06bab7e
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 30 deletions.
59 changes: 30 additions & 29 deletions src/day8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,43 @@ use std::collections::HashMap;

pub fn part1(input: &str) -> miette::Result<usize> {
let maze = parse(input, maze())?;
let mut curr = "AAA";
for (count, dir) in maze.instructions().enumerate() {
if curr == "ZZZ" {
return Ok(count);
}
curr = maze.apply(curr, dir)?;
}
Err(miette!("empty instructions"))
steps(&maze, "AAA")
}

pub fn part2(input: &str) -> miette::Result<usize> {
let maze = parse(input, maze())?;

let mut instances = maze.starts();
for (count, dir) in maze.instructions().enumerate() {
if is_goal(&instances) {
return Ok(count);
}
for instance in &mut instances {
*instance = maze.apply(instance, dir)?;
}
let steps = maze
.starts()
.map(|node| steps(&maze, node))
.collect::<miette::Result<Vec<_>>>()?;
steps
.into_iter()
.reduce(lcm)
.ok_or_else(|| miette!("empty set"))
}

fn gcd(mut a: usize, mut b: usize) -> usize {
while b != 0 {
let t = b;
b = a % b;
a = t;
}
Err(miette!("empty instructions"))
a
}

fn lcm(a: usize, b: usize) -> usize {
(a * b) / gcd(a, b)
}

fn is_goal(instances: &[&str]) -> bool {
for instance in instances {
if !instance.ends_with('Z') {
return false;
fn steps(maze: &Maze, start: &str) -> miette::Result<usize> {
let mut curr = start;
for (count, dir) in maze.instructions().enumerate() {
if curr.ends_with('Z') {
return Ok(count);
}
curr = maze.apply(curr, dir)?;
}
true
Err(miette!("empty instructions"))
}

struct Maze<'a> {
Expand All @@ -45,12 +50,8 @@ struct Maze<'a> {
}

impl<'a> Maze<'a> {
fn starts(&self) -> Vec<&'a str> {
self.nodes
.keys()
.filter(|key| key.ends_with('A'))
.copied()
.collect()
fn starts(&self) -> impl Iterator<Item = &'a str> + '_ {
self.nodes.keys().filter(|key| key.ends_with('A')).copied()
}
fn instructions(&self) -> impl Iterator<Item = Direction> + '_ {
self.instr.iter().cycle().copied()
Expand Down
2 changes: 1 addition & 1 deletion tests/day8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,5 @@ fn part2_sample() {
fn part2_input() {
let input = common::read_string(INPUT_PATH).unwrap();
let result = day8::part2(&input).unwrap();
assert_eq!(result, 250506580);
assert_eq!(result, 21083806112641); // wow
}

0 comments on commit 06bab7e

Please sign in to comment.