Skip to content

Commit

Permalink
aoc2023/day5: Update solution
Browse files Browse the repository at this point in the history
Signed-off-by: Andrej Orsula <orsula.andrej@gmail.com>
  • Loading branch information
AndrejOrsula committed Dec 25, 2023
1 parent 6a12812 commit f48e33f
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 40 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ My solutions to [Advent of Code](https://adventofcode.com) puzzles.
| 21 | [Step Counter](https://adventofcode.com/2023/day/21) | [day21.rs](aoc2023/src/day21.rs) |
| 22 | [Sand Slabs](https://adventofcode.com/2023/day/22) | [day22.rs](aoc2023/src/day22.rs) |
| 23 | [A Long Walk](https://adventofcode.com/2023/day/23) | [day23.rs](aoc2023/src/day23.rs) |
| 24 | [Never Tell Me The ...](https://adventofcode.com/2023/day/24) | [day24.rs](aoc2023/src/day24.rs) |
| 24 | [Never Tell Me The Odds](https://adventofcode.com/2023/day/24) | [day24.rs](aoc2023/src/day24.rs) |
| 25 | [Snowverload](https://adventofcode.com/2023/day/25) | [day25.rs](aoc2023/src/day25.rs) |

</td><td>
Expand All @@ -53,7 +53,7 @@ My solutions to [Advent of Code](https://adventofcode.com) puzzles.
| 112.7 µs | 1.056 µs |
| 5.884 µs | 508.0 µs |
| 92.21 µs | 27.78 µs |
| 46.67 µs | 5.350 µs |
| 21.77 µs | 5.197 µs |
| 16.90 µs | 0.248 µs |
| 170.1 µs | 76.89 µs |
| 181.6 µs | 323.7 µs |
Expand Down Expand Up @@ -83,7 +83,7 @@ My solutions to [Advent of Code](https://adventofcode.com) puzzles.
| 126.6 µs | 1.347 µs |
| 0.462 µs | 437.1 µs |
| 113.4 µs | 27.97 µs |
| 47.31 µs | 22.520 s |
| 17.87 µs | 108.7 µs |
| 0.666 µs | 0.659 µs |
| 177.0 µs | 66.30 µs |
| 153.8 µs | 1.069 ms |
Expand Down
112 changes: 75 additions & 37 deletions aoc2023/src/day5.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,46 +60,84 @@ fn part1(input: &utils::Almanac) -> u64 {

#[aoc(day5, part2)]
fn part2(input: &utils::Almanac) -> u64 {
use rayon::prelude::*;

let utils::Almanac { seeds, mappings } = input;
seeds
.par_chunks(2)
.map(|chunk| {
let (seed_range_start, seed_range_end) = (chunk[0], chunk[0] + chunk[1]);
seed_range_start..seed_range_end
})
.map(|seed_range| {
let mut cached_index =
smallvec::SmallVec::<[usize; 7]>::from_elem(usize::MAX, mappings.len());
let mut cached_diff = smallvec::SmallVec::<[i64; 7]>::from_elem(0, mappings.len());
seed_range
.map(|seed| {
mappings
.iter()
.enumerate()
.fold(seed, |value, (i, mapping)| {
if cached_index[i] != usize::MAX
&& mapping[cached_index[i]].from.contains(&value)
{
value.wrapping_add_signed(cached_diff[i])
} else {
mapping
.iter()
.enumerate()
.find(|(_, range_map)| range_map.from.contains(&value))
.map_or(value, |(j, range_map)| {
cached_index[i] = j;
cached_diff[i] = i64::try_from(range_map.to_start).unwrap()
- i64::try_from(range_map.from.start).unwrap();
value.wrapping_add_signed(cached_diff[i])
})
}
})
})
.min()
.unwrap()
.chunks(2)
.map(|nums| nums[0]..(nums[0] + nums[1]))
.flat_map(|seed_range| {
mappings.iter().fold(
smallvec::SmallVec::<[_; 32]>::from_elem(seed_range, 1),
|seed_ranges, mappings| {
let mut mapped_ranges = smallvec::SmallVec::new();
let leftover_ranges =
mappings.iter().fold(seed_ranges, |seed_ranges, mapping| {
seed_ranges
.into_iter()
.flat_map(|seed_range| {
if seed_range.start >= mapping.from.end
|| seed_range.end <= mapping.from.start
{
[seed_range, std::ops::Range::default()]
} else if seed_range.start <= mapping.from.start
&& seed_range.end >= mapping.from.end
{
let mapped = mapping.to_start
..mapping.to_start + mapping.from.end
- mapping.from.start;
if mapped.start < mapped.end {
mapped_ranges.push(mapped);
}

[
seed_range.start..mapping.from.start,
mapping.from.end..seed_range.end,
]
} else if seed_range.start >= mapping.from.start
&& seed_range.end <= mapping.from.end
{
let mapped = seed_range.start - mapping.from.start
+ mapping.to_start
..seed_range.end - mapping.from.start
+ mapping.to_start;
if mapped.start < mapped.end {
mapped_ranges.push(mapped);
}

[std::ops::Range::default(), std::ops::Range::default()]
} else {
let mapped = seed_range.start.max(mapping.from.start)
- mapping.from.start
+ mapping.to_start
..seed_range.end.min(mapping.from.end)
- mapping.from.start
+ mapping.to_start;
if mapped.start < mapped.end {
mapped_ranges.push(mapped);
}

let leftover_start =
if seed_range.start < mapping.from.start {
seed_range.start
} else {
mapping.from.end
};
let leftover_end = if seed_range.end > mapping.from.end {
seed_range.end
} else {
mapping.from.start
};
[leftover_start..leftover_end, std::ops::Range::default()]
}
})
.filter(|range| range.start < range.end)
.collect()
});
mapped_ranges.extend(leftover_ranges);
mapped_ranges
},
)
})
.map(|range| range.start)
.min()
.unwrap()
}
Expand Down

0 comments on commit f48e33f

Please sign in to comment.