175 lines
3.9 KiB
Go
175 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/thoas/go-funk"
|
|
)
|
|
|
|
func main() {
|
|
inputBytes, _ := os.ReadFile("input.txt")
|
|
inputs := strings.Split(string(inputBytes), "\n")
|
|
|
|
log.Println("Puzzle 1:", puzzle1(inputs))
|
|
log.Println("Puzzle 2:", puzzle2(inputs))
|
|
}
|
|
|
|
func puzzle1(input []string) int {
|
|
called, bingos := parseBingos(input)
|
|
// Iterate through called numbers
|
|
lastCalledNumber := -1
|
|
firstBingo := -1
|
|
callnumbers:
|
|
for _, calledNumber := range called {
|
|
lastCalledNumber = calledNumber
|
|
// Replace called number in every bingo with -1
|
|
for _, bingo := range bingos {
|
|
for i := 0; i < 5; i++ {
|
|
for j := 0; j < 5; j++ {
|
|
if bingo[i][j] == calledNumber {
|
|
bingo[i][j] = -1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Check if any bingo has row or column with sum of just 0
|
|
for b, bingo := range bingos {
|
|
// Check rows
|
|
for i := 0; i < 5; i++ {
|
|
if funk.SumInt(bingo[i]) == -5 {
|
|
firstBingo = b
|
|
break callnumbers
|
|
}
|
|
}
|
|
// Check columns
|
|
for i := 0; i < 5; i++ {
|
|
if bingo[0][i]+bingo[1][i]+bingo[2][i]+bingo[3][i]+bingo[4][i] == -5 {
|
|
firstBingo = b
|
|
break callnumbers
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Get sum of remaining numbers in first bingo
|
|
sum := 0
|
|
for _, row := range bingos[firstBingo] {
|
|
for _, number := range row {
|
|
if number != -1 {
|
|
sum += number
|
|
}
|
|
}
|
|
}
|
|
// Return product of sum and last called number
|
|
return sum * lastCalledNumber
|
|
}
|
|
|
|
func puzzle2(input []string) int {
|
|
called, bingos := parseBingos(input)
|
|
// Iterate through called numbers
|
|
lastCalledNumber := -1
|
|
solvedBingos := []int{}
|
|
lastSolvedBingo := -1
|
|
callnumbers:
|
|
for _, calledNumber := range called {
|
|
lastCalledNumber = calledNumber
|
|
// Replace called number in every bingo with -1
|
|
for _, bingo := range bingos {
|
|
for i := 0; i < 5; i++ {
|
|
for j := 0; j < 5; j++ {
|
|
if bingo[i][j] == calledNumber {
|
|
bingo[i][j] = -1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Check if any bingo has row or column with sum of just 0
|
|
bingoiter:
|
|
for b, bingo := range bingos {
|
|
// Skip solved bingos
|
|
if funk.ContainsInt(solvedBingos, b) {
|
|
continue bingoiter
|
|
}
|
|
// Check rows
|
|
for i := 0; i < 5; i++ {
|
|
if funk.SumInt(bingo[i]) == -5 {
|
|
// Add bingo to solved bingos
|
|
solvedBingos = append(solvedBingos, b)
|
|
lastSolvedBingo = b
|
|
continue bingoiter
|
|
}
|
|
}
|
|
// Check columns
|
|
for i := 0; i < 5; i++ {
|
|
if bingo[0][i]+bingo[1][i]+bingo[2][i]+bingo[3][i]+bingo[4][i] == -5 {
|
|
// Add bingo to solved bingos
|
|
solvedBingos = append(solvedBingos, b)
|
|
lastSolvedBingo = b
|
|
continue bingoiter
|
|
}
|
|
}
|
|
}
|
|
// Check if all bingos but are solved
|
|
if len(bingos) == len(solvedBingos) {
|
|
break callnumbers
|
|
}
|
|
}
|
|
// Get sum of remaining numbers in last solved bingo
|
|
sum := 0
|
|
for _, row := range bingos[lastSolvedBingo] {
|
|
for _, number := range row {
|
|
if number != -1 {
|
|
sum += number
|
|
}
|
|
}
|
|
}
|
|
// Return product of sum and last called number
|
|
return sum * lastCalledNumber
|
|
}
|
|
|
|
func parseBingos(input []string) (called []int, bingos [][][]int) {
|
|
// Parse called numbers
|
|
called = []int{}
|
|
for _, number := range strings.Split(input[0], ",") {
|
|
no, _ := strconv.Atoi(number)
|
|
called = append(called, no)
|
|
}
|
|
// Parse bingos
|
|
bingos = [][][]int{}
|
|
bingoCurrentRow := 0
|
|
currentBingo := [][]int{}
|
|
for _, line := range input[2:] {
|
|
// Trim spaces
|
|
line = strings.TrimSpace(line)
|
|
// Replace double spaces with single spaces
|
|
line = strings.ReplaceAll(line, " ", " ")
|
|
// Check if line is empty
|
|
if line == "" {
|
|
continue
|
|
}
|
|
// Parse row
|
|
row := []int{}
|
|
for i, number := range strings.Split(line, " ") {
|
|
if i > 4 {
|
|
break
|
|
}
|
|
no, _ := strconv.Atoi(number)
|
|
row = append(row, no)
|
|
}
|
|
// Add row to bingo
|
|
currentBingo = append(currentBingo, row)
|
|
// Check if bingo is complete
|
|
if bingoCurrentRow == 4 {
|
|
bingos = append(bingos, currentBingo)
|
|
bingoCurrentRow = 0
|
|
currentBingo = [][]int{}
|
|
} else {
|
|
bingoCurrentRow++
|
|
}
|
|
}
|
|
// Return called numbers and bingos
|
|
return
|
|
}
|