Day 5 part 1

This commit is contained in:
tarneo 2023-12-10 12:06:09 +01:00
parent 87ebc6d971
commit c79740f313
Signed by: tarneo
GPG Key ID: BA924E53D0EB3FCC
1 changed files with 22 additions and 39 deletions

View File

@ -2,12 +2,10 @@
use color_eyre::eyre;
use color_eyre::eyre::eyre;
use color_eyre::eyre::OptionExt;
use std::collections::HashMap;
use std::ops::RangeInclusive;
fn main() {
let input = std::fs::read_to_string("input").unwrap();
let seeds: Vec<u32> = input
let seeds: Vec<u64> = input
.lines()
.next()
.unwrap()
@ -21,19 +19,13 @@ fn main() {
.skip(1)
.map(|v| v.lines().skip(1).collect::<Vec<_>>())
.map(|v| MultiMap::new_from_lines(v))
.collect();
println!("{:?}", multimaps);
let reduced_map = multimaps
.into_iter()
.reduce(|a, b| a?.merge_with_next(b?))
.unwrap()
.try_collect()
.unwrap();
println!("{:?}", reduced_map);
let seed_locations: Vec<_> = seeds
.iter()
.map(|s| (*s, reduced_map.convert(*s)))
.map(|s| multimaps.iter().fold(*s, |previous, m| m.convert(previous)))
.collect();
println!("{:?}", seed_locations)
println!("{:?}", seed_locations.iter().min().unwrap());
}
#[derive(Debug)]
@ -48,52 +40,43 @@ impl MultiMap {
})
}
pub fn convert(&self, input: u32) -> u32 {
pub fn convert(&self, input: u64) -> u64 {
self.maps
.iter()
.find_map(|m| m.try_convert(input))
.unwrap_or(input)
}
pub fn merge_with_next(self, next: Self) -> eyre::Result<Self> {
let my_allowed_inputs: Vec<u32> = (0..100).collect();
let hm: HashMap<u32, u32> = my_allowed_inputs
.iter()
.map(|i| (*i, self.convert(*i)))
.map(|(i, o)| (i, next.convert(o)))
.collect();
Ok(Self {
maps: vec![Map::HashMap(hm)],
})
}
}
#[derive(Debug)]
enum Map {
Ranges(RangeInclusive<u32>, RangeInclusive<u32>),
HashMap(HashMap<u32, u32>),
struct Map {
src_start: u64,
dest_start: u64,
len: u64,
}
impl Map {
pub fn new_from_line(line: &str) -> eyre::Result<Self> {
let mut line = line.split_whitespace();
let mut get_one =
|| -> eyre::Result<u32> { Ok(line.next().ok_or_eyre("Not enough words")?.parse()?) };
let (dest_range_start, src_range_start, range_len): (u32, u32, u32) =
(get_one()?, get_one()?, get_one()?);
|| -> eyre::Result<u64> { Ok(line.next().ok_or_eyre("Not enough words")?.parse()?) };
let (dest_start, src_start, len) = (get_one()?, get_one()?, get_one()?);
if !line.next().is_none() {
return Err(eyre!("Too many words"));
}
Ok(Self::Ranges(
src_range_start..=(src_range_start + range_len),
dest_range_start..=(dest_range_start + range_len),
))
Ok(Self {
src_start,
dest_start,
len,
})
}
pub fn try_convert(&self, input: u32) -> Option<u32> {
match self {
Self::Ranges(ir, or) => or.clone().nth(ir.clone().position(|v| v == input)?),
Self::HashMap(h) => Some(h[&input]),
pub fn try_convert(&self, input: u64) -> Option<u64> {
let input_index = input.checked_sub(self.src_start)?;
if input_index < self.len {
Some(self.dest_start + (input_index))
} else {
None
}
}
}