My attempts to solve puzzles of Advent of Code
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(2022) - day11

+290 -2
+55
data/day11.txt
··· 1 + Monkey 0: 2 + Starting items: 89, 73, 66, 57, 64, 80 3 + Operation: new = old * 3 4 + Test: divisible by 13 5 + If true: throw to monkey 6 6 + If false: throw to monkey 2 7 + 8 + Monkey 1: 9 + Starting items: 83, 78, 81, 55, 81, 59, 69 10 + Operation: new = old + 1 11 + Test: divisible by 3 12 + If true: throw to monkey 7 13 + If false: throw to monkey 4 14 + 15 + Monkey 2: 16 + Starting items: 76, 91, 58, 85 17 + Operation: new = old * 13 18 + Test: divisible by 7 19 + If true: throw to monkey 1 20 + If false: throw to monkey 4 21 + 22 + Monkey 3: 23 + Starting items: 71, 72, 74, 76, 68 24 + Operation: new = old * old 25 + Test: divisible by 2 26 + If true: throw to monkey 6 27 + If false: throw to monkey 0 28 + 29 + Monkey 4: 30 + Starting items: 98, 85, 84 31 + Operation: new = old + 7 32 + Test: divisible by 19 33 + If true: throw to monkey 5 34 + If false: throw to monkey 7 35 + 36 + Monkey 5: 37 + Starting items: 78 38 + Operation: new = old + 8 39 + Test: divisible by 5 40 + If true: throw to monkey 3 41 + If false: throw to monkey 0 42 + 43 + Monkey 6: 44 + Starting items: 86, 70, 60, 88, 88, 78, 74, 83 45 + Operation: new = old + 4 46 + Test: divisible by 11 47 + If true: throw to monkey 1 48 + If false: throw to monkey 2 49 + 50 + Monkey 7: 51 + Starting items: 81, 58 52 + Operation: new = old + 5 53 + Test: divisible by 17 54 + If true: throw to monkey 3 55 + If false: throw to monkey 5
+2 -2
src/main.rs
··· 1 - use crate::solutions::year_2022::{Day2, Day3, Day4, Day5, Day6, Day7, Day8, Day9, Day10}; 1 + use crate::solutions::year_2022::{Day2, Day3, Day4, Day5, Day6, Day7, Day8, Day9, Day10, Day11}; 2 2 use aoc_lib::Solver; 3 3 pub mod solutions; 4 4 5 5 fn main() { 6 - let sol = Day10::solve_part2(); 6 + let sol = Day11::solve_part2(); 7 7 println!("{:?}", sol); 8 8 }
+231
src/solutions/year_2022/day11.rs
··· 1 + use aoc_lib::{Input, Solver}; 2 + use nom::{ 3 + branch::alt, 4 + bytes::complete::tag, 5 + character::complete::{digit1, multispace1, space1, u128, u8}, 6 + combinator::{map, map_opt}, 7 + multi::separated_list1, 8 + sequence::{pair, preceded, separated_pair}, 9 + IResult, 10 + }; 11 + 12 + #[derive(Debug, Default, Clone)] 13 + pub struct Day11 { 14 + monkey_holdings: Vec<Monkey>, 15 + } 16 + 17 + impl Day11 { 18 + fn monkey_business(&self) -> Option<u128> { 19 + let mut xs = self 20 + .monkey_holdings 21 + .iter() 22 + .map(|m| m.inspected_items) 23 + .collect::<Vec<_>>(); 24 + xs.sort_by(|a, b| b.cmp(a)); 25 + if xs.len() > 2 { 26 + Some(xs[0] as u128 * xs[1] as u128) 27 + } else { 28 + None 29 + } 30 + } 31 + } 32 + 33 + impl Solver for Day11 { 34 + fn day() -> u8 { 35 + 11 36 + } 37 + type OutputPart1 = u128; 38 + type OutputPart2 = u128; 39 + 40 + fn solution_part1(input: aoc_lib::Input) -> Option<Self::OutputPart1> { 41 + let mut d = Day11::load_notes(input); 42 + for _ in 1..=20 { 43 + d.play_round(false, 1); 44 + } 45 + 46 + d.monkey_business() 47 + } 48 + 49 + fn solution_part2(input: aoc_lib::Input) -> Option<Self::OutputPart2> { 50 + let mut d = Day11::load_notes(input); 51 + let common_divisor = d 52 + .monkey_holdings 53 + .iter() 54 + .map(|x| x.test.divisible_by as u32) 55 + .product::<u32>(); 56 + for _ in 1..=10000 { 57 + d.play_round(true, common_divisor); 58 + } 59 + 60 + d.monkey_business() 61 + } 62 + } 63 + 64 + fn monkey_id_parser<'a>() -> impl FnMut(&'a str) -> IResult<&'a str, usize> { 65 + preceded(pair(tag("Monkey"), space1), map(u8, |x| x as usize)) 66 + } 67 + 68 + fn items_parser<'a>() -> impl FnMut(&'a str) -> IResult<&'a str, Vec<Item>> { 69 + preceded( 70 + pair(multispace1, pair(tag("Starting items:"), space1)), 71 + separated_list1(tag(", "), map(u128, |x| Item { worry_level: x })), 72 + ) 73 + } 74 + 75 + fn operation_parser<'a>() -> impl FnMut(&'a str) -> IResult<&'a str, Operation> { 76 + preceded( 77 + pair(space1, tag("Operation: new = old ")), 78 + map_opt( 79 + separated_pair(alt((tag("*"), tag("+"))), space1, alt((tag("old"), digit1))), 80 + |(c, v)| match c { 81 + "*" => { 82 + if v == "old" { 83 + Some(Operation::Pow(2)) 84 + } else { 85 + Some(Operation::Multiply(v.parse().unwrap_or(1))) 86 + } 87 + } 88 + "+" => { 89 + if v == "old" { 90 + Some(Operation::Multiply(2)) 91 + } else { 92 + Some(Operation::Plus(v.parse().unwrap_or(0))) 93 + } 94 + } 95 + _ => None, 96 + }, 97 + ), 98 + ) 99 + } 100 + 101 + fn test_div_parser<'a>() -> impl FnMut(&'a str) -> IResult<&'a str, u8> { 102 + preceded(pair(space1, tag("Test: divisible by ")), u8) 103 + } 104 + 105 + fn test_true_parser<'a>() -> impl FnMut(&'a str) -> IResult<&'a str, usize> { 106 + preceded( 107 + pair(space1, tag("If true: throw to monkey ")), 108 + map(u8, |x| x as usize), 109 + ) 110 + } 111 + 112 + fn test_false_parser<'a>() -> impl FnMut(&'a str) -> IResult<&'a str, usize> { 113 + preceded( 114 + pair(space1, tag("If false: throw to monkey ")), 115 + map(u8, |x| x as usize), 116 + ) 117 + } 118 + 119 + fn monkey_parser(is: [String; 6]) -> Monkey { 120 + Monkey { 121 + id: monkey_id_parser()(&is[0]) 122 + .expect("could not parse monkey id") 123 + .1, 124 + operation: operation_parser()(&is[2]) 125 + .expect("could not parse operation") 126 + .1, 127 + test: Test { 128 + divisible_by: test_div_parser()(&is[3]) 129 + .expect("could not parse divisible by") 130 + .1, 131 + if_true: test_true_parser()(&is[4]) 132 + .expect("could not parse if true") 133 + .1, 134 + if_false: test_false_parser()(&is[5]) 135 + .expect("could not parse if false") 136 + .1, 137 + }, 138 + inspected_items: 0, 139 + current_holdings: items_parser()(&is[1]) 140 + .expect("could not parse starting items") 141 + .1, 142 + } 143 + } 144 + 145 + impl Day11 { 146 + fn load_notes(input: Input) -> Self { 147 + let monkey_holdings = input 148 + .lines 149 + .split(|x| x.is_empty()) 150 + .map(|ys| { 151 + let mut slice: [String; 6] = Default::default(); 152 + ys.iter().enumerate().for_each(|(i, s)| { 153 + slice[i] = s.clone(); 154 + }); 155 + slice 156 + }) 157 + .map(monkey_parser) 158 + .collect::<Vec<_>>(); 159 + Day11 { monkey_holdings } 160 + } 161 + 162 + fn play_round(&mut self, more_worried: bool, common_div: u32) -> &mut Self { 163 + self.monkey_holdings = self.monkey_holdings.iter().enumerate().fold( 164 + self.monkey_holdings.clone(), 165 + |mut acc, (index, _)| { 166 + let mut monkey = acc[index].clone(); 167 + 168 + monkey.current_holdings.clone().into_iter().for_each(|x| { 169 + monkey.inspected_items += 1; 170 + 171 + let mut wl = match monkey.operation { 172 + Operation::Plus(v) => x.worry_level.checked_add(v as u128).unwrap_or(0), 173 + Operation::Multiply(v) => x.worry_level.checked_mul(v as u128).unwrap_or(1), 174 + Operation::Pow(v) => x.worry_level.checked_pow(v as u32).unwrap_or(1), 175 + }; 176 + if !more_worried { 177 + wl /= 3; 178 + } else { 179 + wl = wl.checked_rem(common_div as u128).unwrap_or(wl); 180 + } 181 + if wl 182 + .checked_rem(monkey.test.divisible_by as u128) 183 + .expect("div by 0") 184 + == 0 185 + { 186 + acc[monkey.test.if_true] 187 + .current_holdings 188 + .push(Item { worry_level: wl }); 189 + } else { 190 + acc[monkey.test.if_false] 191 + .current_holdings 192 + .push(Item { worry_level: wl }); 193 + } 194 + }); 195 + 196 + monkey.current_holdings = vec![]; 197 + acc[index] = monkey; 198 + acc 199 + }, 200 + ); 201 + self 202 + } 203 + } 204 + 205 + #[derive(Debug, Clone)] 206 + struct Monkey { 207 + id: usize, 208 + operation: Operation, 209 + test: Test, 210 + inspected_items: u64, 211 + current_holdings: Vec<Item>, 212 + } 213 + 214 + #[derive(Debug, Clone, Copy)] 215 + enum Operation { 216 + Plus(u8), 217 + Multiply(u8), 218 + Pow(u8), 219 + } 220 + 221 + #[derive(Debug, Clone, Copy)] 222 + struct Test { 223 + divisible_by: u8, 224 + if_true: usize, 225 + if_false: usize, 226 + } 227 + 228 + #[derive(Debug, Clone, Copy)] 229 + struct Item { 230 + worry_level: u128, 231 + }
+2
src/solutions/year_2022/mod.rs
··· 8 8 mod day8; 9 9 mod day9; 10 10 mod day10; 11 + mod day11; 11 12 pub(crate) use day1::*; 12 13 pub(crate) use day2::*; 13 14 pub(crate) use day3::*; ··· 18 19 pub(crate) use day8::*; 19 20 pub(crate) use day9::*; 20 21 pub(crate) use day10::*; 22 + pub(crate) use day11::*;