Day 14, puzzle 1
This commit is contained in:
parent
6d3686c946
commit
215e067d33
|
@ -0,0 +1,17 @@
|
|||
use aoc22::{day14, util};
|
||||
|
||||
pub fn main() {
|
||||
let mut cave = day14::parse_cave(&util::parse_input());
|
||||
|
||||
println!("Initial cave:");
|
||||
cave.print();
|
||||
|
||||
let mut sand = 0;
|
||||
while cave.drop_sand() {
|
||||
sand += 1;
|
||||
}
|
||||
|
||||
println!("Final cave:");
|
||||
cave.print();
|
||||
println!("Total sand dropped: {}", sand);
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::util::Coord;
|
||||
|
||||
pub const SAND_SOURCE: Coord = (0, 500);
|
||||
|
||||
pub struct Cave {
|
||||
pub rows: usize,
|
||||
pub cols: usize,
|
||||
pub blocked: Vec<Vec<bool>>,
|
||||
pub sand_source: Coord,
|
||||
}
|
||||
|
||||
impl Cave {
|
||||
pub fn print(&self) {
|
||||
for row in 0..self.rows {
|
||||
for col in 0..self.cols {
|
||||
if (row, col) == self.sand_source {
|
||||
print!("+")
|
||||
} else if self.blocked[row][col] {
|
||||
print!("#");
|
||||
} else {
|
||||
print!(".");
|
||||
}
|
||||
}
|
||||
print!("\n")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn drop_sand(&mut self) -> bool {
|
||||
let (y, x) = self.sand_source;
|
||||
let mut y = y as isize;
|
||||
let mut x = x as isize;
|
||||
|
||||
while y < self.rows as isize && x > 0 && x < self.cols as isize {
|
||||
if !self.is_blocked(y + 1, x) {
|
||||
y += 1;
|
||||
} else if !self.is_blocked(y + 1, x - 1) {
|
||||
y += 1;
|
||||
x -= 1;
|
||||
} else if !self.is_blocked(y + 1, x + 1) {
|
||||
y += 1;
|
||||
x += 1;
|
||||
} else {
|
||||
self.blocked[y as usize][x as usize] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn is_blocked(&self, y: isize, x: isize) -> bool {
|
||||
!(y < 0 || y >= self.rows as isize || x < 0 || x >= self.cols as isize)
|
||||
&& self.blocked[y as usize][x as usize]
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_cave(input: &String) -> Cave {
|
||||
let mut paths = HashSet::new();
|
||||
|
||||
for line in input.lines() {
|
||||
let mut path = line.split("->").map(|n| parse_coord(n.trim()));
|
||||
let mut last = path.next().unwrap();
|
||||
paths.insert(last);
|
||||
for next in path {
|
||||
let y_min = next.0.min(last.0);
|
||||
let y_max = next.0.max(last.0);
|
||||
let x_min = next.1.min(last.1);
|
||||
let x_max = next.1.max(last.1);
|
||||
let horizontal = y_min == y_max;
|
||||
let vertical = x_min == x_max;
|
||||
|
||||
assert!(horizontal ^ vertical);
|
||||
if horizontal {
|
||||
for x in x_min..=x_max {
|
||||
paths.insert((y_min, x));
|
||||
}
|
||||
} else {
|
||||
for y in y_min..=y_max {
|
||||
paths.insert((y, x_max));
|
||||
}
|
||||
}
|
||||
|
||||
last = next;
|
||||
}
|
||||
}
|
||||
|
||||
assert_ne!(paths.len(), 0);
|
||||
|
||||
let (y_min, y_max) = paths.iter().map(|c| c.0).minmax().into_option().unwrap();
|
||||
let (x_min, x_max) = paths.iter().map(|c| c.1).minmax().into_option().unwrap();
|
||||
|
||||
// Sand source is always at y = 0, x = 500
|
||||
let y_min = y_min.min(SAND_SOURCE.0);
|
||||
let x_min = x_min.min(SAND_SOURCE.1);
|
||||
let x_max = x_max.max(SAND_SOURCE.1);
|
||||
|
||||
let rows = y_max - y_min + 1;
|
||||
let cols = x_max - x_min + 1;
|
||||
|
||||
let mut blocked = vec![vec![false; cols]; rows];
|
||||
|
||||
for coord in paths {
|
||||
blocked[coord.0 - y_min][coord.1 - x_min] = true;
|
||||
}
|
||||
|
||||
Cave {
|
||||
rows,
|
||||
cols,
|
||||
blocked,
|
||||
sand_source: (SAND_SOURCE.0 - y_min, SAND_SOURCE.1 - x_min),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_coord(input: &str) -> Coord {
|
||||
let (x, y) = input.split_once(',').unwrap();
|
||||
(y.parse().unwrap(), x.parse().unwrap())
|
||||
}
|
|
@ -3,6 +3,7 @@ pub mod day10;
|
|||
pub mod day11;
|
||||
pub mod day12;
|
||||
pub mod day13;
|
||||
pub mod day14;
|
||||
pub mod day2;
|
||||
pub mod day3;
|
||||
pub mod day4;
|
||||
|
|
|
@ -35,3 +35,5 @@ pub fn max_n<T: Ord + Copy>(slice: &[T], n: usize) -> Result<Vec<T>, ()> {
|
|||
|
||||
Ok(max_vals)
|
||||
}
|
||||
|
||||
pub type Coord = (usize, usize);
|
||||
|
|
Loading…
Reference in New Issue