2023 Day 4 Complete!
This commit is contained in:
104
2023/day04/main.go
Normal file
104
2023/day04/main.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strings"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
part1(inp)
|
||||
fmt.Println()
|
||||
part2(inp)
|
||||
}
|
||||
|
||||
func part1(input []string) {
|
||||
var total int
|
||||
for i := range input {
|
||||
total += cardFromLine(input[i]).Value()
|
||||
}
|
||||
fmt.Println("# Part 1")
|
||||
fmt.Println(total)
|
||||
}
|
||||
|
||||
func part2(input []string) {
|
||||
cards := make(map[int]*Card)
|
||||
for i := range input {
|
||||
c := cardFromLine(input[i])
|
||||
cards[c.id] = c
|
||||
}
|
||||
result := len(cards)
|
||||
for _, card := range cards {
|
||||
result += card.TotalCardsWon(cards)
|
||||
}
|
||||
|
||||
fmt.Println("# Part 2")
|
||||
fmt.Println(result)
|
||||
}
|
||||
|
||||
type Card struct {
|
||||
id int
|
||||
winners []int
|
||||
numbers []int
|
||||
|
||||
winsCards []int
|
||||
totalCardsWon int
|
||||
}
|
||||
|
||||
func (c Card) String() string {
|
||||
return fmt.Sprintf("Card %d: %v | %v", c.id, c.winners, c.numbers)
|
||||
}
|
||||
|
||||
func cardFromLine(input string) *Card {
|
||||
pts := strings.Fields(input)
|
||||
ret := Card{id: h.Atoi(pts[1]), totalCardsWon: -1}
|
||||
winners := true
|
||||
for _, s := range pts[2:] {
|
||||
if s == "|" {
|
||||
winners = false
|
||||
} else {
|
||||
if winners {
|
||||
ret.winners = append(ret.winners, h.Atoi(s))
|
||||
} else {
|
||||
ret.numbers = append(ret.numbers, h.Atoi(s))
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, w := range ret.winners {
|
||||
for _, n := range ret.numbers {
|
||||
skip := h.IntSliceContains(ret.winsCards, w)
|
||||
if n == w && !skip {
|
||||
ret.winsCards = append(ret.winsCards, w)
|
||||
}
|
||||
if skip {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &ret
|
||||
}
|
||||
|
||||
func (c *Card) Value() int {
|
||||
return int(math.Pow(2, float64(len(c.winsCards)-1)))
|
||||
}
|
||||
|
||||
func (c *Card) TotalCardsWon(cm map[int]*Card) int {
|
||||
if c.totalCardsWon != -1 {
|
||||
return c.totalCardsWon
|
||||
}
|
||||
result := len(c.winsCards)
|
||||
// TODO: It doesn't with cards that match the ID,
|
||||
// it wins X cards increasing from the current cards ID
|
||||
// where x is the number of winning numbers matched
|
||||
for i := 1; i <= len(c.winsCards); i++ {
|
||||
if v, ok := cm[c.id+i]; ok {
|
||||
result += v.TotalCardsWon(cm)
|
||||
}
|
||||
}
|
||||
c.totalCardsWon = result
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user