98 lines
1.8 KiB
Go
98 lines
1.8 KiB
Go
package day04
|
|
|
|
import (
|
|
"math"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"fmt"
|
|
|
|
"adventofcode2023/utils"
|
|
|
|
mapset "github.com/deckarep/golang-set/v2"
|
|
)
|
|
|
|
type Game struct {
|
|
ID int
|
|
matches int
|
|
count int
|
|
winners mapset.Set[int]
|
|
cards mapset.Set[int]
|
|
}
|
|
|
|
func Part1(input string) int {
|
|
games, err := parseGames(input)
|
|
if err != nil {
|
|
fmt.Println("Error:", err)
|
|
return -1
|
|
}
|
|
|
|
points := 0.0
|
|
for _, game := range games {
|
|
matches := len(game.cards.Intersect(game.winners).ToSlice())
|
|
if matches > 0 {
|
|
points += math.Pow(2, float64(matches - 1))
|
|
}
|
|
}
|
|
return int(points)
|
|
}
|
|
|
|
func Part2(input string) int {
|
|
games, err := parseGames(input)
|
|
if err != nil {
|
|
fmt.Println("Error:", err)
|
|
return -1
|
|
}
|
|
|
|
for i, game := range games {
|
|
matches := game.cards.Intersect(game.winners).ToSlice()
|
|
games[i].matches = len(matches)
|
|
games[i].count = 1
|
|
}
|
|
|
|
for i:=0;i<len(games);i++{
|
|
for j:=0;j<games[i].count;j++ {
|
|
for k:=1;k<=games[i].matches;k++ {
|
|
games[i+k].count++
|
|
}
|
|
}
|
|
}
|
|
|
|
cards := 0
|
|
for i:=0;i<len(games);i++{
|
|
cards += games[i].count
|
|
}
|
|
return cards
|
|
}
|
|
|
|
func parseGames(input string) ([]Game, error) {
|
|
|
|
var game Game
|
|
var games []Game
|
|
|
|
lines := strings.Split(input, "\n")
|
|
for _, line := range lines {
|
|
reID := regexp.MustCompile(`Card\s*(\d+):(.*) \| (.*)`)
|
|
match := reID.FindStringSubmatch(line)
|
|
if len(match) != 4 {
|
|
return games, fmt.Errorf("unable to extract game")
|
|
}
|
|
|
|
game.ID = utils.MustAtoi(match[1])
|
|
game.winners = getNumbers(match[2])
|
|
game.cards = getNumbers(match[3])
|
|
|
|
games = append(games, game)
|
|
}
|
|
return games, nil
|
|
}
|
|
|
|
func getNumbers(input string) mapset.Set[int] {
|
|
tokens := strings.Fields(input)
|
|
var numbers []int
|
|
for _, token := range tokens {
|
|
num := utils.MustAtoi(token)
|
|
numbers = append(numbers, num)
|
|
}
|
|
return mapset.NewSet[int](numbers...)
|
|
} |