After bruteforcing, implemented reverse map.

This commit is contained in:
Dennis Brentjes 2023-12-06 14:12:12 +01:00
parent 0837ae6fa0
commit 5adbbfc276

View File

@ -19,6 +19,16 @@ impl RangeMap {
None
}
}
fn inverse_map(&self, input: u32) -> Option<u32> {
let upper_bound: u64 = self.dest as u64 + self.length as u64;
if input >= self.dest && (input as u64) < upper_bound {
Some(input - self.dest + self.start)
}
else {
None
}
}
}
#[derive(Debug)]
@ -36,6 +46,16 @@ impl Mapping {
}
input
}
fn inverse_map(self: &Self, input: u32) -> u32 {
for range_map in self.range_maps.iter() {
match range_map.inverse_map(input) {
Some(x) => return x,
None => continue
}
}
input
}
}
#[derive(Debug)]
@ -64,23 +84,41 @@ impl Almanac {
}
}
fn find_closest(self: &Self) -> u32 {
let total_mapping = vec![
fn find_closest(self: &Self, forward: bool) -> Result<u32, AdventError> {
let mut total_mapping = vec![
&self.seed_to_soil_map,
&self.soil_to_fertilizer_map,
&self.fertilizer_to_water_map,
&self.water_to_light_map,
&self.light_to_temperature_map,
&self.temperature_to_humidity_map,
&self.humidity_to_location_map
&self.humidity_to_location_map,
];
self.seeds.clone().into_iter().map(|seed| {
total_mapping
.iter()
.fold(seed, | input, map| {
map.map(input)
})
}).min().unwrap()
if forward {
self.seeds.iter().map(|seed| {
total_mapping
.iter()
.fold(*seed, | input, map| {
map.map(input)
})
}).min().ok_or(AdventError("mapping procedure went wrong".into()))
} else {
total_mapping.reverse();
for loc in 0..u32::MAX {
let seed = total_mapping
.iter()
.fold(loc, | input, map| {
map.inverse_map(input)
});
match self.seeds.binary_search(&seed) {
Ok(_) => return Ok(loc),
Err(_) => continue
}
};
Err(AdventError("Scanned location space, found nothing".into()))
}
}
fn interpret_range(self: &mut Self) -> () {
@ -91,7 +129,8 @@ impl Almanac {
vec.push(seed);
}
}
self.seeds = vec;
vec.sort();
self.seeds = vec
}
}
@ -178,12 +217,12 @@ impl FromStr for Almanac {
pub fn one() -> Result<u32, AdventError>
{
let almanac = read_into::<Almanac>(Path::new("resources/input5.txt".into()))?;
Ok(almanac.find_closest())
Ok(almanac.find_closest(true)?)
}
pub fn two() -> Result<u32, AdventError>
{
let mut almanac = read_into::<Almanac>(Path::new("resources/input5.txt".into()))?;
almanac.interpret_range();
Ok(almanac.find_closest())
Ok(almanac.find_closest(false)?)
}