[TASK] Solved Day 9

This commit is contained in:
2022-12-11 14:52:15 +01:00
parent ae90aad6dc
commit 563cddce78
5 changed files with 2175 additions and 1 deletions

2000
input/day9.txt Normal file

File diff suppressed because it is too large Load Diff

8
input/day9_example.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
input/day9_example2.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

155
src/day9.rs Normal file
View File

@@ -0,0 +1,155 @@
use std::collections::HashSet;
use crate::day_solver::DaySolver;
use super::util;
pub struct Day9 {
commands: Vec<Command>
}
impl Day9 {
pub fn create() -> Self {
// let lines = util::read_file("input/day9_example.txt");
// let lines = util::read_file(/"input/day9_example2.txt");
let lines = util::read_file("input/day9.txt");
// Put the input into the day struct
return Day9 {
commands: lines.iter()
.map(|s| {
let mut split = s.split_whitespace();
Command {
direction: split.next().unwrap().chars().next().unwrap(),
steps: split.next().unwrap().parse().unwrap()
}
})
.collect()
}
}
}
impl DaySolver for Day9 {
fn solve_part1(&mut self) -> String {
let mut head = Vec2 { x: 0, y: 0 };
let mut tail = Vec2 { x: 0, y: 0 };
let mut tail_positions: HashSet<Vec2> = HashSet::new();
tail_positions.insert(tail.to_owned());
for command in &self.commands {
for _ in 0..command.steps {
head.move_into_direction(&command.direction);
if !tail.is_adjacent(&head) {
tail.move_towards(&head);
tail_positions.insert(tail.to_owned());
}
}
}
return tail_positions.len().to_string();
}
fn solve_part2(&mut self) -> String {
let mut knot_positions = vec![Vec2 { x: 0, y: 0 }; 9];
let mut head = Vec2 { x: 0, y: 0 };
let mut tail_positions: HashSet<Vec2> = HashSet::new();
tail_positions.insert(knot_positions.last().unwrap().to_owned());
for command in &self.commands {
for _ in 0..command.steps {
head.move_into_direction(&command.direction);
let mut connected_knot = &head;
for knot in &mut knot_positions {
if !knot.is_adjacent(connected_knot) {
knot.move_towards(connected_knot);
}
connected_knot = knot;
}
tail_positions.insert(knot_positions.last().unwrap().to_owned());
}
// println!("After step {} {}", command.direction, command.steps);
// draw_rope(&head, &knot_positions);
}
return tail_positions.len().to_string();
}
}
#[derive(Debug, Clone)]
struct Command {
direction: char,
steps: i32
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct Vec2 {
x: i32,
y: i32
}
impl Vec2 {
fn is_adjacent(&self, other: &Vec2) -> bool {
self.x.abs_diff(other.x) <= 1 && self.y.abs_diff(other.y) <= 1
}
fn move_into_direction(&mut self, direction: &char) {
match direction {
'U' => self.y += 1,
'D' => self.y -= 1,
'L' => self.x -= 1,
'R' => self.x += 1,
_ => panic!("Unknown direction: {}", direction)
}
}
fn move_towards(&mut self, target: &Vec2) {
if target.x > self.x {
self.x += 1;
} else if target.x < self.x {
self.x -= 1;
}
if target.y > self.y {
self.y += 1;
} else if target.y < self.y {
self.y -= 1;
}
}
}
#[allow(dead_code)]
fn draw_rope(head: &Vec2, knot_positions: &Vec<Vec2>) {
let min_x = 0.min(head.x.min(knot_positions.iter().map(|k| k.x).min().unwrap()));
let max_x = head.x.max(knot_positions.iter().map(|k| k.x).max().unwrap());
let min_y = 0.min(head.y.min(knot_positions.iter().map(|k| k.y).min().unwrap()));
let max_y = head.y.max(knot_positions.iter().map(|k| k.y).max().unwrap());
for y in (min_y..max_y+1).rev() {
for x in min_x..max_x+1 {
if head.x == x && head.y == y {
print!("H")
} else if let Some(k) = knot_positions.iter().enumerate()
.find_map(|(i, k)| if k.x == x && k.y == y { Some(i)} else { None }) {
if k == knot_positions.len() - 1 {
print!("T");
} else {
print!("{}", k + 1);
}
} else if x == 0 && y == 0 {
print!("s");
} else {
print!(".");
}
}
println!()
}
}

View File

@@ -7,6 +7,7 @@ use crate::day5::Day5;
use crate::day6::Day6;
use crate::day7::Day7;
use crate::day8::Day8;
use crate::day9::Day9;
use crate::day_solver::DaySolver;
mod util;
@@ -19,8 +20,9 @@ mod day5;
mod day6;
mod day7;
mod day8;
mod day9;
const MAX_DAY: u8 = 8;
const MAX_DAY: u8 = 9;
const DEFAULT_BENCHMARK_AMOUNT: u32 = 100;
fn main() {
@@ -92,6 +94,7 @@ fn build_day_solver(day: u8) -> Option<Box<dyn DaySolver>> {
6 => Some(Box::new(Day6::create())),
7 => Some(Box::new(Day7::create())),
8 => Some(Box::new(Day8::create())),
9 => Some(Box::new(Day9::create())),
_ => None
}
}