summaryrefslogtreecommitdiff
path: root/2022/Rust
diff options
context:
space:
mode:
Diffstat (limited to '2022/Rust')
-rwxr-xr-x2022/Rust/Cargo.toml4
-rw-r--r--2022/Rust/input/day11.prod55
-rw-r--r--2022/Rust/input/day11.test27
-rw-r--r--2022/Rust/src/day10.rs13
-rw-r--r--2022/Rust/src/day11.rs147
-rwxr-xr-x2022/Rust/src/day6.rs4
-rw-r--r--2022/Rust/src/day9.rs53
7 files changed, 258 insertions, 45 deletions
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<i32> {
+ fn is_overlapping_with_sprite(&self, sprite: &Sprite, cycle: i32) -> Option<i32> {
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<i64>,
+ 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::<i64>()
+ .expect("Should be parasble to i64")
+}
+
+impl FromStr for Monkey {
+ type Err = ParseError;
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ let lines: Vec<_> = s.lines().collect();
+ let items: VecDeque<i64> = parse_items(lines[1])
+ .split(", ")
+ .map(|x| x.parse::<i64>().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::<i64>().unwrap()),
+ "*" => Op::Prod(v[0].parse::<i64>().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::<Vec<_>>();
+ 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));
}
}
}