Day 5 part 2
This commit is contained in:
parent
ae10705a38
commit
5b65e8ec71
110
2021/src/day5.rs
110
2021/src/day5.rs
@ -1,3 +1,4 @@
|
|||||||
|
//!
|
||||||
//! --- Day 5: Hydrothermal Venture ---
|
//! --- 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.
|
//! 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.
|
//! 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?
|
//! 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::{
|
use std::{
|
||||||
fmt::{Debug, Error, Formatter},
|
fmt::{Debug, Error, Formatter},
|
||||||
@ -54,7 +78,6 @@ struct Point {
|
|||||||
y: i32,
|
y: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct Line {
|
struct Line {
|
||||||
p0: Point,
|
p0: Point,
|
||||||
p1: Point,
|
p1: Point,
|
||||||
@ -68,6 +91,16 @@ enum LineError {
|
|||||||
PrematureEOL,
|
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 {
|
impl FromStr for Line {
|
||||||
type Err = LineError;
|
type Err = LineError;
|
||||||
|
|
||||||
@ -113,13 +146,13 @@ impl Image {
|
|||||||
impl Index<(usize, usize)> for Image {
|
impl Index<(usize, usize)> for Image {
|
||||||
type Output = u32;
|
type Output = u32;
|
||||||
fn index(&self, (x, y): (usize, usize)) -> &Self::Output {
|
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 {
|
impl IndexMut<(usize, usize)> for Image {
|
||||||
fn index_mut(&mut self, (x, y): (usize, usize)) -> &mut Self::Output {
|
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)?;
|
writeln!(f, "({}, {})", self.width, self.height)?;
|
||||||
for y in 0..self.height {
|
for y in 0..self.height {
|
||||||
for x in 0..self.width {
|
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)?;
|
writeln!(f)?;
|
||||||
}
|
}
|
||||||
@ -146,8 +184,8 @@ fn parse(input: &str) -> Result<Vec<Line>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw(im: &mut Image, l: &Line) {
|
fn draw(im: &mut Image, l: &Line) {
|
||||||
let dx = l.p0.x - l.p1.x;
|
let dx = l.p1.x - l.p0.x;
|
||||||
let dy = l.p0.y - l.p1.y;
|
let dy = l.p1.y - l.p0.y;
|
||||||
|
|
||||||
if dx == 0 {
|
if dx == 0 {
|
||||||
let x = l.p0.x as usize;
|
let x = l.p0.x as usize;
|
||||||
@ -157,8 +195,7 @@ fn draw(im: &mut Image, l: &Line) {
|
|||||||
for y in sy..=ey {
|
for y in sy..=ey {
|
||||||
im[(x, y as usize)] += 1;
|
im[(x, y as usize)] += 1;
|
||||||
}
|
}
|
||||||
}
|
} else if dy == 0 {
|
||||||
if dy == 0 {
|
|
||||||
let y = l.p0.y as usize;
|
let y = l.p0.y as usize;
|
||||||
let sx = l.p0.x;
|
let sx = l.p0.x;
|
||||||
let ex = l.p1.x;
|
let ex = l.p1.x;
|
||||||
@ -166,6 +203,20 @@ fn draw(im: &mut Image, l: &Line) {
|
|||||||
for x in sx..=ex {
|
for x in sx..=ex {
|
||||||
im[(x as usize, y)] += 1;
|
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()
|
.iter()
|
||||||
.map(|l| l.p0.x.max(l.p1.x) as usize)
|
.map(|l| l.p0.x.max(l.p1.x) as usize)
|
||||||
.max()
|
.max()
|
||||||
.expect("couldn't find max width");
|
.expect("couldn't find max width")
|
||||||
|
+ 1;
|
||||||
let height = lines
|
let height = lines
|
||||||
.iter()
|
.iter()
|
||||||
.map(|l| l.p0.y.max(l.p1.y) as usize)
|
.map(|l| l.p0.y.max(l.p1.y) as usize)
|
||||||
.max()
|
.max()
|
||||||
.expect("couldn't find max height");
|
.expect("couldn't find max height")
|
||||||
|
+ 1;
|
||||||
let mut im = Image::new(width, height);
|
let mut im = Image::new(width, height);
|
||||||
for l in lines
|
for l in lines
|
||||||
.iter()
|
.iter()
|
||||||
@ -191,13 +244,26 @@ fn part1(lines: &[Line]) -> Result<u32> {
|
|||||||
Ok(im.answer())
|
Ok(im.answer())
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
#[aoc(day5, part2)]
|
#[aoc(day5, part2)]
|
||||||
fn part2(depths: &[u32]) -> Result<u32> {
|
fn part2(lines: &[Line]) -> Result<u32> {
|
||||||
todo!("part2")
|
let width = lines
|
||||||
Ok(())
|
.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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
@ -222,14 +288,22 @@ mod tests {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part2() -> Result<()> {
|
fn test_part2() -> Result<()> {
|
||||||
let input = r#"
|
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();
|
.trim();
|
||||||
assert_eq!(part2(&parse(input)?)?, TODO);
|
assert_eq!(part2(&parse(input)?)?, 12);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user