Add day 11
This commit is contained in:
		@@ -49,4 +49,8 @@ path = "src/day9/main.rs"
 | 
				
			|||||||
name = "day10"
 | 
					name = "day10"
 | 
				
			||||||
path = "src/day10/main.rs"
 | 
					path = "src/day10/main.rs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[bin]]
 | 
				
			||||||
 | 
					name = "day11"
 | 
				
			||||||
 | 
					path = "src/day11/main.rs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[dependencies]
 | 
					[dependencies]
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										55
									
								
								day11.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								day11.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					Monkey 0:
 | 
				
			||||||
 | 
					  Starting items: 97, 81, 57, 57, 91, 61
 | 
				
			||||||
 | 
					  Operation: new = old * 7
 | 
				
			||||||
 | 
					  Test: divisible by 11
 | 
				
			||||||
 | 
					    If true: throw to monkey 5
 | 
				
			||||||
 | 
					    If false: throw to monkey 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Monkey 1:
 | 
				
			||||||
 | 
					  Starting items: 88, 62, 68, 90
 | 
				
			||||||
 | 
					  Operation: new = old * 17
 | 
				
			||||||
 | 
					  Test: divisible by 19
 | 
				
			||||||
 | 
					    If true: throw to monkey 4
 | 
				
			||||||
 | 
					    If false: throw to monkey 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Monkey 2:
 | 
				
			||||||
 | 
					  Starting items: 74, 87
 | 
				
			||||||
 | 
					  Operation: new = old + 2
 | 
				
			||||||
 | 
					  Test: divisible by 5
 | 
				
			||||||
 | 
					    If true: throw to monkey 7
 | 
				
			||||||
 | 
					    If false: throw to monkey 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Monkey 3:
 | 
				
			||||||
 | 
					  Starting items: 53, 81, 60, 87, 90, 99, 75
 | 
				
			||||||
 | 
					  Operation: new = old + 1
 | 
				
			||||||
 | 
					  Test: divisible by 2
 | 
				
			||||||
 | 
					    If true: throw to monkey 2
 | 
				
			||||||
 | 
					    If false: throw to monkey 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Monkey 4:
 | 
				
			||||||
 | 
					  Starting items: 57
 | 
				
			||||||
 | 
					  Operation: new = old + 6
 | 
				
			||||||
 | 
					  Test: divisible by 13
 | 
				
			||||||
 | 
					    If true: throw to monkey 7
 | 
				
			||||||
 | 
					    If false: throw to monkey 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Monkey 5:
 | 
				
			||||||
 | 
					  Starting items: 54, 84, 91, 55, 59, 72, 75, 70
 | 
				
			||||||
 | 
					  Operation: new = old * old
 | 
				
			||||||
 | 
					  Test: divisible by 7
 | 
				
			||||||
 | 
					    If true: throw to monkey 6
 | 
				
			||||||
 | 
					    If false: throw to monkey 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Monkey 6:
 | 
				
			||||||
 | 
					  Starting items: 95, 79, 79, 68, 78
 | 
				
			||||||
 | 
					  Operation: new = old + 3
 | 
				
			||||||
 | 
					  Test: divisible by 3
 | 
				
			||||||
 | 
					    If true: throw to monkey 1
 | 
				
			||||||
 | 
					    If false: throw to monkey 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Monkey 7:
 | 
				
			||||||
 | 
					  Starting items: 61, 97, 67
 | 
				
			||||||
 | 
					  Operation: new = old + 4
 | 
				
			||||||
 | 
					  Test: divisible by 17
 | 
				
			||||||
 | 
					    If true: throw to monkey 0
 | 
				
			||||||
 | 
					    If false: throw to monkey 5
 | 
				
			||||||
							
								
								
									
										27
									
								
								day11_test.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								day11_test.txt
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
				
			||||||
							
								
								
									
										127
									
								
								src/day11/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								src/day11/main.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,127 @@
 | 
				
			|||||||
 | 
					use std::collections::HashMap;
 | 
				
			||||||
 | 
					use std::str::FromStr;
 | 
				
			||||||
 | 
					use base::read_file;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Copy, Clone)]
 | 
				
			||||||
 | 
					enum Op {
 | 
				
			||||||
 | 
					    Add(u64),
 | 
				
			||||||
 | 
					    Multiply(u64),
 | 
				
			||||||
 | 
					    MultiplySelf,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl FromStr for Op {
 | 
				
			||||||
 | 
					    type Err = ();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn from_str(s: &str) -> Result<Self, Self::Err> {
 | 
				
			||||||
 | 
					        let mut iter = s.split_whitespace();
 | 
				
			||||||
 | 
					        let _ = iter.next();
 | 
				
			||||||
 | 
					        let op = iter.next().ok_or(())?.chars().next().ok_or(())?;
 | 
				
			||||||
 | 
					        let value = iter.next().ok_or(())?;
 | 
				
			||||||
 | 
					        if value == "old" && op == '*' {
 | 
				
			||||||
 | 
					            return Ok(Op::MultiplySelf);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        let value = value.parse::<u64>().ok().ok_or(())?;
 | 
				
			||||||
 | 
					        return match op {
 | 
				
			||||||
 | 
					            '+' => Ok(Op::Add(value)),
 | 
				
			||||||
 | 
					            '*' => Ok(Op::Multiply(value)),
 | 
				
			||||||
 | 
					            _ => Err(())
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clone)]
 | 
				
			||||||
 | 
					struct Monkey {
 | 
				
			||||||
 | 
					    id: usize,
 | 
				
			||||||
 | 
					    items: Vec<u64>,
 | 
				
			||||||
 | 
					    operation: Op,
 | 
				
			||||||
 | 
					    test_value: u64,
 | 
				
			||||||
 | 
					    next_success: usize,
 | 
				
			||||||
 | 
					    next_failure: usize,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn do_round<const F: u64>(monkeys: &mut Vec<Monkey>, monkey_counter: &mut HashMap<usize, u64>) {
 | 
				
			||||||
 | 
					    let lcm = monkeys.iter().map(|m| m.test_value).reduce(|acc, item| acc * item).unwrap();
 | 
				
			||||||
 | 
					    let mut items_to_add = HashMap::new();
 | 
				
			||||||
 | 
					    for monkey in monkeys.iter_mut() {
 | 
				
			||||||
 | 
					        if let Some(new_items) = items_to_add.remove(&monkey.id) {
 | 
				
			||||||
 | 
					            for new_item in new_items {
 | 
				
			||||||
 | 
					                monkey.items.push(new_item);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for item in &monkey.items {
 | 
				
			||||||
 | 
					            *monkey_counter.entry(monkey.id).or_insert_with(|| 0) += 1;
 | 
				
			||||||
 | 
					            let worry_level = match monkey.operation {
 | 
				
			||||||
 | 
					                Op::Add(x) => *item + x,
 | 
				
			||||||
 | 
					                Op::Multiply(x) => *item * x,
 | 
				
			||||||
 | 
					                Op::MultiplySelf => *item * *item
 | 
				
			||||||
 | 
					            } / F;
 | 
				
			||||||
 | 
					            let worry_level = worry_level % lcm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            let test_successful = worry_level % monkey.test_value == 0;
 | 
				
			||||||
 | 
					            items_to_add.entry(if test_successful {
 | 
				
			||||||
 | 
					                monkey.next_success
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                monkey.next_failure
 | 
				
			||||||
 | 
					            }).or_insert_with(|| Vec::new()).push(worry_level);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        monkey.items.clear();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    for monkey in monkeys.iter_mut() {
 | 
				
			||||||
 | 
					        if let Some(new_items) = items_to_add.remove(&monkey.id) {
 | 
				
			||||||
 | 
					            for new_item in new_items {
 | 
				
			||||||
 | 
					                monkey.items.push(new_item);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					    let input = read_file("day11.txt");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut monkeys = vec![];
 | 
				
			||||||
 | 
					    let monkeys_strings = input.chunks(7);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for monkeys_string in monkeys_strings {
 | 
				
			||||||
 | 
					        let id = monkeys_string[0].replace(":", "").split_whitespace().collect::<Vec<_>>()[1].parse::<usize>().unwrap();
 | 
				
			||||||
 | 
					        let items = monkeys_string[1].replace(",", "").split_whitespace().skip(2).filter_map(|s| s.parse::<u64>().ok()).collect::<Vec<_>>();
 | 
				
			||||||
 | 
					        let operation = monkeys_string[2].split(" = ").filter_map(|s| s.parse::<Op>().ok()).next().unwrap();
 | 
				
			||||||
 | 
					        let test_value = monkeys_string[3].split_whitespace().filter_map(|s| s.parse::<u64>().ok()).next().unwrap();
 | 
				
			||||||
 | 
					        let next_success = monkeys_string[4].split_whitespace().filter_map(|s| s.parse::<usize>().ok()).next().unwrap();
 | 
				
			||||||
 | 
					        let next_failure = monkeys_string[5].split_whitespace().filter_map(|s| s.parse::<usize>().ok()).next().unwrap();
 | 
				
			||||||
 | 
					        monkeys.push(Monkey {
 | 
				
			||||||
 | 
					            id,
 | 
				
			||||||
 | 
					            items,
 | 
				
			||||||
 | 
					            operation,
 | 
				
			||||||
 | 
					            test_value,
 | 
				
			||||||
 | 
					            next_success,
 | 
				
			||||||
 | 
					            next_failure,
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut monkey_counter = HashMap::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut monkey_copy = monkeys.clone();
 | 
				
			||||||
 | 
					    for _ in 0..20 {
 | 
				
			||||||
 | 
					        do_round::<3>(&mut monkey_copy, &mut monkey_counter);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut items = monkey_counter.values().collect::<Vec<_>>();
 | 
				
			||||||
 | 
					    items.sort();
 | 
				
			||||||
 | 
					    items.reverse();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    println!("1. Result: {}", items[0] * items[1]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    monkey_counter.clear();
 | 
				
			||||||
 | 
					    let mut monkey_copy = monkeys.clone();
 | 
				
			||||||
 | 
					    for _ in 0..10000 {
 | 
				
			||||||
 | 
					        do_round::<1>(&mut monkey_copy, &mut monkey_counter);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut items = monkey_counter.values().collect::<Vec<_>>();
 | 
				
			||||||
 | 
					    items.sort();
 | 
				
			||||||
 | 
					    items.reverse();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    println!("2. Result: {}", items[0] * items[1]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user