diff --git a/advent_of_code/2022/11/Cargo.lock b/advent_of_code/2022/11/Cargo.lock new file mode 100644 index 0000000..9a9e38b --- /dev/null +++ b/advent_of_code/2022/11/Cargo.lock @@ -0,0 +1,48 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "either" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "main" +version = "0.1.0" +dependencies = [ + "itertools", + "nom", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] diff --git a/advent_of_code/2022/11/Cargo.toml b/advent_of_code/2022/11/Cargo.toml new file mode 100644 index 0000000..ff37989 --- /dev/null +++ b/advent_of_code/2022/11/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "main" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +itertools = "0.10.5" +nom = "7.1.1" diff --git a/advent_of_code/2022/11/input.txt b/advent_of_code/2022/11/input.txt new file mode 100644 index 0000000..da2854d --- /dev/null +++ b/advent_of_code/2022/11/input.txt @@ -0,0 +1,55 @@ +Monkey 0: + Starting items: 64, 89, 65, 95 + Operation: new = old * 7 + Test: divisible by 3 + If true: throw to monkey 4 + If false: throw to monkey 1 + +Monkey 1: + Starting items: 76, 66, 74, 87, 70, 56, 51, 66 + Operation: new = old + 5 + Test: divisible by 13 + If true: throw to monkey 7 + If false: throw to monkey 3 + +Monkey 2: + Starting items: 91, 60, 63 + Operation: new = old * old + Test: divisible by 2 + If true: throw to monkey 6 + If false: throw to monkey 5 + +Monkey 3: + Starting items: 92, 61, 79, 97, 79 + Operation: new = old + 6 + Test: divisible by 11 + If true: throw to monkey 2 + If false: throw to monkey 6 + +Monkey 4: + Starting items: 93, 54 + Operation: new = old * 11 + Test: divisible by 5 + If true: throw to monkey 1 + If false: throw to monkey 7 + +Monkey 5: + Starting items: 60, 79, 92, 69, 88, 82, 70 + Operation: new = old + 8 + Test: divisible by 17 + If true: throw to monkey 4 + If false: throw to monkey 0 + +Monkey 6: + Starting items: 64, 57, 73, 89, 55, 53 + Operation: new = old + 1 + Test: divisible by 19 + If true: throw to monkey 0 + If false: throw to monkey 5 + +Monkey 7: + Starting items: 62 + Operation: new = old + 4 + Test: divisible by 7 + If true: throw to monkey 3 + If false: throw to monkey 2 \ No newline at end of file diff --git a/advent_of_code/2022/11/src/main.rs b/advent_of_code/2022/11/src/main.rs new file mode 100644 index 0000000..ff4db3f --- /dev/null +++ b/advent_of_code/2022/11/src/main.rs @@ -0,0 +1,193 @@ +use std::collections::VecDeque; + +use nom::{ + character::complete::{self, multispace1, one_of, multispace0}, + multi::{separated_list1, many1}, + bytes::complete::tag, + sequence::{delimited, preceded}, + branch::alt, + *, +}; + +#[derive(Debug)] +enum Value { + Old, + Val(u32), +} use Value::*; + +#[derive(Debug)] +enum Operation { + Mult(Value), + Add(Value), +} use Operation::*; + +#[derive(Debug)] +pub struct Test { + divisible_by: u32, + on_false: usize, + on_true: usize, +} + +#[derive(Debug)] +pub struct Monkey { + items: VecDeque, + operation: Operation, + test: Test, + number_of_inspections: u32, +} + +impl Monkey { + pub fn handle_items(&mut self) -> Vec<(u32, usize)> { + let mut result = Vec::new(); + + while !self.items.is_empty() { + self.number_of_inspections += 1; + + let mut item = self.items.pop_front().unwrap(); + item = match self.operation { + Mult(Old) => {item * item}, + Mult(Val(num)) => {item * num}, + Add(Old) => {item * 2}, + Add(Val(num)) => {item + num}, + }; + + item /= 3; + + let throw_to_monkey = match item % self.test.divisible_by == 0 { + true => self.test.on_true, + false => self.test.on_false, + }; + + result.push((item, throw_to_monkey)); + } + + result + } +} + +fn parse_operation(input: &str) -> IResult<&str, Operation> { + let (input, op) = preceded( + tag("Operation: new = old "), + one_of("+*"), + )(input)?; + + let (input, num) : (&str, Value) = preceded( + multispace1, + alt(( + complete::u32.map(|num| Value::Val(num)), + tag("old").map(|_| Value::Old), + )), + )(input)?; + + let func = match op { + '*' => Operation::Mult(num), + '+' => Operation::Add(num), + _ => unreachable!(), + }; + + Ok((input, func)) +} + +fn parse_test(input: &str) -> IResult<&str, Test> { + let (input, divisible_by) = preceded( + tag("Test: divisible by "), + complete::u32, + )(input)?; + + let (input, _) = multispace1(input)?; + + let (input, on_true) = preceded( + tag("If true: throw to monkey "), + complete::u32, + )(input)?; + + let (input, _) = multispace1(input)?; + + let (input, on_false) = preceded( + tag("If false: throw to monkey "), + complete::u32, + )(input)?; + + // Generate Test + + let t = Test { + divisible_by, + on_false: on_false as usize, + on_true: on_true as usize, + }; + + Ok((input, t)) +} + +fn parse_input(input: &str) -> IResult<&str, Monkey> { + // Parse: Monkey _id: + let (input, _id) = delimited( + tag("Monkey "), + complete::u32, + tag(":"), + )(input)?; + + let (input, _) = multispace1(input)?; + + // Parse: Starting items: num1, num2 + let (input, levels) = preceded( + tag("Starting items: "), + separated_list1(tag(", "), complete::u32), + )(input)?; + + let (input, _) = multispace1(input)?; + + //Parse: Operation: new = old {+ num|old}, {* num|old} + let (input, operation) = parse_operation(input)?; + + let (input, _) = multispace1(input)?; + + //Parse: Test: divisible by num + // If true: throw to monkey # + // If false: throw to monkey # + let (input, test) = parse_test(input)?; + + let (input, _) = multispace0(input)?; + + // Generate a monkey here + + let items = VecDeque::from_iter(levels); + + let m = Monkey { + items, + operation, + test, + number_of_inspections: 0, + }; + + Ok((input, m)) +} + +fn part1() { + let input_text = include_str!("../input.txt"); + let (_, mut monkeys) = many1(parse_input)(input_text).unwrap(); + + for _i in 0..20 { + for monkey_index in 0..monkeys.len() { + let monkey = monkeys.get_mut(monkey_index).unwrap(); + let new_item_list = monkey.handle_items(); + + for (item, thrown_to_monkey) in new_item_list { + monkeys[thrown_to_monkey].items.push_back(item); + } + } + } + + let mut results = monkeys + .iter() + .map(|m| m.number_of_inspections) + .collect::>(); + results.sort_by(|a, b| b.cmp(a)); + + println!("{}", results[0] * results[1]); + +} + +fn main() { + part1(); +} diff --git a/advent_of_code/2022/11/test.txt b/advent_of_code/2022/11/test.txt new file mode 100644 index 0000000..c04eddb --- /dev/null +++ b/advent_of_code/2022/11/test.txt @@ -0,0 +1,27 @@ +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 \ No newline at end of file