Advent of Code solutions
1use advent_core::{day_stuff, ex_for_day, Day};
2use utils::pos::Position;
3
4pub struct Day9;
5
6impl Day for Day9 {
7 day_stuff!(9, "50", "24", Vec<Position>);
8
9 fn part_1(input: Self::Input) -> Option<String> {
10 let ans = input
11 .iter()
12 .enumerate()
13 .flat_map(|(i, a)| {
14 input.iter().skip(i + 1).map(|b| {
15 let p = (*b - *a).abs();
16 (p.x + 1) * (p.y + 1)
17 })
18 })
19 .max()
20 .unwrap();
21
22 Some(ans.to_string())
23 }
24
25 fn part_2(mut input: Self::Input) -> Option<String> {
26 let mut max = 0;
27
28 input.push(*input.first().unwrap());
29
30 let lines = input.windows(2).map(|w| (w[0], w[1])).collect::<Vec<_>>();
31
32 for (i, a) in input.iter().enumerate() {
33 // println!("Start {} ({}/{})", *a, i + 1, input.len());
34 for b in input.iter().skip(i + 1) {
35 let p = (*b - *a).abs();
36 let area = (p.x + 1) * (p.y + 1);
37
38 if area > max {
39 let check = lines.iter().any(|&l| {
40 let (cons, b1, b2, c1, c2, r1, r2) = if l.0.x == l.1.x {
41 (l.0.x, a.x, b.x, l.0.y, l.1.y, a.y, b.y)
42 } else {
43 (l.0.y, a.y, b.y, l.0.x, l.1.x, a.x, b.x)
44 };
45
46 let (lower_cons, upper_cons) = (b1.min(b2), b1.max(b2));
47 let (line_range_lower, line_range_upper) = (c1.min(c2), c1.max(c2));
48 let (rect_range_lower, rect_range_upper) = (r1.min(r2), r1.max(r2));
49
50 let cons_in_range = cons > lower_cons && cons < upper_cons;
51 let ranges_overlap = if line_range_lower < rect_range_lower {
52 line_range_upper > rect_range_lower
53 } else {
54 rect_range_upper > line_range_lower
55 };
56
57 cons_in_range && ranges_overlap
58 });
59
60 if !check {
61 max = area;
62 }
63 }
64 }
65 }
66
67 Some(max.to_string())
68 }
69
70 fn parse_input(input: &str) -> Self::Input {
71 input
72 .lines()
73 .map(|l| {
74 let (x, y) = l.split_once(',').unwrap();
75 Position {
76 x: x.parse().unwrap(),
77 y: y.parse().unwrap(),
78 }
79 })
80 .collect()
81 }
82}