Advent-of-Code-2023/day2/day-two.go

103 lines
2.2 KiB
Go

package day2
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"strings"
)
var Restriction map[string]int = map[string]int{
"red": 12,
"green": 13,
"blue": 14,
}
type Game struct {
Num int
Sets []map[string]int
}
// now i need to encode the restriction,
// code 'compare game to restriction'
// scan though input lines, keep only numbers of games that pass the restriction, or rather sum them
func Run() int {
filename := "./day2/input"
file, err := os.Open(filename)
if err != nil {
panic(fmt.Sprintf("error opening file", filename))
}
defer file.Close()
scanner := bufio.NewScanner(file)
result := 0
for scanner.Scan() {
line := scanner.Text()
game := ReadLine(line)
log.Printf("reading %s got game %+v it is %t", line, game, game.isPossible(Restriction))
if game.isPossible(Restriction) {
result += game.Num
}
}
return result
}
func (g Game)isPossible(restriction map[string]int) bool {
for color, maxAmount := range restriction {
for _, set := range g.Sets {
seenAmount, found := set[color]
if found && seenAmount > maxAmount {
return false
}
}
}
return true
}
func ReadLine(line string) Game {
result := Game{}
result.Sets = make([]map[string]int, 0)
infoIndex := strings.IndexRune(line, ':')
gameTitle := line[0:infoIndex]
titleNumStr := strings.Split(gameTitle, " ")[1]
titleNum, err := strconv.Atoi(titleNumStr)
if err != nil {
panic(fmt.Sprintf("error getting game number from %s\n", line))
}
result.Num = titleNum
setsLints := strings.Split(line[infoIndex+1:], ";")
for _, set := range setsLints {
result.Sets = append(result.Sets, readSet(set))
}
return result
}
// line like this
// 8 green, 6 blue, 20 red
func readSet(setLine string) map[string]int {
log.Printf("> reading set: %s", setLine)
result := make(map[string]int)
itemLines := strings.Split(setLine, ",")
for _, line := range itemLines {
keyValue := strings.Split(strings.Trim(line, " "), " ")
if len(keyValue) != 2 {
panic(fmt.Sprintf("part '%s' of '%s' was of wrong lenght! %+v len is %d", line, setLine, keyValue, len(keyValue)))
}
num, err := strconv.Atoi(keyValue[0])
if err != nil {
panic(fmt.Sprint(setLine, line, err))
}
result[keyValue[1]] = num
}
return result
}