This commit is contained in:
2022-12-21 11:09:30 +01:00
parent 6e90e2675d
commit dc8232fee3
3 changed files with 256 additions and 0 deletions

228
day21/common/monkey2.go Normal file
View File

@@ -0,0 +1,228 @@
package common
import (
"bufio"
"strconv"
"strings"
)
type Monkey interface {
Apply() int
Invert(int) int
IsHuman() bool
}
type Human struct {
name string
number int
}
func (monkey *Human) Apply() int {
return monkey.number
}
func (monkey *Human) Invert(total int) int {
return total
}
func (monkey *Human) IsHuman() bool {
return true
}
type NumberMonkey struct {
name string
number int
}
func (monkey *NumberMonkey) Apply() int {
return monkey.number
}
func (monkey *NumberMonkey) Invert(total int) int {
return total - monkey.number
}
func (monkey *NumberMonkey) IsHuman() bool {
return false
}
type PlusMonkey struct {
name string
operand1 Monkey
operand2 Monkey
}
func (monkey *PlusMonkey) Apply() int {
return monkey.operand1.Apply() + monkey.operand2.Apply()
}
func (monkey *PlusMonkey) Invert(total int) int {
if monkey.operand1.IsHuman() {
return monkey.operand1.Invert(total - monkey.operand2.Apply())
} else {
return monkey.operand2.Invert(total - monkey.operand1.Apply())
}
}
func (monkey *PlusMonkey) IsHuman() bool {
return monkey.operand1.IsHuman() || monkey.operand2.IsHuman()
}
type MinusMonkey struct {
name string
operand1 Monkey
operand2 Monkey
}
func (monkey *MinusMonkey) Apply() int {
return monkey.operand1.Apply() - monkey.operand2.Apply()
}
func (monkey *MinusMonkey) Invert(total int) int {
if monkey.operand1.IsHuman() {
return monkey.operand1.Invert(total + monkey.operand2.Apply())
} else {
return monkey.operand2.Invert(monkey.operand1.Apply() - total)
}
}
func (monkey *MinusMonkey) IsHuman() bool {
return monkey.operand1.IsHuman() || monkey.operand2.IsHuman()
}
type TimesMonkey struct {
name string
operand1 Monkey
operand2 Monkey
}
func (monkey *TimesMonkey) Apply() int {
return monkey.operand1.Apply() * monkey.operand2.Apply()
}
func (monkey *TimesMonkey) Invert(total int) int {
if monkey.operand1.IsHuman() {
return monkey.operand1.Invert(total / monkey.operand2.Apply())
} else {
return monkey.operand2.Invert(total / monkey.operand1.Apply())
}
}
func (monkey *TimesMonkey) IsHuman() bool {
return monkey.operand1.IsHuman() || monkey.operand2.IsHuman()
}
type DivisionMonkey struct {
name string
operand1 Monkey
operand2 Monkey
}
func (monkey *DivisionMonkey) Apply() int {
return monkey.operand1.Apply() / monkey.operand2.Apply()
}
func (monkey *DivisionMonkey) Invert(total int) int {
if monkey.operand1.IsHuman() {
return monkey.operand1.Invert(total * monkey.operand2.Apply())
} else {
return monkey.operand2.Invert(monkey.operand1.Apply() / total)
}
}
func (monkey *DivisionMonkey) IsHuman() bool {
return monkey.operand1.IsHuman() || monkey.operand2.IsHuman()
}
type EqualityMonkey struct {
name string
operand1 Monkey
operand2 Monkey
}
func (monkey *EqualityMonkey) Apply() int {
if monkey.operand1.Apply() == monkey.operand2.Apply() {
return 1
} else {
return 0
}
}
func (monkey *EqualityMonkey) Invert(total int) int {
if monkey.operand1.IsHuman() {
return monkey.operand1.Invert(monkey.operand2.Apply() - total)
} else {
return monkey.operand2.Invert(monkey.operand1.Apply() - total)
}
}
func (monkey *EqualityMonkey) IsHuman() bool {
return monkey.operand1.IsHuman() || monkey.operand2.IsHuman()
}
type StringCouple struct {
left string
right string
}
type UnresolvedMonkey struct {
name string
symbol string
}
func Parse(scanner bufio.Scanner, rootIsEquality bool) Monkey {
unresolvedMonkeys := make(map[StringCouple]UnresolvedMonkey)
resolvedMonkeys := make(map[string]Monkey)
for scanner.Scan() {
line := scanner.Text()
splittedLine := strings.Split(line, " ")
if len(splittedLine) == 2 {
number, _ := strconv.Atoi(splittedLine[1])
if splittedLine[0][:4] == "humn" {
resolvedMonkeys[splittedLine[0][:4]] = &Human{splittedLine[0][:4], number}
} else {
resolvedMonkeys[splittedLine[0][:4]] = &NumberMonkey{splittedLine[0][:4], number}
}
} else {
unresolvedMonkeys[StringCouple{splittedLine[1], splittedLine[3]}] = UnresolvedMonkey{splittedLine[0][:4], splittedLine[2]}
}
}
for len(unresolvedMonkeys) > 0 {
for monkeyCouple := range(unresolvedMonkeys) {
monkey1, ok1 := resolvedMonkeys[monkeyCouple.left]
monkey2, ok2 := resolvedMonkeys[monkeyCouple.right]
if ok1 && ok2 {
if rootIsEquality && unresolvedMonkeys[monkeyCouple].name == "root" {
resolvedMonkeys[unresolvedMonkeys[monkeyCouple].name] = &EqualityMonkey{unresolvedMonkeys[monkeyCouple].name, monkey1, monkey2}
} else {
switch unresolvedMonkeys[monkeyCouple].symbol {
case "+":
resolvedMonkeys[unresolvedMonkeys[monkeyCouple].name] = &PlusMonkey{unresolvedMonkeys[monkeyCouple].name, monkey1, monkey2}
case "-":
resolvedMonkeys[unresolvedMonkeys[monkeyCouple].name] = &MinusMonkey{unresolvedMonkeys[monkeyCouple].name, monkey1, monkey2}
case "*":
resolvedMonkeys[unresolvedMonkeys[monkeyCouple].name] = &TimesMonkey{unresolvedMonkeys[monkeyCouple].name, monkey1, monkey2}
case "/":
resolvedMonkeys[unresolvedMonkeys[monkeyCouple].name] = &DivisionMonkey{unresolvedMonkeys[monkeyCouple].name, monkey1, monkey2}
}
}
delete(unresolvedMonkeys, monkeyCouple)
}
}
}
return resolvedMonkeys["root"]
}

14
day21/ex1/main.go Normal file
View File

@@ -0,0 +1,14 @@
package main
import (
"aoc2022/day21/common"
"bufio"
"fmt"
"os"
)
func main() {
rootMonkey := common.Parse(*bufio.NewScanner(os.Stdin), false)
fmt.Println(rootMonkey.Apply())
}

14
day21/ex2/main.go Normal file
View File

@@ -0,0 +1,14 @@
package main
import (
"aoc2022/day21/common"
"bufio"
"fmt"
"os"
)
func main() {
rootMonkey := common.Parse(*bufio.NewScanner(os.Stdin), true)
fmt.Println(rootMonkey.Invert(0))
}