2022 day 24 rust

This commit is contained in:
Maciej Jur 2022-12-24 11:57:26 +01:00
parent cc4ccca943
commit b6bb78439c

View file

@ -1,3 +1,4 @@
#![allow(dead_code)]
use std::cmp::Ordering;
use std::collections::{BinaryHeap, HashMap, HashSet};
use crate::utils;
@ -25,7 +26,6 @@ struct Blizzard {
pos: Pos,
}
fn offset_blizzards(blizzards: &[Blizzard], (rows, cols): (isize, isize), offset: isize) -> HashSet<Pos> {
blizzards.iter()
.map(|&Blizzard { dir, pos: (row, col) }| match dir {
@ -37,7 +37,6 @@ fn offset_blizzards(blizzards: &[Blizzard], (rows, cols): (isize, isize), offset
.collect()
}
#[derive(Copy, Clone, Eq, PartialEq)]
struct State {
cost: isize,
@ -57,20 +56,21 @@ impl PartialOrd for State {
}
fn neighbours((row, col): Pos, (rows, cols): (isize, isize)) -> impl Iterator<Item=Pos> {
[(row, col), (row+1, col), (row-1, col), (row, col+1), (row, col-1)].into_iter().filter(move |&(n_row, n_col)|
0 <= n_row && (n_row < rows || n_col == cols - 1) && 0 <= n_col && n_col < cols)
[(row, col), (row+1, col), (row-1, col), (row, col+1), (row, col-1)].into_iter()
.filter(move |&(n_row, n_col)|
(0 <= n_row || n_col == 0) && (n_row < rows || n_col == cols - 1) && 0 <= n_col && n_col < cols)
}
fn manhattan(start: Pos, goal: Pos) -> isize {
(start.0.abs_diff(goal.0) + start.1.abs_diff(goal.1)) as isize
}
fn a_star(start: Pos, goal: Pos, dims: (isize, isize), blizzards: &[Blizzard]) -> Option<isize> {
fn a_star(start: Pos, goal: Pos, dims: (isize, isize), blizzards: &[Blizzard], offset: isize) -> Option<isize> {
let mut frontier: BinaryHeap<State> = BinaryHeap::new();
let mut parent: HashMap<(isize, Pos), (isize, Pos)> = HashMap::new();
let mut cost: HashMap<(isize, Pos), isize> = HashMap::from([((0, start), 0)]);
let mut cost: HashMap<(isize, Pos), isize> = HashMap::from([((offset, start), 0)]);
frontier.push(State { cost: 0, position: (0, start) });
frontier.push(State { cost: 0, position: (offset, start) });
while let Some(State { position: (cur_t, cur_pos), .. }) = frontier.pop() {
if cur_pos == goal { return Some(cur_t) };
let next_t = cur_t + 1;
@ -93,11 +93,14 @@ fn a_star(start: Pos, goal: Pos, dims: (isize, isize), blizzards: &[Blizzard]) -
fn solve1((dims, blizzards): &((isize, isize), Vec<Blizzard>)) -> isize {
let (start, goal) = ((-1_isize, 0_isize), (dims.0, dims.1 - 1));
a_star(start, goal, *dims, blizzards).unwrap()
a_star(start, goal, *dims, blizzards, 0).unwrap()
}
fn solve2(data: &((isize, isize), Vec<Blizzard>)) -> i32 {
2
fn solve2((dims, blizzards): &((isize, isize), Vec<Blizzard>)) -> isize {
let (start, goal) = ((-1_isize, 0_isize), (dims.0, dims.1 - 1));
let offset = a_star(start, goal, *dims, blizzards, 0).unwrap();
let offset = a_star(goal, start, *dims, blizzards, offset).unwrap();
a_star(start, goal, *dims, blizzards, offset).unwrap()
}
@ -139,13 +142,11 @@ mod tests {
#[test]
fn part1() {
let data = parse_data(DATA);
assert_eq!(18, solve1(&data));
assert_eq!(18, solve1(&parse_data(DATA)));
}
#[test]
fn part2() {
let data = parse_data(DATA);
assert_eq!(2, solve2(&data));
assert_eq!(54, solve2(&parse_data(DATA)));
}
}