Add day 9

This commit is contained in:
Sebastian Knackstedt 2022-12-09 15:44:54 +01:00
parent a0a911ec7c
commit e76573b78c
Signed by: sebastian
GPG Key ID: CDCD9AF904D93EF7
5 changed files with 2136 additions and 0 deletions

View File

@ -41,4 +41,8 @@ path = "src/day7/main.rs"
name = "day8"
path = "src/day8/main.rs"
[[bin]]
name = "day9"
path = "src/day9/main.rs"
[dependencies]

2000
day9.txt Normal file

File diff suppressed because it is too large Load Diff

8
day9_test.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

8
day9_test_2.txt Normal file
View File

@ -0,0 +1,8 @@
R 5
U 8
L 8
D 3
R 17
D 10
L 25
U 20

116
src/day9/main.rs Normal file
View File

@ -0,0 +1,116 @@
use std::collections::HashSet;
use base::read_file;
#[derive(Hash, Eq, PartialEq, Copy, Clone, Debug)]
struct Position {
x: i32,
y: i32,
}
#[derive(Debug)]
enum Direction {
UP,
DOWN,
LEFT,
RIGHT,
}
#[derive(Debug)]
struct MoveCommand(Direction, i32);
impl Position {
fn move_by(&mut self, dir: &Direction) {
match dir {
Direction::UP => self.y += 1,
Direction::DOWN => self.y -= 1,
Direction::LEFT => self.x -= 1,
Direction::RIGHT => self.x += 1
}
}
fn move_to(&mut self, other: &Position) {
if self.x > other.x {
self.x -= 1;
} else if self.x < other.x {
self.x += 1;
}
if self.y > other.y {
self.y -= 1;
} else if self.y < other.y {
self.y += 1;
}
}
}
struct Map<const N: usize> {
rope: [Position; N],
history: HashSet<Position>,
}
impl<const N: usize> Default for Map<N> {
fn default() -> Self {
assert!(N > 1, "Length must be larger than one");
Map {
rope: [Position { x: 0, y: 0 }; N],
history: Default::default(),
}
}
}
impl<const N: usize> Map<N> {
fn move_head(&mut self, cmd: &MoveCommand) {
for _ in 0..cmd.1 {
self.rope[0].move_by(&cmd.0);
for rope_element in 1..N {
if !self.is_in_reach(rope_element) {
let element_before = self.rope[rope_element - 1];
self.rope[rope_element].move_to(&element_before);
if rope_element == N - 1 {
self.history.insert(self.rope[rope_element]);
}
}
}
}
}
fn is_in_reach(&self, which: usize) -> bool {
(self.rope[which - 1].x - self.rope[which].x).abs() <= 1 && (self.rope[which].y - self.rope[which - 1].y).abs() <= 1
}
}
fn main() {
let mut commands = vec![];
for line in read_file("day9.txt") {
let splits = line.split_whitespace().collect::<Vec<_>>();
let count = splits[1].parse::<i32>().unwrap();
commands.push(match splits[0] {
"U" => MoveCommand(Direction::UP, count),
"L" => MoveCommand(Direction::LEFT, count),
"D" => MoveCommand(Direction::DOWN, count),
"R" => MoveCommand(Direction::RIGHT, count),
_ => {
panic!("Unknown option")
}
});
}
let mut task_1 = Map::<2>::default();
for command in &commands {
task_1.move_head(command);
}
println!("Tail was at {} unique fields", task_1.history.len() + 1);
let mut task_2 = Map::<10>::default();
for command in &commands {
task_2.move_head(command);
}
println!("Tail was at {} unique fields", task_2.history.len() + 1);
}