Advertisement
nairby

AOC 2023 Day 5

Dec 5th, 2023
1,176
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.81 KB | None | 0 0
  1. use std::env;
  2. use std::io::{self};
  3.  
  4. use rayon::prelude::*;
  5.  
  6. extern crate regex;
  7. use regex::Regex;
  8.  
  9. extern crate itertools;
  10. use itertools::Itertools;
  11.  
  12. struct Mapping {
  13.     dest_range_start: usize,
  14.     source_range_start: usize,
  15.     range_length: usize,
  16. }
  17. impl Mapping {
  18.     pub fn in_source_range(&self, number: usize) -> bool {
  19.         number >= self.source_range_start && number <= self.source_range_start + self.range_length - 1
  20.     }
  21. }
  22. impl From<&str> for Mapping {
  23.     fn from(s: &str) -> Self {
  24.         let re = Regex::new(r"(\d+) (\d+) (\d+)").unwrap();
  25.         let matches = re.captures(&s).unwrap();
  26.         Self {
  27.             dest_range_start:   matches[1].parse().unwrap(),
  28.             source_range_start: matches[2].parse().unwrap(),
  29.             range_length:       matches[3].parse().unwrap(),
  30.         }
  31.     }
  32. }
  33.  
  34. struct Day5Map {
  35.     mappings: Vec<Mapping>,
  36. }
  37. impl Day5Map {
  38.     fn load_mappings(lines: &str) -> Self {
  39.         let mappings = lines.split("\n").skip(1).map(Mapping::from).collect();
  40.         Self { mappings: mappings }
  41.     }
  42.     pub fn destination(&self, from: usize) -> usize {
  43.         for map in &self.mappings {
  44.             if map.in_source_range(from) {
  45.                 return map.dest_range_start + (from - map.source_range_start);
  46.             }
  47.         }
  48.         from
  49.     }
  50. }
  51.  
  52. fn read_seeds(s: &str) -> Vec<usize> {
  53.     let re = Regex::new(r"(\d+)").unwrap();
  54.     let matches: Vec<_> = re
  55.         .find_iter(s)
  56.         .map(|x| x.as_str().parse::<usize>().unwrap())
  57.         .collect();
  58.     matches
  59. }
  60.  
  61. fn solve(input: &str) -> io::Result<()> {
  62.  
  63.     // Input
  64.     let input_str = std::fs::read_to_string(input).unwrap();
  65.     let input_str = input_str.trim();
  66.     let input: Vec<_> = input_str.split("\n\n").collect();
  67.  
  68.     // Seeds & mappings
  69.     let seeds = read_seeds(input[0]);
  70.     let seed_to_soil_map            = Day5Map::load_mappings(input[1]);
  71.     let soil_to_fertilizer_map      = Day5Map::load_mappings(input[2]);
  72.     let fertilizer_to_water_map     = Day5Map::load_mappings(input[3]);
  73.     let water_to_light_map          = Day5Map::load_mappings(input[4]);
  74.     let light_to_temperature_map    = Day5Map::load_mappings(input[5]);
  75.     let temperature_to_humidity_map = Day5Map::load_mappings(input[6]);
  76.     let humidity_to_location_map    = Day5Map::load_mappings(input[7]);
  77.  
  78.     // Part 1
  79.     let part1 = seeds
  80.         .iter()
  81.         .map(|x| seed_to_soil_map           .destination(*x))
  82.         .map(|x| soil_to_fertilizer_map     .destination( x))
  83.         .map(|x| fertilizer_to_water_map    .destination( x))
  84.         .map(|x| water_to_light_map         .destination( x))
  85.         .map(|x| light_to_temperature_map   .destination( x))
  86.         .map(|x| temperature_to_humidity_map.destination( x))
  87.         .map(|x| humidity_to_location_map   .destination( x))
  88.         .min()
  89.         .unwrap();
  90.     println!("Part 1: {part1}"); // 579439039
  91.  
  92.     let mut part2 = usize::max_value();
  93.     for (start,range) in seeds.iter().tuples() {
  94.         let new = (*start..(*start + *range))
  95.             .into_par_iter()
  96.             .map(|x| seed_to_soil_map           .destination( x))
  97.             .map(|x| soil_to_fertilizer_map     .destination( x))
  98.             .map(|x| fertilizer_to_water_map    .destination( x))
  99.             .map(|x| water_to_light_map         .destination( x))
  100.             .map(|x| light_to_temperature_map   .destination( x))
  101.             .map(|x| temperature_to_humidity_map.destination( x))
  102.             .map(|x| humidity_to_location_map   .destination( x))
  103.             .min()
  104.             .unwrap();
  105.         part2 = std::cmp::min(part2,new);
  106.     }
  107.     println!("Part 2: {part2}"); // 7873084
  108.  
  109.     Ok(())
  110. }
  111.  
  112. fn main() {
  113.     let args: Vec<String> = env::args().collect();
  114.     let filename = &args[1];
  115.     solve(&filename).unwrap();
  116. }
  117.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement