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