Monkey in the Middle
Tags: adventofcode, algorithms, javascript, programming
Published: 2022-12-12 16:12:02

## [Advent of Code 2022 Day 11](https://adventofcode.com/2022/day/11)

## Part 1
1. Ugh, this kind of puzzle again?
2. Planning my data structures
3. Skipping input parsing
4. My algorithm in JavaScript in stages

### Ugh, this kind of puzzle again?
You know the kind:
- Several players
- Multiple rounds
- Lots of player attributes to track
- Attributes of multiple players changing multiple times in a single round

It will likely require:
- Multiple collections of dictionaries (array of objects in JavaScript)
- Multiple properties
- Some being methods, some being arrays
- Lots of re-checking the puzzle explanations
- Lots of trial and error
- Lots of patience

Hopefully I can earn at least one star when this is all done.

But prior disappointments have me feeling not too confident.

Still, I'm excited to get to work!

### Planning my data structures
Referring to the first monkey in the example input:
```
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
```

I need a list of monkeys:
```
[
  { },
  { },
  ...
]
```

Monkey `0` has three properties:
```
{
  items: ...,
  operation: ...,
  test: ...
}
```

`items` is an array:
```js
  items: [79, 98]
```

`operation` is a function that works with each number in `items`:
```js
  operation: (index) => {
    let new = items[index] * 19
    new = Math.floor(new / 3)
    items[index] = new
  }
```

`test` is a function that works with each updated number in `items`:
```js
  test: (index) => {
    let item = items.splice(index, 1)
    if (item % 23 == 0) {
      monkeys[1].items.push(item)
    } else {
      monkeys[2].items.push(item)
    }    
  }
```

I foresee needing to edit each property and method due to misreading the instructions.

Now for the tracker of each monkey's number of inspected items.

At the end of each round, I need to tally up each monkeys number of inspected items.

In the example, there are four monkeys:
```
[0, 0, 0, 0]
```

At the end of round 1, these are each monkey's items:
```
Monkey 0: 20, 23, 27, 26
Monkey 1: 2080, 25, 167, 207, 401, 1046
Monkey 2: 
Monkey 3:
``` 

So this needs to be my tally:
```
[4, 6, 0, 0]
```

I think I just need to increment each amount by the length of each monkey's `items`.

Hopefully it ends up being that simple.

### Skipping input parsing
- This puzzle's input would require a lot of code to parse into the data structure I outlined above
- I'm confident I *could* do it, but am more interested in writing an algorithm that plays each round than I am in parsing the input
- I don't intend to build a simulator for this puzzle, mostly because I still have doubts that I'll solve Part 1 let alone Part 2
- Therefore, I'll manually build my monkeys array

### My algorithm in JavaScript in stages
`Monkey 0` in my `monkeys` array:
```js
{
  items: [79, 98],
  operation() {
    let now = this.items[0] * 19
    now = Math.floor(next / 3)
    this.items[0] = now
    this.test()
  },
  test() {
    let item = this.items.shift()
    if (item % 23 == 0) {
      monkeys[2].items.push(item)
    } else {
      monkeys[3].items.push(item)
    }    
  }
}
```

Issues I overlooked when writing the object above:
- Having to remove each item after passing it to another monkey
- Avoiding use of the keyword `new`
- Using `this` in each method

I store the count of each monkey's inspected items as:
```js
let times = [0,0,0,0]
```

Each round of Keep Away is represented as:
```js
for (let m = 0; m < monkeys.length; m++) {
  times[m] += monkeys[m].items.length
  while (monkeys[m].items.length) {
    monkeys[m].operation()
  }
}
```

Finally, I calculate the product of the two largest counts:
```js
times
    .sort((a, b) => b - a)
    .slice(0, 2)
    .reduce((product, count) => product * count)
```

It works on the example input.

Will it work on my puzzle input?

...

Too high.

With manual entry of data comes high likelihood for errors.

Did I mis-enter some number?

Yes. Yes I did.

Will it work now?

Correct answer!

## Part 2

### Confused and thus prohibited
- I understand that I no longer need to divide and round down
- But after removing that line from each monkey in my example input and processing 20 rounds, I get three correct amounts and one amount that is two higher than expected
- Since the example tests go from 1 to 20, I can't easily confirm where my algorithm is going wrong
- Plus, I honestly don't know another way to `manage my relief` so that I could run all 10000 rounds

So, sadly, I don't think I'll be earning this second star.

## I did it!
- I solved Part 1!
- By troubleshooting my way through writing a working data structure, loop and fixing data that I manually entered!

I have a poor track record with Part 2's that are performance tests.

Even if I wanted to run my algorithm and hope that it eventually processes all 10000 rounds, I'm sure it wouldn't generate the correct answer since it didn't work on 20 rounds of the example input.

Nonetheless, I'm proud that I earned one star.