[rs] Solve 2022_14 part 2

This commit is contained in:
Joscha 2022-12-14 22:14:09 +01:00
parent 8fd9c338ca
commit 6a56be2041
3 changed files with 50 additions and 30 deletions

View file

@ -1,2 +1,2 @@
Part 1: 979 Part 1: 979
Part 2: ??? Part 2: 29044

View file

@ -1,15 +1,16 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::thread;
use std::time::Duration;
#[derive(Clone, Copy, PartialEq, Eq)] #[derive(Clone, Copy, PartialEq, Eq)]
enum Cell { enum Cell {
Wall, Wall,
Sand, Sand,
Source,
} }
struct Grid(HashMap<(i32, i32), Cell>); #[derive(Clone)]
struct Grid {
grid: HashMap<(i32, i32), Cell>,
max_y: i32,
}
impl Grid { impl Grid {
fn parse(input: &str) -> Self { fn parse(input: &str) -> Self {
@ -33,42 +34,53 @@ impl Grid {
} }
} }
} }
Self(grid) let max_y = *grid.keys().map(|(_, y)| y).max().unwrap();
Self { grid, max_y }
}
fn insert(&mut self, pos: (i32, i32), cell: Cell) {
self.max_y = self.max_y.max(pos.1);
self.grid.insert(pos, cell);
} }
fn eprint(&self) { fn eprint(&self) {
let min_x = *self.0.keys().map(|(x, _)| x).min().unwrap(); let min_x = (*self.grid.keys().map(|(x, _)| x).min().unwrap()).min(500);
let max_x = *self.0.keys().map(|(x, _)| x).max().unwrap(); let max_x = (*self.grid.keys().map(|(x, _)| x).max().unwrap()).max(500);
let min_y = *self.0.keys().map(|(_, y)| y).min().unwrap(); let min_y = (*self.grid.keys().map(|(_, y)| y).min().unwrap()).min(0);
let max_y = *self.0.keys().map(|(_, y)| y).max().unwrap(); let max_y = (*self.grid.keys().map(|(_, y)| y).max().unwrap()).max(0);
for y in min_y..=max_y { for y in min_y..=max_y {
for x in min_x..=max_x { for x in min_x..=max_x {
match self.0.get(&(x, y)) { let symbol = match self.grid.get(&(x, y)) {
None => eprint!(".."), _ if (x, y) == (500, 0) => "++",
Some(Cell::Wall) => eprint!("##"), None => "..",
Some(Cell::Sand) => eprint!("()"), Some(Cell::Wall) => "##",
Some(Cell::Source) => eprint!("++"), Some(Cell::Sand) => "()",
} };
eprint!("{symbol}");
} }
eprintln!(); eprintln!();
} }
} }
/// Returns true if the sand emitted from the source came to rest. /// Returns `true` if the sand emitted from the source came to rest. Returns
/// `false` if the source is blocked or the sand fell into infinity.
fn step(&mut self, source: (i32, i32)) -> bool { fn step(&mut self, source: (i32, i32)) -> bool {
if self.grid.get(&source).is_some() {
return false;
}
let (mut x, mut y) = source; let (mut x, mut y) = source;
let max_y = *self.0.keys().map(|(_, y)| y).max().unwrap(); while y <= self.max_y {
while y <= max_y { if self.grid.get(&(x, y + 1)).is_none() {
if self.0.get(&(x, y + 1)).is_none() {
y += 1; y += 1;
} else if self.0.get(&(x - 1, y + 1)).is_none() { } else if self.grid.get(&(x - 1, y + 1)).is_none() {
x -= 1; x -= 1;
y += 1; y += 1;
} else if self.0.get(&(x + 1, y + 1)).is_none() { } else if self.grid.get(&(x + 1, y + 1)).is_none() {
x += 1; x += 1;
y += 1; y += 1;
} else { } else {
self.0.insert((x, y), Cell::Sand); self.grid.insert((x, y), Cell::Sand);
return true; return true;
} }
} }
@ -77,15 +89,23 @@ impl Grid {
} }
pub fn solve(input: String) { pub fn solve(input: String) {
let mut grid = Grid::parse(&input); let grid = Grid::parse(&input);
// grid.eprint();
let mut part1_grid = grid.clone();
let mut part1 = 0; let mut part1 = 0;
while grid.step((500, 0)) { while part1_grid.step((500, 0)) {
part1 += 1; part1 += 1;
// eprintln!("\x1b[;H\x1b[J");
// eprintln!();
// grid.eprint();
} }
println!("Part 1: {part1}"); println!("Part 1: {part1}");
let mut part2_grid = grid;
let floor_y = part2_grid.max_y + 2;
for x in 500 - floor_y..=500 + floor_y {
part2_grid.insert((x, floor_y), Cell::Wall);
}
let mut part2 = 0;
while part2_grid.step((500, 0)) {
part2 += 1;
}
println!("Part 2: {part2}");
} }

View file

@ -1,2 +1,2 @@
Part 1: 24 Part 1: 24
Part 2: ??? Part 2: 93