day23
This commit is contained in:
parent
b802cf1d16
commit
bdc150d0ed
@ -47,10 +47,10 @@ fn part2(input: &Vec<String>) -> usize {
|
|||||||
if let Some(position) = boxes[box_number].iter().position(|(l, _)| *l == *label) {
|
if let Some(position) = boxes[box_number].iter().position(|(l, _)| *l == *label) {
|
||||||
let _ = std::mem::replace(
|
let _ = std::mem::replace(
|
||||||
&mut boxes[box_number][position],
|
&mut boxes[box_number][position],
|
||||||
(label.clone().to_string(), *focal_length as usize),
|
(label.to_string(), *focal_length as usize),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
boxes[box_number].push((label.clone().to_string(), *focal_length as usize));
|
boxes[box_number].push((label.to_string(), *focal_length as usize));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("invalid step AHHH {}", step)
|
panic!("invalid step AHHH {}", step)
|
||||||
|
156
src/day23.rs
Normal file
156
src/day23.rs
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
|
||||||
|
const NEIGHBORS: &[(i64,i64)] = &[(-1,0),(0,1),(1,0),(0,-1)];
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
#[aoc_generator(day23)]
|
||||||
|
fn parse(input: &str) -> Vec<Vec<char>> {
|
||||||
|
input.lines().map(|x| x.chars().collect::<Vec<_>>()).collect::<Vec<_>>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dfs(graph: &HashMap<(usize,usize), Vec<(usize,usize,usize)>>, seen: &mut Vec<Vec<bool>>, (r,c): (usize, usize)) -> Option<usize> {
|
||||||
|
if r == seen.len() - 1 {
|
||||||
|
return Some(0);
|
||||||
|
}
|
||||||
|
let mut max_dist = None;
|
||||||
|
for &(rr, cc, d) in &graph[&(r,c)] {
|
||||||
|
if !seen[rr][cc] {
|
||||||
|
seen[rr][cc] = true;
|
||||||
|
if let Some(dist) = dfs(graph, seen, (rr,cc)) {
|
||||||
|
max_dist = Some(max_dist.unwrap_or(0).max(d+dist))
|
||||||
|
}
|
||||||
|
seen[rr][cc] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
max_dist
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day23, part1)]
|
||||||
|
fn part1(grid: &Vec<Vec<char>>) -> usize {
|
||||||
|
let mut graph = HashMap::<_,Vec<_>>::new();
|
||||||
|
for (r, c) in (0..grid.len()).cartesian_product(0..grid[0].len()) {
|
||||||
|
let neighbors = match grid[r][c] {
|
||||||
|
'#' => continue,
|
||||||
|
'.' => NEIGHBORS,
|
||||||
|
'^' => &NEIGHBORS[0..][..1],
|
||||||
|
'>' => &NEIGHBORS[1..][..1],
|
||||||
|
'v' => &NEIGHBORS[2..][..1],
|
||||||
|
'<' => &NEIGHBORS[3..][..1],
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
let e = graph.entry((r,c)).or_default();
|
||||||
|
|
||||||
|
for (dr, dc) in neighbors {
|
||||||
|
let rr = (r as i64 + dr) as usize;
|
||||||
|
let cc = (c as i64 + dc) as usize;
|
||||||
|
if grid.get(rr).and_then(|row| row.get(cc)).is_some_and(|&t| t != '#') {
|
||||||
|
e.push((rr,cc,1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let corridors = graph.iter()
|
||||||
|
.filter(|(_, n)| n.len() == 2)
|
||||||
|
.map(|(&node, _)| node)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
for (r,c) in corridors {
|
||||||
|
let neighbors = graph.remove(&(r,c)).unwrap();
|
||||||
|
let (r1, c1, d1) = neighbors[0];
|
||||||
|
let (r2, c2, d2) = neighbors[1];
|
||||||
|
let n1 = graph.get_mut(&(r1,c1)).unwrap();
|
||||||
|
if let Some(i) = n1.iter().position(|&(rr,cc,_)| (rr,cc) == (r,c)) {
|
||||||
|
n1[i] = (r2,c2,d1+d2);
|
||||||
|
}
|
||||||
|
let n2 = graph.get_mut(&(r2,c2)).unwrap();
|
||||||
|
if let Some(i) = n2.iter().position(|&(rr,cc,_)| (rr,cc) == (r,c)) {
|
||||||
|
n2[i] = (r1,c1,d1+d2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dfs(&graph, &mut vec![vec![false; grid[0].len()]; grid.len()], (0,1)).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day23, part2)]
|
||||||
|
fn part2(grid: &Vec<Vec<char>>) -> usize {
|
||||||
|
let mut graph = HashMap::<_,Vec<_>>::new();
|
||||||
|
for (r, c) in (0..grid.len()).cartesian_product(0..grid[0].len()) {
|
||||||
|
let neighbors = match grid[r][c] {
|
||||||
|
'#' => continue,
|
||||||
|
_ => NEIGHBORS,
|
||||||
|
};
|
||||||
|
let e = graph.entry((r,c)).or_default();
|
||||||
|
|
||||||
|
for (dr, dc) in neighbors {
|
||||||
|
let rr = (r as i64 + dr) as usize;
|
||||||
|
let cc = (c as i64 + dc) as usize;
|
||||||
|
if grid.get(rr).and_then(|row| row.get(cc)).is_some_and(|&t| t != '#') {
|
||||||
|
e.push((rr,cc,1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let corridors = graph.iter()
|
||||||
|
.filter(|(_, n)| n.len() == 2)
|
||||||
|
.map(|(&node, _)| node)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
for (r,c) in corridors {
|
||||||
|
let neighbors = graph.remove(&(r,c)).unwrap();
|
||||||
|
let (r1, c1, d1) = neighbors[0];
|
||||||
|
let (r2, c2, d2) = neighbors[1];
|
||||||
|
let n1 = graph.get_mut(&(r1,c1)).unwrap();
|
||||||
|
if let Some(i) = n1.iter().position(|&(rr,cc,_)| (rr,cc) == (r,c)) {
|
||||||
|
n1[i] = (r2,c2,d1+d2);
|
||||||
|
}
|
||||||
|
let n2 = graph.get_mut(&(r2,c2)).unwrap();
|
||||||
|
if let Some(i) = n2.iter().position(|&(rr,cc,_)| (rr,cc) == (r,c)) {
|
||||||
|
n2[i] = (r1,c1,d1+d2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dfs(&graph, &mut vec![vec![false; grid[0].len()]; grid.len()], (0,1)).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const EX: &str = r"#.#####################
|
||||||
|
#.......#########...###
|
||||||
|
#######.#########.#.###
|
||||||
|
###.....#.>.>.###.#.###
|
||||||
|
###v#####.#v#.###.#.###
|
||||||
|
###.>...#.#.#.....#...#
|
||||||
|
###v###.#.#.#########.#
|
||||||
|
###...#.#.#.......#...#
|
||||||
|
#####.#.#.#######.#.###
|
||||||
|
#.....#.#.#.......#...#
|
||||||
|
#.#####.#.#.#########v#
|
||||||
|
#.#...#...#...###...>.#
|
||||||
|
#.#.#v#######v###.###v#
|
||||||
|
#...#.>.#...>.>.#.###.#
|
||||||
|
#####v#.#.###v#.#.###.#
|
||||||
|
#.....#...#...#.#.#...#
|
||||||
|
#.#########.###.#.#.###
|
||||||
|
#...###...#...#...#.###
|
||||||
|
###.###.#.###v#####v###
|
||||||
|
#...#...#.#.>.>.#.>.###
|
||||||
|
#.###.###.#.###.#.#v###
|
||||||
|
#.....###...###...#...#
|
||||||
|
#####################.#";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_example() {
|
||||||
|
assert_eq!(part1(&parse(EX)), 94);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_example() {
|
||||||
|
assert_eq!(part2(&parse(EX)), 154);
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
mod day23;
|
||||||
mod day22;
|
mod day22;
|
||||||
mod day21;
|
mod day21;
|
||||||
mod day20;
|
mod day20;
|
||||||
|
Loading…
Reference in New Issue
Block a user