main
mat ess 2022-12-09 14:46:59 -05:00
parent 75807727a0
commit 5c6facfa66
3 changed files with 2132 additions and 1 deletions

8
inputs/9.small.txt Normal file
View File

@ -0,0 +1,8 @@
R 4
U 4
L 3
D 1
R 4
D 1
L 5
R 2

2000
inputs/9.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -212,7 +212,6 @@ solutions! {
let map = map_trees(input);
let len = map.len();
let mut count: u64 = 4 * len as u64 - 4;
// is_visible(&map, 2, 2, 5);
for x in 1..len - 1 {
for y in 1..len - 1 {
if is_visible(&map, x, y, len) {
@ -237,9 +236,133 @@ solutions! {
}
max.into()
},
],
[
// day 9 part 1
|input| {
let motions = parse_motions(input);
let visits = motion_visits(motions, 2);
(visits.len() as u64).into()
},
// day 9 part 2
|input| {
let motions = parse_motions(input);
let visits = motion_visits(motions, 10);
(visits.len() as u64).into()
},
]
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct Pos {
x: isize,
y: isize,
}
struct Rope {
knots: Vec<Pos>,
tail: usize,
}
impl Rope {
fn head(&mut self) -> &mut Pos {
&mut self.knots[0]
}
fn tail(&mut self) -> &mut Pos {
&mut self.knots[self.tail]
}
fn pull(&mut self) {
for i in 0..self.tail {
let head = self.knots[i];
let tail = self.knots[i + 1];
self.knots[i + 1] = move_tail(head, tail);
}
}
}
fn move_tail(head: Pos, tail: Pos) -> Pos {
let diff_x = head.x - tail.x;
let diff_y = head.y - tail.y;
if diff_x.abs() < 2 && diff_y.abs() < 2 {
tail
} else if diff_y == 0 {
Pos {
x: tail.x + (diff_x / diff_x.abs()),
..tail
}
} else if diff_x == 0 {
Pos {
y: tail.y + (diff_y / diff_y.abs()),
..tail
}
} else {
Pos {
x: tail.x + (diff_x / diff_x.abs()),
y: tail.y + (diff_y / diff_y.abs()),
}
}
}
fn motion_visits(motions: Vec<Motion>, n_knots: usize) -> HashMap<Pos, u64> {
let mut map = HashMap::new();
let pos = Pos { x: 0, y: 0 };
let mut rope = Rope {
knots: vec![pos; n_knots],
tail: n_knots - 1,
};
map.insert(pos, 1);
for motion in motions {
for _ in 0..motion.len {
match motion.dir {
Dir::U => rope.head().y += 1,
Dir::D => rope.head().y -= 1,
Dir::L => rope.head().x -= 1,
Dir::R => rope.head().x += 1,
}
rope.pull();
if let Some(n) = map.get(&pos) {
map.insert(*rope.tail(), *n + 1);
} else {
map.insert(*rope.tail(), 1);
}
}
}
map
}
fn parse_motions(input: String) -> Vec<Motion> {
input
.lines()
.map(|line| {
let (dir, len) = line.split_once(' ').unwrap();
let dir = match dir {
"U" => Dir::U,
"D" => Dir::D,
"L" => Dir::L,
"R" => Dir::R,
_ => unreachable!("ohno"),
};
let len = len.parse::<isize>().unwrap();
Motion { dir, len }
})
.collect()
}
struct Motion {
dir: Dir,
len: isize,
}
#[derive(Debug)]
enum Dir {
U,
D,
L,
R,
}
fn view_length(
me: u8,
map: &[Vec<u8>],