Complete day 5 part 2

This commit is contained in:
Tyler Hallada 2021-12-08 11:43:12 -05:00
parent 59230b8afb
commit f3cac78640

View File

@ -4,66 +4,19 @@ use std::collections::HashMap;
const INPUT: &str = include_str!("input/input.txt");
fn solve_part1(input: &str) -> Result<usize> {
let lines = input.trim().lines();
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct Point {
x: i32,
y: i32,
}
let mut covered_points: HashMap<(i32, i32), i32> = HashMap::new();
for line in lines {
let mut points = line.split(" -> ");
let start_point = points.next().unwrap();
let mut start_point = start_point.split(',');
let start_x = start_point.next().unwrap().parse::<i32>()?;
let start_y = start_point.next().unwrap().parse::<i32>()?;
let end_point = points.next().unwrap();
let mut end_point = end_point.split(',');
let end_x = end_point.next().unwrap().parse::<i32>()?;
let end_y = end_point.next().unwrap().parse::<i32>()?;
if start_x == end_x {
if start_y <= end_y {
for y in start_y..=end_y {
let entry = covered_points.entry((start_x, y)).or_insert(0);
*entry += 1;
}
} else {
for y in end_y..=start_y {
let entry = covered_points.entry((start_x, y)).or_insert(0);
*entry += 1;
}
}
} else if start_y == end_y {
if start_x <= end_x {
for x in start_x..=end_x {
let entry = covered_points.entry((x, start_y)).or_insert(0);
*entry += 1;
}
} else {
for x in end_x..=start_x {
let entry = covered_points.entry((x, start_y)).or_insert(0);
*entry += 1;
}
}
}
println!("{},{} -> {},{}", start_x, start_y, end_x, end_y);
for y in 0..=9 {
for x in 0..=9 {
let overlap = covered_points.get(&(x, y));
if let Some(overlap) = overlap {
print!("{}", overlap);
} else {
print!(".");
}
}
print!("\n");
}
print!("\n");
}
for y in 0..=9 {
for x in 0..=9 {
let overlap = covered_points.get(&(x, y));
#[allow(dead_code)]
fn print_ocean_floor(covered_points: &HashMap<Point, i32>) {
let max_x = covered_points.keys().map(|p| p.x).max().unwrap();
let max_y = covered_points.keys().map(|p| p.y).max().unwrap();
for y in 0..=max_y {
for x in 0..=max_x {
let overlap = covered_points.get(&Point { x, y });
if let Some(overlap) = overlap {
print!("{}", overlap);
} else {
@ -73,15 +26,108 @@ fn solve_part1(input: &str) -> Result<usize> {
print!("\n");
}
print!("\n");
Ok(covered_points.into_values().filter(|&overlap| overlap >= 2).count())
}
fn solve_part2(input: &str) -> Result<u64> {
let lines = input.trim().lines();
fn parse_vents(input: &str) -> Result<Vec<(Point, Point)>> {
input
.trim()
.lines()
.map(|line| {
let mut points = line.split(" -> ");
let start_point = points.next().unwrap();
let mut start_point = start_point.split(',');
let start_x = start_point.next().unwrap().parse::<i32>()?;
let start_y = start_point.next().unwrap().parse::<i32>()?;
let end_point = points.next().unwrap();
let mut end_point = end_point.split(',');
let end_x = end_point.next().unwrap().parse::<i32>()?;
let end_y = end_point.next().unwrap().parse::<i32>()?;
Ok((
Point {
x: start_x,
y: start_y,
},
Point { x: end_x, y: end_y },
))
})
.collect()
}
Ok(2)
fn get_covered_points(vents: Vec<(Point, Point)>) -> Result<HashMap<Point, i32>> {
let mut covered_points: HashMap<Point, i32> = HashMap::new();
for (start, end) in vents.iter() {
if start.x == end.x {
if start.y <= end.y {
for y in start.y..=end.y {
let entry = covered_points.entry(Point { x: start.x, y }).or_insert(0);
*entry += 1;
}
} else {
for y in end.y..=start.y {
let entry = covered_points.entry(Point { x: start.x, y }).or_insert(0);
*entry += 1;
}
}
} else if start.y == end.y {
if start.x <= end.x {
for x in start.x..=end.x {
let entry = covered_points.entry(Point { x, y: start.y }).or_insert(0);
*entry += 1;
}
} else {
for x in end.x..=start.x {
let entry = covered_points.entry(Point { x, y: start.y }).or_insert(0);
*entry += 1;
}
}
} else {
let mut x = start.x;
let mut y = start.y;
let dx = end.x - start.x;
let dy = end.y - start.y;
while (dx > 0 && x <= end.x) || (dx < 0 && x >= end.x) {
let entry = covered_points.entry(Point { x, y }).or_insert(0);
*entry += 1;
if dx > 0 {
x += 1;
} else {
x -= 1;
}
if dy > 0 {
y += 1;
} else {
y -= 1;
}
}
}
}
Ok(covered_points)
}
fn solve_part1(input: &str) -> Result<usize> {
let vents = parse_vents(input)?;
let vents = vents
.into_iter()
.filter(|(start, end)| start.x == end.x || start.y == end.y)
.collect();
let covered_points = get_covered_points(vents)?;
Ok(covered_points
.into_values()
.filter(|&overlap| overlap >= 2)
.count())
}
fn solve_part2(input: &str) -> Result<usize> {
let vents = parse_vents(input)?;
let covered_points = get_covered_points(vents)?;
Ok(covered_points
.into_values()
.filter(|&overlap| overlap >= 2)
.count())
}
fn main() {
@ -101,6 +147,6 @@ mod tests {
#[test]
fn solves_part2() {
assert_eq!(solve_part2(TEST_INPUT).unwrap(), 0);
assert_eq!(solve_part2(TEST_INPUT).unwrap(), 12);
}
}