-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.go
118 lines (98 loc) · 2.64 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package main
import (
"fmt"
"sort"
"strconv"
"strings"
utils "github.com/baspar/adventofcode2022/internal"
)
type Operation struct {
op byte
val int
}
func (operation Operation) Call(old int) int {
n := operation.val
if n == 0 {
n = old
}
if operation.op == '*' {
return old * n
} else {
return old + n
}
}
type Monkey struct {
items []int
operation Operation
testDivisibleBy int
throwIfTrue int
throwIfFalse int
}
func (m *Monkey) InspectAndThrow(monkeyGetsBored bool) (throwToMonkey int, value int) {
item := m.items[0]
m.items = m.items[1:]
item = m.operation.Call(item)
if monkeyGetsBored {
item /= 3
}
if item%m.testDivisibleBy == 0 {
return m.throwIfTrue, item
} else {
return m.throwIfFalse, item
}
}
func NewMonkey(lines []string) (monkey Monkey) {
// Items
for _, item := range strings.Split(strings.Split(lines[1], ": ")[1], ", ") {
n, _ := strconv.Atoi(item)
monkey.items = append(monkey.items, int(n))
}
// Operation
var value string
fmt.Sscanf(lines[2], " Operation: new = old %c %s", &monkey.operation.op, &value)
if value != "old" {
monkey.operation.val, _ = strconv.Atoi(value)
}
// Test
fmt.Sscanf(lines[3], " Test: divisible by %d", &monkey.testDivisibleBy)
fmt.Sscanf(lines[4], " If true: throw to monkey %d", &monkey.throwIfTrue)
fmt.Sscanf(lines[5], " If false: throw to monkey %d", &monkey.throwIfFalse)
return monkey
}
type DayImpl struct {
monkeys []Monkey
}
func (d *DayImpl) getMonkeyBusiness(numberOfRound int, monkeyGetsBored bool) int {
objectsInspected := make([]int, len(d.monkeys))
leastCommonMultiplier := 1
for _, m := range d.monkeys {
leastCommonMultiplier *= m.testDivisibleBy
}
for round := 0; round < numberOfRound; round++ {
for monkeyIndex := 0; monkeyIndex < len(d.monkeys); monkeyIndex++ {
objectsInspected[monkeyIndex] += len(d.monkeys[monkeyIndex].items)
for len(d.monkeys[monkeyIndex].items) > 0 {
throwToMonkey, item := d.monkeys[monkeyIndex].InspectAndThrow(monkeyGetsBored)
d.monkeys[throwToMonkey].items = append(d.monkeys[throwToMonkey].items, item%leastCommonMultiplier)
}
}
}
sort.Sort(sort.Reverse(sort.IntSlice(objectsInspected)))
return objectsInspected[0] * objectsInspected[1]
}
func (d *DayImpl) Init(lines []string) error {
d.monkeys = nil
for i := 0; i < len(lines); i += 7 {
d.monkeys = append(d.monkeys, NewMonkey(lines[i:i+6]))
}
return nil
}
func (d *DayImpl) Part1() (string, error) {
return fmt.Sprint(d.getMonkeyBusiness(20, true)), nil
}
func (d *DayImpl) Part2() (string, error) {
return fmt.Sprint(d.getMonkeyBusiness(10000, false)), nil
}
func main() {
utils.Run(&DayImpl{}, true)
}