Created
December 5, 2023 16:20
-
-
Save typester/6c7f52c9d8c49ed57515308ad365768a to your computer and use it in GitHub Desktop.
2023 Advent of Code Day 5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use lazy_static::lazy_static; | |
use regex::Regex; | |
const INPUT: &str = "..snip.."; | |
lazy_static! { | |
static ref RE_NUM: Regex = Regex::new(r"(\d+)").unwrap(); | |
} | |
#[derive(Debug)] | |
struct Info { | |
seeds: Vec<u64>, | |
seed_to_soil: Vec<Map>, | |
soil_to_fertilizer: Vec<Map>, | |
fertilizer_to_water: Vec<Map>, | |
water_to_light: Vec<Map>, | |
light_to_temperature: Vec<Map>, | |
temperature_to_humidity: Vec<Map>, | |
humidity_to_location: Vec<Map>, | |
} | |
impl Info { | |
fn part2_seeds(&self) -> Vec<(u64, u64)> { | |
let mut r: Vec<(u64, u64)> = vec![]; | |
let mut iter = self.seeds.iter(); | |
while let Some(n1) = iter.next() { | |
match iter.next() { | |
Some(n2) => r.push((*n1, *n2)), | |
None => break, | |
} | |
} | |
r | |
} | |
} | |
#[derive(Debug)] | |
struct Map { | |
dest: u64, | |
source: u64, | |
len: u64, | |
} | |
impl Map { | |
fn match_dest(&self, source: u64) -> Option<u64> { | |
if self.source <= source && source < self.source + self.len { | |
Some(self.dest + (source - self.source)) | |
} else { | |
None | |
} | |
} | |
} | |
fn main() { | |
let info = parse_input(INPUT); | |
let min_location = info.seeds.iter() | |
.map(|seed| find_location(*seed, &info)) | |
.min(); | |
println!("part1: {}", min_location.unwrap()); | |
let min_location = info.part2_seeds().iter() | |
.flat_map(|seed| { | |
let mut loc: Vec<u64> = vec![]; | |
println!("process: {:?}", seed); | |
for s in seed.0..(seed.0+seed.1) { | |
loc.push(find_location(s, &info)); | |
} | |
loc | |
}) | |
.min(); | |
println!("part2: {}", min_location.unwrap()); | |
} | |
fn parse_input(input: &str) -> Info { | |
let mut iter = input.lines(); | |
let seeds: Vec<u64> = RE_NUM.captures_iter(iter.next().unwrap()) | |
.map(|c| c.get(1).map(|m| m.as_str()).unwrap_or("0").parse::<u64>().unwrap()) | |
.collect(); | |
iter.next(); | |
let mut seed_to_soil: Vec<Map> = vec![]; | |
while let Some(line) = iter.next() { | |
if line == "" { break } | |
if let Some(map) = parse_map(line) { | |
seed_to_soil.push(map); | |
} | |
} | |
let mut soil_to_fertilizer: Vec<Map> = vec![]; | |
while let Some(line) = iter.next() { | |
if line == "" { break } | |
if let Some(map) = parse_map(line) { | |
soil_to_fertilizer.push(map); | |
} | |
} | |
let mut fertilizer_to_water: Vec<Map> = vec![]; | |
while let Some(line) = iter.next() { | |
if line == "" { break } | |
if let Some(map) = parse_map(line) { | |
fertilizer_to_water.push(map); | |
} | |
} | |
let mut water_to_light: Vec<Map> = vec![]; | |
while let Some(line) = iter.next() { | |
if line == "" { break } | |
if let Some(map) = parse_map(line) { | |
water_to_light.push(map); | |
} | |
} | |
let mut light_to_temperature: Vec<Map> = vec![]; | |
while let Some(line) = iter.next() { | |
if line == "" { break } | |
if let Some(map) = parse_map(line) { | |
light_to_temperature.push(map); | |
} | |
} | |
let mut temperature_to_humidity: Vec<Map> = vec![]; | |
while let Some(line) = iter.next() { | |
if line == "" { break } | |
if let Some(map) = parse_map(line) { | |
temperature_to_humidity.push(map); | |
} | |
} | |
let mut humidity_to_location: Vec<Map> = vec![]; | |
while let Some(line) = iter.next() { | |
if line == "" { break } | |
if let Some(map) = parse_map(line) { | |
humidity_to_location.push(map); | |
} | |
} | |
Info { | |
seeds, | |
seed_to_soil, | |
soil_to_fertilizer, | |
fertilizer_to_water, | |
water_to_light, | |
light_to_temperature, | |
temperature_to_humidity, | |
humidity_to_location, | |
} | |
} | |
fn parse_map(input: &str) -> Option<Map> { | |
let nums: Vec<u64> = RE_NUM.captures_iter(input) | |
.map(|c| c.get(1).unwrap().as_str().parse::<u64>().unwrap()) | |
.collect(); | |
if nums.len() == 3 { | |
let dest = nums[0]; | |
let source = nums[1]; | |
let len = nums[2]; | |
Some(Map { | |
dest, | |
source, | |
len, | |
}) | |
} else { | |
None | |
} | |
} | |
fn find_location(seed: u64, info: &Info) -> u64 { | |
let soil = info.seed_to_soil.iter().filter_map(|m| m.match_dest(seed)).next().unwrap_or(seed); | |
let fertilizer = info.soil_to_fertilizer.iter().filter_map(|m| m.match_dest(soil)).next().unwrap_or(soil); | |
let water = info.fertilizer_to_water.iter().filter_map(|m| m.match_dest(fertilizer)).next().unwrap_or(fertilizer); | |
let light = info.water_to_light.iter().filter_map(|m| m.match_dest(water)).next().unwrap_or(water); | |
let temperature = info.light_to_temperature.iter().filter_map(|m| m.match_dest(light)).next().unwrap_or(light); | |
let humidity = info.temperature_to_humidity.iter().filter_map(|m| m.match_dest(temperature)).next().unwrap_or(temperature); | |
let location = info.humidity_to_location.iter().filter_map(|m| m.match_dest(humidity)).next().unwrap_or(humidity); | |
location | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment