Day 9
parent
515eff8ef0
commit
7ebb51835c
@ -0,0 +1,131 @@
|
|||||||
|
use crate::util::prelude::*;
|
||||||
|
|
||||||
|
static INPUT: &str = include_str!("inputs/day9.txt");
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
enum Direction {
|
||||||
|
Right,
|
||||||
|
Down,
|
||||||
|
Up,
|
||||||
|
Left,
|
||||||
|
}
|
||||||
|
impl Direction {
|
||||||
|
fn diff(&self) -> (sint, sint) {
|
||||||
|
use Direction::*;
|
||||||
|
|
||||||
|
match self {
|
||||||
|
Right => (1, 0),
|
||||||
|
Up => (0, 1),
|
||||||
|
Down => (0, -1),
|
||||||
|
Left => (-1, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl core::str::FromStr for Direction {
|
||||||
|
type Err = ();
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
Ok(match s {
|
||||||
|
"U" => Direction::Up,
|
||||||
|
"R" => Direction::Right,
|
||||||
|
"L" => Direction::Left,
|
||||||
|
"D" => Direction::Down,
|
||||||
|
_ => return Err(()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
struct Move {
|
||||||
|
count: uint,
|
||||||
|
direction: Direction,
|
||||||
|
}
|
||||||
|
impl core::str::FromStr for Move {
|
||||||
|
type Err = ();
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let mut it = s.split(' ');
|
||||||
|
|
||||||
|
let direction = it.next().ok_or(())?.parse()?;
|
||||||
|
let count = it.next().ok_or(())?.parse().map_err(|_| ())?;
|
||||||
|
|
||||||
|
Ok(Self { count, direction })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn moves(s: &str) -> impl Iterator<Item = Move> + '_ {
|
||||||
|
s.lines()
|
||||||
|
.filter(|s| !s.is_empty())
|
||||||
|
.map(|s| s.parse().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||||
|
struct Pos(sint, sint);
|
||||||
|
|
||||||
|
fn move_tail(head: &Pos, tail: &mut Pos) {
|
||||||
|
let diff_x = head.0 - tail.0;
|
||||||
|
let diff_y = head.1 - tail.1;
|
||||||
|
|
||||||
|
let diff_x_abs = diff_x.abs();
|
||||||
|
let diff_y_abs = diff_y.abs();
|
||||||
|
// diag
|
||||||
|
let mv = if diff_x_abs + diff_y_abs == 3 {
|
||||||
|
(diff_x.signum(), diff_y.signum())
|
||||||
|
} else {
|
||||||
|
((diff_x / 2).signum(), (diff_y / 2).signum())
|
||||||
|
};
|
||||||
|
|
||||||
|
tail.0 += mv.0;
|
||||||
|
tail.1 += mv.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part1() {
|
||||||
|
let mut head = Pos(0, 0);
|
||||||
|
let mut tail = Pos(0, 0);
|
||||||
|
|
||||||
|
let moves = moves(INPUT);
|
||||||
|
let mut locations = HashSet::default();
|
||||||
|
|
||||||
|
for mv in moves {
|
||||||
|
let dir = mv.direction.diff();
|
||||||
|
let count = mv.count;
|
||||||
|
|
||||||
|
for _ in 0..count {
|
||||||
|
head.0 += dir.0;
|
||||||
|
head.1 += dir.1;
|
||||||
|
|
||||||
|
move_tail(&head, &mut tail);
|
||||||
|
|
||||||
|
locations.insert(tail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{}", locations.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part2() {
|
||||||
|
let mut parts = vec![Pos(0, 0); 10];
|
||||||
|
|
||||||
|
let moves = moves(INPUT);
|
||||||
|
let mut locations = HashSet::default();
|
||||||
|
|
||||||
|
for mv in moves {
|
||||||
|
let dir = mv.direction.diff();
|
||||||
|
let count = mv.count;
|
||||||
|
|
||||||
|
for _ in 0..count {
|
||||||
|
parts[0].0 += dir.0;
|
||||||
|
parts[0].1 += dir.1;
|
||||||
|
|
||||||
|
for i in 0..parts.len() - 1 {
|
||||||
|
let tail: &mut _ =
|
||||||
|
unsafe { core::mem::transmute(&mut parts[i + 1]) };
|
||||||
|
move_tail(&parts[i], tail);
|
||||||
|
}
|
||||||
|
|
||||||
|
locations.insert(*parts.last().unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{}", locations.len())
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue