Skip to content

Commit 1a516e0

Browse files
committed
refactor: use the vocanulary of the problem
1 parent c70759c commit 1a516e0

File tree

1 file changed

+72
-70
lines changed

1 file changed

+72
-70
lines changed

21/main.go

+72-70
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
type Operator int
1313

1414
const (
15-
Literal Operator = iota
15+
Nop Operator = iota
1616
Add
1717
Subtract
1818
Multiply
@@ -30,18 +30,18 @@ func ParseOperator(op string) (Operator, error) {
3030
case "/":
3131
return Divide, nil
3232
}
33-
return Literal, fmt.Errorf("invalid operator: %v", op)
33+
return Nop, fmt.Errorf("invalid operator: %v", op)
3434
}
3535

3636
type Side struct {
37-
isLiteral bool
38-
literal int
39-
monkey string
37+
yelled bool
38+
number int
39+
monkey string
4040
}
4141

4242
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, ""}
4545
}
4646
return Side{false, 0, side}
4747
}
@@ -52,133 +52,135 @@ type Monkey struct {
5252
left, right Side
5353
}
5454

55-
func Compute(values *map[string]Monkey) (bool, int) {
55+
func Compute(state *map[string]Monkey) (bool, int) {
5656
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 {
6363
waitingMonkey.left = yellingMonkey.left
6464
}
65-
if !waitingMonkey.right.isLiteral && waitingMonkey.right.monkey == yellingMonkeyName {
65+
if !waitingMonkey.right.yelled && waitingMonkey.right.monkey == yellingMonkeyName {
6666
waitingMonkey.right = yellingMonkey.left
6767
}
68-
if waitingMonkey.left.isLiteral && waitingMonkey.right.isLiteral {
69-
var literal int
68+
if waitingMonkey.left.yelled && waitingMonkey.right.yelled {
69+
var number int
7070
switch waitingMonkey.op {
7171
case Add:
72-
literal = waitingMonkey.left.literal + waitingMonkey.right.literal
72+
number = waitingMonkey.left.number + waitingMonkey.right.number
7373
case Subtract:
74-
literal = waitingMonkey.left.literal - waitingMonkey.right.literal
74+
number = waitingMonkey.left.number - waitingMonkey.right.number
7575
case Multiply:
76-
literal = waitingMonkey.left.literal * waitingMonkey.right.literal
76+
number = waitingMonkey.left.number * waitingMonkey.right.number
7777
case Divide:
78-
literal = waitingMonkey.left.literal / waitingMonkey.right.literal
78+
number = waitingMonkey.left.number / waitingMonkey.right.number
7979
}
8080
if waitingMonkeyName == "root" {
81-
return true, literal
81+
return true, number
8282
}
83-
waitingMonkey.op = Literal
84-
waitingMonkey.left = Side{true, literal, ""}
83+
waitingMonkey.op = Nop
84+
waitingMonkey.left = Side{true, number, ""}
8585
waitingMonkey.right = Side{}
8686
}
87-
(*values)[waitingMonkeyName] = waitingMonkey
87+
(*state)[waitingMonkeyName] = waitingMonkey
8888
}
8989
}
90-
deleteMonkeys = append(deleteMonkeys, yellingMonkeyName)
90+
monkeysToRetire = append(monkeysToRetire, yellingMonkeyName)
9191
}
9292
}
93-
if len(deleteMonkeys) == 0 {
93+
if len(monkeysToRetire) == 0 {
9494
break
9595
}
96-
for _, name := range deleteMonkeys {
97-
delete(*values, name)
96+
for _, monkeyName := range monkeysToRetire {
97+
delete(*state, monkeyName)
9898
}
9999
}
100100
return false, 0
101101
}
102102

103103
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
107107
}
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")
111111
}
112-
return result
112+
return rootNumber
113113
}
114114

115115
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" {
119119
continue
120120
}
121-
values[name] = monkey
121+
state[monkeyName] = monkey
122122
}
123123

124124
root, _ := monkeys["root"]
125-
values["root"] = Monkey{"root", Subtract, root.left, root.right}
125+
state["root"] = Monkey{"root", Subtract, root.left, root.right}
126126

127-
Compute(&values)
127+
Compute(&state)
128128

129-
inferred := map[string]int{}
129+
inferredNumbers := map[string]int{}
130130

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
136136
} else {
137137
log.Fatalf("could not find a solution")
138138
}
139139

140140
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 {
146147
switch monkey.op {
147148
case Add:
148-
reversedValue = value - monkey.left.literal
149+
inferredNUmber = number - monkey.left.number
149150
case Subtract:
150-
reversedValue = monkey.left.literal - value
151+
inferredNUmber = monkey.left.number - number
151152
case Multiply:
152-
reversedValue = value / monkey.left.literal
153+
inferredNUmber = number / monkey.left.number
153154
case Divide:
154-
reversedValue = monkey.left.literal / value
155+
inferredNUmber = monkey.left.number / number
155156
}
156157
if monkey.right.monkey == "humn" {
157-
return reversedValue
158+
return inferredNUmber
158159
}
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 {
162163
switch monkey.op {
163164
case Add:
164-
reversedValue = value - monkey.right.literal
165+
inferredNUmber = number - monkey.right.number
165166
case Subtract:
166-
reversedValue = monkey.right.literal + value
167+
inferredNUmber = monkey.right.number + number
167168
case Multiply:
168-
reversedValue = value / monkey.right.literal
169+
inferredNUmber = number / monkey.right.number
169170
case Divide:
170-
reversedValue = monkey.right.literal * value
171+
inferredNUmber = monkey.right.number * number
171172
}
172173
if monkey.left.monkey == "humn" {
173-
return reversedValue
174+
return inferredNUmber
174175
}
175-
inferred[monkey.left.monkey] = reversedValue
176-
any = true
176+
newInferredNumbers[monkey.left.monkey] = inferredNUmber
177+
found++
177178
}
178179
}
179-
if !any {
180+
if found == 0 {
180181
break
181182
}
183+
inferredNumbers = newInferredNumbers
182184
}
183185

184186
return -1
@@ -206,7 +208,7 @@ func main() {
206208

207209
var monkey Monkey
208210
if len(expr) == 1 {
209-
monkey = Monkey{name, Literal, ParseSide(expr[0]), Side{}}
211+
monkey = Monkey{name, Nop, ParseSide(expr[0]), Side{}}
210212
} else {
211213
op, err := ParseOperator(expr[1])
212214
if err != nil {

0 commit comments

Comments
 (0)