[TASK] Solved Day 14

This commit is contained in:
2022-12-16 12:21:48 +01:00
parent e2386f7f92
commit e6331778f2
5 changed files with 306 additions and 9 deletions

112
input/day14.txt Normal file
View File

@@ -0,0 +1,112 @@
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
501,15 -> 506,15
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
474,73 -> 474,74 -> 486,74 -> 486,73
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
491,29 -> 495,29
491,17 -> 496,17
474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
477,33 -> 482,33 -> 482,32
485,29 -> 489,29
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
477,59 -> 477,60 -> 495,60
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
477,140 -> 488,140
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
485,23 -> 489,23
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
497,65 -> 502,65
488,26 -> 492,26
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
479,29 -> 483,29
474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
498,17 -> 503,17
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
488,20 -> 492,20
494,67 -> 499,67
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
505,17 -> 510,17
487,67 -> 492,67
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
490,65 -> 495,65
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
478,81 -> 483,81
501,67 -> 506,67
484,69 -> 489,69
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
497,29 -> 501,29
493,63 -> 498,63
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
494,26 -> 498,26
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
477,59 -> 477,60 -> 495,60
470,77 -> 475,77
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
497,13 -> 502,13
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
505,69 -> 510,69
474,73 -> 474,74 -> 486,74 -> 486,73
474,73 -> 474,74 -> 486,74 -> 486,73
467,79 -> 472,79
482,26 -> 486,26
465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
465,117 -> 465,120 -> 464,120 -> 464,123 -> 476,123 -> 476,120 -> 471,120 -> 471,117
454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
491,69 -> 496,69
474,36 -> 474,38 -> 468,38 -> 468,41 -> 482,41 -> 482,38 -> 478,38 -> 478,36
498,69 -> 503,69
464,81 -> 469,81
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
491,23 -> 495,23
471,81 -> 476,81
477,33 -> 482,33 -> 482,32
451,104 -> 451,103 -> 451,104 -> 453,104 -> 453,97 -> 453,104 -> 455,104 -> 455,100 -> 455,104
485,153 -> 485,145 -> 485,153 -> 487,153 -> 487,152 -> 487,153 -> 489,153 -> 489,143 -> 489,153 -> 491,153 -> 491,148 -> 491,153
462,84 -> 462,87 -> 455,87 -> 455,91 -> 469,91 -> 469,87 -> 466,87 -> 466,84
481,54 -> 481,47 -> 481,54 -> 483,54 -> 483,45 -> 483,54 -> 485,54 -> 485,52 -> 485,54
471,136 -> 471,130 -> 471,136 -> 473,136 -> 473,128 -> 473,136 -> 475,136 -> 475,132 -> 475,136 -> 477,136 -> 477,133 -> 477,136 -> 479,136 -> 479,133 -> 479,136 -> 481,136 -> 481,132 -> 481,136
454,107 -> 454,110 -> 450,110 -> 450,114 -> 467,114 -> 467,110 -> 459,110 -> 459,107
494,15 -> 499,15
474,79 -> 479,79

2
input/day14_example.txt Normal file
View File

@@ -0,0 +1,2 @@
498,4 -> 498,6 -> 496,6
503,4 -> 502,4 -> 502,9 -> 494,9

164
src/day14.rs Normal file
View File

@@ -0,0 +1,164 @@
use std::fmt::{Display, Formatter};
use crate::{day_solver::DaySolver, util::{Coord, Grid}};
use super::util;
pub struct Day14 {
platforms: Vec<Platform>
}
const STARTING_COORD: Coord<usize> = Coord { x: 500, y: 0};
impl Day14 {
pub fn create() -> Self {
// let lines = util::read_file("input/day14_example.txt");
let lines = util::read_file("input/day14.txt");
// Put the input into the day struct
return Day14 {
platforms: lines.iter().map(|l|
Platform {
coords: l.split(" -> ")
.map(|c| {
let mut c_split = c.split(",");
Coord {
x: c_split.next().unwrap().parse::<u16>().unwrap(),
y: c_split.next().unwrap().parse::<u16>().unwrap(),
}
}).collect::<Vec<Coord<u16>>>()
}).collect()
}
}
fn try_move_to(sand_coord: &mut Coord<usize>, target_x: &usize, target_y: &usize, grid: &Grid<Cell>) -> Option<bool> {
match grid.get(target_x, target_y) {
Cell::Empty => {
sand_coord.x = target_x.to_owned();
sand_coord.y = target_y.to_owned();
Some(true)
},
_ => None
}
}
fn build_grid(&self) -> Grid<Cell> {
// println!("{:?}", self.platforms);
// Build a grid from the platforms:
let max_y = self.platforms.iter().map(|p| p.coords.iter().map(|c| c.y).max().unwrap()).max().unwrap() as usize;
let mut grid = Grid {
data: vec![Cell::Empty; 1000 * (max_y + 3)],
width: 1000
};
// Add the platforms to the grid
for platform in &self.platforms {
let mut coord_iter = platform.coords.iter();
let mut from = coord_iter.next().unwrap();
while let Some(to) = coord_iter.next() {
// println!("Adding wall from {:?} to {:?}", from, to);
for y in from.y.min(to.y)..(to.y.max(from.y) + 1) {
for x in from.x.min(to.x)..(to.x.max(from.x) + 1) {
// println!("Adding {},{}", x, y);
grid.set(&(x as usize), &(y as usize), Cell::Wall);
}
}
from = to;
}
}
// grid.print_range(495, 505, 0, max_y + 3);
grid
}
fn simulate_sand(&self, grid: &mut Grid<Cell>) -> SimulationResult {
let grid_height = grid.height();
let mut sand_coord = STARTING_COORD.clone();
loop {
let target_x = sand_coord.x;
let target_y = sand_coord.y + 1;
if target_y >= grid_height {
// Falling into the abyss!!
return SimulationResult::FellOff
}
if Day14::try_move_to(&mut sand_coord, &target_x, &target_y, &grid)
.or_else(|| Day14::try_move_to(&mut sand_coord, &(target_x - 1), &target_y, &grid))
.or_else(|| Day14::try_move_to(&mut sand_coord, &(target_x + 1), &target_y, &grid)) == None {
// If we didn't find any option, the sand stops moving:
grid.set(&sand_coord.x, &sand_coord.y, Cell::Sand);
return SimulationResult::EndedAt(sand_coord);
}
// println!("Sand is at {:?}", sand_coord)
}
}
}
impl DaySolver for Day14 {
fn solve_part1(&mut self) -> String {
let mut grid = self.build_grid();
// Let's drop some sand
let mut counter = 0;
loop {
if self.simulate_sand(&mut grid) == SimulationResult::FellOff {
return counter.to_string();
}
counter += 1;
// grid.print_range(495, 505, 0, 10);
}
}
fn solve_part2(&mut self) -> String {
let mut grid = self.build_grid();
grid.set_row(grid.height() - 1, Cell::Wall);
// Let's drop some sand
let mut counter = 0;
loop {
self.simulate_sand(&mut grid);
counter += 1;
if grid.get(&STARTING_COORD.x, &STARTING_COORD.y) == &Cell::Sand {
return counter.to_string()
}
// grid.print_range(495, 505, 0, 10);
}
}
}
#[derive(Debug)]
struct Platform {
coords: Vec<Coord<u16>>
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Cell {
Empty, Wall, Sand
}
impl Display for Cell {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
Cell::Empty => ".",
Cell::Wall => "#",
Cell::Sand => "o"
}
)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
enum SimulationResult {
FellOff,
EndedAt(Coord<usize>)
}

View File

@@ -12,6 +12,7 @@ use crate::day10::Day10;
use crate::day11::Day11; use crate::day11::Day11;
use crate::day12::Day12; use crate::day12::Day12;
use crate::day13::Day13; use crate::day13::Day13;
use crate::day14::Day14;
use crate::day_solver::DaySolver; use crate::day_solver::DaySolver;
mod util; mod util;
@@ -29,8 +30,9 @@ mod day10;
mod day11; mod day11;
mod day12; mod day12;
mod day13; mod day13;
mod day14;
const MAX_DAY: u8 = 12; const MAX_DAY: u8 = 14;
const DEFAULT_BENCHMARK_AMOUNT: u32 = 100; const DEFAULT_BENCHMARK_AMOUNT: u32 = 100;
fn main() { fn main() {
@@ -107,6 +109,7 @@ fn build_day_solver(day: u8) -> Option<Box<dyn DaySolver>> {
11 => Some(Box::new(Day11::create())), 11 => Some(Box::new(Day11::create())),
12 => Some(Box::new(Day12::create())), 12 => Some(Box::new(Day12::create())),
13 => Some(Box::new(Day13::create())), 13 => Some(Box::new(Day13::create())),
14 => Some(Box::new(Day14::create())),
_ => None _ => None
} }
} }

View File

@@ -22,15 +22,15 @@ pub struct Grid<T> {
impl<T: Clone + Sized> Grid<T> { impl<T: Clone + Sized> Grid<T> {
#[allow(dead_code)] #[allow(dead_code)]
fn set_row(&mut self, x: usize, v: T) { pub fn set_row(&mut self, y: usize, v: T) {
// let range = &mut self.data[x * self.width..(x+1) * self.width]; // let range = &mut self.data[x * self.width..(x+1) * self.width];
for i in self.width * x..self.width * (x + 1) { for i in self.width * y..self.width * (y + 1) {
self.data[i] = v.to_owned(); self.data[i] = v.to_owned();
} }
} }
#[allow(dead_code)] #[allow(dead_code)]
fn set_col(&mut self, x: usize, v: T) { pub fn set_col(&mut self, x: usize, v: T) {
for y in 0..self.height() { for y in 0..self.height() {
let idx = self.idx(&x, &y); let idx = self.idx(&x, &y);
self.data[idx] = v.to_owned(); self.data[idx] = v.to_owned();
@@ -48,21 +48,37 @@ impl<T: Clone + Sized> Grid<T> {
pub(crate) fn get(&self, x: &usize, y: &usize) -> &T { pub(crate) fn get(&self, x: &usize, y: &usize) -> &T {
let idx = self.idx(x, y); let idx = self.idx(x, y);
&self.data[idx] &self.data[idx]
}
pub fn set(&mut self, x: &usize, y: &usize, v: T) {
let idx = self.idx(x, y);
self.data[idx] = v;
} }
} }
impl <T: Display + Clone + Sized> Grid<T> { impl <T: Display + Clone + Sized> Grid<T> {
#[allow(dead_code)] #[allow(dead_code)]
fn print(&self) { pub fn print(&self) {
for y in 0..self.height() { self.print_range(0, self.width, 0, self.height());
for x in 0..self.width { }
#[allow(dead_code)]
pub fn print_range(&self, from_x: usize, to_x: usize, from_y: usize, to_y: usize) {
for y in from_y.max(0)..to_y.min(self.height()) {
for x in from_x.max(0)..to_x.min(self.width) {
print!("{}", self.get(&x, &y)) print!("{}", self.get(&x, &y))
} }
println!(); println!();
} }
} }
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Coord<T> where T: Sized {
pub x: T,
pub y: T
}