-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday11.chpl
131 lines (114 loc) · 3.33 KB
/
day11.chpl
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
119
120
121
122
123
124
125
126
127
128
129
130
// day11
use IO;
use List;
const numRounds = 20;
iter readInput() {
for line in stdin.lines() {
yield line.strip();
}
}
var inputLines = readInput();
//writeln(inputLines);
enum operation {mult, add, double, square};
record monkey {
var items : list(int);
var op : operation;
// FIXME: when had enum before operation above, syntax error
var operand : int;
var testNum : int; // test if divisible by testNum
var ifFalse : int; // monkey to throw to if test is false
var ifTrue : int; // monkey to throw to if test is true
}
// read in instructions per monkey
const linesPer = 7;
const numMonkeys = inputLines.size/linesPer;
writeln("numMonkeys = ", numMonkeys);
writeln("inputLines.size = ", inputLines.size);
var monkeyState : [0..#numMonkeys] monkey;
for i in 0..#numMonkeys {
// Monkey #, i==# so don't need to parse
// Starting items: 79, 98
var startItemsStrs = inputLines[i*linesPer+1].split(":");
for item in startItemsStrs[1].split(",") {
monkeyState[i].items.append(item : int);
}
// Operation: new = old * 19
const opIdx = 21;
if inputLines[i*linesPer+2][opIdx] == "*" {
monkeyState[i].op = operation.mult;
} else {
monkeyState[i].op = operation.add;
}
//writeln("wholeLine=", inputLines[i*linesPer+2], "=");
var operandStr = inputLines[i*linesPer+2][opIdx+2..];
if operandStr == "old" {
if monkeyState[i].op == operation.mult {
monkeyState[i].op = operation.square;
} else {
monkeyState[i].op = operation.double;
}
} else {
monkeyState[i].operand =
inputLines[i*linesPer+2][opIdx+2..] : int;
}
// Test: divisible by 23
const testNumIdx = 19;
monkeyState[i].testNum =
inputLines[i*linesPer+3][testNumIdx..] : int;
// If true: throw to monkey 2
const trueIdx = 25;
monkeyState[i].ifTrue = inputLines[i*linesPer+4][trueIdx..] : int;
// If false: throw to monkey 3
const falseIdx = 26;
monkeyState[i].ifFalse = inputLines[i*linesPer+5][falseIdx..] : int;
}
writeln(monkeyState);
proc writeItems() {
for i in 0..#numMonkeys {
write("Monkey ", i, ": ");
for item in monkeyState[i].items {
write(item, ", ");
}
writeln();
}
}
writeItems();
proc applyOp(op : operation, old : int, operand : int) {
select op {
when operation.mult do return old * operand;
when operation.add do return old + operand;
when operation.double do return old + old;
when operation.square do return old * old;
otherwise return -1;
}
}
// Do rounds and keep track of how many items each
// monkey inspects
var count : [0..#numMonkeys] int;
for round in 1..numRounds {
for i in 0..#numMonkeys {
for item in monkeyState[i].items {
count[i]+=1;
var opResult = applyOp( monkeyState[i].op, item,
monkeyState[i].operand);
opResult = opResult / 3;
if opResult % monkeyState[i].testNum == 0 {
const trueIdx = monkeyState[i].ifTrue;
monkeyState[trueIdx].items.append(opResult);
} else {
const falseIdx = monkeyState[i].ifFalse;
monkeyState[falseIdx].items.append(opResult);
}
}
monkeyState[i].items.clear();
}
writeln();
writeItems();
}
// compute monkey business
var max1 = max reduce count;
for idx in count.domain {
if count[idx] == max1 then count[idx]=0;
}
var max2 = max reduce count;
writeln("result = ", max1*max2);