2022 day 24 rust
This commit is contained in:
parent
cc4ccca943
commit
b6bb78439c
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(dead_code)]
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::{BinaryHeap, HashMap, HashSet};
|
use std::collections::{BinaryHeap, HashMap, HashSet};
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
@ -25,7 +26,6 @@ struct Blizzard {
|
||||||
pos: Pos,
|
pos: Pos,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn offset_blizzards(blizzards: &[Blizzard], (rows, cols): (isize, isize), offset: isize) -> HashSet<Pos> {
|
fn offset_blizzards(blizzards: &[Blizzard], (rows, cols): (isize, isize), offset: isize) -> HashSet<Pos> {
|
||||||
blizzards.iter()
|
blizzards.iter()
|
||||||
.map(|&Blizzard { dir, pos: (row, col) }| match dir {
|
.map(|&Blizzard { dir, pos: (row, col) }| match dir {
|
||||||
|
@ -37,7 +37,6 @@ fn offset_blizzards(blizzards: &[Blizzard], (rows, cols): (isize, isize), offset
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||||
struct State {
|
struct State {
|
||||||
cost: isize,
|
cost: isize,
|
||||||
|
@ -57,20 +56,21 @@ impl PartialOrd for State {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn neighbours((row, col): Pos, (rows, cols): (isize, isize)) -> impl Iterator<Item=Pos> {
|
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)|
|
[(row, col), (row+1, col), (row-1, col), (row, col+1), (row, col-1)].into_iter()
|
||||||
0 <= n_row && (n_row < rows || n_col == cols - 1) && 0 <= n_col && n_col < cols)
|
.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 {
|
fn manhattan(start: Pos, goal: Pos) -> isize {
|
||||||
(start.0.abs_diff(goal.0) + start.1.abs_diff(goal.1)) as 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 frontier: BinaryHeap<State> = BinaryHeap::new();
|
||||||
let mut parent: HashMap<(isize, Pos), (isize, Pos)> = HashMap::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() {
|
while let Some(State { position: (cur_t, cur_pos), .. }) = frontier.pop() {
|
||||||
if cur_pos == goal { return Some(cur_t) };
|
if cur_pos == goal { return Some(cur_t) };
|
||||||
let next_t = cur_t + 1;
|
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 {
|
fn solve1((dims, blizzards): &((isize, isize), Vec<Blizzard>)) -> isize {
|
||||||
let (start, goal) = ((-1_isize, 0_isize), (dims.0, dims.1 - 1));
|
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 {
|
fn solve2((dims, blizzards): &((isize, isize), Vec<Blizzard>)) -> isize {
|
||||||
2
|
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]
|
#[test]
|
||||||
fn part1() {
|
fn part1() {
|
||||||
let data = parse_data(DATA);
|
assert_eq!(18, solve1(&parse_data(DATA)));
|
||||||
assert_eq!(18, solve1(&data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn part2() {
|
fn part2() {
|
||||||
let data = parse_data(DATA);
|
assert_eq!(54, solve2(&parse_data(DATA)));
|
||||||
assert_eq!(2, solve2(&data));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue