day 23
This commit is contained in:
70
Cargo.lock
generated
70
Cargo.lock
generated
@@ -7,6 +7,7 @@ name = "aoc2022"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"derive_more",
|
||||
"itertools",
|
||||
"nom",
|
||||
"num",
|
||||
@@ -39,6 +40,12 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.6"
|
||||
@@ -82,6 +89,19 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.8.0"
|
||||
@@ -267,6 +287,24 @@ dependencies = [
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.49"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "radium"
|
||||
version = "0.7.0"
|
||||
@@ -295,24 +333,56 @@ dependencies = [
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.107"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.5.1"
|
||||
|
||||
@@ -7,6 +7,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bitvec = "1.0.1"
|
||||
derive_more = "0.99.17"
|
||||
itertools = "0.10.5"
|
||||
nom = "7.1.1"
|
||||
num = "0.4.0"
|
||||
|
||||
71
inputs/day23.txt
Normal file
71
inputs/day23.txt
Normal file
@@ -0,0 +1,71 @@
|
||||
...####..#.#.#....###..#....#..#..#...##..###..##.#...######.##....####
|
||||
..#.##..#.#...###..###.##....#..##......#.###..###....#.#.#....#...#.#.
|
||||
.##...#...####..####....#....#####.##.#.....#.#.#.#..#..#...####....###
|
||||
.####..#.##...#.##..#.#...#..#..##.######.#######.###.##.....####.#.##.
|
||||
##.##.#..######.####..##...##.#.##...###.###..#.#..####..##...###.##.#.
|
||||
...###.#.###..####..###.##..#..###..#..##.###.##.##....##...##.#.#..##.
|
||||
###.##...#...#.#..####..##.#..###.##..#..##.#...#...##..##..##.##.###.#
|
||||
..##....###.##.#...#####.#.#.###.#.#.#.##.#...#####.#####.....###.....#
|
||||
#.####.#...#.#...##..#..#.#...###.#.####.#..##..##.#.###...#.####....##
|
||||
#.##...#.#####...##....##..###..#...##.###..#.#.##.##.....#####....#...
|
||||
#...#..#..#.#...##..#####.#.###......##..##.##.##...###..###...#..###..
|
||||
..#.##.#..##.##.####.....#.###..#..#..#...###.###..#.#.##.##..#####..##
|
||||
.##.#...#.....####......#.#..#..#.#....#.#...####...##.#.#.....#.#.....
|
||||
#..#.##..###..#.....#.###..#.#..........##.......##.##.#..######...###.
|
||||
.#...##.#.#...##.####..######.###.#.#.#.####.##.###..#...###.#..#..##.#
|
||||
#.#.##.#.###..##.###.##.....###.#.#...#...###.##.#.#.##.##.#####.....#.
|
||||
.#...###.##...#.##.#.###.###.##......##...##.#.###..#..#.#.##...####.#.
|
||||
.#.#.##..#...#.##..#..##.....#....#....#.###....#########..#.#.########
|
||||
.#.##..###..##..#.......##.##..#..###.#.##.####....#..#.#...##..##.#...
|
||||
#####.##.#.....#.##...#.#...#.#.####..####....#.#...#.....###...##.....
|
||||
..###....#....##...#.#...###....##.###.#.#...##..##.#..#.##....#.#.#.##
|
||||
########..####...#.#..##.###...##.#...#...#.######...#..#..#..#...#..##
|
||||
#.#....##...##..#...#....#.##....#.###.##.#...###.#..#.#.#...###..#.#.#
|
||||
#.##........#..##...#...##.##.###.#.##...##...#####.#.#.....####.#.#..#
|
||||
##.##...####.##.#...#....#...###.#...#....#.#.#.####...#.#....#.####.#.
|
||||
.###....#..#.#..#..####..###.#.#..#.#..#.####..#####..#.#.#..#.....##.#
|
||||
.#####.#.##.###......#..##.#.....#######..##.##.#####....#..#.#..####.#
|
||||
.#....###....#.##..##.#.#.#.....#####..#.#.#.##...#.#....#.##..##....#.
|
||||
####....####...#.#...#..##....#.#.#.###..#.######.##..##..######...#.#.
|
||||
.#..####..#####.###..#..##.#.####.##.##..#.###..#...##.#...#.#.#.#.#.##
|
||||
#.###########.####.....###.#..#...###.#######...#.#...##..###....#....#
|
||||
#..#.####...###..####.#.##.#.#.#.#####.###.####...#...#....########..#.
|
||||
#######.#..#.#..####.##.##..##.#...##..#######..#.#..#...#..##..#.###.#
|
||||
##.#.....###.#..####.##..#.#######.#.#..#.##.#..###.##..##.##.#...#.#.#
|
||||
#.#######.#.##.#.###.##.##...##..#.#....#.#.#..#.#..###..##.#.#.....##.
|
||||
.##.##.#...####.#####.####.####.....#..####..#..##..###...#.#.###.#...#
|
||||
.####...#..#.#.#.#........#..###...#####..####..##..######.###...#####.
|
||||
###....#..##.##..#####....##.#..#...##.#####..#..###.#####..###.#..##.#
|
||||
..#.#...#.##..#.##.####.####..#######....##....#.#....#.#.#..##.#.#..##
|
||||
.#..#.########.........###.#.....###.######..#.######...####..#..#.#.##
|
||||
.#.#...###...#.#.#.#..#...##.###.#.#.##.##.....####......##.#.#....##.#
|
||||
..##..##...#.#######.#.##.####.###.#..#.....#.#..#...#..####..##..#.###
|
||||
.#...####.##....###..#.###...###.##...###..######.#.#.#.#.#.#.#....#.##
|
||||
.###..#.###.###..##.#..##..#.#.#...#..#.#..#...##..#..#...###...#####.#
|
||||
#.#..#.#.#.....##..#.##..##.#.....#..###..#.#.#.#.#.#.##..#.####..##...
|
||||
..#.#.####...#.##..##.##.####..##.#.#..##.#.###.#.######..#.######.#...
|
||||
###.#.#.#.####..##.######.#.#...##......###..###.#..#...#...#.#..######
|
||||
.###.#..#..######..##.####.###..##.#...#.#.#......###..##.#.#....#.#.#.
|
||||
.##..#...#....#..###.##.#..#####.#.#....######..#....#..######.....#...
|
||||
#.#...#..#.##...#..#..###.......####...#.####...#.#.#....#####.##...#.#
|
||||
....#.####.#...#..#####.#..###..######.###.....#..#.#.#.#.#.##.#.##....
|
||||
#.......#####.#.###..##.###..#####..#.###..#.....#.###.###..###..#.##.#
|
||||
##.#.#....##.#.#..#..#...###.#..#.....###...###...#..#.######.#.#...##.
|
||||
#....####.##.###....#....#....#...#..####...#.#.#.###..##.#.#..##.#..##
|
||||
#.....#.##....###..####..##.#.......#..#.#.#.....#....####.#...#....###
|
||||
###.#..####....#.....#..####....######.....#.#....#..###.#.#..#.#..###.
|
||||
#..#.#.#...##....##.##....##.....#..####.###..##.#.#.##..#.##.###...###
|
||||
....###.#.#.#..###.#.##.#.#.#.#####.#####..#..##...##.##.#...####.#.###
|
||||
#####.....#.#.#.#.#.#.###.#####.#...#.##..#.#.##..##..###...#...#..##..
|
||||
##.####.#.#.##..##.##.###....##.#..###.####..#######.#...##....#..##.##
|
||||
##..#.####.##..#..#.#.#####.#.#.....#####..##..#.##.....##..#.#....##.#
|
||||
.#..####...####.#####.##..#.##.....###.###.#.#.######..####.#...#..#.#.
|
||||
##.####..##..#.....##.#.####..#..#....##...#....#####..##########.###.#
|
||||
#...#.#.....#####.......###.#.#.#.###....#.#..#..#.##..#..#..#.####.###
|
||||
##.###..#..##......##########....###..#######..#....#.#..###.##........
|
||||
####.........#.#...##.#.#.#..#.#.####.#####....##...#.#.##.###..#.##.##
|
||||
.####.#...#..#.##.####..##..#..#...##...........##..###.####..##..#.#..
|
||||
.#####.##....##.#..####.##..##.#.###.....##.#..#..#.#.#...#.#...####...
|
||||
#...####........#.##.####..##.....#####.#.#####.#####..#.##.#..##...##.
|
||||
.###..###.####..###..##..##.#..##.###.#...#..#...#..#...#..#######.#.##
|
||||
.#..#..##...##....##....####..#....#.##.....#.##..#.#..#...#..##.#..#.#
|
||||
8
src/bin/day23_1.rs
Normal file
8
src/bin/day23_1.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
use std::fs;
|
||||
|
||||
use aoc2022::day23::process_part_1;
|
||||
|
||||
fn main() {
|
||||
let file = fs::read_to_string("./inputs/day23.txt").unwrap();
|
||||
println!("{}", process_part_1(&file));
|
||||
}
|
||||
8
src/bin/day23_2.rs
Normal file
8
src/bin/day23_2.rs
Normal file
@@ -0,0 +1,8 @@
|
||||
use std::fs;
|
||||
|
||||
use aoc2022::day23::process_part_2;
|
||||
|
||||
fn main() {
|
||||
let file = fs::read_to_string("./inputs/day23.txt").unwrap();
|
||||
println!("{}", process_part_2(&file));
|
||||
}
|
||||
170
src/day23.rs
170
src/day23.rs
@@ -1,24 +1,180 @@
|
||||
pub fn process_part_1(_input: &str) -> u32 {
|
||||
0
|
||||
use std::collections::BTreeSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use derive_more::{Add, Sub};
|
||||
use itertools::Itertools;
|
||||
use itertools::MinMaxResult::MinMax;
|
||||
use nom::character::complete::{newline, one_of};
|
||||
use nom::multi::{many1, separated_list1};
|
||||
use nom::IResult;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash, Add, Sub)]
|
||||
struct Vec2 {
|
||||
x: i64,
|
||||
y: i64,
|
||||
}
|
||||
impl Display for Vec2 {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "({}, {})", self.x, self.y)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_part_2(_input: &str) -> u32 {
|
||||
0
|
||||
impl From<(usize, usize)> for Vec2 {
|
||||
fn from(value: (usize, usize)) -> Self {
|
||||
Self {
|
||||
x: value.0 as i64,
|
||||
y: value.1 as i64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// didn't wanna write them myself
|
||||
macro_rules! vec2 {
|
||||
($x:expr,$y:expr) => {
|
||||
Vec2 { x: $x, y: $y }
|
||||
};
|
||||
}
|
||||
|
||||
const DIRECTIONS: [[Vec2; 3]; 4] = [
|
||||
[vec2!(-1, -1), vec2!(0, -1), vec2!(1, -1)], // North: NW, N, NE
|
||||
[vec2!(-1, 1), vec2!(0, 1), vec2!(1, 1)], // South: SW, S, SE
|
||||
[vec2!(-1, -1), vec2!(-1, 0), vec2!(-1, 1)], // West: NW, W, SW
|
||||
[vec2!(1, -1), vec2!(1, 0), vec2!(1, 1)], // East: NE, E, SE
|
||||
];
|
||||
|
||||
pub fn process_part_1(input: &str) -> usize {
|
||||
let mut elves = parse_input(input).unwrap().1;
|
||||
for i in 0..10 {
|
||||
elves.step(i);
|
||||
}
|
||||
elves.bounding_box_area() - elves.0.len()
|
||||
}
|
||||
|
||||
pub fn process_part_2(input: &str) -> usize {
|
||||
let mut elves = parse_input(input).unwrap().1;
|
||||
(0..)
|
||||
.take_while(|i| elves.step(*i))
|
||||
.last()
|
||||
.map(|x| x + 2) // we start counting at 0 while aoc expects 1, and take_while 'noms' the one we need to keep away
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
fn parse_input(input: &str) -> IResult<&str, Elves> {
|
||||
let (input, items) = separated_list1(newline, many1(one_of(".#")))(input)?;
|
||||
let result = items
|
||||
.iter()
|
||||
.enumerate()
|
||||
.flat_map(|(y, row)| {
|
||||
row.iter()
|
||||
.enumerate()
|
||||
.flat_map(move |(x, &elem)| match elem {
|
||||
'#' => Some(Vec2::from((x, y))),
|
||||
_ => None,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
Ok((input, Elves(result)))
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Elves(BTreeSet<Vec2>);
|
||||
|
||||
impl Elves {
|
||||
fn step(&mut self, dir_counter: usize) -> bool {
|
||||
let mut desired_moves = Vec::new();
|
||||
let mut has_moved = false;
|
||||
for elf in self.0.iter() {
|
||||
if !self.has_elf_near(*elf) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for i in 0..4 {
|
||||
let offsets = DIRECTIONS[(dir_counter + i) % 4];
|
||||
if !self.has_elf(*elf, &offsets) {
|
||||
let next = *elf + offsets[1];
|
||||
desired_moves.push((next, *elf));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
let moves = desired_moves
|
||||
.into_iter()
|
||||
.sorted_unstable_by(|a, b| a.0.cmp(&b.0))
|
||||
.dedup_by_with_count(|a, b| a.0 == b.0)
|
||||
.filter(|(count, _)| *count == 1)
|
||||
.map(|(_, m)| m);
|
||||
for (next, elf) in moves {
|
||||
self.0.remove(&elf);
|
||||
self.0.insert(next);
|
||||
has_moved = true;
|
||||
}
|
||||
has_moved
|
||||
}
|
||||
|
||||
fn has_elf_near(&self, pos: Vec2) -> bool {
|
||||
DIRECTIONS
|
||||
.iter()
|
||||
.flatten()
|
||||
.any(|d| self.0.contains(&(pos + *d)))
|
||||
}
|
||||
|
||||
fn has_elf(&self, pos: Vec2, offsets: &[Vec2]) -> bool {
|
||||
offsets.iter().any(|d| self.0.contains(&(pos + *d)))
|
||||
}
|
||||
|
||||
fn bounding_box(&self) -> (Vec2, Vec2) {
|
||||
let MinMax(min_x, max_x) = self.0.iter().minmax_by_key(|p| p.x) else {
|
||||
panic!("no min/max x?");
|
||||
};
|
||||
let MinMax(min_y, max_y) = self.0.iter().minmax_by_key(|p| p.y) else {
|
||||
panic!("no min/max y?");
|
||||
};
|
||||
(vec2!(min_x.x, min_y.y), vec2!(max_x.x, max_y.y))
|
||||
}
|
||||
|
||||
fn bounding_box_area(&self) -> usize {
|
||||
let (min, max) = self.bounding_box();
|
||||
((max.x - min.x + 1) * (max.y - min.y + 1)) as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Elves {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let (min, max) = self.bounding_box();
|
||||
for y in min.y..=max.y {
|
||||
for x in min.x..=max.x {
|
||||
let elf = if self.0.contains(&vec2!(x, y)) {
|
||||
'#'
|
||||
} else {
|
||||
'.'
|
||||
};
|
||||
write!(f, "{elf}")?;
|
||||
}
|
||||
writeln!(f)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const INPUT: &str = "";
|
||||
const INPUT: &str = "....#..
|
||||
..###.#
|
||||
#...#.#
|
||||
.#...##
|
||||
#.###..
|
||||
##.#.##
|
||||
.#..#..";
|
||||
|
||||
#[test]
|
||||
fn day1() {
|
||||
assert_eq!(process_part_1(INPUT), 0);
|
||||
assert_eq!(process_part_1(INPUT), 110);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn day2() {
|
||||
assert_eq!(process_part_2(INPUT), 0);
|
||||
assert_eq!(process_part_2(INPUT), 20);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user