Watch
1
0
Fork
You've already forked advent-of-code
0

Fix mutually-correcting bugs 😅

This commit is contained in:
Jeremy Kaplan 2022-12-13 22:46:43 -08:00
commit 2aefc33bc2

View file

@ -3,28 +3,25 @@ use std::collections::HashSet;
const INPUT: &str = include_str!("../../input/day14.txt"); const INPUT: &str = include_str!("../../input/day14.txt");
fn main() { fn main() {
println!("{}", part1(INPUT)); let paths = aoc::lines(INPUT).map(Path::parse).collect();
println!("{}", part2(INPUT)); let wall = Wall::build(paths);
println!("{}", part1(wall.clone()));
println!("{}", part2(wall));
} }
fn part1(input: &str) -> usize { fn part1(mut wall: Wall) -> usize {
let paths = aoc::lines(input).map(Path::parse).collect();
let mut wall = Wall::build(paths);
while wall.add_sand_1().is_some() {} while wall.add_sand_1().is_some() {}
wall.render(); wall.render();
wall.sand.len() wall.sand.len()
} }
fn part2(input: &str) -> usize { fn part2(mut wall: Wall) -> usize {
let paths = aoc::lines(input).map(Path::parse).collect();
let mut wall = Wall::build(paths);
while let Some(_pos) = wall.add_sand_2() {} while let Some(_pos) = wall.add_sand_2() {}
wall.render(); wall.render();
wall.sand.len() + 1 // for the sand source wall.sand.len()
} }
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
@ -96,6 +93,7 @@ impl Segment {
} }
} }
#[derive(Debug, Clone)]
struct Wall { struct Wall {
rocks: HashSet<Point>, rocks: HashSet<Point>,
sand: HashSet<Point>, sand: HashSet<Point>,
@ -120,7 +118,7 @@ impl Wall {
} }
} }
let y_floor = y_abyss; let y_floor = y_abyss + 2;
Self { Self {
rocks, rocks,
@ -178,7 +176,10 @@ impl Point {
impl Wall { impl Wall {
fn filled(&self, p: &Point) -> bool { fn filled(&self, p: &Point) -> bool {
p == &Wall::SAND_SOURCE || self.rocks.contains(p) || self.sand.contains(p) p == &Wall::SAND_SOURCE
|| self.rocks.contains(p)
|| self.sand.contains(p)
|| p.y >= self.y_floor
} }
fn empty(&self, p: &Point) -> bool { fn empty(&self, p: &Point) -> bool {
@ -186,25 +187,7 @@ impl Wall {
} }
fn add_sand_1(&mut self) -> Option<Point> { fn add_sand_1(&mut self) -> Option<Point> {
let mut pos = Wall::SAND_SOURCE; let pos = self.drop_sand(self.y_abyss);
'tick: while pos.y <= self.y_abyss {
let candidates = vec![
pos.mv(0, 1), // down
pos.mv(-1, 1), // down-left
pos.mv(1, 1), // down-right
];
for next in candidates {
if self.empty(&next) {
pos = next;
continue 'tick;
}
}
// Stuck!
break 'tick;
}
if pos.y < self.y_abyss { if pos.y < self.y_abyss {
self.sand.insert(pos); self.sand.insert(pos);
@ -215,9 +198,19 @@ impl Wall {
} }
fn add_sand_2(&mut self) -> Option<Point> { fn add_sand_2(&mut self) -> Option<Point> {
let pos = self.drop_sand(self.y_floor);
if self.sand.insert(pos) {
Some(pos)
} else {
None
}
}
fn drop_sand(&self, y_max: i32) -> Point {
let mut pos = Wall::SAND_SOURCE; let mut pos = Wall::SAND_SOURCE;
'tick: while pos.y <= self.y_floor { 'tick: while pos.y <= y_max {
let candidates = vec![ let candidates = vec![
pos.mv(0, 1), // down pos.mv(0, 1), // down
pos.mv(-1, 1), // down-left pos.mv(-1, 1), // down-left
@ -235,12 +228,7 @@ impl Wall {
break 'tick; break 'tick;
} }
if pos != Wall::SAND_SOURCE { pos
self.sand.insert(pos);
Some(pos)
} else {
None
}
} }
} }