diff --git a/day15/src/main.rs b/day15/src/main.rs index 1501603..baf04a5 100644 --- a/day15/src/main.rs +++ b/day15/src/main.rs @@ -29,6 +29,13 @@ fn combine(ranges: &mut Vec<(i64, i64)>, l: i64, r: i64) { return; } } + if ranges.len() > 0 { + let (_, last_r) = ranges.last_mut().unwrap(); + if l == *last_r + 1 { + *last_r = r; + return; + } + } ranges.push((l, r)); } @@ -50,29 +57,27 @@ fn main() { println!("{:?}", sensors); println!("{:?}", beacons); - let target_y = &env::args().nth(2).expect("line").parse::().unwrap(); - let mut coverage: Vec<(i64, i64)> = Vec::new(); - for (sx, sy, range) in sensors { - let clip = (range as i64) - (sy - target_y).abs(); - if clip < 0 { - continue; - } - let startx = sx - clip; - let endx = sx + clip; - combine(&mut coverage, startx, endx); - - } - println!("{:?}", coverage); - - let mut sum = 0; - for (l, r) in coverage { - let mut overlap = 0; - for (bx, by) in &beacons { - if *by == *target_y && l <= *bx && r >= *bx { - overlap += 1; + let max_y = &env::args().nth(2).expect("max y").parse::().unwrap(); + for target_y in 0..=*max_y { + let mut line_coverages: Vec<(i64, i64)> = Vec::new(); + for (sx, sy, range) in &sensors { + let clip = (*range as i64) - (sy - target_y).abs(); + if clip < 0 { + continue; } + let startx = sx - clip; + let endx = sx + clip; + line_coverages.push((startx, endx)); + } + line_coverages.sort_by_key(|(x, _)| *x); + let mut coverage: Vec<(i64, i64)> = Vec::new(); + for (startx, endx) in line_coverages { + combine(&mut coverage, startx, endx); + } + if coverage.len() > 1 { + let score = 4000000 * (coverage[0].1 + 1) + target_y; + println!("{:?} --> {:?}", coverage, score); + break; } - sum += r - l + 1 - overlap; } - println!("answer: {:?}", sum); } diff --git a/day15/src/main1.rs b/day15/src/main1.rs new file mode 100644 index 0000000..1501603 --- /dev/null +++ b/day15/src/main1.rs @@ -0,0 +1,78 @@ +use std::env; +use std::fs::File; +use std::io::{BufReader, BufRead}; +use std::cmp::{min, max}; +use std::collections::HashSet; + +fn parse_num(s: &[u8]) -> (i64, usize) { + let mut num: i64 = 0; + let negative = s[0] == '-' as u8; + let start = if negative {1} else {0}; + let mut len = if negative {1} else {0}; + + for i in start..s.len() { + if s[i].is_ascii_digit() { + num = num*10 + (s[i] as i64 - '0' as i64); + len += 1; + } else { + break; + } + } + (if negative {-num} else {num}, len) +} + +fn combine(ranges: &mut Vec<(i64, i64)>, l: i64, r: i64) { + for (l0, r0) in ranges.iter_mut() { + if *l0 <= r && l <= *r0 { + *l0 = min(*l0, l); + *r0 = max(*r0, r); + return; + } + } + ranges.push((l, r)); +} + +fn main() { + let file = File::open(&env::args().nth(1).expect("input")).expect("io err"); + let lines = BufReader::new(file).lines(); + let mut sensors: Vec<(i64, i64, u64)> = Vec::new(); + let mut beacons: HashSet<(i64, i64)> = HashSet::new(); + for line in lines.flatten() { + let l_bytes = line.as_bytes(); + let (sx, e1) = parse_num(&l_bytes[12..]); + let (sy, e2) = parse_num(&l_bytes[12 + e1 + 4..]); + let (bx, e3) = parse_num(&l_bytes[12 + e1 + 4 + e2 + 25..]); + let (by, _) = parse_num(&l_bytes[12 + e1 + 4 + e2 + 25 + e3 + 4..]); + sensors.push((sx, sy, ((bx - sx).abs() + (by - sy).abs()) as u64)); + beacons.insert((bx, by)); + } + sensors.sort_by_key(|(x, _, _)| *x); + println!("{:?}", sensors); + println!("{:?}", beacons); + + let target_y = &env::args().nth(2).expect("line").parse::().unwrap(); + let mut coverage: Vec<(i64, i64)> = Vec::new(); + for (sx, sy, range) in sensors { + let clip = (range as i64) - (sy - target_y).abs(); + if clip < 0 { + continue; + } + let startx = sx - clip; + let endx = sx + clip; + combine(&mut coverage, startx, endx); + + } + println!("{:?}", coverage); + + let mut sum = 0; + for (l, r) in coverage { + let mut overlap = 0; + for (bx, by) in &beacons { + if *by == *target_y && l <= *bx && r >= *bx { + overlap += 1; + } + } + sum += r - l + 1 - overlap; + } + println!("answer: {:?}", sum); +}