Skip to content

Commit

Permalink
Year 2024, Day 20, part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
kurisuke committed Dec 20, 2024
1 parent 66002cb commit 693ecab
Showing 1 changed file with 47 additions and 23 deletions.
70 changes: 47 additions & 23 deletions year2024/src/day20.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use std::collections::HashMap;

use common::day::Day;
use util::grid2d::{Coords, Direction, Grid2D};
use util::grid2d::{Coords, Grid2D};

pub struct Day20 {}

impl Day for Day20 {
fn star1(&self, input: &str) -> String {
let grid = parse_input(input);
let track = find_track(&grid);
let shortcuts = find_shortcuts(&grid, &track);
let shortcuts = find_shortcuts(&track, 2);
let result = shortcuts
.iter()
.filter(|(&key, _)| key >= 100)
Expand All @@ -19,8 +19,17 @@ impl Day for Day20 {
result.to_string()
}

fn star2(&self, _input: &str) -> String {
String::from("not implemented")
fn star2(&self, input: &str) -> String {
let grid = parse_input(input);
let track = find_track(&grid);
let shortcuts = find_shortcuts(&track, 20);
let result = shortcuts
.iter()
.filter(|(&key, _)| key >= 100)
.map(|(_, value)| value)
.sum::<usize>();

result.to_string()
}
}

Expand Down Expand Up @@ -70,25 +79,17 @@ fn find_track(grid: &Grid2D<Field>) -> Vec<Coords> {
track
}

fn find_shortcuts(grid: &Grid2D<Field>, track: &[Coords]) -> HashMap<usize, usize> {
fn find_shortcuts(track: &[Coords], max_len: usize) -> HashMap<usize, usize> {
let mut shortcuts = HashMap::new();
for (pos_index, pos) in track.iter().enumerate() {
for d in [Direction::N, Direction::E, Direction::S, Direction::W] {
let skip_pos = pos.mov(d);
let next_pos = skip_pos.mov(d);
if let (Some(skip_field), Some(next_field)) = (grid.at(&skip_pos), grid.at(&next_pos)) {
if skip_field == &Field::Wall && next_field != &Field::Wall {
let next_index = track
.iter()
.position(|&track_pos| track_pos == next_pos)
.unwrap();

if pos_index < next_index {
let saved_time = next_index - pos_index - 2;
let e = shortcuts.entry(saved_time).or_insert(0);
*e += 1;
}
}
for (next_index, next_pos) in track.iter().enumerate().skip(pos_index + max_len + 1) {
let regular_distance = next_index - pos_index;
let shortcut_distance = pos.manhattan(next_pos) as usize;
if shortcut_distance <= max_len && shortcut_distance < regular_distance {
let e = shortcuts
.entry(regular_distance - shortcut_distance)
.or_insert(0);
*e += 1;
}
}
}
Expand Down Expand Up @@ -116,12 +117,12 @@ mod tests {
###############"#;

#[test]
fn ex1() {
fn star1() {
let grid = parse_input(INPUT);
let track = find_track(&grid);
assert_eq!(track.len(), 85);

let shortcuts = find_shortcuts(&grid, &track);
let shortcuts = find_shortcuts(&track, 2);
assert_eq!(shortcuts.get(&2), Some(&14));
assert_eq!(shortcuts.get(&4), Some(&14));
assert_eq!(shortcuts.get(&6), Some(&2));
Expand All @@ -134,4 +135,27 @@ mod tests {
assert_eq!(shortcuts.get(&40), Some(&1));
assert_eq!(shortcuts.get(&64), Some(&1));
}

#[test]
fn star2() {
let grid = parse_input(INPUT);
let track = find_track(&grid);
assert_eq!(track.len(), 85);

let shortcuts = find_shortcuts(&track, 20);
assert_eq!(shortcuts.get(&50), Some(&32));
assert_eq!(shortcuts.get(&52), Some(&31));
assert_eq!(shortcuts.get(&54), Some(&29));
assert_eq!(shortcuts.get(&56), Some(&39));
assert_eq!(shortcuts.get(&58), Some(&25));
assert_eq!(shortcuts.get(&60), Some(&23));
assert_eq!(shortcuts.get(&62), Some(&20));
assert_eq!(shortcuts.get(&64), Some(&19));
assert_eq!(shortcuts.get(&66), Some(&12));
assert_eq!(shortcuts.get(&68), Some(&14));
assert_eq!(shortcuts.get(&70), Some(&12));
assert_eq!(shortcuts.get(&72), Some(&22));
assert_eq!(shortcuts.get(&74), Some(&4));
assert_eq!(shortcuts.get(&76), Some(&3));
}
}

0 comments on commit 693ecab

Please sign in to comment.