Broke part 5 but I'm committing anyway
This commit is contained in:
@@ -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<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)]
|
||||
struct ItemMap {
|
||||
before: u64,
|
||||
@@ -41,6 +51,23 @@ impl ItemMap {
|
||||
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)]
|
||||
@@ -60,6 +87,31 @@ impl FullMap {
|
||||
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
|
||||
@@ -89,14 +141,12 @@ fn parse_seeds(input: &str) -> IResult<&str, Vec<u64>> {
|
||||
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(
|
||||
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<u64>, Vec<FullMap>)> {
|
||||
@@ -105,7 +155,7 @@ fn parse_all(input: &str) -> IResult<&str, (Vec<u64>, Vec<FullMap>)> {
|
||||
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)?;
|
||||
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 {
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user