From 8b39941cb56ea46ec2ed51b0667cc03df8d04c4c Mon Sep 17 00:00:00 2001 From: Ishan Jain Date: Tue, 5 Dec 2023 18:52:42 +0530 Subject: [PATCH] day5: optimized --- src/day5/2.rs | 83 ++++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/src/day5/2.rs b/src/day5/2.rs index 8ea6e79..42a8a04 100644 --- a/src/day5/2.rs +++ b/src/day5/2.rs @@ -1,4 +1,3 @@ -#![feature(iter_array_chunks)] #![feature(test)] use std::ops::Range; @@ -20,79 +19,80 @@ fn process(data: &str) -> i64 { .collect(); v.chunks(2) - .map(|x| (x[0]..x[0] + x[1])) + .map(|x| x[0]..x[0] + x[1]) .collect::>>() }) .unwrap(); - let maps: Vec, Range)>> = lines - .map(|lines| { - lines - .lines() - .skip(1) - .map(|line| { - let y: Vec = line - .split_ascii_whitespace() - .map(|y| y.parse::().unwrap()) - .collect(); - let size = y[2]; + let maps = lines.map(|lines| { + lines + .lines() + .skip(1) + .map(|line| { + let y: Vec = line + .split_ascii_whitespace() + .map(|y| y.parse::().unwrap()) + .collect(); + let size = y[2]; + + (y[1]..y[1] + size, y[0]..y[0] + size) + }) + .collect::, Range)>>() + }); - (y[1]..y[1] + size, y[0]..y[0] + size) - }) - .collect() - }) - .collect(); for map in maps { - let mut out = vec![]; + let mut out = Vec::with_capacity(seeds.len()); - for seed in seeds.drain(..) { + for seed in seeds { // split seed based on this rangemap let splitted = split(&map, seed); out.extend(splitted); } - seeds.extend_from_slice(&out); + seeds = out } seeds.into_iter().map(|x| x.start).min().unwrap() } fn split(map: &[(Range, Range)], node: Range) -> Vec> { - let mut out = vec![]; - + let mut out = Vec::with_capacity(map.len()); let mut stack = vec![node]; while let Some(node) = stack.pop() { let mut found_match = false; - for (src, dst) in map.iter() { + for (src, dst) in map + .iter() + .skip_while(|(src, _)| node.end.min(src.end) - node.start.max(src.start) <= 0) + { let overlap = std::cmp::max(0, node.end.min(src.end) - node.start.max(src.start)); + if overlap <= 0 { + break; + } - if overlap == 0 { - continue; - } else if node.start > src.start && node.end < src.end { + let dst = if node.start == src.start && node.end == src.end { + dst.clone() + } else if node.start >= src.start && node.end <= src.end { + // src engulfs node let offset = std::cmp::max(0, node.start - src.start); - let dst = dst.start + offset..dst.start + offset + overlap; - found_match = true; - out.push(dst); + + dst.start + offset..dst.start + offset + overlap } else if node.start < src.start && node.end > src.end { + // node engulfs src let r1_non = node.start..src.start; let r2_non = src.end..node.end; - found_match = true; + stack.extend([r1_non, r2_non]); - out.push(dst.clone()); - stack.push(r1_non); - stack.push(r2_non); + dst.clone() } else { // Partial overlap let offset = std::cmp::max(0, node.start - src.start); - let dst_range = dst.start + offset..dst.start + offset + overlap; - found_match = true; let new_range = if node.start < src.start { node.start..src.start } else { @@ -100,8 +100,11 @@ fn split(map: &[(Range, Range)], node: Range) -> Vec> }; stack.push(new_range); - out.push(dst_range); - } + dst_range + }; + + found_match = true; + out.push(dst); } if !found_match { @@ -114,12 +117,12 @@ fn split(map: &[(Range, Range)], node: Range) -> Vec> fn main() { for input in INPUTS.iter() { - println!("total = {}", process(input)); + println!("answer = {}", process(input)); } } #[bench] -fn part1(b: &mut test::Bencher) { +fn part2(b: &mut test::Bencher) { b.iter(|| { let v = process(INPUTS[1]); test::black_box(v);