diff --git a/inputs/input.txt b/inputs/input.txt index e7c314b..a458ed3 100644 --- a/inputs/input.txt +++ b/inputs/input.txt @@ -1,141 +1,56 @@ -noop -noop -noop -addx 4 -addx 3 -addx 3 -addx 3 -noop -addx 2 -addx 1 -addx -7 -addx 10 -addx 1 -addx 5 -addx -3 -addx -7 -addx 13 -addx 5 -addx 2 -addx 1 -addx -30 -addx -8 -noop -addx 3 -addx 2 -addx 7 -noop -addx -2 -addx 5 -addx 2 -addx -7 -addx 8 -addx 2 -addx 5 -addx 2 -addx -12 -noop -addx 17 -addx 3 -addx -2 -addx 2 -noop -addx 3 -addx -38 -noop -addx 3 -addx 4 -noop -addx 5 -noop -noop -noop -addx 1 -addx 2 -addx 5 -addx 2 -addx -3 -addx 4 -addx 2 -noop -noop -addx 7 -addx -30 -addx 31 -addx 4 -noop -addx -24 -addx -12 -addx 1 -addx 5 -addx 5 -noop -noop -noop -addx -12 -addx 13 -addx 4 -noop -addx 23 -addx -19 -addx 1 -addx 5 -addx 12 -addx -28 -addx 19 -noop -addx 3 -addx 2 -addx 5 -addx -40 -addx 4 -addx 32 -addx -31 -noop -addx 13 -addx -8 -addx 5 -addx 2 -addx 5 -noop -noop -noop -addx 2 -addx -7 -addx 8 -addx -7 -addx 14 -addx 3 -addx -2 -addx 2 -addx 5 -addx -40 -noop -noop -addx 3 -addx 4 -addx 1 -noop -addx 2 -addx 5 -addx 2 -addx 21 -noop -addx -16 -addx 3 -noop -addx 2 -noop -addx 1 -noop -noop -addx 4 -addx 5 -noop -noop -noop -noop -noop -noop -noop +Monkey 0: + Starting items: 83, 97, 95, 67 + Operation: new = old * 19 + Test: divisible by 17 + If true: throw to monkey 2 + If false: throw to monkey 7 + +Monkey 1: + Starting items: 71, 70, 79, 88, 56, 70 + Operation: new = old + 2 + Test: divisible by 19 + If true: throw to monkey 7 + If false: throw to monkey 0 + +Monkey 2: + Starting items: 98, 51, 51, 63, 80, 85, 84, 95 + Operation: new = old + 7 + Test: divisible by 7 + If true: throw to monkey 4 + If false: throw to monkey 3 + +Monkey 3: + Starting items: 77, 90, 82, 80, 79 + Operation: new = old + 1 + Test: divisible by 11 + If true: throw to monkey 6 + If false: throw to monkey 4 + +Monkey 4: + Starting items: 68 + Operation: new = old * 5 + Test: divisible by 13 + If true: throw to monkey 6 + If false: throw to monkey 5 + +Monkey 5: + Starting items: 60, 94 + Operation: new = old + 5 + Test: divisible by 3 + If true: throw to monkey 1 + If false: throw to monkey 0 + +Monkey 6: + Starting items: 81, 51, 85 + Operation: new = old * old + Test: divisible by 5 + If true: throw to monkey 5 + If false: throw to monkey 1 + +Monkey 7: + Starting items: 98, 81, 63, 65, 84, 71, 84 + Operation: new = old + 3 + Test: divisible by 2 + If true: throw to monkey 2 + If false: throw to monkey 3 diff --git a/inputs/sample.txt b/inputs/sample.txt index 37ee8ee..30e09e5 100644 --- a/inputs/sample.txt +++ b/inputs/sample.txt @@ -1,146 +1,27 @@ -addx 15 -addx -11 -addx 6 -addx -3 -addx 5 -addx -1 -addx -8 -addx 13 -addx 4 -noop -addx -1 -addx 5 -addx -1 -addx 5 -addx -1 -addx 5 -addx -1 -addx 5 -addx -1 -addx -35 -addx 1 -addx 24 -addx -19 -addx 1 -addx 16 -addx -11 -noop -noop -addx 21 -addx -15 -noop -noop -addx -3 -addx 9 -addx 1 -addx -3 -addx 8 -addx 1 -addx 5 -noop -noop -noop -noop -noop -addx -36 -noop -addx 1 -addx 7 -noop -noop -noop -addx 2 -addx 6 -noop -noop -noop -noop -noop -addx 1 -noop -noop -addx 7 -addx 1 -noop -addx -13 -addx 13 -addx 7 -noop -addx 1 -addx -33 -noop -noop -noop -addx 2 -noop -noop -noop -addx 8 -noop -addx -1 -addx 2 -addx 1 -noop -addx 17 -addx -9 -addx 1 -addx 1 -addx -3 -addx 11 -noop -noop -addx 1 -noop -addx 1 -noop -noop -addx -13 -addx -19 -addx 1 -addx 3 -addx 26 -addx -30 -addx 12 -addx -1 -addx 3 -addx 1 -noop -noop -noop -addx -9 -addx 18 -addx 1 -addx 2 -noop -noop -addx 9 -noop -noop -noop -addx -1 -addx 2 -addx -37 -addx 1 -addx 3 -noop -addx 15 -addx -21 -addx 22 -addx -6 -addx 1 -noop -addx 2 -addx 1 -noop -addx -10 -noop -noop -addx 20 -addx 1 -addx 2 -addx 2 -addx -6 -addx -11 -noop -noop -noop +Monkey 0: + Starting items: 79, 98 + Operation: new = old * 19 + Test: divisible by 23 + If true: throw to monkey 2 + If false: throw to monkey 3 + +Monkey 1: + Starting items: 54, 65, 75, 74 + Operation: new = old + 6 + Test: divisible by 19 + If true: throw to monkey 2 + If false: throw to monkey 0 + +Monkey 2: + Starting items: 79, 60, 97 + Operation: new = old * old + Test: divisible by 13 + If true: throw to monkey 1 + If false: throw to monkey 3 + +Monkey 3: + Starting items: 74 + Operation: new = old + 3 + Test: divisible by 17 + If true: throw to monkey 0 + If false: throw to monkey 1 diff --git a/src/main.rs b/src/main.rs index 57d69c6..cc2ac2b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,33 +1,87 @@ #![feature(test)] + +use std::{cmp::Reverse, rc::Rc}; extern crate test; -const INPUTS: [&[u8]; 2] = [ - include_bytes!("../inputs/sample.txt"), - include_bytes!("../inputs/input.txt"), +const INPUTS: [&str; 2] = [ + include_str!("../inputs/sample.txt"), + include_str!("../inputs/input.txt"), ]; -#[derive(Debug)] -enum Ins { - Noop, - Addx(i32), +#[derive(Clone)] +struct Monkey { + items: Vec, + operation: Rc usize>>, + div_by_test: usize, + if_true: usize, + if_false: usize, } -fn parse(input: &[u8]) -> Vec { +fn parse(input: &'static str) -> Vec { input - .split(|&c| c == b'\n') + .split("\n\n") .filter(|c| !c.is_empty()) - .map(|line| match &line[0..4] { - [b'n', b'o', b'o', b'p'] => Ins::Noop, - [b'a', b'd', b'd', b'x'] => { - let is_neg = line[5] == b'-'; - let b: i32 = line[5..] - .iter() - .filter(|&&c| (b'0'..=b'9').contains(&c)) - .fold(0, |a, &x| (a * 10) + (x - b'0') as i32); + .map(|set| { + let mut lines = set.lines().skip(1); - Ins::Addx(if is_neg { -b } else { b }) + let sitems: Vec = lines + .next() + .unwrap() + .split(',') + .map(|c| { + c.chars() + .filter(|c| c.is_numeric()) + .fold(0, |a, x| (a * 10) + (x as u8 - b'0') as usize) + }) + .collect(); + + let op = lines.next().unwrap(); + let nop = op + .bytes() + .filter(|c| (b'0'..=b'9').contains(c)) + .fold(0, |a, x| (a * 10) + (x - b'0') as usize); + + let op = move |old: usize| -> usize { + if op.contains("old * old") { + old * old + } else if op.contains("old +") { + old + nop + } else if op.contains("old *") { + old * nop + } else { + unreachable!() + } + }; + + let test = lines + .next() + .unwrap() + .bytes() + .filter(|c| (b'0'..=b'9').contains(c)) + .fold(0, |a, x| (a * 10) + (x - b'0') as usize); + + let true_result = lines + .next() + .unwrap() + .bytes() + .filter(|c| (b'0'..=b'9').contains(c)) + .fold(0, |a, x| (a * 10) + (x - b'0') as usize); + + let false_result = lines + .next() + .unwrap() + .bytes() + .filter(|c| (b'0'..=b'9').contains(c)) + .fold(0, |a, x| (a * 10) + (x - b'0') as usize); + + Monkey { + items: sitems, + operation: Rc::new(Box::new(op)), + div_by_test: test, + if_true: true_result, + if_false: false_result, } - _ => unreachable!(), + // }) .collect() } @@ -40,80 +94,36 @@ fn main() { } } -fn solution(input: Vec) -> String { - let mut register = 1i32; - let mut cycle = 0; - let mut line: u64 = 0; - let mut sprite: u64 = 0b111 << 61; +fn solution(mut input: Vec) -> usize { + let mlen = input.len(); + let mut activity = vec![0; mlen]; - let mut answer = Vec::with_capacity(10); + for _ in 0..20 { + for i in 0..mlen { + let monkey = &input[i].clone(); + let ilen = monkey.items.len(); - let mut i = 0; - for ip in input.into_iter() { - match ip { - Ins::Noop => { - if sprite & ((1 << 63) >> i) > 0 { - line |= (1 << 63) >> i; + for j in 0..ilen { + let item = monkey.items[j]; + + let newwlevel = (monkey.operation)(item); + let calmed_down_level = newwlevel / 3; + + if calmed_down_level % monkey.div_by_test == 0 { + input[monkey.if_true].items.push(calmed_down_level); + } else { + input[monkey.if_false].items.push(calmed_down_level); } - cycle += 1; - i += 1; - - if cycle % 40 == 0 { - answer.push(line); - line = 0; - i = 0; - } - } - Ins::Addx(v) => { - // Noop - if sprite & ((1 << 63) >> i) > 0 { - line |= (1 << 63) >> i; - } - - cycle += 1; - i += 1; - - if cycle % 40 == 0 { - answer.push(line); - line = 0; - i = 0; - } - - // Add - if sprite & ((1 << 63) >> i) > 0 { - line |= (1 << 63) >> i; - } - - register += v; - sprite = (0b111 << 61) >> (register - 1); - - cycle += 1; - i += 1; - - if cycle % 40 == 0 { - answer.push(line); - line = 0; - i = 0; - } + activity[i] += 1; } + input[i].items.clear(); } } - let mut output = String::with_capacity(40 * 10); + activity.select_nth_unstable_by_key(1, |c| Reverse(*c)); - for row in answer { - for i in 0..40 { - if row & ((1 << 63) >> i) > 0 { - output.push('\u{2588}'); - } else { - output.push(' '); - } - } - output.push('\n'); - } - - output + activity[0] * activity[1] } #[bench]