generated from janezicmatej/aoc-template
Compare commits
2 Commits
000002201f
...
00000240fc
Author | SHA1 | Date |
---|---|---|
Matej Janezic | 00000240fc | |
Matej Janezic | 00000230cf |
|
@ -0,0 +1,25 @@
|
|||
5,4
|
||||
4,2
|
||||
4,5
|
||||
3,0
|
||||
2,1
|
||||
6,3
|
||||
2,4
|
||||
1,5
|
||||
0,6
|
||||
3,3
|
||||
2,6
|
||||
5,1
|
||||
1,2
|
||||
5,5
|
||||
2,5
|
||||
6,5
|
||||
1,4
|
||||
0,4
|
||||
6,4
|
||||
1,1
|
||||
6,1
|
||||
1,0
|
||||
0,5
|
||||
1,6
|
||||
2,0
|
|
@ -22,7 +22,7 @@ fn dijkstra(grid: &Grid, start: Point) -> (Visited, Prev) {
|
|||
let mut visited: Visited = HashMap::new();
|
||||
|
||||
let mut bh = BinaryHeap::new();
|
||||
bh.push(Reverse((0, start, Direction::EAST, start, Direction::EAST)));
|
||||
bh.push(Reverse((0, start, Direction::E, start, Direction::E)));
|
||||
|
||||
while let Some(Reverse((len, loc, dir, ploc, pdir))) = bh.pop() {
|
||||
let best = visited.entry((loc, dir)).or_insert(usize::MAX);
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use itertools::Itertools;
|
||||
|
||||
use aoc::{
|
||||
grid_vec::{Direction, Point},
|
||||
pnt,
|
||||
};
|
||||
|
||||
fn parse_input(input: &str) -> Vec<Point> {
|
||||
input
|
||||
.lines()
|
||||
.map(|x| {
|
||||
x.split(',')
|
||||
.filter_map(|y| y.parse().ok())
|
||||
.collect_tuple()
|
||||
.unwrap()
|
||||
})
|
||||
.map(|x: (usize, usize)| Point { i: x.1, j: x.0 })
|
||||
.collect_vec()
|
||||
}
|
||||
|
||||
fn bfs(
|
||||
visited: &mut HashMap<Point, usize>,
|
||||
queue: &mut VecDeque<(Point, usize)>,
|
||||
corruption: &HashSet<Point>,
|
||||
end: Point,
|
||||
) -> Option<usize> {
|
||||
visited.clear();
|
||||
queue.clear();
|
||||
|
||||
queue.push_back((pnt!(0, 0), 0));
|
||||
|
||||
while let Some((p, l)) = queue.pop_front() {
|
||||
if visited.contains_key(&p) {
|
||||
continue;
|
||||
}
|
||||
visited.insert(p, l);
|
||||
|
||||
if p == end {
|
||||
break;
|
||||
}
|
||||
|
||||
for d in Direction::CROSS {
|
||||
let n = p + d;
|
||||
|
||||
let in_bounds = n.bounded_by(&end);
|
||||
let not_visited = !visited.contains_key(&n);
|
||||
let not_corrupted = !corruption.contains(&n);
|
||||
|
||||
if in_bounds && not_visited && not_corrupted {
|
||||
queue.push_back((n, l + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visited.get(&end).copied()
|
||||
}
|
||||
|
||||
pub fn part_one(input: &str) -> Option<usize> {
|
||||
let falling_bytes = parse_input(input);
|
||||
|
||||
let mut visited = HashMap::new();
|
||||
let mut queue = VecDeque::new();
|
||||
|
||||
let end = pnt!(70, 70);
|
||||
let corruption = HashSet::from_iter(falling_bytes.iter().copied().take(1024));
|
||||
|
||||
bfs(&mut visited, &mut queue, &corruption, end)
|
||||
}
|
||||
|
||||
pub fn part_two(input: &str) -> Option<String> {
|
||||
let falling_bytes = parse_input(input);
|
||||
|
||||
let mut visited = HashMap::new();
|
||||
let mut queue = VecDeque::new();
|
||||
|
||||
let end = pnt!(70, 70);
|
||||
let mut corruption = HashSet::new();
|
||||
let mut c = 0;
|
||||
|
||||
while bfs(&mut visited, &mut queue, &corruption, end).is_some() {
|
||||
corruption.insert(falling_bytes[c]);
|
||||
c += 1;
|
||||
}
|
||||
|
||||
let fb = falling_bytes[c - 1];
|
||||
|
||||
Some(format!("{},{}", fb.j, fb.i))
|
||||
}
|
||||
|
||||
aoc::solution!(18);
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
use std::fmt::Display;
|
||||
use std::{fmt::Display, ops::Mul};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
||||
pub struct Direction {
|
||||
|
@ -12,11 +12,33 @@ impl Display for Direction {
|
|||
}
|
||||
}
|
||||
|
||||
impl Mul<usize> for Direction {
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: usize) -> Self::Output {
|
||||
Self {
|
||||
i: self.i * rhs as isize,
|
||||
j: self.j * rhs as isize,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
pub const NORTH: Self = Direction { i: -1, j: 0 };
|
||||
pub const EAST: Self = Direction { i: 0, j: 1 };
|
||||
pub const SOUTH: Self = Direction { i: 1, j: 0 };
|
||||
pub const WEST: Self = Direction { i: 0, j: -1 };
|
||||
pub const N: Self = Direction { i: -1, j: 0 };
|
||||
pub const E: Self = Direction { i: 0, j: 1 };
|
||||
pub const S: Self = Direction { i: 1, j: 0 };
|
||||
pub const W: Self = Direction { i: 0, j: -1 };
|
||||
|
||||
pub const NE: Self = Direction { i: -1, j: 1 };
|
||||
pub const NW: Self = Direction { i: -1, j: -1 };
|
||||
pub const SE: Self = Direction { i: 1, j: 1 };
|
||||
pub const SW: Self = Direction { i: 1, j: -1 };
|
||||
|
||||
pub const CROSS: [Self; 4] = [Self::N, Self::E, Self::S, Self::W];
|
||||
#[rustfmt::skip]
|
||||
pub const OMNI: [Self; 8] = [
|
||||
Self::N, Self::E, Self::S, Self::W,
|
||||
Self::NE, Self::NW, Self::SE, Self::SW
|
||||
];
|
||||
|
||||
pub fn new(i: isize, j: isize) -> Self {
|
||||
Self { i, j }
|
||||
|
|
|
@ -81,6 +81,10 @@ impl Point {
|
|||
pub fn sw(self) -> Self {
|
||||
self.s().w()
|
||||
}
|
||||
|
||||
pub fn bounded_by(&self, other: &Self) -> bool {
|
||||
self.i <= other.i && self.j <= other.j
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
|
|
Loading…
Reference in New Issue