AoC 2023 day 5
The snippet can be accessed without any authentication.
Authored by
s91149
main.rs 3.24 KiB
use std::ops::Range;
fn main() {
let input = std::fs::read_to_string("../inputs/input.txt").unwrap();
let mut seeds: Vec<u64> = Vec::new();
let mut all_ranges: Vec<Vec<Ranges>> = Vec::new();
for block in input.split("\n\n") {
if block.contains(": ") {
seeds = block
.split(':')
.skip(1)
.map(|s| {
s.split_whitespace()
.map(|n| n.parse::<u64>().unwrap())
.collect::<Vec<u64>>()
})
.next()
.unwrap();
} else {
let numbers: String = block.split(":\n").skip(1).collect();
let ranges_in_block: Vec<Ranges> = numbers
.lines()
.map(|number_line| {
let n: Vec<u64> = number_line
.split_whitespace()
.map(|n| n.parse().unwrap())
.collect();
if let &[dest_range_start, source_range_start, len] = &n[..] {
Ranges::new(dest_range_start, source_range_start, len)
} else {
unreachable!();
}
})
.collect();
all_ranges.push(ranges_in_block);
}
}
part_1(&seeds, &all_ranges);
part_2(&seeds, &all_ranges);
}
fn part_1(seeds: &[u64], all_ranges: &[Vec<Ranges>]) {
let location_numbers = seeds.iter().map(|seed| {
let mut current_value = *seed;
for block_of_ranges in all_ranges.iter() {
if let Some(valid_range) = block_of_ranges
.iter()
.find(|ranges| ranges.source.contains(¤t_value))
{
let pos = current_value - valid_range.source.start;
current_value = valid_range.destination.start + pos;
}
}
current_value
});
println!("part 1: {}", location_numbers.min().unwrap());
}
fn part_2(seeds: &[u64], all_ranges: &[Vec<Ranges>]) {
let seed_ranges: Vec<Range<u64>> = seeds
.chunks(2)
.map(|c| {
if let &[start, len] = c {
start..(start + len)
} else {
unreachable!()
}
})
.collect();
for seed in 0..2402036949 {
let mut current_value = seed;
for block_of_ranges in all_ranges.iter().rev() {
if let Some(valid_range) = block_of_ranges
.iter()
.find(|ranges| ranges.destination.contains(¤t_value))
{
let pos = current_value - valid_range.destination.start;
current_value = valid_range.source.start + pos;
}
}
if seed_ranges.iter().any(|r| r.contains(¤t_value)) {
println!("part 2: {}", seed);
return;
};
}
}
#[derive(Debug)]
struct Ranges {
source: Range<u64>,
destination: Range<u64>,
}
impl Ranges {
fn new(dest_range_start: u64, source_range_start: u64, len: u64) -> Self {
Self {
destination: dest_range_start..(dest_range_start + len),
source: source_range_start..(source_range_start + len),
}
}
}
Please register or sign in to comment