2022 - Day 15
This commit is contained in:
parent
0da86585cb
commit
c43808fbfc
33
2022/input/15/input
Normal file
33
2022/input/15/input
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
Sensor at x=407069, y=1770807: closest beacon is at x=105942, y=2000000
|
||||||
|
Sensor at x=2968955, y=2961853: closest beacon is at x=2700669, y=3091664
|
||||||
|
Sensor at x=3069788, y=2289672: closest beacon is at x=3072064, y=2287523
|
||||||
|
Sensor at x=2206, y=1896380: closest beacon is at x=105942, y=2000000
|
||||||
|
Sensor at x=3010408, y=2580417: closest beacon is at x=2966207, y=2275132
|
||||||
|
Sensor at x=2511130, y=2230361: closest beacon is at x=2966207, y=2275132
|
||||||
|
Sensor at x=65435, y=2285654: closest beacon is at x=105942, y=2000000
|
||||||
|
Sensor at x=2811709, y=3379959: closest beacon is at x=2801189, y=3200444
|
||||||
|
Sensor at x=168413, y=3989039: closest beacon is at x=-631655, y=3592291
|
||||||
|
Sensor at x=165506, y=2154294: closest beacon is at x=105942, y=2000000
|
||||||
|
Sensor at x=2720578, y=3116882: closest beacon is at x=2700669, y=3091664
|
||||||
|
Sensor at x=786521, y=1485720: closest beacon is at x=105942, y=2000000
|
||||||
|
Sensor at x=82364, y=2011850: closest beacon is at x=105942, y=2000000
|
||||||
|
Sensor at x=2764729, y=3156203: closest beacon is at x=2801189, y=3200444
|
||||||
|
Sensor at x=1795379, y=1766882: closest beacon is at x=1616322, y=907350
|
||||||
|
Sensor at x=2708986, y=3105910: closest beacon is at x=2700669, y=3091664
|
||||||
|
Sensor at x=579597, y=439: closest beacon is at x=1616322, y=907350
|
||||||
|
Sensor at x=2671201, y=2736834: closest beacon is at x=2700669, y=3091664
|
||||||
|
Sensor at x=3901, y=2089464: closest beacon is at x=105942, y=2000000
|
||||||
|
Sensor at x=144449, y=813212: closest beacon is at x=105942, y=2000000
|
||||||
|
Sensor at x=3619265, y=3169784: closest beacon is at x=2801189, y=3200444
|
||||||
|
Sensor at x=2239333, y=3878605: closest beacon is at x=2801189, y=3200444
|
||||||
|
Sensor at x=2220630, y=2493371: closest beacon is at x=2966207, y=2275132
|
||||||
|
Sensor at x=1148022, y=403837: closest beacon is at x=1616322, y=907350
|
||||||
|
Sensor at x=996105, y=3077490: closest beacon is at x=2700669, y=3091664
|
||||||
|
Sensor at x=3763069, y=3875159: closest beacon is at x=2801189, y=3200444
|
||||||
|
Sensor at x=3994575, y=2268273: closest beacon is at x=3072064, y=2287523
|
||||||
|
Sensor at x=3025257, y=2244500: closest beacon is at x=2966207, y=2275132
|
||||||
|
Sensor at x=2721366, y=1657084: closest beacon is at x=2966207, y=2275132
|
||||||
|
Sensor at x=3783491, y=1332930: closest beacon is at x=3072064, y=2287523
|
||||||
|
Sensor at x=52706, y=2020407: closest beacon is at x=105942, y=2000000
|
||||||
|
Sensor at x=2543090, y=47584: closest beacon is at x=3450858, y=-772833
|
||||||
|
Sensor at x=3499766, y=2477193: closest beacon is at x=3072064, y=2287523
|
14
2022/input/15/test-1
Normal file
14
2022/input/15/test-1
Normal file
|
@ -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
|
229
2022/src/bin/day15.rs
Normal file
229
2022/src/bin/day15.rs
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
#![feature(test)]
|
||||||
|
use std::{str::FromStr, cmp::{min, max}};
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use aoc::Solver;
|
||||||
|
|
||||||
|
// -- Runners --
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
Day::solve()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_test1() -> Result<()> {
|
||||||
|
Day::test(Day::part1, "test-1", 26)
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn part1_solution() -> Result<()> {
|
||||||
|
Day::test(Day::part1, "input", 4883971)
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn part2_test1() -> Result<()> {
|
||||||
|
Day::test(Day::part2, "test-1", 56000011)
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn part2_solutin() -> Result<()> {
|
||||||
|
Day::test(Day::part2, "input", 12691026767556)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Benchmarks
|
||||||
|
extern crate test;
|
||||||
|
#[bench]
|
||||||
|
#[ignore]
|
||||||
|
fn part1_bench(b: &mut test::Bencher) {
|
||||||
|
Day::benchmark(Day::part1, b)
|
||||||
|
}
|
||||||
|
#[bench]
|
||||||
|
#[ignore]
|
||||||
|
fn part2_bench(b: &mut test::Bencher) {
|
||||||
|
Day::benchmark(Day::part2, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Position {
|
||||||
|
x: isize,
|
||||||
|
y: isize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Sensor {
|
||||||
|
position: Position,
|
||||||
|
beacon: Position,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Sensor {
|
||||||
|
fn distance(&self) -> isize {
|
||||||
|
return (self.position.x - self.beacon.x).abs() + (self.position.y - self.beacon.y).abs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for Sensor {
|
||||||
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
let mut split = s.split(" ").map(|entry| {
|
||||||
|
entry.chars().filter(|c| c.is_digit(10) || *c == '-').collect::<String>()
|
||||||
|
}).filter(|entry| !entry.is_empty())
|
||||||
|
.map(|num| num.parse().unwrap());
|
||||||
|
|
||||||
|
// Sensor
|
||||||
|
let x = split.next().unwrap();
|
||||||
|
let y = split.next().unwrap();
|
||||||
|
let position = Position{ x, y };
|
||||||
|
|
||||||
|
// Beacon
|
||||||
|
let x = split.next().unwrap();
|
||||||
|
let y = split.next().unwrap();
|
||||||
|
let beacon = Position{ x, y };
|
||||||
|
|
||||||
|
Ok(Self { position, beacon })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
|
struct Range {
|
||||||
|
start: isize,
|
||||||
|
end: isize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Range {
|
||||||
|
fn len(&self) -> isize {
|
||||||
|
self.end - self.start
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn merge_step(ranges: &mut Vec<Range>) {
|
||||||
|
let mut merged = vec![false; ranges.len()];
|
||||||
|
let mut counter = 0;
|
||||||
|
|
||||||
|
for idx in 0..ranges.len() {
|
||||||
|
if merged[idx] {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut r = ranges[idx];
|
||||||
|
for (jdx, other) in ranges.iter().enumerate().skip(idx+1) {
|
||||||
|
if ranges[idx].end < other.start || other.end < ranges[idx].start {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
merged[idx] = true;
|
||||||
|
merged[jdx] = true;
|
||||||
|
|
||||||
|
r.start = min(r.start, other.start);
|
||||||
|
r.end = max(r.end, other.end);
|
||||||
|
}
|
||||||
|
|
||||||
|
ranges[counter] = r;
|
||||||
|
counter += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ranges.truncate(counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn merge(ranges: &mut Vec<Range>) {
|
||||||
|
loop {
|
||||||
|
let old_len = ranges.len();
|
||||||
|
merge_step(ranges);
|
||||||
|
|
||||||
|
if old_len == ranges.len() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// @TODO Implement this without doing a bunch of memory allocation
|
||||||
|
fn get_ranges(sensors: &Vec<Sensor>, y_level: isize, exclude_beacons: bool) -> Vec<Range> {
|
||||||
|
let mut ranges = Vec::new();
|
||||||
|
for sensor in sensors {
|
||||||
|
let offset = sensor.distance() - (sensor.position.y - y_level).abs();
|
||||||
|
if offset < 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut start = sensor.position.x - offset;
|
||||||
|
let mut end = sensor.position.x + offset + 1;
|
||||||
|
|
||||||
|
if exclude_beacons && sensor.beacon.y == y_level && sensor.beacon.x >= start && sensor.beacon.x < end {
|
||||||
|
// If there is a beacon in the range we actually have to create two different
|
||||||
|
// ranges that exclude the beacon
|
||||||
|
if sensor.beacon.x != start && sensor.beacon.x+1 != end {
|
||||||
|
ranges.push(Range { start, end: sensor.beacon.x });
|
||||||
|
start = sensor.beacon.x + 1;
|
||||||
|
} else if sensor.beacon.x == start {
|
||||||
|
start += 1;
|
||||||
|
} else if sensor.beacon.x+1 == end {
|
||||||
|
end -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if end > start {
|
||||||
|
ranges.push(Range{start,end});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
merge(&mut ranges);
|
||||||
|
|
||||||
|
return ranges;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Solution --
|
||||||
|
pub struct Day;
|
||||||
|
impl aoc::Solver for Day {
|
||||||
|
type Output1 = isize;
|
||||||
|
type Output2 = isize;
|
||||||
|
|
||||||
|
fn day() -> u8 {
|
||||||
|
15
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(input: &str) -> Self::Output1 {
|
||||||
|
let sensors = input
|
||||||
|
.lines()
|
||||||
|
.flat_map(Sensor::from_str)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let y_level;
|
||||||
|
if input.lines().count() > 14 {
|
||||||
|
y_level = 2000000;
|
||||||
|
} else {
|
||||||
|
y_level = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
get_ranges(&sensors, y_level, true)
|
||||||
|
.iter()
|
||||||
|
// .inspect(|range| println!("{range:?}"))
|
||||||
|
.map(Range::len)
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(input: &str) -> Self::Output2 {
|
||||||
|
let sensors = input
|
||||||
|
.lines()
|
||||||
|
.flat_map(Sensor::from_str)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let max;
|
||||||
|
if input.lines().count() > 14 {
|
||||||
|
max = 4000000;
|
||||||
|
} else {
|
||||||
|
max = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
for y_level in 0..(max+1) {
|
||||||
|
let ranges = get_ranges(&sensors, y_level, false);
|
||||||
|
|
||||||
|
if ranges.len() > 1 {
|
||||||
|
let x = ranges[0].end;
|
||||||
|
|
||||||
|
return x * 4000000 + y_level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user