This repository has been archived on 2021-12-06. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
adventofcode/pkg/four/four.go
T

178 lines
3.6 KiB
Go
Raw Normal View History

2021-12-05 10:11:42 +01:00
package four
import (
"bufio"
"fmt"
"log"
"os"
"strconv"
"strings"
)
func Run() {
draws, boards := readInput()
fmt.Printf("1st winning board: %d\n", calculateWinningBoard(findFirstWinningBoard(boards, createPlayboards(boards), draws)))
fmt.Printf("2nd winning board: %d\n", calculateWinningBoard(findLastWinningBoard(boards, createPlayboards(boards), draws)))
}
func calculateWinningBoard(board [][]int, playboard [][]bool, draw int) int {
r := 0
for i, row := range playboard {
for j, val := range row {
if !val {
r += board[i][j]
}
}
}
return r * draw
}
func isIntInSlice(i int, slice []int) bool {
for _, v := range slice {
if i == v {
return true
}
}
return false
}
func findLastWinningBoard(boards [][][]int, playboard [][][]bool, draws []int) ([][]int, [][]bool, int) {
winners := make([]int, 0)
for _, draw := range draws {
for i, board := range boards {
for j, row := range board {
for k, num := range row {
if num == draw {
playboard[i][j][k] = true
if !isIntInSlice(i, winners) && checkIfWinner(playboard[i]) {
winners = append(winners, i)
if len(winners) == len(boards) {
return board, playboard[i], draw
}
}
}
}
}
}
}
return nil, nil, 0
}
func findFirstWinningBoard(boards [][][]int, playboard [][][]bool, draws []int) ([][]int, [][]bool, int) {
for _, draw := range draws {
for i, board := range boards {
for j, row := range board {
for k, num := range row {
if num == draw {
playboard[i][j][k] = true
if checkIfWinner(playboard[i]) {
return board, playboard[i], draw
}
}
}
}
}
}
return nil, nil, 0
}
func checkIfWinner(board [][]bool) bool {
// check horizontals
var checks int
for _, row := range board { // rows
checks = 0
for _, v := range row {
if v {
checks++
}
}
if checks == len(row) {
return true
}
}
for i := 0; i < len(board[0]); i++ {
checks = 0
for j := 0; j < len(board); j++ {
if board[j][i] == true {
checks++
}
}
if checks == len(board) {
return true
}
}
return false
}
func createPlayboards(boards [][][]int) [][][]bool {
playboard := make([][][]bool, len(boards))
for i := range playboard {
playboard[i] = make([][]bool, len(boards[0]))
for j := range playboard[i] {
playboard[i][j] = make([]bool, len(boards[0][0]))
}
}
return playboard
}
func readInput() ([]int, [][][]int) {
file, err := os.Open("./pkg/four/input.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
boards := make([][][]int, 0)
scanner := bufio.NewScanner(file)
// first line are the draws
scanner.Scan()
drawsString := scanner.Text()
draws := make([]int, 0)
for _, v := range strings.Split(drawsString, ",") {
n, err := strconv.Atoi(v)
if err != nil {
log.Fatal(err)
}
draws = append(draws, n)
}
scanner.Scan()
board := *new([][]int)
for scanner.Scan() {
if scanner.Text() == "" {
boards = append(boards, board)
board = *new([][]int)
continue
}
currentLine := scanner.Text()
currentLine = strings.ReplaceAll(currentLine, " ", " ")
if len(currentLine) > 0 && currentLine[0] == ' ' {
currentLine = strings.Replace(currentLine, " ", "", 1)
}
splitCurrentLine := strings.Split(currentLine, " ")
row := *new([]int)
for i := 0; i < len(splitCurrentLine); i++ {
x, err := strconv.Atoi(splitCurrentLine[i])
if err != nil {
log.Fatal(err)
}
row = append(row, x)
}
board = append(board, row)
}
boards = append(boards, board)
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
return draws, boards
}