day 9
This commit is contained in:
parent
a9f0f93558
commit
7e626035f7
163
src/days/day9.rs
Normal file
163
src/days/day9.rs
Normal file
|
@ -0,0 +1,163 @@
|
|||
use std::{
|
||||
cmp::Ordering,
|
||||
collections::HashSet,
|
||||
ops::{Add, Sub},
|
||||
};
|
||||
|
||||
use aoc_runner_derive::{aoc, aoc_generator};
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum Direction {
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right,
|
||||
UpLeft,
|
||||
UpRight,
|
||||
DownLeft,
|
||||
DownRight,
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
fn to_vec2(self) -> Vec2 {
|
||||
match self {
|
||||
Direction::Up => (0, 1),
|
||||
Direction::Down => (0, -1),
|
||||
Direction::Left => (-1, 0),
|
||||
Direction::Right => (1, 0),
|
||||
Direction::UpLeft => (-1, 1),
|
||||
Direction::UpRight => (1, 1),
|
||||
Direction::DownLeft => (-1, -1),
|
||||
Direction::DownRight => (1, -1),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
struct Vec2 {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
impl From<(i32, i32)> for Vec2 {
|
||||
fn from((x, y): (i32, i32)) -> Self {
|
||||
Self { x, y }
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Vec2 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Self {
|
||||
x: self.x + rhs.x,
|
||||
y: self.y + rhs.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for Vec2 {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
Self {
|
||||
x: self.x - rhs.x,
|
||||
y: self.y - rhs.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[aoc_generator(day9)]
|
||||
fn generator(input: &str) -> Vec<(Direction, u32)> {
|
||||
input
|
||||
.lines()
|
||||
.map(|l| {
|
||||
(
|
||||
match l.chars().next().unwrap() {
|
||||
'U' => Direction::Up,
|
||||
'D' => Direction::Down,
|
||||
'L' => Direction::Left,
|
||||
'R' => Direction::Right,
|
||||
_ => panic!(),
|
||||
},
|
||||
l[2..].parse().unwrap(),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn do_pull(head: Vec2, tail: Vec2) -> Vec2 {
|
||||
let head_relative_to_tail = head - tail;
|
||||
|
||||
if head_relative_to_tail.x.abs() <= 1 && head_relative_to_tail.y.abs() <= 1 {
|
||||
return tail;
|
||||
}
|
||||
|
||||
use Ordering::*;
|
||||
|
||||
let dir_to_move_tail = match (
|
||||
head_relative_to_tail.x.cmp(&0),
|
||||
head_relative_to_tail.y.cmp(&0),
|
||||
) {
|
||||
(Less, Less) => Direction::DownLeft,
|
||||
(Less, Equal) => Direction::Left,
|
||||
(Less, Greater) => Direction::UpLeft,
|
||||
(Equal, Less) => Direction::Down,
|
||||
(Equal, Equal) => unreachable!(),
|
||||
(Equal, Greater) => Direction::Up,
|
||||
(Greater, Less) => Direction::DownRight,
|
||||
(Greater, Equal) => Direction::Right,
|
||||
(Greater, Greater) => Direction::UpRight,
|
||||
};
|
||||
|
||||
tail + dir_to_move_tail.to_vec2()
|
||||
}
|
||||
|
||||
struct Rope<const N: usize> {
|
||||
inner: [Vec2; N],
|
||||
}
|
||||
|
||||
impl<const N: usize> Rope<N> {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
inner: [(0, 0).into(); N],
|
||||
}
|
||||
}
|
||||
|
||||
fn do_move(&mut self, dir: Direction) {
|
||||
self.inner[0] = self.inner[0] + dir.to_vec2();
|
||||
for i in 0..N - 1 {
|
||||
self.inner[i + 1] = do_pull(self.inner[i], self.inner[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
fn tail(&self) -> Vec2 {
|
||||
*self.inner.last().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn run_simulation<const N: usize>(input: &[(Direction, u32)]) -> usize {
|
||||
let mut rope = Rope::<N>::new();
|
||||
let mut tail_locations = HashSet::new();
|
||||
tail_locations.insert(rope.tail());
|
||||
|
||||
for instruction in input {
|
||||
for _ in 0..instruction.1 {
|
||||
rope.do_move(instruction.0);
|
||||
tail_locations.insert(rope.tail());
|
||||
}
|
||||
}
|
||||
|
||||
tail_locations.len()
|
||||
}
|
||||
|
||||
#[aoc(day9, part1)]
|
||||
fn part1_indexing(input: &[(Direction, u32)]) -> usize {
|
||||
run_simulation::<2>(input)
|
||||
}
|
||||
|
||||
#[aoc(day9, part2)]
|
||||
fn part2(input: &[(Direction, u32)]) -> usize {
|
||||
run_simulation::<10>(input)
|
||||
}
|
|
@ -9,6 +9,7 @@ mod days {
|
|||
mod day6;
|
||||
mod day7;
|
||||
mod day8;
|
||||
mod day9;
|
||||
}
|
||||
|
||||
aoc_lib! { year = 2022 }
|
||||
|
|
Loading…
Reference in a new issue