Day 21
This commit is contained in:
228
day21/common/monkey2.go
Normal file
228
day21/common/monkey2.go
Normal 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
14
day21/ex1/main.go
Normal 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
14
day21/ex2/main.go
Normal 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))
|
||||
}
|
||||
Reference in New Issue
Block a user