day 05 part 2.
This commit is contained in:
parent
019a51ddd4
commit
d4f4b22973
|
@ -10,5 +10,5 @@ fn main() {
|
||||||
println!("Result: {}", part1::part1(&structured_input));
|
println!("Result: {}", part1::part1(&structured_input));
|
||||||
|
|
||||||
println!("Part Two");
|
println!("Part Two");
|
||||||
println!("Result: {}", part2::part2());
|
println!("Result: {}", part2::part2(&structured_input));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::ops::Range;
|
||||||
|
|
||||||
use nom::{
|
use nom::{
|
||||||
bytes::complete::tag,
|
bytes::complete::tag,
|
||||||
character::complete::{alpha1, multispace0},
|
character::complete::{alpha1, multispace0},
|
||||||
|
@ -6,15 +8,63 @@ use nom::{
|
||||||
IResult,
|
IResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub type SeedRange = Range<u64>;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct Map {
|
pub struct Map {
|
||||||
pub from: String,
|
pub from: String,
|
||||||
pub to: String,
|
pub to: String,
|
||||||
pub ranges: Vec<Range>,
|
pub ranges: Vec<MapRange>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Map {
|
impl Map {
|
||||||
pub fn map(&self, src: u64)->u64 {
|
pub fn map_ranges(&self, seeds: SeedRange) -> Vec<SeedRange> {
|
||||||
|
let mut unprocessed_seeds = vec![seeds];
|
||||||
|
let mut processed_seeds = Vec::new();
|
||||||
|
//using this instead of a for loop so that we can continue to push new stuff onto the
|
||||||
|
//unprocessed queue
|
||||||
|
while let Some(seed) = unprocessed_seeds.pop() {
|
||||||
|
//find map with intersection with seed
|
||||||
|
let map_to_apply = self
|
||||||
|
.ranges
|
||||||
|
.iter()
|
||||||
|
.find(|&map_range| !map_range.intersection_with_seed(&seed).is_empty());
|
||||||
|
|
||||||
|
let Some(map_to_apply) = map_to_apply else {
|
||||||
|
//if no mapping to do, consider seed processed
|
||||||
|
processed_seeds.push(seed);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let map_end = map_to_apply.src_start + map_to_apply.len;
|
||||||
|
let offset = map_to_apply.dest_start as i64 - map_to_apply.src_start as i64;
|
||||||
|
let intersection = map_to_apply.intersection_with_seed(&seed);
|
||||||
|
|
||||||
|
processed_seeds.push(Range {
|
||||||
|
start: (intersection.start as i64 + offset) as u64,
|
||||||
|
end: (intersection.end as i64 + offset) as u64,
|
||||||
|
});
|
||||||
|
|
||||||
|
//add the part before the map range back to the queue
|
||||||
|
if seed.start < map_to_apply.src_start {
|
||||||
|
unprocessed_seeds.push(Range {
|
||||||
|
start: seed.start,
|
||||||
|
end: intersection.start,
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
//add the part after the map range back to the queue
|
||||||
|
if seed.end > map_end {
|
||||||
|
unprocessed_seeds.push(Range {
|
||||||
|
start: intersection.end,
|
||||||
|
end: seed.end,
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
processed_seeds
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map(&self, src: u64) -> u64 {
|
||||||
for range in &self.ranges {
|
for range in &self.ranges {
|
||||||
if range.is_applicable(&src) {
|
if range.is_applicable(&src) {
|
||||||
return range.map(src);
|
return range.map(src);
|
||||||
|
@ -24,7 +74,7 @@ impl Map {
|
||||||
}
|
}
|
||||||
fn parse(input: &str) -> IResult<&str, Self> {
|
fn parse(input: &str) -> IResult<&str, Self> {
|
||||||
let (input, (from, to)) = delimited(multispace0, Self::parse_to_from, multispace0)(input)?;
|
let (input, (from, to)) = delimited(multispace0, Self::parse_to_from, multispace0)(input)?;
|
||||||
let (input, ranges) = many1(Range::parse)(input)?;
|
let (input, ranges) = many1(MapRange::parse)(input)?;
|
||||||
Ok((input, Map { from, to, ranges }))
|
Ok((input, Map { from, to, ranges }))
|
||||||
}
|
}
|
||||||
fn parse_to_from(input: &str) -> IResult<&str, (String, String)> {
|
fn parse_to_from(input: &str) -> IResult<&str, (String, String)> {
|
||||||
|
@ -35,13 +85,17 @@ impl Map {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub struct Range {
|
pub struct MapRange {
|
||||||
pub dest_start: u64,
|
pub dest_start: u64,
|
||||||
pub src_start: u64,
|
pub src_start: u64,
|
||||||
pub len: u64,
|
pub len: u64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Range {
|
impl MapRange {
|
||||||
|
fn intersection_with_seed(&self, seed: &SeedRange) -> SeedRange {
|
||||||
|
seed.start.max(self.src_start)..seed.end.min(self.src_start + self.len)
|
||||||
|
}
|
||||||
|
|
||||||
fn is_applicable(&self, src: &u64) -> bool {
|
fn is_applicable(&self, src: &u64) -> bool {
|
||||||
self.src_start <= *src && *src < (self.src_start + self.len)
|
self.src_start <= *src && *src < (self.src_start + self.len)
|
||||||
}
|
}
|
||||||
|
@ -60,7 +114,7 @@ impl Range {
|
||||||
let (input, numbers) = count(number, 3)(input)?;
|
let (input, numbers) = count(number, 3)(input)?;
|
||||||
Ok((
|
Ok((
|
||||||
input,
|
input,
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: numbers[0],
|
dest_start: numbers[0],
|
||||||
src_start: numbers[1],
|
src_start: numbers[1],
|
||||||
len: numbers[2],
|
len: numbers[2],
|
||||||
|
@ -86,18 +140,65 @@ pub fn parse(input: &str) -> (Vec<u64>, Vec<Map>) {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_map_range() {
|
||||||
|
let tested = Map {
|
||||||
|
from: "seed".to_string(),
|
||||||
|
to: "soil".to_string(),
|
||||||
|
ranges: vec![
|
||||||
|
MapRange {
|
||||||
|
dest_start: 50,
|
||||||
|
src_start: 98,
|
||||||
|
len: 2,
|
||||||
|
},
|
||||||
|
MapRange {
|
||||||
|
dest_start: 52,
|
||||||
|
src_start: 50,
|
||||||
|
len: 48,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
let input: SeedRange = 40..120;
|
||||||
|
assert_eq!(
|
||||||
|
tested.map_ranges(input),
|
||||||
|
vec![
|
||||||
|
50..52,
|
||||||
|
100..120,
|
||||||
|
52..100,
|
||||||
|
40..50
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_intersection_with_seed() {
|
||||||
|
let tested = MapRange {
|
||||||
|
dest_start: 52,
|
||||||
|
src_start: 50,
|
||||||
|
len: 48,
|
||||||
|
};
|
||||||
|
let input: SeedRange = 80..120;
|
||||||
|
assert_eq!(tested.intersection_with_seed(&input), 80..98);
|
||||||
|
let input: SeedRange = 40..60;
|
||||||
|
assert_eq!(tested.intersection_with_seed(&input), 50..60);
|
||||||
|
let input: SeedRange = 55..79;
|
||||||
|
assert_eq!(tested.intersection_with_seed(&input), 55..79);
|
||||||
|
let input: SeedRange = 40..120;
|
||||||
|
assert_eq!(tested.intersection_with_seed(&input), 50..98);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_map() {
|
fn test_map() {
|
||||||
let tested = Map {
|
let tested = Map {
|
||||||
from: "seed".to_string(),
|
from: "seed".to_string(),
|
||||||
to: "soil".to_string(),
|
to: "soil".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 50,
|
dest_start: 50,
|
||||||
src_start: 98,
|
src_start: 98,
|
||||||
len: 2,
|
len: 2,
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 52,
|
dest_start: 52,
|
||||||
src_start: 50,
|
src_start: 50,
|
||||||
len: 48,
|
len: 48,
|
||||||
|
@ -111,7 +212,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_is_appliccable() {
|
fn test_is_appliccable() {
|
||||||
let tested = Range {
|
let tested = MapRange {
|
||||||
dest_start: 50,
|
dest_start: 50,
|
||||||
src_start: 98,
|
src_start: 98,
|
||||||
len: 2,
|
len: 2,
|
||||||
|
@ -120,9 +221,10 @@ mod tests {
|
||||||
assert!(!tested.is_applicable(&100));
|
assert!(!tested.is_applicable(&100));
|
||||||
assert!(!tested.is_applicable(&97));
|
assert!(!tested.is_applicable(&97));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_range_map() {
|
fn test_range_map() {
|
||||||
let tested = Range {
|
let tested = MapRange {
|
||||||
dest_start: 52,
|
dest_start: 52,
|
||||||
src_start: 50,
|
src_start: 50,
|
||||||
len: 48,
|
len: 48,
|
||||||
|
@ -142,12 +244,12 @@ mod tests {
|
||||||
from: "seed".to_string(),
|
from: "seed".to_string(),
|
||||||
to: "soil".to_string(),
|
to: "soil".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 50,
|
dest_start: 50,
|
||||||
src_start: 98,
|
src_start: 98,
|
||||||
len: 2
|
len: 2
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 52,
|
dest_start: 52,
|
||||||
src_start: 50,
|
src_start: 50,
|
||||||
len: 48
|
len: 48
|
||||||
|
@ -161,10 +263,10 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_range_parse() {
|
fn test_range_parse() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Range::parse("50 98 2\n").unwrap(),
|
MapRange::parse("50 98 2\n").unwrap(),
|
||||||
(
|
(
|
||||||
"",
|
"",
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 50,
|
dest_start: 50,
|
||||||
src_start: 98,
|
src_start: 98,
|
||||||
len: 2,
|
len: 2,
|
||||||
|
@ -172,10 +274,10 @@ mod tests {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Range::parse("0 15 37\n").unwrap(),
|
MapRange::parse("0 15 37\n").unwrap(),
|
||||||
(
|
(
|
||||||
"",
|
"",
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 0,
|
dest_start: 0,
|
||||||
src_start: 15,
|
src_start: 15,
|
||||||
len: 37,
|
len: 37,
|
||||||
|
@ -221,12 +323,12 @@ mod tests {
|
||||||
from: "seed".to_string(),
|
from: "seed".to_string(),
|
||||||
to: "soil".to_string(),
|
to: "soil".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 50,
|
dest_start: 50,
|
||||||
src_start: 98,
|
src_start: 98,
|
||||||
len: 2
|
len: 2
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 52,
|
dest_start: 52,
|
||||||
src_start: 50,
|
src_start: 50,
|
||||||
len: 48
|
len: 48
|
||||||
|
@ -237,17 +339,17 @@ mod tests {
|
||||||
from: "soil".to_string(),
|
from: "soil".to_string(),
|
||||||
to: "fertilizer".to_string(),
|
to: "fertilizer".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 0,
|
dest_start: 0,
|
||||||
src_start: 15,
|
src_start: 15,
|
||||||
len: 37
|
len: 37
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 37,
|
dest_start: 37,
|
||||||
src_start: 52,
|
src_start: 52,
|
||||||
len: 2
|
len: 2
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 39,
|
dest_start: 39,
|
||||||
src_start: 0,
|
src_start: 0,
|
||||||
len: 15
|
len: 15
|
||||||
|
@ -306,12 +408,12 @@ mod tests {
|
||||||
from: "seed".to_string(),
|
from: "seed".to_string(),
|
||||||
to: "soil".to_string(),
|
to: "soil".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 50,
|
dest_start: 50,
|
||||||
src_start: 98,
|
src_start: 98,
|
||||||
len: 2
|
len: 2
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 52,
|
dest_start: 52,
|
||||||
src_start: 50,
|
src_start: 50,
|
||||||
len: 48
|
len: 48
|
||||||
|
@ -322,17 +424,17 @@ mod tests {
|
||||||
from: "soil".to_string(),
|
from: "soil".to_string(),
|
||||||
to: "fertilizer".to_string(),
|
to: "fertilizer".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 0,
|
dest_start: 0,
|
||||||
src_start: 15,
|
src_start: 15,
|
||||||
len: 37
|
len: 37
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 37,
|
dest_start: 37,
|
||||||
src_start: 52,
|
src_start: 52,
|
||||||
len: 2
|
len: 2
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 39,
|
dest_start: 39,
|
||||||
src_start: 0,
|
src_start: 0,
|
||||||
len: 15
|
len: 15
|
||||||
|
@ -343,22 +445,22 @@ mod tests {
|
||||||
from: "fertilizer".to_string(),
|
from: "fertilizer".to_string(),
|
||||||
to: "water".to_string(),
|
to: "water".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 49,
|
dest_start: 49,
|
||||||
src_start: 53,
|
src_start: 53,
|
||||||
len: 8
|
len: 8
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 0,
|
dest_start: 0,
|
||||||
src_start: 11,
|
src_start: 11,
|
||||||
len: 42
|
len: 42
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 42,
|
dest_start: 42,
|
||||||
src_start: 0,
|
src_start: 0,
|
||||||
len: 7
|
len: 7
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 57,
|
dest_start: 57,
|
||||||
src_start: 7,
|
src_start: 7,
|
||||||
len: 4
|
len: 4
|
||||||
|
@ -369,12 +471,12 @@ mod tests {
|
||||||
from: "water".to_string(),
|
from: "water".to_string(),
|
||||||
to: "light".to_string(),
|
to: "light".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 88,
|
dest_start: 88,
|
||||||
src_start: 18,
|
src_start: 18,
|
||||||
len: 7
|
len: 7
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 18,
|
dest_start: 18,
|
||||||
src_start: 25,
|
src_start: 25,
|
||||||
len: 70
|
len: 70
|
||||||
|
@ -385,17 +487,17 @@ mod tests {
|
||||||
from: "light".to_string(),
|
from: "light".to_string(),
|
||||||
to: "temperature".to_string(),
|
to: "temperature".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 45,
|
dest_start: 45,
|
||||||
src_start: 77,
|
src_start: 77,
|
||||||
len: 23
|
len: 23
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 81,
|
dest_start: 81,
|
||||||
src_start: 45,
|
src_start: 45,
|
||||||
len: 19
|
len: 19
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 68,
|
dest_start: 68,
|
||||||
src_start: 64,
|
src_start: 64,
|
||||||
len: 13
|
len: 13
|
||||||
|
@ -406,12 +508,12 @@ mod tests {
|
||||||
from: "temperature".to_string(),
|
from: "temperature".to_string(),
|
||||||
to: "humidity".to_string(),
|
to: "humidity".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 0,
|
dest_start: 0,
|
||||||
src_start: 69,
|
src_start: 69,
|
||||||
len: 1
|
len: 1
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 1,
|
dest_start: 1,
|
||||||
src_start: 0,
|
src_start: 0,
|
||||||
len: 69
|
len: 69
|
||||||
|
@ -422,12 +524,12 @@ mod tests {
|
||||||
from: "humidity".to_string(),
|
from: "humidity".to_string(),
|
||||||
to: "location".to_string(),
|
to: "location".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 60,
|
dest_start: 60,
|
||||||
src_start: 56,
|
src_start: 56,
|
||||||
len: 37
|
len: 37
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 56,
|
dest_start: 56,
|
||||||
src_start: 93,
|
src_start: 93,
|
||||||
len: 4
|
len: 4
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::parse::*;
|
||||||
|
|
||||||
pub fn part1(input: &(Vec<u64>, Vec<Map>)) -> usize {
|
pub fn part1(input: &(Vec<u64>, Vec<Map>)) -> usize {
|
||||||
let mut seeds = input.0.clone();
|
let mut seeds = input.0.clone();
|
||||||
for map in &input.1{
|
for map in &input.1 {
|
||||||
seeds = seeds.into_iter().map(|s| map.map(s)).collect()
|
seeds = seeds.into_iter().map(|s| map.map(s)).collect()
|
||||||
}
|
}
|
||||||
*seeds.iter().min().unwrap() as usize
|
*seeds.iter().min().unwrap() as usize
|
||||||
|
@ -15,142 +15,142 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part1() {
|
fn test_part1() {
|
||||||
let input = (
|
let input = (
|
||||||
vec![79, 14, 55, 13],
|
vec![79, 14, 55, 13],
|
||||||
vec![
|
vec![
|
||||||
Map {
|
Map {
|
||||||
from: "seed".to_string(),
|
from: "seed".to_string(),
|
||||||
to: "soil".to_string(),
|
to: "soil".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 50,
|
dest_start: 50,
|
||||||
src_start: 98,
|
src_start: 98,
|
||||||
len: 2
|
len: 2,
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 52,
|
dest_start: 52,
|
||||||
src_start: 50,
|
src_start: 50,
|
||||||
len: 48
|
len: 48,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
Map {
|
Map {
|
||||||
from: "soil".to_string(),
|
from: "soil".to_string(),
|
||||||
to: "fertilizer".to_string(),
|
to: "fertilizer".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 0,
|
dest_start: 0,
|
||||||
src_start: 15,
|
src_start: 15,
|
||||||
len: 37
|
len: 37,
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 37,
|
dest_start: 37,
|
||||||
src_start: 52,
|
src_start: 52,
|
||||||
len: 2
|
len: 2,
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 39,
|
dest_start: 39,
|
||||||
src_start: 0,
|
src_start: 0,
|
||||||
len: 15
|
len: 15,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
Map {
|
Map {
|
||||||
from: "fertilizer".to_string(),
|
from: "fertilizer".to_string(),
|
||||||
to: "water".to_string(),
|
to: "water".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 49,
|
dest_start: 49,
|
||||||
src_start: 53,
|
src_start: 53,
|
||||||
len: 8
|
len: 8,
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 0,
|
dest_start: 0,
|
||||||
src_start: 11,
|
src_start: 11,
|
||||||
len: 42
|
len: 42,
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 42,
|
dest_start: 42,
|
||||||
src_start: 0,
|
src_start: 0,
|
||||||
len: 7
|
len: 7,
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 57,
|
dest_start: 57,
|
||||||
src_start: 7,
|
src_start: 7,
|
||||||
len: 4
|
len: 4,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
Map {
|
Map {
|
||||||
from: "water".to_string(),
|
from: "water".to_string(),
|
||||||
to: "light".to_string(),
|
to: "light".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 88,
|
dest_start: 88,
|
||||||
src_start: 18,
|
src_start: 18,
|
||||||
len: 7
|
len: 7,
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 18,
|
dest_start: 18,
|
||||||
src_start: 25,
|
src_start: 25,
|
||||||
len: 70
|
len: 70,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
Map {
|
Map {
|
||||||
from: "light".to_string(),
|
from: "light".to_string(),
|
||||||
to: "temperature".to_string(),
|
to: "temperature".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 45,
|
dest_start: 45,
|
||||||
src_start: 77,
|
src_start: 77,
|
||||||
len: 23
|
len: 23,
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 81,
|
dest_start: 81,
|
||||||
src_start: 45,
|
src_start: 45,
|
||||||
len: 19
|
len: 19,
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 68,
|
dest_start: 68,
|
||||||
src_start: 64,
|
src_start: 64,
|
||||||
len: 13
|
len: 13,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
Map {
|
Map {
|
||||||
from: "temperature".to_string(),
|
from: "temperature".to_string(),
|
||||||
to: "humidity".to_string(),
|
to: "humidity".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 0,
|
dest_start: 0,
|
||||||
src_start: 69,
|
src_start: 69,
|
||||||
len: 1
|
len: 1,
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 1,
|
dest_start: 1,
|
||||||
src_start: 0,
|
src_start: 0,
|
||||||
len: 69
|
len: 69,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
Map {
|
Map {
|
||||||
from: "humidity".to_string(),
|
from: "humidity".to_string(),
|
||||||
to: "location".to_string(),
|
to: "location".to_string(),
|
||||||
ranges: vec![
|
ranges: vec![
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 60,
|
dest_start: 60,
|
||||||
src_start: 56,
|
src_start: 56,
|
||||||
len: 37
|
len: 37,
|
||||||
},
|
},
|
||||||
Range {
|
MapRange {
|
||||||
dest_start: 56,
|
dest_start: 56,
|
||||||
src_start: 93,
|
src_start: 93,
|
||||||
len: 4
|
len: 4,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
);
|
);
|
||||||
assert_eq!(part1(&input), 35);
|
assert_eq!(part1(&input), 35);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,168 @@
|
||||||
use crate::parse::*;
|
use crate::parse::*;
|
||||||
|
|
||||||
pub fn part2() -> usize {
|
pub fn part2(input: &(Vec<u64>, Vec<Map>)) -> usize {
|
||||||
unimplemented!()
|
let mut seeds = convert_seeds_to_ranges(&input.0);
|
||||||
|
for map in &input.1{
|
||||||
|
seeds = seeds.into_iter().flat_map(|s|{
|
||||||
|
map.map_ranges(s)
|
||||||
|
}).collect();
|
||||||
|
};
|
||||||
|
seeds.iter().map(|s| s.start).min().unwrap() as usize
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_seeds_to_ranges(seeds: &[u64]) -> Vec<SeedRange> {
|
||||||
|
seeds.chunks(2).map(|c| c[0]..(c[0] + c[1])).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_convert_seeds_to_ranges() {
|
||||||
|
let input = [79, 14, 55, 13];
|
||||||
|
assert_eq!(convert_seeds_to_ranges(&input), vec![79..93, 55..68])
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part2() {
|
fn test_part2() {
|
||||||
assert_eq!(0, 0);
|
let input = (
|
||||||
|
vec![79, 14, 55, 13],
|
||||||
|
vec![
|
||||||
|
Map {
|
||||||
|
from: "seed".to_string(),
|
||||||
|
to: "soil".to_string(),
|
||||||
|
ranges: vec![
|
||||||
|
MapRange {
|
||||||
|
dest_start: 50,
|
||||||
|
src_start: 98,
|
||||||
|
len: 2,
|
||||||
|
},
|
||||||
|
MapRange {
|
||||||
|
dest_start: 52,
|
||||||
|
src_start: 50,
|
||||||
|
len: 48,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Map {
|
||||||
|
from: "soil".to_string(),
|
||||||
|
to: "fertilizer".to_string(),
|
||||||
|
ranges: vec![
|
||||||
|
MapRange {
|
||||||
|
dest_start: 0,
|
||||||
|
src_start: 15,
|
||||||
|
len: 37,
|
||||||
|
},
|
||||||
|
MapRange {
|
||||||
|
dest_start: 37,
|
||||||
|
src_start: 52,
|
||||||
|
len: 2,
|
||||||
|
},
|
||||||
|
MapRange {
|
||||||
|
dest_start: 39,
|
||||||
|
src_start: 0,
|
||||||
|
len: 15,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Map {
|
||||||
|
from: "fertilizer".to_string(),
|
||||||
|
to: "water".to_string(),
|
||||||
|
ranges: vec![
|
||||||
|
MapRange {
|
||||||
|
dest_start: 49,
|
||||||
|
src_start: 53,
|
||||||
|
len: 8,
|
||||||
|
},
|
||||||
|
MapRange {
|
||||||
|
dest_start: 0,
|
||||||
|
src_start: 11,
|
||||||
|
len: 42,
|
||||||
|
},
|
||||||
|
MapRange {
|
||||||
|
dest_start: 42,
|
||||||
|
src_start: 0,
|
||||||
|
len: 7,
|
||||||
|
},
|
||||||
|
MapRange {
|
||||||
|
dest_start: 57,
|
||||||
|
src_start: 7,
|
||||||
|
len: 4,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Map {
|
||||||
|
from: "water".to_string(),
|
||||||
|
to: "light".to_string(),
|
||||||
|
ranges: vec![
|
||||||
|
MapRange {
|
||||||
|
dest_start: 88,
|
||||||
|
src_start: 18,
|
||||||
|
len: 7,
|
||||||
|
},
|
||||||
|
MapRange {
|
||||||
|
dest_start: 18,
|
||||||
|
src_start: 25,
|
||||||
|
len: 70,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Map {
|
||||||
|
from: "light".to_string(),
|
||||||
|
to: "temperature".to_string(),
|
||||||
|
ranges: vec![
|
||||||
|
MapRange {
|
||||||
|
dest_start: 45,
|
||||||
|
src_start: 77,
|
||||||
|
len: 23,
|
||||||
|
},
|
||||||
|
MapRange {
|
||||||
|
dest_start: 81,
|
||||||
|
src_start: 45,
|
||||||
|
len: 19,
|
||||||
|
},
|
||||||
|
MapRange {
|
||||||
|
dest_start: 68,
|
||||||
|
src_start: 64,
|
||||||
|
len: 13,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Map {
|
||||||
|
from: "temperature".to_string(),
|
||||||
|
to: "humidity".to_string(),
|
||||||
|
ranges: vec![
|
||||||
|
MapRange {
|
||||||
|
dest_start: 0,
|
||||||
|
src_start: 69,
|
||||||
|
len: 1,
|
||||||
|
},
|
||||||
|
MapRange {
|
||||||
|
dest_start: 1,
|
||||||
|
src_start: 0,
|
||||||
|
len: 69,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
Map {
|
||||||
|
from: "humidity".to_string(),
|
||||||
|
to: "location".to_string(),
|
||||||
|
ranges: vec![
|
||||||
|
MapRange {
|
||||||
|
dest_start: 60,
|
||||||
|
src_start: 56,
|
||||||
|
len: 37,
|
||||||
|
},
|
||||||
|
MapRange {
|
||||||
|
dest_start: 56,
|
||||||
|
src_start: 93,
|
||||||
|
len: 4,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
);
|
||||||
|
assert_eq!(part2(&input), 46);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue