initial commit
commit
e3641e144d
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
.vscode/
|
|
@ -0,0 +1,35 @@
|
|||
Sensor at x=545406, y=2945484: closest beacon is at x=772918, y=2626448
|
||||
Sensor at x=80179, y=3385522: closest beacon is at x=772918, y=2626448
|
||||
Sensor at x=2381966, y=3154542: closest beacon is at x=2475123, y=3089709
|
||||
Sensor at x=2607868, y=1728571: closest beacon is at x=2715626, y=2000000
|
||||
Sensor at x=746476, y=2796469: closest beacon is at x=772918, y=2626448
|
||||
Sensor at x=911114, y=2487289: closest beacon is at x=772918, y=2626448
|
||||
Sensor at x=2806673, y=3051666: closest beacon is at x=2475123, y=3089709
|
||||
Sensor at x=1335361, y=3887240: closest beacon is at x=2505629, y=4282497
|
||||
Sensor at x=2432913, y=3069935: closest beacon is at x=2475123, y=3089709
|
||||
Sensor at x=1333433, y=35725: closest beacon is at x=1929144, y=529341
|
||||
Sensor at x=2289207, y=1556729: closest beacon is at x=2715626, y=2000000
|
||||
Sensor at x=2455525, y=3113066: closest beacon is at x=2475123, y=3089709
|
||||
Sensor at x=3546858, y=3085529: closest beacon is at x=3629407, y=2984857
|
||||
Sensor at x=3542939, y=2742086: closest beacon is at x=3629407, y=2984857
|
||||
Sensor at x=2010918, y=2389107: closest beacon is at x=2715626, y=2000000
|
||||
Sensor at x=3734968, y=3024964: closest beacon is at x=3629407, y=2984857
|
||||
Sensor at x=2219206, y=337159: closest beacon is at x=1929144, y=529341
|
||||
Sensor at x=1969253, y=890542: closest beacon is at x=1929144, y=529341
|
||||
Sensor at x=3522991, y=3257032: closest beacon is at x=3629407, y=2984857
|
||||
Sensor at x=2303155, y=3239124: closest beacon is at x=2475123, y=3089709
|
||||
Sensor at x=2574308, y=111701: closest beacon is at x=1929144, y=529341
|
||||
Sensor at x=14826, y=2490395: closest beacon is at x=772918, y=2626448
|
||||
Sensor at x=3050752, y=2366125: closest beacon is at x=2715626, y=2000000
|
||||
Sensor at x=3171811, y=2935106: closest beacon is at x=3629407, y=2984857
|
||||
Sensor at x=3909938, y=1033557: closest beacon is at x=3493189, y=-546524
|
||||
Sensor at x=1955751, y=452168: closest beacon is at x=1929144, y=529341
|
||||
Sensor at x=2159272, y=614653: closest beacon is at x=1929144, y=529341
|
||||
Sensor at x=3700981, y=2930103: closest beacon is at x=3629407, y=2984857
|
||||
Sensor at x=3236266, y=3676457: closest beacon is at x=3373823, y=4223689
|
||||
Sensor at x=3980003, y=3819278: closest beacon is at x=3373823, y=4223689
|
||||
Sensor at x=1914391, y=723058: closest beacon is at x=1929144, y=529341
|
||||
Sensor at x=474503, y=1200604: closest beacon is at x=-802154, y=776650
|
||||
Sensor at x=2650714, y=3674470: closest beacon is at x=2505629, y=4282497
|
||||
Sensor at x=1696740, y=586715: closest beacon is at x=1929144, y=529341
|
||||
Sensor at x=3818789, y=2961752: closest beacon is at x=3629407, y=2984857
|
|
@ -0,0 +1,226 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
|
||||
|
||||
[[package]]
|
||||
name = "curl"
|
||||
version = "0.4.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22"
|
||||
dependencies = [
|
||||
"curl-sys",
|
||||
"libc",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"socket2",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curl-sys"
|
||||
version = "0.4.59+curl-7.86.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cfce34829f448b08f55b7db6d0009e23e2e86a34e8c2b366269bf5799b4a407"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"libz-sys",
|
||||
"openssl-sys",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "day15"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"curl",
|
||||
"libc",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.138"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
|
||||
|
||||
[[package]]
|
||||
name = "libz-sys"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5454462c0eced1e97f2ec09036abc8da362e66802f66fd20f86854d9d8cbcbc4"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
|
||||
dependencies = [
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.36.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "day15"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
curl = "0.4.44"
|
||||
libc = "0.2.138"
|
||||
regex = "1.7.0"
|
|
@ -0,0 +1,196 @@
|
|||
use std::collections::HashMap;
|
||||
use std::thread;
|
||||
use std::ops::RangeInclusive;
|
||||
use std::panic;
|
||||
use std::str;
|
||||
use std::cmp;
|
||||
use std::ops::Sub;
|
||||
use std::ops::{Deref};
|
||||
use std::fs;
|
||||
use std::convert::TryFrom;
|
||||
use std::process;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[derive(Default,Debug,PartialEq)]
|
||||
struct Location {
|
||||
x: isize,
|
||||
y: isize
|
||||
}
|
||||
impl<'a> Sub for &'a Location {
|
||||
type Output = isize;
|
||||
|
||||
fn sub(self, other: &'a Location) -> isize {
|
||||
(self.x - other.x).abs() + (self.y - other.y).abs()
|
||||
}
|
||||
}
|
||||
#[derive(Default,PartialEq)]
|
||||
struct Sensor {
|
||||
loc: Location,
|
||||
visibility: usize,
|
||||
}
|
||||
#[derive(Default,Debug,PartialEq)]
|
||||
struct Beacon {
|
||||
loc: Location
|
||||
}
|
||||
|
||||
|
||||
struct ComparableRange(RangeInclusive<isize>);
|
||||
|
||||
impl ComparableRange {
|
||||
pub fn intersects(&self, other:&ComparableRange) -> bool {
|
||||
self.contains(other.start()) ||
|
||||
other.contains(self.start())
|
||||
}
|
||||
|
||||
pub fn intersection(&self, other:&ComparableRange) -> ComparableRange {
|
||||
match self.intersects(other) {
|
||||
false => panic!("Ranges do not intersect"),
|
||||
true => ComparableRange(cmp::min(*self.start(), *other.start())..=cmp::max(*self.end(),*other.end()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for ComparableRange {
|
||||
type Target = RangeInclusive<isize>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
const PART_1_CONST:isize = 2000000;
|
||||
const PART_2_CONST:isize = 4000000;
|
||||
|
||||
fn main() {
|
||||
run();
|
||||
}
|
||||
|
||||
fn run() {
|
||||
let contents = fs::read_to_string("15").unwrap();
|
||||
process_part_1(contents.lines());
|
||||
process_part_2(contents.lines());
|
||||
}
|
||||
|
||||
fn process_part_2<'a, T>(lines: T) where T: IntoIterator<Item = &'a str> {
|
||||
let (sensors, _) = parse(lines);
|
||||
let mut worker_bundles = HashMap::new();
|
||||
for worker in 0..99 {
|
||||
let mut work_item = Vec::new();
|
||||
for sensor in &sensors {
|
||||
let chunk_s = sensor.visibility / 100;
|
||||
// let remainder = sensor.visibility - (99*chunk_s); <1% chance this worker contains solution.. ignore for now
|
||||
work_item.push(chunk_s);
|
||||
}
|
||||
worker_bundles.insert(worker, work_item);
|
||||
};
|
||||
|
||||
let mut handles = Vec::new();
|
||||
let bundle_storage = Arc::new(worker_bundles);
|
||||
let sensor_storage = Arc::new(sensors);
|
||||
for worker in 0..=99 {
|
||||
let worker_bundles = Arc::clone(&bundle_storage);
|
||||
let sensors = Arc::clone(&sensor_storage);
|
||||
let bounds = 0..=PART_2_CONST;
|
||||
let handle = thread::spawn(move || {do_part2_work(worker_bundles, worker, &bounds, sensors)} );
|
||||
handles.push(handle);
|
||||
}
|
||||
handles.into_iter().for_each(|handle|{ handle.join();});
|
||||
}
|
||||
|
||||
fn do_part2_work(worker_bundles: Arc<HashMap<isize, Vec<usize>>>, worker: isize, bounds: &RangeInclusive<isize>, sensors: Arc<Vec<Sensor>>) {
|
||||
worker_bundles.get(&worker).and_then(
|
||||
|x| {
|
||||
for (work_idx, work_item) in x.into_iter().enumerate() {
|
||||
for idx in 0..*work_item {
|
||||
let dist = isize::try_from(idx).unwrap() + worker*isize::try_from(*work_item).unwrap();
|
||||
let sensor = &sensors[work_idx];
|
||||
let visibility = isize::try_from(sensor.visibility).unwrap();
|
||||
let x_left = sensor.loc.x-dist;
|
||||
let x_right = sensor.loc.x+dist;
|
||||
let y_lower = sensor.loc.y + (visibility-dist) + 1;
|
||||
let y_upper = sensor.loc.y - (visibility-dist) - 1;
|
||||
[(x_left, y_upper), (x_right, y_upper), (x_left, y_lower), (x_right, y_lower)].into_iter().for_each(|coord| {
|
||||
if !(bounds).contains(&coord.0) || !(bounds).contains(&coord.1) { return }
|
||||
if (sensors).iter().all(|tgt_sensor| {
|
||||
&tgt_sensor.loc - &Location{x:coord.0, y:coord.1} > isize::try_from(tgt_sensor.visibility).unwrap()
|
||||
|
||||
}) {
|
||||
println!("{:?}", coord.0*4000000+coord.1);
|
||||
process::exit(0);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Some(())
|
||||
});
|
||||
}
|
||||
|
||||
fn process_part_1<'a, T>(lines: T) where T: IntoIterator<Item = &'a str> {
|
||||
let (sensors, beacons) = parse(lines);
|
||||
let target_row = PART_1_CONST;
|
||||
let mut impossible_ranges:Vec<ComparableRange> = Vec::new();
|
||||
for sensor in (&sensors).into_iter() {
|
||||
let visibility = isize::try_from(sensor.visibility).unwrap();
|
||||
let dist_to_target = &sensor.loc - &(Location {x:sensor.loc.x, y:target_row});
|
||||
if dist_to_target > visibility { continue }
|
||||
|
||||
let impossible_width = visibility - dist_to_target;
|
||||
let impossible_range = sensor.loc.x-impossible_width..=sensor.loc.x+impossible_width;
|
||||
impossible_ranges.push(ComparableRange(impossible_range));
|
||||
};
|
||||
impossible_ranges.sort_by(|a,b| a.start().cmp(b.start()));
|
||||
|
||||
merge(&mut impossible_ranges);
|
||||
|
||||
let beacons_in_row = beacons.into_iter().filter(|b| {
|
||||
if b.loc.y != target_row {
|
||||
return false
|
||||
}
|
||||
(&impossible_ranges).into_iter().any(|r| r.contains(&b.loc.x))
|
||||
}).count();
|
||||
println!("{}", impossible_ranges.into_iter().map(|r| r.end()-r.start()+1).sum::<isize>()-isize::try_from(beacons_in_row).unwrap());
|
||||
}
|
||||
|
||||
fn merge(impossible_ranges: &mut Vec<ComparableRange>) {
|
||||
let mut merge_idx = 0;
|
||||
while merge_idx < impossible_ranges.len()-1 {
|
||||
if (*impossible_ranges)[merge_idx].intersects(&impossible_ranges[merge_idx+1]) {
|
||||
let r1 = &impossible_ranges[merge_idx];
|
||||
let r2 = &impossible_ranges[merge_idx+1];
|
||||
impossible_ranges.insert(merge_idx+2,r1.intersection(&r2));
|
||||
impossible_ranges.remove(merge_idx+1);
|
||||
impossible_ranges.remove(merge_idx);
|
||||
} else {
|
||||
merge_idx += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse<'a, T>(lines: T) -> (Vec<Sensor>, Vec<Beacon>)
|
||||
where T: IntoIterator<Item = &'a str> {
|
||||
let mut sensors = Vec::new();
|
||||
let mut beacons = Vec::new();
|
||||
let extract_ints = |s: &str| {
|
||||
s
|
||||
.split(&['=',',',':'][..])
|
||||
.filter_map(|s| s.parse::<isize>().ok())
|
||||
.collect::<Vec<isize>>()
|
||||
};
|
||||
let loc_sets = lines.into_iter().map(extract_ints);
|
||||
loc_sets.for_each(|loc_set| {
|
||||
let sensor_loc = Location {x:loc_set[0], y:loc_set[1]};
|
||||
let beacon_loc = Location {x:loc_set[2], y:loc_set[3]};
|
||||
let visibility = usize::try_from(&sensor_loc-&beacon_loc).unwrap();
|
||||
sensors.push(Sensor{
|
||||
loc: sensor_loc,
|
||||
visibility: visibility
|
||||
});
|
||||
let beacon = Beacon{
|
||||
loc: beacon_loc
|
||||
};
|
||||
if !beacons.contains(&beacon) {
|
||||
beacons.push(beacon);
|
||||
}
|
||||
});
|
||||
(sensors, beacons)
|
||||
}
|
Loading…
Reference in New Issue