Day 15 - task 2

This commit is contained in:
Jonathan Flueren 2022-12-15 23:16:42 +01:00
parent cb8d6e64ce
commit feccd2992a

View file

@ -1,12 +1,14 @@
use std::{collections::HashSet, fs}; use std::{collections::HashSet, fs};
const ROW: i32 = 2000000; const ROW: i32 = 2_000_000;
const TASK_2_CONST: i32 = 4_000_000;
pub fn solve() { pub fn solve() {
let path = "res/15/input.txt"; let path = "res/15/input.txt";
let contents = fs::read_to_string(path).expect("File read error"); let contents = fs::read_to_string(path).expect("File read error");
// parse sensors as tuples with (sensor, beacon, radius)
let sensors: Vec<((i32, i32), (i32, i32), i32)> = contents let sensors: Vec<((i32, i32), (i32, i32), i32)> = contents
.lines() .lines()
.filter(|line| *line != "") .filter(|line| *line != "")
@ -29,10 +31,11 @@ pub fn solve() {
}) })
.collect(); .collect();
// task 1
// go through sensors, add x-indices to hashset which are covered by sensors on y=2_000_000
let mut row_map = HashSet::<i32>::new(); let mut row_map = HashSet::<i32>::new();
sensors.iter().for_each(|sensor| { sensors.iter().for_each(|sensor| {
let ((x1, y1), (x2, y2), rad) = sensor; let ((x1, y1), (_, _), rad) = sensor;
let y_diff = y1.abs_diff(ROW) as i32; let y_diff = y1.abs_diff(ROW) as i32;
let x_diff = rad - y_diff; let x_diff = rad - y_diff;
@ -44,7 +47,7 @@ pub fn solve() {
row_map.insert(i); row_map.insert(i);
}) })
}); });
// remove all x-indices with beacons
sensors.iter().for_each(|sensor| { sensors.iter().for_each(|sensor| {
let ((_, _), (x2, y2), _) = sensor; let ((_, _), (x2, y2), _) = sensor;
@ -56,47 +59,57 @@ pub fn solve() {
let res = row_map.len(); let res = row_map.len();
println!("Result 1: {res}"); println!("Result 1: {res}");
let mut sen_tup = Vec::<((i32, i32, i32), (i32, i32, i32))>::new(); // task 2
let mut up_outlines = Vec::<i32>::new(); // build vec with all outline points of sensor ranges
let mut down_outlines = Vec::<i32>::new(); let mut outline = Vec::<(i32, i32)>::new();
sensors.iter().for_each(|s1| { sensors.iter().for_each(|sensor| {
sensors.iter().for_each(|s2| { let ((x, y), (_, _), rad) = *sensor;
if s1 != s2 { let mut curr_x = x + rad + 1;
let ((x1, y1), (_, _), rad1) = *s1; let mut curr_y = y;
let ((x2, y2), (_, _), rad2) = *s2; for _ in 0..=rad {
let dist = x1.abs_diff(x2) as i32 + y1.abs_diff(y2) as i32; curr_x -= 1;
if dist == rad1 + rad2 + 1 { curr_y += 1;
sen_tup.push(((x1, y1, rad1), (x2, y2, rad2))); outline.push((curr_x, curr_y));
// s2 in quadrant 1 }
if x1 - x2 < 0 && y1 - y2 > 0 { for _ in 0..=rad {
down_outlines.push(y1 - (x1 + rad1) - 1) curr_x -= 1;
} curr_y -= 1;
// s2 in quadrant 3 outline.push((curr_x, curr_y));
else if x1 - x2 > 0 && y1 - y2 < 0 { }
down_outlines.push(y2 - (x2 + rad2) - 1) for _ in 0..=rad {
} curr_x += 1;
// s2 in quadrant 2 curr_y -= 1;
else if x1 - x2 > 0 && y1 - y2 > 0 { outline.push((curr_x, curr_y));
up_outlines.push(y2 + (x2 + rad2) + 1) }
} for _ in 0..=rad {
// s2 in quadrant 4 curr_x += 1;
else if x1 - x2 < 0 && y1 - y2 < 0 { curr_y += 1;
up_outlines.push(y1 + (x1 + rad1) + 1) outline.push((curr_x, curr_y));
} }
}
}
})
}); });
let mut intersections = Vec::<(i32, i32)>::new(); // find point that is out of RAD for each sensor
up_outlines.iter().for_each(|up_line| { let mut res_point = (-1, -1);
down_outlines.iter().for_each(|down_line| { for p in outline {
if up_line > down_line && up_line % 2 == down_line % 2 { let mut point_in_sensor_range = false;
let intersection = down_line + (up_line - down_line) / 2; for s in &sensors {
// TODO continue let dist = p.0.abs_diff(s.0 .0) as i32 + p.1.abs_diff(s.0 .1) as i32;
if dist <= s.2 {
point_in_sensor_range = true;
break;
} }
}) }
}); if !point_in_sensor_range
&& p.0 >= 0
&& p.0 <= TASK_2_CONST
&& p.1 >= 0
&& p.1 <= TASK_2_CONST
{
res_point = p;
break;
}
}
sen_tup.iter().for_each(|tup| {}); let res = TASK_2_CONST as i64 * res_point.0 as i64 + res_point.1 as i64;
println!("Result 2: {res}");
} }