Day 5 part 2

This commit is contained in:
Bill Thiede 2021-12-05 14:43:03 -08:00
parent ae10705a38
commit 5b65e8ec71

View File

@ -1,3 +1,4 @@
//!
//! --- Day 5: Hydrothermal Venture ---
//! You come across a field of hydrothermal vents on the ocean floor! These vents constantly produce large, opaque clouds, so it would be best to avoid them if possible.
//!
@ -36,6 +37,29 @@
//! To avoid the most dangerous areas, you need to determine the number of points where at least two lines overlap. In the above example, this is anywhere in the diagram with a 2 or larger - a total of 5 points.
//!
//! Consider only horizontal and vertical lines. At how many points do at least two lines overlap?
//!
//! --- Part Two ---
//! Unfortunately, considering only horizontal and vertical lines doesn't give you the full picture; you need to also consider diagonal lines.
//!
//! Because of the limits of the hydrothermal vent mapping system, the lines in your list will only ever be horizontal, vertical, or a diagonal line at exactly 45 degrees. In other words:
//!
//! An entry like 1,1 -> 3,3 covers points 1,1, 2,2, and 3,3.
//! An entry like 9,7 -> 7,9 covers points 9,7, 8,8, and 7,9.
//! Considering all lines from the above example would now produce the following diagram:
//!
//! 1.1....11.
//! .111...2..
//! ..2.1.111.
//! ...1.2.2..
//! .112313211
//! ...1.2....
//! ..1...1...
//! .1.....1..
//! 1.......1.
//! 222111....
//! You still need to determine the number of points where at least two lines overlap. In the above example, this is still anywhere in the diagram with a 2 or larger - now a total of 12 points.
//!
//! Consider all of the lines. At how many points do at least two lines overlap?
use std::{
fmt::{Debug, Error, Formatter},
@ -54,7 +78,6 @@ struct Point {
y: i32,
}
#[derive(Debug)]
struct Line {
p0: Point,
p1: Point,
@ -68,6 +91,16 @@ enum LineError {
PrematureEOL,
}
impl Debug for Line {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
writeln!(
f,
"{},{} -> {},{}",
self.p0.x, self.p0.y, self.p1.x, self.p1.y,
)
}
}
impl FromStr for Line {
type Err = LineError;
@ -113,13 +146,13 @@ impl Image {
impl Index<(usize, usize)> for Image {
type Output = u32;
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
&self.pixels[x + y * (self.width - 1)]
&self.pixels[x + y * self.width]
}
}
impl IndexMut<(usize, usize)> for Image {
fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output {
&mut self.pixels[x + y * (self.width - 1)]
&mut self.pixels[x + y * self.width]
}
}
@ -128,7 +161,12 @@ impl Debug for Image {
writeln!(f, "({}, {})", self.width, self.height)?;
for y in 0..self.height {
for x in 0..self.width {
write!(f, "{:2}", self[(x, y)])?;
let v = self[(x, y)];
if v == 0 {
write!(f, ".")?;
} else {
write!(f, "{}", v)?;
}
}
writeln!(f)?;
}
@ -146,8 +184,8 @@ fn parse(input: &str) -> Result<Vec<Line>> {
}
fn draw(im: &mut Image, l: &Line) {
let dx = l.p0.x - l.p1.x;
let dy = l.p0.y - l.p1.y;
let dx = l.p1.x - l.p0.x;
let dy = l.p1.y - l.p0.y;
if dx == 0 {
let x = l.p0.x as usize;
@ -157,8 +195,7 @@ fn draw(im: &mut Image, l: &Line) {
for y in sy..=ey {
im[(x, y as usize)] += 1;
}
}
if dy == 0 {
} else if dy == 0 {
let y = l.p0.y as usize;
let sx = l.p0.x;
let ex = l.p1.x;
@ -166,6 +203,20 @@ fn draw(im: &mut Image, l: &Line) {
for x in sx..=ex {
im[(x as usize, y)] += 1;
}
} else {
// We only support 45 degree angles.
assert_eq!(dx.abs(), dy.abs());
let dx = dx / dx.abs();
let dy = dy / dy.abs();
let mut x = l.p0.x;
let mut y = l.p0.y;
while x != l.p1.x && y != l.p1.y {
im[(x as usize, y as usize)] += 1;
x += dx;
y += dy;
}
im[(x as usize, y as usize)] += 1;
}
}
@ -175,12 +226,14 @@ fn part1(lines: &[Line]) -> Result<u32> {
.iter()
.map(|l| l.p0.x.max(l.p1.x) as usize)
.max()
.expect("couldn't find max width");
.expect("couldn't find max width")
+ 1;
let height = lines
.iter()
.map(|l| l.p0.y.max(l.p1.y) as usize)
.max()
.expect("couldn't find max height");
.expect("couldn't find max height")
+ 1;
let mut im = Image::new(width, height);
for l in lines
.iter()
@ -191,13 +244,26 @@ fn part1(lines: &[Line]) -> Result<u32> {
Ok(im.answer())
}
/*
#[aoc(day5, part2)]
fn part2(depths: &[u32]) -> Result<u32> {
todo!("part2")
Ok(())
fn part2(lines: &[Line]) -> Result<u32> {
let width = lines
.iter()
.map(|l| l.p0.x.max(l.p1.x) as usize)
.max()
.expect("couldn't find max width")
+ 1;
let height = lines
.iter()
.map(|l| l.p0.y.max(l.p1.y) as usize)
.max()
.expect("couldn't find max height")
+ 1;
let mut im = Image::new(width, height);
for l in lines {
draw(&mut im, l);
}
Ok(im.answer())
}
*/
#[cfg(test)]
mod tests {
@ -222,14 +288,22 @@ mod tests {
Ok(())
}
/*
#[test]
fn test_part2()->Result<()> {
let input = r#"
fn test_part2() -> Result<()> {
let input = r#"
0,9 -> 5,9
8,0 -> 0,8
9,4 -> 3,4
2,2 -> 2,1
7,0 -> 7,4
6,4 -> 2,0
0,9 -> 2,9
3,4 -> 1,4
0,0 -> 8,8
5,5 -> 8,2
"#
.trim();
assert_eq!(part2(&parse(input)?)?, TODO);
Ok(())
.trim();
assert_eq!(part2(&parse(input)?)?, 12);
Ok(())
}
*/
}