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 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)] #[derive(Debug)]
@ -36,6 +46,16 @@ impl Mapping {
} }
input 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)] #[derive(Debug)]
@ -64,23 +84,41 @@ impl Almanac {
} }
} }
fn find_closest(self: &Self) -> u32 { fn find_closest(self: &Self, forward: bool) -> Result<u32, AdventError> {
let total_mapping = vec![ let mut total_mapping = vec![
&self.seed_to_soil_map, &self.seed_to_soil_map,
&self.soil_to_fertilizer_map, &self.soil_to_fertilizer_map,
&self.fertilizer_to_water_map, &self.fertilizer_to_water_map,
&self.water_to_light_map, &self.water_to_light_map,
&self.light_to_temperature_map, &self.light_to_temperature_map,
&self.temperature_to_humidity_map, &self.temperature_to_humidity_map,
&self.humidity_to_location_map &self.humidity_to_location_map,
]; ];
self.seeds.clone().into_iter().map(|seed| {
if forward {
self.seeds.iter().map(|seed| {
total_mapping total_mapping
.iter() .iter()
.fold(seed, | input, map| { .fold(*seed, | input, map| {
map.map(input) map.map(input)
}) })
}).min().unwrap() }).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) -> () { fn interpret_range(self: &mut Self) -> () {
@ -91,7 +129,8 @@ impl Almanac {
vec.push(seed); 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> pub fn one() -> Result<u32, AdventError>
{ {
let almanac = read_into::<Almanac>(Path::new("resources/input5.txt".into()))?; 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> pub fn two() -> Result<u32, AdventError>
{ {
let mut almanac = read_into::<Almanac>(Path::new("resources/input5.txt".into()))?; let mut almanac = read_into::<Almanac>(Path::new("resources/input5.txt".into()))?;
almanac.interpret_range(); almanac.interpret_range();
Ok(almanac.find_closest()) Ok(almanac.find_closest(false)?)
} }