main
idylls 1 year ago
parent 515eff8ef0
commit 7ebb51835c
Signed by: idylls
GPG Key ID: 8A7167CBC2CC9F0F

@ -20,7 +20,10 @@ impl Stacks {
let to = mv.to - 1;
// SAFETY: should be safe, borrowing from disjoint sub-vectors and
// not modifying the length of the primary vector
// not modifying the length of the primary vector. Technically it
// is possible that this could alias if to and from are the same,
// but even if that happened this should be safe (although the
// answer given would be incorrect)
unsafe {
let from: &'static mut Vec<_> =
core::mem::transmute(&mut self.0[from]);

@ -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

@ -8,8 +8,9 @@ mod day5;
mod day6;
mod day7;
mod day8;
mod day9;
mod util;
fn main() {
day8::part2();
day9::part2();
}

Loading…
Cancel
Save