Advertisement
nairby

2022 Day 11

Dec 11th, 2022
1,595
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 4.42 KB | None | 0 0
  1. use std::env;
  2. use std::io::{self};
  3.  
  4. extern crate regex;
  5. use regex::Regex;
  6.  
  7. #[derive(Debug)]
  8. enum Operation {
  9.     Add(i64),
  10.     Multiply(i64),
  11.     Square,
  12. }
  13. #[derive(Debug)]
  14. struct Monkey {
  15.     pub items: Vec<i64>,
  16.     pub operation: Operation,
  17.     pub test_value: i64,
  18.     pub target_true: i64,
  19.     pub target_false: i64,
  20.     pub inspections: i64,
  21. }
  22. impl From<&str> for Monkey {
  23.     fn from(s: &str) -> Self {
  24.         let lines: Vec<_> = s.split("\n").collect();
  25.  
  26.         // Regexes
  27.         let re_starting  = Regex::new(r"Starting items: ([0-9 ,]+)").unwrap();
  28.         let re_operation = Regex::new(r"Operation: new = old (\+|\*) (old|[\d]+)").unwrap();
  29.         let re_test      = Regex::new(r"Test: divisible by ([\d]+)").unwrap();
  30.         let re_true      = Regex::new(r"If true: throw to monkey ([\d]+)").unwrap();
  31.         let re_false     = Regex::new(r"If false: throw to monkey ([\d]+)").unwrap();
  32.  
  33.         // Captures
  34.         let starting_captures = re_starting.captures(&lines[1]).unwrap();
  35.         let operate_captures = re_operation.captures(&lines[2]).unwrap();
  36.         let test_captures = re_test.captures(&lines[3]).unwrap();
  37.         let true_captures = re_true.captures(&lines[4]).unwrap();
  38.         let false_captures = re_false.captures(&lines[5]).unwrap();
  39.  
  40.         // Data extractions
  41.         let starting_items: Vec<i64> = starting_captures[1].split(",").map(|x| x.trim().parse().unwrap()).collect();
  42.         let operation = if &operate_captures[2] == "old" {
  43.             Operation::Square
  44.         } else {
  45.             match &operate_captures[1] {
  46.                 "+" => Operation::Add     (operate_captures[2].parse().unwrap()),
  47.                 "*" => Operation::Multiply(operate_captures[2].parse().unwrap()),
  48.                 other => panic!("Error: Unknown operation {other}"),
  49.             }
  50.         };
  51.  
  52.         let test_value: i64 = test_captures[1].parse().unwrap();
  53.         let target_true  = true_captures[1].parse().unwrap();
  54.         let target_false = false_captures[1].parse().unwrap();
  55.  
  56.         // Construct object
  57.         Self {
  58.             items: starting_items,
  59.             operation: operation,
  60.             test_value: test_value,
  61.             target_true: target_true,
  62.             target_false: target_false,
  63.             inspections: 0,
  64.         }
  65.     }
  66. }
  67.  
  68. fn solve(input: &str, part2: bool) -> io::Result<()> {
  69.     let input_str = std::fs::read_to_string(input).unwrap();
  70.     let input_str = input_str.trim();
  71.     let input: Vec<_> = input_str.split("\n\n").collect();
  72.  
  73.     // Initialize
  74.     let mut monkeys: Vec<_> = input.iter().map(|x| Monkey::from(*x)).collect();
  75.     let num_monkeys = &monkeys.len();
  76.     let lcm = &monkeys.iter().map(|x| x.test_value).product::<i64>();
  77.  
  78.     // Turns
  79.     let lcm = &monkeys.iter().map(|x| x.test_value).product::<i64>();
  80.     let rounds = if part2 { 10_000 } else { 20 };
  81.     for round in 0..rounds {
  82.         for m_id in 0..*num_monkeys {
  83.             for item_id in 0..monkeys[m_id].items.len() {
  84.                 monkeys[m_id].inspections += 1;
  85.                 match monkeys[m_id].operation {
  86.                     Operation::Add(v) => monkeys[m_id].items[item_id] += v,
  87.                     Operation::Multiply(v) => monkeys[m_id].items[item_id] *= v,
  88.                     Operation::Square => monkeys[m_id].items[item_id] *= monkeys[m_id].items[item_id],
  89.                 }
  90.                 if !part2 { monkeys[m_id].items[item_id] /= 3; }
  91.                 let target_monkey = if monkeys[m_id].items[item_id] % monkeys[m_id].test_value == 0 {
  92.                     monkeys[m_id].target_true
  93.                 } else {
  94.                     monkeys[m_id].target_false
  95.                 };
  96.                 if part2 { monkeys[m_id].items[item_id] %= lcm; }
  97.                 let item_transferred = monkeys[m_id].items[item_id];
  98.                 monkeys[target_monkey as usize].items.push(item_transferred);
  99.             }
  100.             monkeys[m_id].items.clear();
  101.         }
  102.     }
  103.  
  104.     // Monkey Business
  105.     monkeys.sort_by(|a, b| b.inspections.cmp(&a.inspections));
  106.     let top_two: i64 = monkeys.iter().take(2).map(|x| x.inspections).product();
  107.     let part = if part2 { 2 } else { 1 };
  108.     println!("Part {part}: {top_two}");
  109.     // Part 1: 120384
  110.     // Part 2: 32059801242
  111.  
  112.     Ok(())
  113. }
  114.  
  115. fn main() {
  116.     let args: Vec<String> = env::args().collect();
  117.     let filename = &args[1];
  118.     solve(&filename,false).unwrap();
  119.     solve(&filename,true).unwrap();
  120. }
  121.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement