103 lines
2.2 KiB
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
|
|
}
|