[TASK] Solved day 10 pt 1

This commit is contained in:
2023-12-13 22:31:21 +01:00
parent 26ca49660f
commit 70a56313d0
4 changed files with 308 additions and 4 deletions

133
src/day10.rs Normal file
View File

@@ -0,0 +1,133 @@
use std::collections::HashSet;
use crate::day_solver::DaySolver;
use crate::util::{Coord, Grid};
#[cfg(test)]
use crate::util::read_file;
pub struct Day10 {
grid: Grid<char>
}
impl Day10 {
pub fn create(input: String) -> Self {
// let lines = input.lines();
// Put the input into the day struct
return Day10 {
grid: Grid {
width: input.lines().next().unwrap().len(),
data: input.replace("\n", "").chars().collect(),
default: Some('.')
}
}
}
fn is_connected_south(&self, p: &Coord<usize>) -> bool {
let c = self.grid.get(&p.x, &p.y);
return c == &'|' || c == &'F' || c == &'7' || c == &'S';
}
fn is_connected_north(&self, p: &Coord<usize>) -> bool {
let c = self.grid.get(&p.x, &p.y);
return c == &'|' || c == &'L' || c == &'J' || c == &'S';
}
fn is_connected_east(&self, p: &Coord<usize>) -> bool {
let c = self.grid.get(&p.x, &p.y);
return c == &'-' || c == &'L' || c == &'F' || c == &'S';
}
fn is_connected_west(&self, p: &Coord<usize>) -> bool {
let c = self.grid.get(&p.x, &p.y);
return c == &'-' || c == &'J' || c == &'7' || c == &'S';
}
}
impl DaySolver for Day10 {
fn solve_part1(&mut self) -> String {
self.grid.validate();
let mut dist_grid: Grid<usize> = Grid {
data: vec![0; self.grid.data.len()],
width: self.grid.width,
default: Some(0)
};
let start_pos = self.grid.find(&'S').unwrap();
dist_grid.set(&start_pos.x, &start_pos.y, 0);
let mut to_search = Vec::new();
let mut searched = HashSet::new();
to_search.push((start_pos, 0));
while !to_search.is_empty() {
to_search.sort_by_key(|(_, d)| usize::MAX - d);
let (cur, dist) = to_search.pop().unwrap();
let neighbor_dist = dist + 1;
if self.is_connected_north(&cur) && cur.y > 0 {
let north_pos = Coord::new(cur.x, cur.y - 1);
if !searched.contains(&north_pos) && self.is_connected_south(&north_pos) {
dist_grid.set(&north_pos.x, &north_pos.y, neighbor_dist);
to_search.push((north_pos, neighbor_dist));
}
}
if self.is_connected_south(&cur) {
let south_pos = Coord::new(cur.x, cur.y + 1);
if !searched.contains(&south_pos) && self.is_connected_north(&south_pos) {
dist_grid.set(&south_pos.x, &south_pos.y, neighbor_dist);
to_search.push((south_pos, neighbor_dist));
}
}
if self.is_connected_west(&cur) && cur.x > 0 {
let west_pos = Coord::new(cur.x - 1, cur.y);
if !searched.contains(&west_pos) && self.is_connected_east(&west_pos) {
dist_grid.set(&west_pos.x, &west_pos.y, neighbor_dist);
to_search.push((west_pos, neighbor_dist));
}
}
if self.is_connected_east(&cur) {
let east_pos = Coord::new(cur.x + 1, cur.y);
if !searched.contains(&east_pos) && self.is_connected_west(&east_pos) {
dist_grid.set(&east_pos.x, &east_pos.y, neighbor_dist);
to_search.push((east_pos, neighbor_dist));
}
}
searched.insert(cur);
}
// self.grid.print();
// println!();
// dist_grid.print();
return dist_grid.data.iter().filter(|d| d < &&usize::MAX).max().unwrap().to_string();
}
fn solve_part2(&mut self) -> String {
return 0.to_string();
}
}
#[test]
fn test_part1() {
let mut day = Day10::create(String::from("-L|F7
7S-7|
L|7||
-L-J|
L|-JF"));
assert_eq!("4", day.solve_part1());
}
#[test]
fn test_part1_2() {
let mut day = Day10::create(String::from("7-F7-
.FJ|7
SJLL7
|F--J
LJ.LJ"));
assert_eq!("8", day.solve_part1());
}
#[test]
fn test_part2() {
let mut day = Day10::create(read_file("input/dayX_example.txt"));
assert_eq!("EXAMPLE_ANSWER", day.solve_part2());
}

View File

@@ -1,6 +1,7 @@
extern crate core;
use std::time::Instant;
use crate::day10::Day10;
use crate::day1::Day1;
use crate::day2::Day2;
use crate::day3::Day3;
@@ -24,8 +25,9 @@ mod day6;
mod day7;
mod day8;
mod day9;
mod day10;
const MAX_DAY: u8 = 9;
const MAX_DAY: u8 = 10;
const DEFAULT_BENCHMARK_AMOUNT: u32 = 100;
fn main() {
@@ -105,6 +107,7 @@ fn build_day_solver(day: u8, input: String) -> Option<Box<dyn DaySolver>> {
7 => Some(Box::new(Day7::create(input))),
8 => Some(Box::new(Day8::create(input))),
9 => Some(Box::new(Day9::create(input))),
10 => Some(Box::new(Day10::create(input))),
_ => None
}
}

View File

@@ -1,5 +1,6 @@
use std::fs;
use std::fmt::Display;
use itertools::Itertools;
use num::Integer;
@@ -18,7 +19,9 @@ pub fn into_lines(input: String) -> Vec<String> {
#[derive(Debug, Clone)]
pub struct Grid<T> {
pub(crate) width: usize,
pub(crate) data: Vec<T>
pub(crate) data: Vec<T>,
/** What to return if a coordinate that is out of bounds is requested */
pub(crate) default: Option<T>
}
impl<T: Clone + Sized> Grid<T> {
@@ -48,8 +51,14 @@ impl<T: Clone + Sized> Grid<T> {
}
pub(crate) fn get(&self, x: &usize, y: &usize) -> &T {
let idx = self.idx(x, y);
&self.data[idx]
if self.in_bounds(x, y) {
let idx = self.idx(x, y);
&self.data[idx]
} else if let Some(x) = &self.default {
return x;
} else {
panic!("Out of grid bounds: {}, {}", x, y);
}
}
#[allow(dead_code)]
@@ -57,6 +66,14 @@ impl<T: Clone + Sized> Grid<T> {
let idx = self.idx(x, y);
self.data[idx] = v;
}
pub fn in_bounds(&self, x: &usize, y: &usize) -> bool {
return x < &self.width && y < &self.height()
}
pub fn validate(&self) {
debug_assert!(&self.data.len() % self.width == 0)
}
}
impl <T: Display + Clone + Sized> Grid<T> {
@@ -79,6 +96,17 @@ impl <T: Display + Clone + Sized> Grid<T> {
}
}
impl <T: PartialEq> Grid<T> {
pub fn find(&self, v: &T) -> Option<Coord<usize>> {
return if let Some((i, _)) = self.data.iter().find_position(|x| x == &v) {
return Some(Coord::new(i % self.width, i / self.width))
} else {
None
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Coord<T> where T: Sized {
pub x: T,