diff --git a/2022/input/day_15.txt b/2022/input/day_15.txt new file mode 100644 index 0000000..c918beb --- /dev/null +++ b/2022/input/day_15.txt @@ -0,0 +1,24 @@ +Sensor at x=98246, y=1908027: closest beacon is at x=1076513, y=2000000 +Sensor at x=1339369, y=2083853: closest beacon is at x=1076513, y=2000000 +Sensor at x=679177, y=3007305: closest beacon is at x=1076513, y=2000000 +Sensor at x=20262, y=3978297: closest beacon is at x=13166, y=4136840 +Sensor at x=3260165, y=2268955: closest beacon is at x=4044141, y=2290104 +Sensor at x=2577675, y=3062584: closest beacon is at x=2141091, y=2828176 +Sensor at x=3683313, y=2729137: closest beacon is at x=4044141, y=2290104 +Sensor at x=1056412, y=370641: closest beacon is at x=1076513, y=2000000 +Sensor at x=2827280, y=1827095: closest beacon is at x=2757345, y=1800840 +Sensor at x=1640458, y=3954524: closest beacon is at x=2141091, y=2828176 +Sensor at x=2139884, y=1162189: closest beacon is at x=2757345, y=1800840 +Sensor at x=3777450, y=3714504: closest beacon is at x=3355953, y=3271922 +Sensor at x=1108884, y=2426713: closest beacon is at x=1076513, y=2000000 +Sensor at x=2364307, y=20668: closest beacon is at x=2972273, y=-494417 +Sensor at x=3226902, y=2838842: closest beacon is at x=3355953, y=3271922 +Sensor at x=22804, y=3803886: closest beacon is at x=13166, y=4136840 +Sensor at x=2216477, y=2547945: closest beacon is at x=2141091, y=2828176 +Sensor at x=1690953, y=2203555: closest beacon is at x=1076513, y=2000000 +Sensor at x=3055156, y=3386812: closest beacon is at x=3355953, y=3271922 +Sensor at x=3538996, y=719130: closest beacon is at x=2972273, y=-494417 +Sensor at x=2108918, y=2669413: closest beacon is at x=2141091, y=2828176 +Sensor at x=3999776, y=2044283: closest beacon is at x=4044141, y=2290104 +Sensor at x=2184714, y=2763072: closest beacon is at x=2141091, y=2828176 +Sensor at x=2615462, y=2273553: closest beacon is at x=2757345, y=1800840 diff --git a/2022/input/day_15_sample.txt b/2022/input/day_15_sample.txt new file mode 100644 index 0000000..a612424 --- /dev/null +++ b/2022/input/day_15_sample.txt @@ -0,0 +1,14 @@ +Sensor at x=2, y=18: closest beacon is at x=-2, y=15 +Sensor at x=9, y=16: closest beacon is at x=10, y=16 +Sensor at x=13, y=2: closest beacon is at x=15, y=3 +Sensor at x=12, y=14: closest beacon is at x=10, y=16 +Sensor at x=10, y=20: closest beacon is at x=10, y=16 +Sensor at x=14, y=17: closest beacon is at x=10, y=16 +Sensor at x=8, y=7: closest beacon is at x=2, y=10 +Sensor at x=2, y=0: closest beacon is at x=2, y=10 +Sensor at x=0, y=11: closest beacon is at x=2, y=10 +Sensor at x=20, y=14: closest beacon is at x=25, y=17 +Sensor at x=17, y=20: closest beacon is at x=21, y=22 +Sensor at x=16, y=7: closest beacon is at x=15, y=3 +Sensor at x=14, y=3: closest beacon is at x=15, y=3 +Sensor at x=20, y=1: closest beacon is at x=15, y=3 diff --git a/2022/src/day_15.rs b/2022/src/day_15.rs new file mode 100644 index 0000000..1b5ed24 --- /dev/null +++ b/2022/src/day_15.rs @@ -0,0 +1,93 @@ +use std::collections::HashMap; +use State::*; + +type Point = (i64, i64); +#[derive(Debug, PartialEq, Eq, Hash)] +enum State { + Sensor, + Beacon, + Empty, +} +type Data = Vec<(Point, Point)>; +type Output = i64; +fn parse(input: &str) -> Data { + fn parse_point(input: &str) -> Point { + let (_, rest) = input.split_once("x=").unwrap(); + let (x, rest) = rest.split_once(", ").unwrap(); + let (_, y) = rest.split_once("y=").unwrap(); + (x.parse().unwrap(), y.parse().unwrap()) + } + + input + .lines() + .map(str::to_owned) + .map(|l| { + let (s, b) = l.split_once(':').unwrap(); + (parse_point(s), parse_point(b)) + }) + .collect() +} +fn manhattan_distance(a: Point, b: Point) -> i64 { + (a.0.abs_diff(b.0) + a.1.abs_diff(b.1)) as i64 +} +fn is_star_input(data: &Data) -> bool { + // hacky trick to distinguish sample vs start input + data[0].0 .0 == 98_246 +} +fn part_one(data: Data) -> Output { + let row = if is_star_input(&data) { 2_000_000 } else { 10 }; + let mut map: HashMap = data + .iter() + .flat_map(|(s, b)| [(*s, Sensor), (*b, Beacon)]) + .collect(); + + for (s, b) in data { + let dist = manhattan_distance(s, b); + let x_offset = dist - s.1.abs_diff(row) as i64; + for x in s.0 - x_offset..=s.0 + x_offset { + map.entry((x, row)).or_insert(Empty); + } + } + map.iter() + .filter(|(p, state)| p.1 == row && Empty == **state) + .count() as Output +} +fn part_two(data: Data) -> Output { + let max_bounds = if is_star_input(&data) { 4_000_000 } else { 20 }; + + let data: Vec<_> = data + .into_iter() + .map(|(s, b)| (s, manhattan_distance(s, b))) + .collect(); + for y in 0..max_bounds { + let mut x = 0; + while x < max_bounds { + let next_idx = data.iter().find_map(|(s, dist)| { + let curr_dist = manhattan_distance(*s, (x, y)); + if curr_dist > *dist { + return None; + } + let x_offset = dist - s.1.abs_diff(y) as i64; + if (s.0 - x_offset..=s.0 + x_offset).contains(&x) { + Some(s.0 + x_offset + 1) + } else { + None + } + }); + if next_idx.is_none() { + return x * 4000000 + y; + } + x = next_idx.unwrap(); + } + } + unreachable!() +} + +advent_of_code_macro::generate_tests!( + day 15, + parse, + part_one, + part_two, + sample tests [26, 56_000_011], + star tests [5_125_700, 11_379_394_658_764] +); diff --git a/2022/src/lib.rs b/2022/src/lib.rs index c1ae1bf..cefc13e 100644 --- a/2022/src/lib.rs +++ b/2022/src/lib.rs @@ -13,3 +13,4 @@ mod day_11; mod day_12; mod day_13; mod day_14; +mod day_15;