2021 - Day 4 (Compacted solution)

This commit is contained in:
Dreaded_X 2021-12-04 21:56:52 +01:00
parent 54ca341d0a
commit 54a19892dd
2 changed files with 68 additions and 106 deletions

View File

@ -1,4 +1,4 @@
module AoC/2021/3 module AoC/2021/4
require AoC/2021/common v0.0.0 require AoC/2021/common v0.0.0

View File

@ -14,6 +14,7 @@ type Card struct {
column [5]int column [5]int
} }
// Remove empty entries
func filter(in []string) []string { func filter(in []string) []string {
n := 0 n := 0
for _, s := range in { for _, s := range in {
@ -74,17 +75,23 @@ func findLosing(numbers []int, cards []Card) (int, []int) {
if cards[j].row[row] == 5 || cards[j].column[column] == 5 { if cards[j].row[row] == 5 || cards[j].column[column] == 5 {
hasWon = true hasWon = true
// If this is the last cardm then it is the one we are looking for
if len(cards) == 1 { if len(cards) == 1 {
return n, cards[j].numbers return n, cards[j].numbers
} }
} }
} }
} }
// Keep the card if it has not won
if !hasWon { if !hasWon {
cards[i] = cards[j] cards[i] = cards[j]
i++ i++
} }
} }
// Truncate the array of cards
cards = cards[:i] cards = cards[:i]
} }
@ -93,6 +100,64 @@ func findLosing(numbers []int, cards []Card) (int, []int) {
return -1, nil return -1, nil
} }
func solution(selector func (number []int, cards []Card) (winning int, numbers []int)) (func (*bufio.Scanner) int) {
return func (input *bufio.Scanner) int {
// Read in the drawn numbers
input.Scan()
line := input.Text()
var numbers []int
for _, num := range strings.Split(line, ",") {
n, err := strconv.Atoi(num)
if err != nil {
panic(err)
}
numbers = append(numbers, n)
}
// Read in all the cards
var cards []Card
var rowNumber int
cardIndex := -1
for input.Scan() {
line = input.Text()
// A new line means that we start a new card
if len(line) == 0 {
card := Card{}
cards = append(cards, card)
rowNumber = 0
cardIndex++
} else {
row := filter(strings.Split(line, " "))
for _, num := range row {
n, err := strconv.Atoi(num)
if err != nil {
panic(err)
}
cards[cardIndex].numbers = append(cards[cardIndex].numbers, n)
}
rowNumber++
}
}
// Play bingo and find the desired card and winnnig number
winning, unmarked := selector(numbers, cards)
// Calculate the sum of unmarked numbers
sum := 0
for _, n := range unmarked {
if n != -1 {
sum += n
}
}
return winning*sum
}
}
func main() { func main() {
aoc := aoc.New(2021, 4) aoc := aoc.New(2021, 4)
@ -118,109 +183,6 @@ func main() {
2 0 12 3 7 2 0 12 3 7
`, []int{4512, 1924}) `, []int{4512, 1924})
aoc.Solution(1, func (input *bufio.Scanner) int { aoc.Solution(1, solution(findWinner))
input.Scan() aoc.Solution(2, solution(findLosing))
line := input.Text()
var numbers []int
for _, num := range strings.Split(line, ",") {
n, err := strconv.Atoi(num)
if err != nil {
panic(err)
}
numbers = append(numbers, n)
}
var cards []Card
var rowNumber int
cardIndex := -1
for input.Scan() {
line = input.Text()
// A new line means that we start a new card
if len(line) == 0 {
card := Card{}
card.numbers = make([]int, 25)
cards = append(cards, card)
rowNumber = 0
cardIndex++
} else {
row := filter(strings.Split(line, " "))
for i, num := range row {
n, err := strconv.Atoi(num)
if err != nil {
panic(err)
}
cards[cardIndex].numbers[5*rowNumber + i] = n
}
rowNumber++
}
}
winning, unmarked := findWinner(numbers, cards)
sum := 0
for _, n := range unmarked {
if n != -1 {
sum += n
}
}
return winning*sum
})
aoc.Solution(2, func (input *bufio.Scanner) int {
input.Scan()
line := input.Text()
var numbers []int
for _, num := range strings.Split(line, ",") {
n, err := strconv.Atoi(num)
if err != nil {
panic(err)
}
numbers = append(numbers, n)
}
var cards []Card
var rowNumber int
cardIndex := -1
for input.Scan() {
line = input.Text()
// A new line means that we start a new card
if len(line) == 0 {
card := Card{}
card.numbers = make([]int, 25)
cards = append(cards, card)
rowNumber = 0
cardIndex++
} else {
row := filter(strings.Split(line, " "))
for i, num := range row {
n, err := strconv.Atoi(num)
if err != nil {
panic(err)
}
cards[cardIndex].numbers[5*rowNumber + i] = n
}
rowNumber++
}
}
winning, unmarked := findLosing(numbers, cards)
sum := 0
for _, n := range unmarked {
if n != -1 {
sum += n
}
}
return winning*sum
})
} }