aoc

My solutions for the Advent of Code
git clone https://git.tronto.net/aoc
Download | Log | Files | Refs | README

common.rs (2801B)


      1 #[derive(Debug)]
      2 pub struct Monkey {
      3     items: Vec<i64>,
      4     op: fn(i64, i64) -> i64,
      5     oparg: i64,
      6     div: i64,
      7     iftrue: usize,
      8     iffalse: usize,
      9     pub inspected: usize
     10 }
     11 
     12 fn read_monkey_from_stdin() -> Monkey {
     13     let mut line = String::new();
     14     let stdin = std::io::stdin();
     15 
     16     let _ = stdin.read_line(&mut line);
     17     line.clear();
     18 
     19     let _ = stdin.read_line(&mut line);
     20     let mut l = 16;
     21     let mut items = Vec::<i64>::new();
     22     while line.chars().nth(l).unwrap() != '\n' {
     23         l += 2;
     24         let end = line[l..].find(|c| c == ',' || c == '\n').unwrap() + l;
     25         items.push(line[l..end].parse::<i64>().unwrap());
     26         l = end;
     27     }
     28     line.clear();
     29 
     30     let _ = stdin.read_line(&mut line);
     31     let old = line.chars().nth(25).unwrap() == 'o';
     32     let oparg = if old { 0 } else {
     33         line[25..line.len()-1].parse::<i64>().unwrap()
     34     };
     35     let op = match line.chars().nth(23).unwrap() {
     36         '*' => if old { |x, _| x * x } else { |x, y| x * y },
     37         '+' => if old { |x, _| x + x } else { |x, y| x + y },
     38         c => panic!("Expected operator, got {}", c)
     39     };
     40     line.clear();
     41 
     42     let _ = stdin.read_line(&mut line);
     43     let div = line[21..line.len()-1].parse::<i64>().unwrap();
     44     line.clear();
     45 
     46     let _ = stdin.read_line(&mut line);
     47     let iftrue = line[29..line.len()-1].parse::<usize>().unwrap();
     48     line.clear();
     49 
     50     let _ = stdin.read_line(&mut line);
     51     let iffalse = line[30..line.len()-1].parse::<usize>().unwrap();
     52     line.clear();
     53 
     54     Monkey { items, op, oparg, div, iftrue, iffalse, inspected: 0 }
     55 }
     56 
     57 pub fn read_input() -> Vec<Monkey> {
     58     let mut v = Vec::<Monkey>::new();
     59     let mut line = String::new();
     60     loop {
     61         v.push(read_monkey_from_stdin());
     62         if std::io::stdin().read_line(&mut line).unwrap() == 0 { break; }
     63     }
     64     v
     65 }
     66 
     67 fn play_round(m: &mut Vec<Monkey>, div: i64, modulus: i64) {
     68     for i in 0..m.len() {
     69         for k in 0..m[i].items.len() {
     70             let mut x = (m[i].op)(m[i].items[k], m[i].oparg) / div;
     71             if div == 1 { x %= modulus; }
     72             let j = if x % m[i].div == 0 { m[i].iftrue } else { m[i].iffalse };
     73             m[j].items.push(x);
     74         }
     75         m[i].inspected += m[i].items.len();
     76         m[i].items.clear();
     77     }
     78 }
     79 
     80 fn get_modulus(monkeys: &Vec<Monkey>) -> i64 {
     81     let mut modulus = 1;
     82     for m in monkeys { modulus *= m.div; }
     83     modulus
     84 }
     85 
     86 pub fn res_after_n_rounds(m: &mut Vec<Monkey>, n: usize, div: i64) -> usize {
     87     let modulus = get_modulus(&m);
     88     for _ in 0..n { play_round(m, div, modulus); }
     89 
     90     let mut m1 = 0;
     91     let mut m2 = 0;
     92     for m in m {
     93         if m.inspected >= m1 {
     94             m2 = m1;
     95             m1 = m.inspected;
     96         } else if m.inspected >= m2 {
     97             m2 = m.inspected;
     98         }
     99     }
    100 
    101     m1 * m2
    102 }