solves day11 part1
This commit is contained in:
parent
dcdc93a6c6
commit
da8635c06b
1 changed files with 200 additions and 14 deletions
|
@ -4,19 +4,17 @@ use aoc_runner_derive::{aoc as aoc_run, aoc_generator};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
struct Monkey {
|
struct Monkey {
|
||||||
items: VecDeque<Item>,
|
items: VecDeque<u128>,
|
||||||
op: Operation,
|
op: Operation,
|
||||||
tmod: u32,
|
tmod: u128,
|
||||||
target: (usize, usize),
|
target: (usize, usize),
|
||||||
|
business: u128,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
|
|
||||||
struct Item(u32);
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
enum Operation {
|
enum Operation {
|
||||||
Add(Option<u32>),
|
Add(Option<u128>),
|
||||||
Mul(Option<u32>),
|
Mul(Option<u128>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Operation {
|
impl Default for Operation {
|
||||||
|
@ -25,6 +23,32 @@ impl Default for Operation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Monkey {
|
||||||
|
pub fn inspect(&mut self) -> Vec<(usize, u128)> {
|
||||||
|
let mut out = Vec::with_capacity(self.items.len());
|
||||||
|
while let Some(item) = self.items.pop_front() {
|
||||||
|
let item = self.op(item) / 3;
|
||||||
|
if item % self.tmod == 0 {
|
||||||
|
out.push((self.target.0, item));
|
||||||
|
} else {
|
||||||
|
out.push((self.target.1, item));
|
||||||
|
}
|
||||||
|
self.business += 1;
|
||||||
|
}
|
||||||
|
self.items.clear();
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
fn op(&self, item: u128) -> u128 {
|
||||||
|
match self.op {
|
||||||
|
Operation::Add(Some(v)) => item + v,
|
||||||
|
Operation::Add(None) => item + item,
|
||||||
|
Operation::Mul(Some(v)) => item * v,
|
||||||
|
Operation::Mul(None) => item * item,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[aoc_generator(day11)]
|
#[aoc_generator(day11)]
|
||||||
fn parse_input(input: &str) -> Vec<Monkey> {
|
fn parse_input(input: &str) -> Vec<Monkey> {
|
||||||
let mut out = Vec::new();
|
let mut out = Vec::new();
|
||||||
|
@ -35,6 +59,7 @@ fn parse_input(input: &str) -> Vec<Monkey> {
|
||||||
let line = line.trim();
|
let line = line.trim();
|
||||||
|
|
||||||
if line.starts_with("Monkey") {
|
if line.starts_with("Monkey") {
|
||||||
|
monkey.business = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if line.starts_with("Starting") {
|
if line.starts_with("Starting") {
|
||||||
|
@ -65,11 +90,11 @@ fn parse_input(input: &str) -> Vec<Monkey> {
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_items(items: &str) -> VecDeque<Item> {
|
fn parse_items(items: &str) -> VecDeque<u128> {
|
||||||
let mut out = VecDeque::new();
|
let mut out = VecDeque::new();
|
||||||
let (_, items) = items.split_once(" items: ").unwrap();
|
let (_, items) = items.split_once(" items: ").unwrap();
|
||||||
for item in items.split(", ") {
|
for item in items.split(", ") {
|
||||||
out.push_back(Item(item.parse().unwrap()));
|
out.push_back(item.parse().unwrap());
|
||||||
}
|
}
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
@ -85,25 +110,63 @@ fn parse_operation(op: &str) -> Operation {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[aoc_run(day11, part1)]
|
#[aoc_run(day11, part1)]
|
||||||
fn part1(troop: &[Monkey]) -> u32 {
|
fn part1(troop: &[Monkey]) -> u128 {
|
||||||
0
|
let mut troop = troop.to_owned();
|
||||||
|
for _round in 0..20 {
|
||||||
|
for i in 0..troop.len() {
|
||||||
|
let monkey = &mut troop[i];
|
||||||
|
let items = monkey.inspect();
|
||||||
|
for (target, item) in items {
|
||||||
|
let m = &mut troop[target];
|
||||||
|
m.items.push_back(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
troop.sort_by(|m1, m2| m2.business.cmp(&m1.business));
|
||||||
|
troop.iter().take(2).map(|m| m.business).product()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[aoc_run(day11, part2)]
|
#[aoc_run(day11, part2)]
|
||||||
fn part2(troop: &[Monkey]) -> u32 {
|
fn part2(troop: &[Monkey]) -> u128 {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
const INPUT: &str = "";
|
const INPUT: &str = "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";
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn part1_test() {
|
fn part1_test() {
|
||||||
let v = parse_input(INPUT);
|
let v = parse_input(INPUT);
|
||||||
|
|
||||||
assert_eq!(part1(&v), 1);
|
assert_eq!(part1(&v), 10605);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -111,4 +174,127 @@ mod test {
|
||||||
let v = parse_input(INPUT);
|
let v = parse_input(INPUT);
|
||||||
assert_eq!(part2(&v), 1);
|
assert_eq!(part2(&v), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn leah_test() {
|
||||||
|
let troop = parse_input(
|
||||||
|
"Monkey 0:
|
||||||
|
Starting items: 54, 82, 90, 88, 86, 54
|
||||||
|
Operation: new = old * 7
|
||||||
|
Test: divisible by 11
|
||||||
|
If true: throw to monkey 2
|
||||||
|
If false: throw to monkey 6
|
||||||
|
|
||||||
|
Monkey 1:
|
||||||
|
Starting items: 91, 65
|
||||||
|
Operation: new = old * 13
|
||||||
|
Test: divisible by 5
|
||||||
|
If true: throw to monkey 7
|
||||||
|
If false: throw to monkey 4
|
||||||
|
|
||||||
|
Monkey 2:
|
||||||
|
Starting items: 62, 54, 57, 92, 83, 63, 63
|
||||||
|
Operation: new = old + 1
|
||||||
|
Test: divisible by 7
|
||||||
|
If true: throw to monkey 1
|
||||||
|
If false: throw to monkey 7
|
||||||
|
|
||||||
|
Monkey 3:
|
||||||
|
Starting items: 67, 72, 68
|
||||||
|
Operation: new = old * old
|
||||||
|
Test: divisible by 2
|
||||||
|
If true: throw to monkey 0
|
||||||
|
If false: throw to monkey 6
|
||||||
|
|
||||||
|
Monkey 4:
|
||||||
|
Starting items: 68, 89, 90, 86, 84, 57, 72, 84
|
||||||
|
Operation: new = old + 7
|
||||||
|
Test: divisible by 17
|
||||||
|
If true: throw to monkey 3
|
||||||
|
If false: throw to monkey 5
|
||||||
|
|
||||||
|
Monkey 5:
|
||||||
|
Starting items: 79, 83, 64, 58
|
||||||
|
Operation: new = old + 6
|
||||||
|
Test: divisible by 13
|
||||||
|
If true: throw to monkey 3
|
||||||
|
If false: throw to monkey 0
|
||||||
|
|
||||||
|
Monkey 6:
|
||||||
|
Starting items: 96, 72, 89, 70, 88
|
||||||
|
Operation: new = old + 4
|
||||||
|
Test: divisible by 3
|
||||||
|
If true: throw to monkey 1
|
||||||
|
If false: throw to monkey 2
|
||||||
|
|
||||||
|
Monkey 7:
|
||||||
|
Starting items: 79
|
||||||
|
Operation: new = old + 8
|
||||||
|
Test: divisible by 19
|
||||||
|
If true: throw to monkey 4
|
||||||
|
If false: throw to monkey 5",
|
||||||
|
);
|
||||||
|
assert_eq!(part1(&troop), 78960);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rippy_part1() {
|
||||||
|
let input = "Monkey 0:
|
||||||
|
Starting items: 96, 60, 68, 91, 83, 57, 85
|
||||||
|
Operation: new = old * 2
|
||||||
|
Test: divisible by 17
|
||||||
|
If true: throw to monkey 2
|
||||||
|
If false: throw to monkey 5
|
||||||
|
|
||||||
|
Monkey 1:
|
||||||
|
Starting items: 75, 78, 68, 81, 73, 99
|
||||||
|
Operation: new = old + 3
|
||||||
|
Test: divisible by 13
|
||||||
|
If true: throw to monkey 7
|
||||||
|
If false: throw to monkey 4
|
||||||
|
|
||||||
|
Monkey 2:
|
||||||
|
Starting items: 69, 86, 67, 55, 96, 69, 94, 85
|
||||||
|
Operation: new = old + 6
|
||||||
|
Test: divisible by 19
|
||||||
|
If true: throw to monkey 6
|
||||||
|
If false: throw to monkey 5
|
||||||
|
|
||||||
|
Monkey 3:
|
||||||
|
Starting items: 88, 75, 74, 98, 80
|
||||||
|
Operation: new = old + 5
|
||||||
|
Test: divisible by 7
|
||||||
|
If true: throw to monkey 7
|
||||||
|
If false: throw to monkey 1
|
||||||
|
|
||||||
|
Monkey 4:
|
||||||
|
Starting items: 82
|
||||||
|
Operation: new = old + 8
|
||||||
|
Test: divisible by 11
|
||||||
|
If true: throw to monkey 0
|
||||||
|
If false: throw to monkey 2
|
||||||
|
|
||||||
|
Monkey 5:
|
||||||
|
Starting items: 72, 92, 92
|
||||||
|
Operation: new = old * 5
|
||||||
|
Test: divisible by 3
|
||||||
|
If true: throw to monkey 6
|
||||||
|
If false: throw to monkey 3
|
||||||
|
|
||||||
|
Monkey 6:
|
||||||
|
Starting items: 74, 61
|
||||||
|
Operation: new = old * old
|
||||||
|
Test: divisible by 2
|
||||||
|
If true: throw to monkey 3
|
||||||
|
If false: throw to monkey 1
|
||||||
|
|
||||||
|
Monkey 7:
|
||||||
|
Starting items: 76, 86, 83, 55
|
||||||
|
Operation: new = old + 4
|
||||||
|
Test: divisible by 5
|
||||||
|
If true: throw to monkey 4
|
||||||
|
If false: throw to monkey 0";
|
||||||
|
let troop = parse_input(input);
|
||||||
|
assert_eq!(part1(&troop), 56595);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue