aoc-2022/day02/solution.go

129 lines
2.5 KiB
Go

package day02
import (
"fmt"
"strings"
)
type Solver struct {
rounds []*Round
}
type ActionType int
const (
Rock ActionType = iota
Paper
Scissors
)
func (a ActionType) Score() int {
m := map[ActionType]int{Rock: 1, Paper: 2, Scissors: 3}
return m[a]
}
func NewAction(s string) ActionType {
switch s {
case "A", "X":
return Rock
case "B", "Y":
return Paper
case "C", "Z":
return Scissors
}
panic(fmt.Sprintf("Unhandled action type: %s", s))
}
type Result int
const (
Win Result = iota
Loss
Draw
)
func NewDesiredResult(s string) Result {
return map[string]Result{"X": Loss, "Y": Draw, "Z": Win}[s]
}
func (r Result) Score() int {
return map[Result]int{Win: 6, Draw: 3, Loss: 0}[r]
}
type Round struct {
OpponentAction, OwnAction ActionType
DesiredResult Result
}
func (r Round) Score() int {
var result Result
switch {
case r.OwnAction == r.OpponentAction:
result = Draw
case r.OwnAction == Rock && r.OpponentAction == Scissors:
result = Win
case r.OwnAction == Paper && r.OpponentAction == Rock:
result = Win
case r.OwnAction == Scissors && r.OpponentAction == Paper:
result = Win
case r.OwnAction == Rock && r.OpponentAction == Paper:
result = Loss
case r.OwnAction == Paper && r.OpponentAction == Scissors:
result = Loss
case r.OwnAction == Scissors && r.OpponentAction == Rock:
result = Loss
}
return result.Score() + r.OwnAction.Score()
}
func (s *Solver) ParseInput(input []string) {
s.rounds = make([]*Round, len(input))
for i, line := range input {
split := strings.Split(line, " ")
s.rounds[i] = &Round{
OpponentAction: NewAction(split[0]),
OwnAction: NewAction(split[1]),
DesiredResult: NewDesiredResult(split[1]),
}
}
}
func (s *Solver) SolvePart1() any {
return s.score()
}
func (s *Solver) SolvePart2() any {
for _, r := range s.rounds {
switch {
case r.DesiredResult == Draw:
r.OwnAction = r.OpponentAction
case r.OpponentAction == Rock && r.DesiredResult == Win:
r.OwnAction = Paper
case r.OpponentAction == Rock && r.DesiredResult == Loss:
r.OwnAction = Scissors
case r.OpponentAction == Paper && r.DesiredResult == Win:
r.OwnAction = Scissors
case r.OpponentAction == Paper && r.DesiredResult == Loss:
r.OwnAction = Rock
case r.OpponentAction == Scissors && r.DesiredResult == Win:
r.OwnAction = Rock
case r.OpponentAction == Scissors && r.DesiredResult == Loss:
r.OwnAction = Paper
}
}
return s.score()
}
func (s *Solver) score() int {
score := 0
for _, s := range s.rounds {
score += s.Score()
}
return score
}