From 01fe0c7d69cfc15c44bf8da9e7bc12c4b4ced264 Mon Sep 17 00:00:00 2001 From: omagdy7 Date: Wed, 12 Apr 2023 04:58:02 +0200 Subject: Day11 done in rust --- .gitignore | 1 + 2022/Rust/Cargo.toml | 4 ++ 2022/Rust/input/day11.prod | 55 +++++++++++++++++ 2022/Rust/input/day11.test | 27 +++++++++ 2022/Rust/src/day10.rs | 13 ++-- 2022/Rust/src/day11.rs | 147 +++++++++++++++++++++++++++++++++++++++++++++ 2022/Rust/src/day6.rs | 4 +- 2022/Rust/src/day9.rs | 53 ++++++---------- 8 files changed, 259 insertions(+), 45 deletions(-) mode change 100644 => 100755 .gitignore create mode 100644 2022/Rust/input/day11.prod create mode 100644 2022/Rust/input/day11.test create mode 100644 2022/Rust/src/day11.rs diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 index b0cc9ee..7580566 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.o **/target +/2021 diff --git a/2022/Rust/Cargo.toml b/2022/Rust/Cargo.toml index 382ee7a..f1b5c75 100755 --- a/2022/Rust/Cargo.toml +++ b/2022/Rust/Cargo.toml @@ -48,3 +48,7 @@ path = "src/day9.rs" [[bin]] name = "day10" path = "src/day10.rs" + +[[bin]] +name = "day11" +path = "src/day11.rs" diff --git a/2022/Rust/input/day11.prod b/2022/Rust/input/day11.prod new file mode 100644 index 0000000..8d04886 --- /dev/null +++ b/2022/Rust/input/day11.prod @@ -0,0 +1,55 @@ +Monkey 0: +Starting items: 92, 73, 86, 83, 65, 51, 55, 93 +Operation: new = old * 5 +Test: divisible by 11 +If true: throw to monkey 3 +If false: throw to monkey 4 + +Monkey 1: +Starting items: 99, 67, 62, 61, 59, 98 +Operation: new = old * old +Test: divisible by 2 +If true: throw to monkey 6 +If false: throw to monkey 7 + +Monkey 2: +Starting items: 81, 89, 56, 61, 99 +Operation: new = old * 7 +Test: divisible by 5 +If true: throw to monkey 1 +If false: throw to monkey 5 + +Monkey 3: +Starting items: 97, 74, 68 +Operation: new = old + 1 +Test: divisible by 17 +If true: throw to monkey 2 +If false: throw to monkey 5 + +Monkey 4: +Starting items: 78, 73 +Operation: new = old + 3 +Test: divisible by 19 +If true: throw to monkey 2 +If false: throw to monkey 3 + +Monkey 5: +Starting items: 50 +Operation: new = old + 5 +Test: divisible by 7 +If true: throw to monkey 1 +If false: throw to monkey 6 + +Monkey 6: +Starting items: 95, 88, 53, 75 +Operation: new = old + 8 +Test: divisible by 3 +If true: throw to monkey 0 +If false: throw to monkey 7 + +Monkey 7: +Starting items: 50, 77, 98, 85, 94, 56, 89 +Operation: new = old + 2 +Test: divisible by 13 +If true: throw to monkey 4 +If false: throw to monkey 0 diff --git a/2022/Rust/input/day11.test b/2022/Rust/input/day11.test new file mode 100644 index 0000000..8a2b419 --- /dev/null +++ b/2022/Rust/input/day11.test @@ -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 diff --git a/2022/Rust/src/day10.rs b/2022/Rust/src/day10.rs index 992c503..92a27d4 100644 --- a/2022/Rust/src/day10.rs +++ b/2022/Rust/src/day10.rs @@ -27,13 +27,12 @@ impl Crt { } } - fn get_overlap_with_sprite(&self, sprite: &Sprite, cycle: i32) -> Option { + fn is_overlapping_with_sprite(&self, sprite: &Sprite, cycle: i32) -> Option { let x = cycle % 40; - if x == sprite.location || x == sprite.location - 1 || x == sprite.location + 1 { - Some(x) - } else { - None + if ((x - 1)..=(x + 1)).contains(&sprite.location) { + return Some(x); } + None } } @@ -129,7 +128,7 @@ fn solve_part_two(data: &str) { y_val += 1; } } - match crt.get_overlap_with_sprite(&sprite, cur_cycle) { + match crt.is_overlapping_with_sprite(&sprite, cur_cycle) { Some(idx) => crt.pixels[y_val as usize] .replace_range((idx as usize)..=idx as usize, "#"), None => {} @@ -144,7 +143,7 @@ fn solve_part_two(data: &str) { y_val += 1; } } - match crt.get_overlap_with_sprite(&sprite, cur_cycle) { + match crt.is_overlapping_with_sprite(&sprite, cur_cycle) { Some(idx) => { crt.pixels[y_val as usize].replace_range((idx as usize)..=idx as usize, "#") } diff --git a/2022/Rust/src/day11.rs b/2022/Rust/src/day11.rs new file mode 100644 index 0000000..d0c16de --- /dev/null +++ b/2022/Rust/src/day11.rs @@ -0,0 +1,147 @@ +use std::{collections::VecDeque, str::FromStr, string::ParseError}; + +#[derive(Debug, Clone, Copy)] +enum Op { + Add(i64), + Prod(i64), + Square, +} + +#[derive(Debug, Clone)] +struct Monkey { + starting_items: VecDeque, + inspected_items: i64, + operation: Op, + test: i64, + monkey_true: i64, + monkey_false: i64, +} + +fn parse_items(line: &str) -> String { + line.chars().skip_while(|&ch| ch != ':').skip(2).collect() +} + +fn get_last_token(line: &str) -> i64 { + line.split(" ") + .last() + .unwrap() + .parse::() + .expect("Should be parasble to i64") +} + +impl FromStr for Monkey { + type Err = ParseError; + fn from_str(s: &str) -> Result { + let lines: Vec<_> = s.lines().collect(); + let items: VecDeque = parse_items(lines[1]) + .split(", ") + .map(|x| x.parse::().expect("Should be parsable to i64")) + .collect(); + let line_2: Vec<_> = lines[2].split(" ").collect(); + let v: Vec<_> = line_2.iter().rev().take(2).collect(); + let op = { + match *v[0] { + "old" => Op::Square, + _ => match *v[1] { + "+" => Op::Add(v[0].parse::().unwrap()), + "*" => Op::Prod(v[0].parse::().unwrap()), + _ => unreachable!(), + }, + } + }; + let test = get_last_token(lines[3]); + let monkey_true = get_last_token(lines[4]); + let monkey_false = get_last_token(lines[5]); + Ok(Monkey { + starting_items: items, + inspected_items: 0, + operation: op, + test, + monkey_true, + monkey_false, + }) + } +} + +fn solve_part_one(data: &str) -> i64 { + let monkeys_input: Vec<_> = data.split("\n\n").collect(); + let mut monkeys: Vec<_> = monkeys_input + .iter() + .map(|monkey| Monkey::from_str(monkey).unwrap()) + .collect(); + + for _ in 0..20 { + for i in 0..monkeys.len() { + while !monkeys[i].starting_items.is_empty() { + use Op::*; + monkeys[i].inspected_items += 1; + let mut worry = monkeys[i].starting_items[0]; + match monkeys[i].operation { + Add(x) => worry += x, + Prod(x) => worry *= x, + Square => worry *= worry, + }; + worry /= 3; + let monkey_truth = monkeys[i].monkey_true as usize; + let monkey_false = monkeys[i].monkey_false as usize; + match worry % monkeys[i].test == 0 { + true => monkeys[monkey_truth].starting_items.push_back(worry), + false => monkeys[monkey_false].starting_items.push_back(worry), + } + monkeys[i].starting_items.pop_front(); + } + } + } + let mut inspected_items: Vec<_> = monkeys.iter().map(|x| x.inspected_items).collect(); + inspected_items.sort(); + inspected_items.reverse(); + inspected_items.iter().take(2).product() +} + +fn solve_part_two(data: &str) -> i64 { + let monkeys_input: Vec<_> = data.split("\n\n").collect(); + let mut monkeys: Vec<_> = monkeys_input + .iter() + .map(|monkey| Monkey::from_str(monkey).unwrap()) + .collect(); + + for _ in 0..10000 { + for i in 0..monkeys.len() { + let divisors_product: i64 = monkeys.iter().map(|x| x.test).product(); + while !monkeys[i].starting_items.is_empty() { + use Op::*; + monkeys[i].inspected_items += 1; + let mut worry = monkeys[i].starting_items[0]; + worry %= divisors_product; + match monkeys[i].operation { + Add(x) => worry = worry + x, + Prod(x) => worry = worry * x, + Square => worry = worry * worry, + }; + let monkey_truth = monkeys[i].monkey_true as usize; + let monkey_false = monkeys[i].monkey_false as usize; + match worry % monkeys[i].test == 0 { + true => monkeys[monkey_truth].starting_items.push_back(worry), + false => monkeys[monkey_false].starting_items.push_back(worry), + } + monkeys[i].starting_items.pop_front(); + } + } + } + let mut inspected_items: Vec<_> = monkeys + .iter() + .map(|x| x.inspected_items) + .collect::>(); + inspected_items.sort(); + inspected_items.reverse(); + inspected_items.iter().take(2).product() +} + +fn main() { + let test = include_str!("../input/day11.test"); + let prod = include_str!("../input/day11.prod"); + println!("part1: test {:?}", solve_part_one(test)); + println!("part1: prod {:?}", solve_part_one(prod)); + println!("part2: test {:?}", solve_part_two(test)); + println!("part2: prod {:?}", solve_part_two(prod)); +} diff --git a/2022/Rust/src/day6.rs b/2022/Rust/src/day6.rs index d4c669f..45ae9b4 100755 --- a/2022/Rust/src/day6.rs +++ b/2022/Rust/src/day6.rs @@ -42,8 +42,8 @@ fn solve_part_two(data: &str) -> usize { } fn main() { - let data_test = include_str!("../data/day6.test"); - let data_prod = include_str!("../data/day6.prod"); + let data_test = include_str!("../input/day6.test"); + let data_prod = include_str!("../input/day6.prod"); println!("{}", solve_part_one(data_test)); println!("{}", solve_part_one(data_prod)); diff --git a/2022/Rust/src/day9.rs b/2022/Rust/src/day9.rs index b32c910..fbc28d9 100644 --- a/2022/Rust/src/day9.rs +++ b/2022/Rust/src/day9.rs @@ -81,51 +81,32 @@ impl Simulation { } } + fn update_head_helper(&mut self, amount: &usize, tail_idx: usize, pos_increment: (i32, i32)) { + for _ in 1..=*amount { + self.head_pos.0 += pos_increment.0; + self.head_pos.1 += pos_increment.1; + for i in 0..9 { + if !self.is_tail_one_block_away(i) { + self.update_tail(&self.get_direction(i), i); + self.unique_pos.insert(self.tail_pos[tail_idx]); + } + } + } + } + fn update_head(&mut self, command: &Command, tail_idx: usize) { match command { Command::Up(amount) => { - for _ in 1..=*amount { - self.head_pos.1 += 1; - for i in 0..9 { - if !self.is_tail_one_block_away(i) { - self.update_tail(&self.get_direction(i), i); - self.unique_pos.insert(self.tail_pos[tail_idx]); - } - } - } + self.update_head_helper(amount, tail_idx, (0, 1)); } Command::Down(amount) => { - for _ in 1..=*amount { - self.head_pos.1 -= 1; - for i in 0..9 { - if !self.is_tail_one_block_away(i) { - self.update_tail(&self.get_direction(i), i); - self.unique_pos.insert(self.tail_pos[tail_idx]); - } - } - } + self.update_head_helper(amount, tail_idx, (0, -1)); } Command::Right(amount) => { - for _ in 1..=*amount { - self.head_pos.0 += 1; - for i in 0..9 { - if !self.is_tail_one_block_away(i) { - self.update_tail(&self.get_direction(i), i); - self.unique_pos.insert(self.tail_pos[tail_idx]); - } - } - } + self.update_head_helper(amount, tail_idx, (1, 0)); } Command::Left(amount) => { - for _ in 1..=*amount { - self.head_pos.0 -= 1; - for i in 0..9 { - if !self.is_tail_one_block_away(i) { - self.update_tail(&self.get_direction(i), i); - self.unique_pos.insert(self.tail_pos[tail_idx]); - } - } - } + self.update_head_helper(amount, tail_idx, (-1, 0)); } } } -- cgit v1.2.3