Archived
add 4th december solutions
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user