Fix mutually-correcting bugs 😅
This commit is contained in:
parent
f74bf1cab8
commit
2aefc33bc2
1 changed files with 27 additions and 39 deletions
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue