@@ -12,7 +12,7 @@ import (
12
12
type Operator int
13
13
14
14
const (
15
- Literal Operator = iota
15
+ Nop Operator = iota
16
16
Add
17
17
Subtract
18
18
Multiply
@@ -30,18 +30,18 @@ func ParseOperator(op string) (Operator, error) {
30
30
case "/" :
31
31
return Divide , nil
32
32
}
33
- return Literal , fmt .Errorf ("invalid operator: %v" , op )
33
+ return Nop , fmt .Errorf ("invalid operator: %v" , op )
34
34
}
35
35
36
36
type Side struct {
37
- isLiteral bool
38
- literal int
39
- monkey string
37
+ yelled bool
38
+ number int
39
+ monkey string
40
40
}
41
41
42
42
func ParseSide (side string ) Side {
43
- if literal , err := strconv .Atoi (side ); err == nil {
44
- return Side {true , literal , "" }
43
+ if number , err := strconv .Atoi (side ); err == nil {
44
+ return Side {true , number , "" }
45
45
}
46
46
return Side {false , 0 , side }
47
47
}
@@ -52,133 +52,135 @@ type Monkey struct {
52
52
left , right Side
53
53
}
54
54
55
- func Compute (values * map [string ]Monkey ) (bool , int ) {
55
+ func Compute (state * map [string ]Monkey ) (bool , int ) {
56
56
for {
57
- var deleteMonkeys []string
58
- for yellingMonkeyName , yellingMonkey := range * values {
59
- if yellingMonkey .op == Literal {
60
- for waitingMonkeyName , waitingMonkey := range * values {
61
- if waitingMonkey .op != Literal {
62
- if ! waitingMonkey .left .isLiteral && waitingMonkey .left .monkey == yellingMonkeyName {
57
+ var monkeysToRetire []string
58
+ for yellingMonkeyName , yellingMonkey := range * state {
59
+ if yellingMonkey .op == Nop {
60
+ for waitingMonkeyName , waitingMonkey := range * state {
61
+ if waitingMonkey .op != Nop {
62
+ if ! waitingMonkey .left .yelled && waitingMonkey .left .monkey == yellingMonkeyName {
63
63
waitingMonkey .left = yellingMonkey .left
64
64
}
65
- if ! waitingMonkey .right .isLiteral && waitingMonkey .right .monkey == yellingMonkeyName {
65
+ if ! waitingMonkey .right .yelled && waitingMonkey .right .monkey == yellingMonkeyName {
66
66
waitingMonkey .right = yellingMonkey .left
67
67
}
68
- if waitingMonkey .left .isLiteral && waitingMonkey .right .isLiteral {
69
- var literal int
68
+ if waitingMonkey .left .yelled && waitingMonkey .right .yelled {
69
+ var number int
70
70
switch waitingMonkey .op {
71
71
case Add :
72
- literal = waitingMonkey .left .literal + waitingMonkey .right .literal
72
+ number = waitingMonkey .left .number + waitingMonkey .right .number
73
73
case Subtract :
74
- literal = waitingMonkey .left .literal - waitingMonkey .right .literal
74
+ number = waitingMonkey .left .number - waitingMonkey .right .number
75
75
case Multiply :
76
- literal = waitingMonkey .left .literal * waitingMonkey .right .literal
76
+ number = waitingMonkey .left .number * waitingMonkey .right .number
77
77
case Divide :
78
- literal = waitingMonkey .left .literal / waitingMonkey .right .literal
78
+ number = waitingMonkey .left .number / waitingMonkey .right .number
79
79
}
80
80
if waitingMonkeyName == "root" {
81
- return true , literal
81
+ return true , number
82
82
}
83
- waitingMonkey .op = Literal
84
- waitingMonkey .left = Side {true , literal , "" }
83
+ waitingMonkey .op = Nop
84
+ waitingMonkey .left = Side {true , number , "" }
85
85
waitingMonkey .right = Side {}
86
86
}
87
- (* values )[waitingMonkeyName ] = waitingMonkey
87
+ (* state )[waitingMonkeyName ] = waitingMonkey
88
88
}
89
89
}
90
- deleteMonkeys = append (deleteMonkeys , yellingMonkeyName )
90
+ monkeysToRetire = append (monkeysToRetire , yellingMonkeyName )
91
91
}
92
92
}
93
- if len (deleteMonkeys ) == 0 {
93
+ if len (monkeysToRetire ) == 0 {
94
94
break
95
95
}
96
- for _ , name := range deleteMonkeys {
97
- delete (* values , name )
96
+ for _ , monkeyName := range monkeysToRetire {
97
+ delete (* state , monkeyName )
98
98
}
99
99
}
100
100
return false , 0
101
101
}
102
102
103
103
func Solve1 (monkeys map [string ]Monkey ) int {
104
- values := map [string ]Monkey {}
105
- for name , monkey := range monkeys {
106
- values [ name ] = monkey
104
+ state := map [string ]Monkey {}
105
+ for monkeyName , monkey := range monkeys {
106
+ state [ monkeyName ] = monkey
107
107
}
108
- found , result := Compute (& values )
109
- if ! found {
110
- log .Fatalf ("no value for root found " )
108
+ rootYelled , rootNumber := Compute (& state )
109
+ if ! rootYelled {
110
+ log .Fatalf ("root couldn't yell a number " )
111
111
}
112
- return result
112
+ return rootNumber
113
113
}
114
114
115
115
func Solve2 (monkeys map [string ]Monkey ) int {
116
- values := map [string ]Monkey {}
117
- for name , monkey := range monkeys {
118
- if name == "humn" || name == "root" {
116
+ state := map [string ]Monkey {}
117
+ for monkeyName , monkey := range monkeys {
118
+ if monkeyName == "humn" || monkeyName == "root" {
119
119
continue
120
120
}
121
- values [ name ] = monkey
121
+ state [ monkeyName ] = monkey
122
122
}
123
123
124
124
root , _ := monkeys ["root" ]
125
- values ["root" ] = Monkey {"root" , Subtract , root .left , root .right }
125
+ state ["root" ] = Monkey {"root" , Subtract , root .left , root .right }
126
126
127
- Compute (& values )
127
+ Compute (& state )
128
128
129
- inferred := map [string ]int {}
129
+ inferredNumbers := map [string ]int {}
130
130
131
- root = values ["root" ]
132
- if root .left .isLiteral {
133
- inferred [root .right .monkey ] = root .left .literal
134
- } else if root .right .isLiteral {
135
- inferred [root .left .monkey ] = root .right .literal
131
+ root = state ["root" ]
132
+ if root .left .yelled {
133
+ inferredNumbers [root .right .monkey ] = root .left .number
134
+ } else if root .right .yelled {
135
+ inferredNumbers [root .left .monkey ] = root .right .number
136
136
} else {
137
137
log .Fatalf ("could not find a solution" )
138
138
}
139
139
140
140
for {
141
- any := false
142
- for name , value := range inferred {
143
- monkey := values [name ]
144
- var reversedValue int
145
- if monkey .left .isLiteral {
141
+ newInferredNumbers := map [string ]int {}
142
+ found := 0
143
+ for monkeyName , number := range inferredNumbers {
144
+ monkey := state [monkeyName ]
145
+ var inferredNUmber int
146
+ if monkey .left .yelled {
146
147
switch monkey .op {
147
148
case Add :
148
- reversedValue = value - monkey .left .literal
149
+ inferredNUmber = number - monkey .left .number
149
150
case Subtract :
150
- reversedValue = monkey .left .literal - value
151
+ inferredNUmber = monkey .left .number - number
151
152
case Multiply :
152
- reversedValue = value / monkey .left .literal
153
+ inferredNUmber = number / monkey .left .number
153
154
case Divide :
154
- reversedValue = monkey .left .literal / value
155
+ inferredNUmber = monkey .left .number / number
155
156
}
156
157
if monkey .right .monkey == "humn" {
157
- return reversedValue
158
+ return inferredNUmber
158
159
}
159
- inferred [monkey .right .monkey ] = reversedValue
160
- any = true
161
- } else if monkey .right .isLiteral {
160
+ newInferredNumbers [monkey .right .monkey ] = inferredNUmber
161
+ found ++
162
+ } else if monkey .right .yelled {
162
163
switch monkey .op {
163
164
case Add :
164
- reversedValue = value - monkey .right .literal
165
+ inferredNUmber = number - monkey .right .number
165
166
case Subtract :
166
- reversedValue = monkey .right .literal + value
167
+ inferredNUmber = monkey .right .number + number
167
168
case Multiply :
168
- reversedValue = value / monkey .right .literal
169
+ inferredNUmber = number / monkey .right .number
169
170
case Divide :
170
- reversedValue = monkey .right .literal * value
171
+ inferredNUmber = monkey .right .number * number
171
172
}
172
173
if monkey .left .monkey == "humn" {
173
- return reversedValue
174
+ return inferredNUmber
174
175
}
175
- inferred [monkey .left .monkey ] = reversedValue
176
- any = true
176
+ newInferredNumbers [monkey .left .monkey ] = inferredNUmber
177
+ found ++
177
178
}
178
179
}
179
- if ! any {
180
+ if found == 0 {
180
181
break
181
182
}
183
+ inferredNumbers = newInferredNumbers
182
184
}
183
185
184
186
return - 1
@@ -206,7 +208,7 @@ func main() {
206
208
207
209
var monkey Monkey
208
210
if len (expr ) == 1 {
209
- monkey = Monkey {name , Literal , ParseSide (expr [0 ]), Side {}}
211
+ monkey = Monkey {name , Nop , ParseSide (expr [0 ]), Side {}}
210
212
} else {
211
213
op , err := ParseOperator (expr [1 ])
212
214
if err != nil {
0 commit comments