Add day 9
This commit is contained in:
parent
a0a911ec7c
commit
e76573b78c
@ -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]
|
||||
|
8
day9_test.txt
Normal file
8
day9_test.txt
Normal 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
8
day9_test_2.txt
Normal 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
116
src/day9/main.rs
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user