qzazwxsx

Untitled

Dec 5th, 2023
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.60 KB | Source Code | 0 0
  1. use crate::{Solution, SolutionPair};
  2. use regex::Regex;
  3. use std::cmp::min;
  4. ///////////////////////////////////////////////////////////////////////////////
  5.  
  6. #[derive(Clone)]
  7. struct AlmanacEntry {
  8.     destination: u64,
  9.     source: u64,
  10.     delta: u64
  11. }
  12.  
  13. fn extract_integers(inp: &str) -> Vec<u64> {
  14.     Regex::new(r"\d+")
  15.         .unwrap()
  16.         .find_iter(inp)
  17.         .map(|m| m.as_str().parse::<u64>().unwrap())
  18.         .collect()
  19. }
  20.  
  21. fn map_entry(entry: u64, mappings: Vec<AlmanacEntry>) -> u64 {
  22.     for map in mappings {
  23.         let source = map.source;
  24.         let delta = map.delta;
  25.         if !(source <= entry && entry < source + delta) {
  26.             continue;
  27.         }
  28.         let inp_diff = entry - source;
  29.         let dest = map.destination;
  30.         return dest + inp_diff;
  31.     }
  32.     return entry;
  33. }
  34.  
  35. fn get_min_next_src(entry: u64, mappings: Vec<AlmanacEntry>) -> u64 {
  36.     let mut min_next_src = u64::MAX;
  37.     for map in mappings {
  38.         let source = map.source;
  39.         if source <= entry {
  40.             continue;
  41.         }
  42.         min_next_src = min(min_next_src, source);
  43.     }
  44.     return min_next_src;
  45. }
  46.  
  47. fn map_entry_range(entry_min: u64, entry_max: u64, mappings: Vec<AlmanacEntry>) -> Vec<(u64, u64)> {
  48.     let mut all_mapped_entries: Vec<(u64, u64)> = Vec::new();
  49.     let mut curr_entry = entry_min;
  50.  
  51.     while curr_entry < entry_max {
  52.         let mapped = map_entry(curr_entry, mappings.clone());
  53.         let next_source = get_min_next_src(curr_entry, mappings.clone());
  54.         let delta = mapped - curr_entry;
  55.         all_mapped_entries.push((curr_entry + delta, min(next_source - 1, entry_max) + delta));
  56.         curr_entry = next_source;
  57.     }
  58.  
  59.     return all_mapped_entries
  60. }
  61.  
  62. pub fn solve(input: std::str::Lines<'_>) -> SolutionPair {
  63.  
  64.    let lines: Vec<&str> = input.clone().collect();
  65.  
  66.    let mut all_mappings: Vec<Vec<AlmanacEntry>> = Vec::with_capacity(7);
  67.  
  68.    for _ in 0..7 {
  69.        all_mappings.push(Vec::new());
  70.    }
  71.  
  72.    let seeds: Vec<u64> = extract_integers(lines[0]);
  73.  
  74.    let mut map_idx = 0;
  75.    for i in &lines[3..] {
  76.        if i == &"" {
  77.            map_idx += 1;
  78.            continue;
  79.        }
  80.        if i.contains("map") {
  81.            continue;
  82.        }
  83.        let nums = extract_integers(i);
  84.        let new_entry = AlmanacEntry {
  85.            destination: nums[0],
  86.            source: nums[1],
  87.            delta: nums[2]
  88.        };
  89.        all_mappings[map_idx].push(new_entry);
  90.    }
  91.  
  92.    
  93.    let mut min_all_entries: u64 = u64::MAX;
  94.    for seed in seeds.clone() {
  95.        let mut temp_seed = seed;
  96.        for i in 0..7 {
  97.            temp_seed = map_entry(temp_seed, all_mappings[i].clone());
  98.        }
  99.        if temp_seed < min_all_entries {
  100.            min_all_entries = temp_seed;
  101.        }
  102.    }
  103.    
  104.    let mut seed_ranges: Vec<(u64, u64)> = seeds
  105.        .clone()
  106.        .chunks(2)
  107.        .map(|chunk| {
  108.            let e1 = chunk[0];
  109.            let e2 = chunk[1];
  110.            (e1, e1 + e2)
  111.        })
  112.        .collect();
  113.  
  114.    for i in 0..7 {
  115.        let mappings = all_mappings[i].clone();
  116.        let mut new_seed_ranges: Vec<(u64, u64)> = Vec::new();
  117.        for range in seed_ranges {
  118.            let new_ranges = map_entry_range(range.0, range.1, mappings.clone());
  119.            new_seed_ranges.extend(new_ranges.clone());
  120.        }
  121.        seed_ranges = new_seed_ranges;
  122.    }
  123.  
  124.    let mut min_all_ranges = u64::MAX;
  125.    for i in seed_ranges {
  126.        min_all_ranges = min(min_all_ranges, i.0);
  127.    }
  128.  
  129.    (Solution::from(min_all_entries), Solution::from(min_all_ranges))
  130. }
  131.  
Advertisement
Add Comment
Please, Sign In to add comment