After bruteforcing, implemented reverse map.
This commit is contained in:
parent
0837ae6fa0
commit
5adbbfc276
@ -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)?)
|
||||
}
|
Loading…
Reference in New Issue
Block a user