Broke part 5 but I'm committing anyway

This commit is contained in:
Connor Johnstone
2023-12-07 23:51:33 -07:00
parent 58e0f7fcea
commit b3f768f211
2 changed files with 61 additions and 18 deletions

View File

@@ -9,6 +9,7 @@ use nom::{
}; };
use std::str::FromStr; use std::str::FromStr;
use std::ops::Range;
extern crate strum; extern crate strum;
#[macro_use] extern crate strum_macros; #[macro_use] extern crate strum_macros;
@@ -26,6 +27,15 @@ enum Item {
Location, Location,
} }
pub enum Intersection {
Below(Range<u64>),
InsideLow(Range<u64>, Range<u64>),
Inside(Range<u64>),
InsideHigh(Range<u64>, Range<u64>),
Above(Range<u64>),
Surrounding(Range<u64>, Range<u64>, Range<u64>),
}
#[derive(Debug, Eq, PartialEq)] #[derive(Debug, Eq, PartialEq)]
struct ItemMap { struct ItemMap {
before: u64, before: u64,
@@ -41,6 +51,23 @@ impl ItemMap {
None None
} }
} }
pub fn convert_range(&self, range: Range<u64>) -> 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)] #[derive(Debug, Eq, PartialEq)]
@@ -60,6 +87,31 @@ impl FullMap {
None => num, None => num,
} }
} }
pub fn convert_range(&self, ranges: Vec<Range<u64>>) -> Vec<Range<u64>> {
let mut current_ranges = ranges;
for item_map in self.maps {
let next_ranges = Vec::<Range<u64>>::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::<Vec<_>>();
println!{"{:?} -> {:?}", acc, result};
result
})
}
} }
// 50 98 2 // 50 98 2
@@ -89,14 +141,12 @@ fn parse_seeds(input: &str) -> IResult<&str, Vec<u64>> {
Ok((input, seeds)) Ok((input, seeds))
} }
fn parse_seeds_alt(input: &str) -> IResult<&str, Vec<u64>> { fn parse_seeds_alt(input: &str) -> IResult<&str, Vec<Range<u64>>> {
let (input, seed_ranges) = preceded( let (input, seed_ranges) = preceded(
tag("seeds: "), tag("seeds: "),
separated_list1(space1, separated_pair(complete::u64, space1, complete::u64)) separated_list1(space1, separated_pair(complete::u64, space1, complete::u64))
)(input)?; )(input)?;
let mut seeds = vec![]; Ok((input, seed_ranges.into_iter().map(|(start, length)| { start..start+length }).collect()))
seed_ranges.into_iter().for_each(|(start, length)| { (start..start+length).for_each(|x| {seeds.push(x);}) });
Ok((input, seeds))
} }
fn parse_all(input: &str) -> IResult<&str, (Vec<u64>, Vec<FullMap>)> { fn parse_all(input: &str) -> IResult<&str, (Vec<u64>, Vec<FullMap>)> {
@@ -105,7 +155,7 @@ fn parse_all(input: &str) -> IResult<&str, (Vec<u64>, Vec<FullMap>)> {
Ok((input, (seeds, full_maps))) Ok((input, (seeds, full_maps)))
} }
fn parse_all_alt(input: &str) -> IResult<&str, (Vec<u64>, Vec<FullMap>)> { fn parse_all_alt(input: &str) -> IResult<&str, (Vec<Range<u64>>, Vec<FullMap>)> {
let (input, seeds) = terminated(parse_seeds_alt, tuple((newline, newline)))(input)?; let (input, seeds) = terminated(parse_seeds_alt, tuple((newline, newline)))(input)?;
dbg!(seeds.len()); dbg!(seeds.len());
let (input, full_maps) = separated_list1(tuple((newline,newline)), parse_full_map)(input)?; 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 { pub fn part2(input: &str) -> String {
let (_, (seeds, full_maps)) = parse_all_alt(input).unwrap(); let (_, (seed_ranges, full_maps)) = parse_all_alt(input).unwrap();
seeds.into_iter().enumerate().map(|(i,seed)| { seed_ranges.iter().map(|seed_range| {
if i % 1_000_000 == 0 { println!( "{}", i as f64 / 2291774376.0 ); } full_maps.iter().fold(vec![seed_range.clone()], |value, x| {
full_maps.iter().fold(seed, |value, x| { x.convert_range(value)
x.convert(value)
}) })
}).min().unwrap().to_string() }).flatten().map(|x| {x.start}).min().unwrap().to_string()
} }
pub mod prelude { pub mod prelude {

View File

@@ -50,21 +50,15 @@ humidity-to-location map:
#[test] #[test]
fn test_part2() { fn test_part2() {
let test_input = "seeds: 79 14 55 13 let test_input = "seeds: 79 14
seed-to-soil map: seed-to-soil map:
50 98 2
52 50 48 52 50 48
soil-to-fertilizer map: soil-to-fertilizer map:
0 15 37
37 52 2
39 0 15 39 0 15
fertilizer-to-water map: fertilizer-to-water map:
49 53 8
0 11 42
42 0 7
57 7 4 57 7 4
water-to-light map: water-to-light map: