Add day 9
This commit is contained in:
		| @@ -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); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user