diff --git a/day_05/src/lib.rs b/day_05/src/lib.rs index 8549a7a..dac49ef 100644 --- a/day_05/src/lib.rs +++ b/day_05/src/lib.rs @@ -9,6 +9,7 @@ use nom::{ }; use std::str::FromStr; +use std::ops::Range; extern crate strum; #[macro_use] extern crate strum_macros; @@ -26,6 +27,15 @@ enum Item { Location, } +pub enum Intersection { + Below(Range), + InsideLow(Range, Range), + Inside(Range), + InsideHigh(Range, Range), + Above(Range), + Surrounding(Range, Range, Range), +} + #[derive(Debug, Eq, PartialEq)] struct ItemMap { before: u64, @@ -41,6 +51,23 @@ impl ItemMap { None } } + + pub fn convert_range(&self, range: Range) -> Intersection { + match ( + range.start < self.before, + range.start < self.before + self.length, + range.end <= self.before, + range.end <= self.before + self.length, + ) { + (true, _, true, _) => Intersection::Below(range), + (true, _, false, true) => Intersection::InsideLow(range.start..self.before,self.after..range.end+self.after-self.before), + (false, true, false, true) => Intersection::Inside(range.start+self.after-self.before..range.end+self.after-self.before), + (false, true, _, false) => Intersection::InsideHigh(range.start+self.after-self.before..self.after+self.length,self.before+self.length..range.end), + (_, false, _, false) => Intersection::Above(range), + (true, _, _, false) => Intersection::Surrounding(range.start..self.before,self.after..self.after+self.length,self.before+self.length..range.end), + _ => panic!(), + } + } } #[derive(Debug, Eq, PartialEq)] @@ -60,6 +87,31 @@ impl FullMap { None => num, } } + + pub fn convert_range(&self, ranges: Vec>) -> Vec> { + let mut current_ranges = ranges; + for item_map in self.maps { + let next_ranges = Vec::>::new(); + for seed_range in current_ranges { + match item_map.convert_range(seed_range) { + Intersection::Below() => {}, + Intersection::InsideLow() => {}, + Intersection::Inside() => {}, + Intersection::InsideHigh() => {}, + Intersection::Above() => {}, + Intersection::Surrounding() => {}, + } + } + } + println!("{:?} -> {:?}", self.in_type, self.out_type); + self.maps.iter().fold( ranges, |acc, item_map| { + let result = acc.iter().flat_map(|range| { + item_map.convert_range(range.clone()) + }).collect::>(); + println!{"{:?} -> {:?}", acc, result}; + result + }) + } } // 50 98 2 @@ -89,14 +141,12 @@ fn parse_seeds(input: &str) -> IResult<&str, Vec> { Ok((input, seeds)) } -fn parse_seeds_alt(input: &str) -> IResult<&str, Vec> { +fn parse_seeds_alt(input: &str) -> IResult<&str, Vec>> { let (input, seed_ranges) = preceded( tag("seeds: "), separated_list1(space1, separated_pair(complete::u64, space1, complete::u64)) )(input)?; - let mut seeds = vec![]; - seed_ranges.into_iter().for_each(|(start, length)| { (start..start+length).for_each(|x| {seeds.push(x);}) }); - Ok((input, seeds)) + Ok((input, seed_ranges.into_iter().map(|(start, length)| { start..start+length }).collect())) } fn parse_all(input: &str) -> IResult<&str, (Vec, Vec)> { @@ -105,7 +155,7 @@ fn parse_all(input: &str) -> IResult<&str, (Vec, Vec)> { Ok((input, (seeds, full_maps))) } -fn parse_all_alt(input: &str) -> IResult<&str, (Vec, Vec)> { +fn parse_all_alt(input: &str) -> IResult<&str, (Vec>, Vec)> { let (input, seeds) = terminated(parse_seeds_alt, tuple((newline, newline)))(input)?; dbg!(seeds.len()); let (input, full_maps) = separated_list1(tuple((newline,newline)), parse_full_map)(input)?; @@ -122,13 +172,12 @@ pub fn part1(input: &str) -> String { } pub fn part2(input: &str) -> String { - let (_, (seeds, full_maps)) = parse_all_alt(input).unwrap(); - seeds.into_iter().enumerate().map(|(i,seed)| { - if i % 1_000_000 == 0 { println!( "{}", i as f64 / 2291774376.0 ); } - full_maps.iter().fold(seed, |value, x| { - x.convert(value) + let (_, (seed_ranges, full_maps)) = parse_all_alt(input).unwrap(); + seed_ranges.iter().map(|seed_range| { + full_maps.iter().fold(vec![seed_range.clone()], |value, x| { + x.convert_range(value) }) - }).min().unwrap().to_string() + }).flatten().map(|x| {x.start}).min().unwrap().to_string() } pub mod prelude { diff --git a/day_05/src/main.rs b/day_05/src/main.rs index d5052a5..3565395 100644 --- a/day_05/src/main.rs +++ b/day_05/src/main.rs @@ -50,21 +50,15 @@ humidity-to-location map: #[test] fn test_part2() { - let test_input = "seeds: 79 14 55 13 + let test_input = "seeds: 79 14 seed-to-soil map: -50 98 2 52 50 48 soil-to-fertilizer map: -0 15 37 -37 52 2 39 0 15 fertilizer-to-water map: -49 53 8 -0 11 42 -42 0 7 57 7 4 water-to-light map: