diff --git a/src/day9.rs b/src/day9.rs index c2048b2..e429d01 100644 --- a/src/day9.rs +++ b/src/day9.rs @@ -1,13 +1,16 @@ +use itertools::Itertools; + #[aoc(day9, part1)] pub fn part1(input: &str) -> i64 { let mut coords = parse(input); coords.sort_unstable_by_key(|x| x.0 + x.1); - //println!("{:?}", coords); let mut area = 0; for (x1, y1) in coords.iter().rev().take(10) { for (x2, y2) in coords.iter().take(10) { + if ((x1 - x2 + 1) * (y1 - y2 + 1)) > area { + println!("{:?}", ((x1, y1), (x2, y2))) + }; area = area.max((x1 - x2 + 1) * (y1 - y2 + 1)); - //println!("{}", area); } } area @@ -15,69 +18,66 @@ pub fn part1(input: &str) -> i64 { #[aoc(day9, part2)] pub fn part2(input: &str) -> i64 { - let mut coords = parse(input); - let (x_lines, y_lines) = rg_lines(&coords); - coords.sort_unstable_by_key(|x| x.0 + x.1); - - println!("{:?}", coords); - println!("{:?}", x_lines); - println!("{:?}", y_lines); - + let coords = parse(input); let mut area = 0; - for (x1, y1) in coords.iter() { - for (x2, y2) in coords.iter() { - if y_lines - .iter() - .filter(|(x, y_a, y_b)| x2 == x && y_a <= y1 && y1 <= y_b) - .count() - > 1 - // && x_lines - // .iter() - // .filter(|(x, y_a, y_b)| x1 == x && y_a <= y2 && y2 <= y_b) - // .count() - // > 1 - // && y_lines - // .iter() - // .filter(|(y, x_a, x_b)| y1 == y && x_a <= x2 && x2 <= x_b) - // .count() - // > 1 - // && x_lines - // .iter() - // .filter(|(y, x_a, x_b)| y2 == y && x_a <= x1 && x1 <= x_b) - // .count() - // > 1 - { - println!("check"); - area = area.max((x1 - x2 + 1) * (y1 - y2 + 1)); + for i1 in 0..coords.len() { + for i3 in (0)..coords.len() { + let this_area = ((coords[i1].0 - coords[i3].0).abs() + 1) + * ((coords[i1].1 - coords[i3].1).abs() + 1); + + if this_area > area && check(i1, i3, &coords) { + area = this_area; } } } area } -fn rg_lines(coords: &Vec<(i64, i64)>) -> (Vec<(i64, i64, i64)>, Vec<(i64, i64, i64)>) { - let x_lines = coords - .iter() - .map(|(x1, y1)| { - coords - .iter() - .filter(move |(x2, y2)| x1 == x2 && y1 < y2) - .map(move |(x2, y2)| (*x1, *y1, *y2)) - }) - .flatten() - .collect(); - let y_lines = coords - .iter() - .map(|(x1, y1)| { - coords - .iter() - .filter(move |(x2, y2)| y1 == y2 && x1 < x2) - .map(move |(x2, y2)| (*y1, *x1, *x2)) - }) - .flatten() - .collect(); +fn check(corner_1: usize, corner_3: usize, coords: &Vec<(i64, i64)>) -> bool { + // Check by filtering coords between corners; then check if any consecutive + // ones cross the rectangle. + let a1 = coords[corner_1]; + let a3 = coords[corner_3]; - (x_lines, y_lines) + let upper_left = (a1.0.min(a3.0), a1.1.min(a3.1)); + let lower_right = (a1.0.max(a3.0), a1.1.max(a3.1)); + + for ((x1, y1), (x2, y2)) in coords.iter().circular_tuple_windows() { + if y1 == y2 { + // line horizontal + if !(y1 >= &lower_right.1 + || y1 <= &upper_left.1 + || (x1 <= &upper_left.0 && x2 <= &upper_left.0) + || (x1 >= &lower_right.0 && x2 >= &lower_right.0)) + { + // println!( + // "rejected horizontal of {:?},{:?} due to line {:?} {:?}", + // upper_left, + // lower_right, + // (x1, y1), + // (x2, y2) + // ); + return false; + } + } else { + // line horizontal + if !(x1 >= &lower_right.0 + || x1 <= &upper_left.0 + || (y1 <= &upper_left.1 && y2 <= &upper_left.1) + || (y1 >= &lower_right.1 && y2 >= &lower_right.1)) + { + // println!( + // "rejected vertical of {:?},{:?} due to line {:?} {:?}", + // upper_left, + // lower_right, + // (x1, y1), + // (x2, y2) + // ); + return false; + } + } + } + true } fn parse(input: &str) -> Vec<(i64, i64)> {