d4 and d4p4
This commit is contained in:
parent
a9d9d67a46
commit
72dc38807d
3 changed files with 192 additions and 1 deletions
132
d4/d4.go
Normal file
132
d4/d4.go
Normal file
|
@ -0,0 +1,132 @@
|
|||
package d4
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type cell struct {
|
||||
value int
|
||||
marked bool
|
||||
}
|
||||
|
||||
type board []cell
|
||||
|
||||
const SIDE_SIZE = 5
|
||||
|
||||
func createBoards(rawBoards []string) []board {
|
||||
boards := make([]board, len(rawBoards))
|
||||
|
||||
for i, rawBoard := range rawBoards {
|
||||
for _, cellRow := range strings.Split(rawBoard, "\n") {
|
||||
for _, rawCell := range strings.Split(cellRow, " ") {
|
||||
if rawCell != "" {
|
||||
value, _ := strconv.Atoi(rawCell)
|
||||
boards[i] = append(boards[i], cell{value, false})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return boards
|
||||
}
|
||||
|
||||
func markBoard(b board, take int) board {
|
||||
for i := range b {
|
||||
if b[i].value == take {
|
||||
b[i].marked = true
|
||||
}
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
func gotBingo(b board) bool {
|
||||
|
||||
for i := 0; i < SIDE_SIZE; i++ {
|
||||
if b[i*SIDE_SIZE].marked &&
|
||||
b[i*SIDE_SIZE+1].marked &&
|
||||
b[i*SIDE_SIZE+2].marked &&
|
||||
b[i*SIDE_SIZE+3].marked &&
|
||||
b[i*SIDE_SIZE+4].marked {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
for j := 0; j < SIDE_SIZE; j++ {
|
||||
if b[j].marked &&
|
||||
b[j+SIDE_SIZE].marked &&
|
||||
b[j+SIDE_SIZE*2].marked &&
|
||||
b[j+SIDE_SIZE*3].marked &&
|
||||
b[j+SIDE_SIZE*4].marked {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func findBingo(boards []board, takes []string) (board, int) {
|
||||
|
||||
for _, take := range takes {
|
||||
converted, _ := strconv.Atoi(take)
|
||||
for _, board := range boards {
|
||||
marked := markBoard(board, converted)
|
||||
if gotBingo(marked) {
|
||||
return marked, converted
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
func findBingo2(boards []board, takes []string) (board, int) {
|
||||
bingos := make(map[*board]int)
|
||||
wins := []*board{}
|
||||
for _, take := range takes {
|
||||
converted, _ := strconv.Atoi(take)
|
||||
for boardIndex := range boards {
|
||||
board := &boards[boardIndex]
|
||||
if _, ok := bingos[board]; !ok {
|
||||
marked := markBoard(*board, converted)
|
||||
if gotBingo(marked) {
|
||||
bingos[board] = converted
|
||||
wins = append(wins, board)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *wins[len(wins)-1], bingos[wins[len(wins)-1]]
|
||||
}
|
||||
|
||||
func score(b board, take int) int {
|
||||
sum := 0
|
||||
|
||||
for _, cell := range b {
|
||||
if !cell.marked {
|
||||
sum += cell.value
|
||||
}
|
||||
}
|
||||
|
||||
return sum * take
|
||||
}
|
||||
|
||||
func D4(input string) int {
|
||||
lines := strings.Split(input, "\n\n")
|
||||
takes := strings.Split(lines[0], ",")
|
||||
boards := createBoards(lines[1:])
|
||||
bingo, take := findBingo(boards, takes)
|
||||
|
||||
return score(bingo, take)
|
||||
}
|
||||
|
||||
func D4P2(input string) int {
|
||||
lines := strings.Split(input, "\n\n")
|
||||
takes := strings.Split(lines[0], ",")
|
||||
boards := createBoards(lines[1:])
|
||||
bingo, take := findBingo2(boards, takes)
|
||||
|
||||
return score(bingo, take)
|
||||
}
|
57
d4/d4_test.go
Normal file
57
d4/d4_test.go
Normal file
|
@ -0,0 +1,57 @@
|
|||
package d4
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestD4(t *testing.T) {
|
||||
input := `7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
|
||||
|
||||
22 13 17 11 0
|
||||
8 2 23 4 24
|
||||
21 9 14 16 7
|
||||
6 10 3 18 5
|
||||
1 12 20 15 19
|
||||
|
||||
3 15 0 2 22
|
||||
9 18 13 17 5
|
||||
19 8 7 25 23
|
||||
20 11 10 24 4
|
||||
14 21 16 12 6
|
||||
|
||||
14 21 17 24 4
|
||||
10 16 15 9 19
|
||||
18 8 23 26 20
|
||||
22 11 13 6 5
|
||||
2 0 12 3 7
|
||||
`
|
||||
|
||||
assert.EqualValues(t, 4512, D4(input))
|
||||
}
|
||||
|
||||
func TestD4P2(t *testing.T) {
|
||||
input := `7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
|
||||
|
||||
22 13 17 11 0
|
||||
8 2 23 4 24
|
||||
21 9 14 16 7
|
||||
6 10 3 18 5
|
||||
1 12 20 15 19
|
||||
|
||||
3 15 0 2 22
|
||||
9 18 13 17 5
|
||||
19 8 7 25 23
|
||||
20 11 10 24 4
|
||||
14 21 16 12 6
|
||||
|
||||
14 21 17 24 4
|
||||
10 16 15 9 19
|
||||
18 8 23 26 20
|
||||
22 11 13 6 5
|
||||
2 0 12 3 7
|
||||
`
|
||||
|
||||
assert.EqualValues(t, 1924, D4P2(input))
|
||||
}
|
4
main.go
4
main.go
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/fotonmoton/aoc2021/d1"
|
||||
"github.com/fotonmoton/aoc2021/d2"
|
||||
"github.com/fotonmoton/aoc2021/d3"
|
||||
"github.com/fotonmoton/aoc2021/d4"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -28,5 +29,6 @@ func main() {
|
|||
fmt.Printf("day 2 part 2: %v\n", d2.D2P2(client.Day(2)))
|
||||
fmt.Printf("day 3: %v\n", d3.D3(client.Day(3)))
|
||||
fmt.Printf("day 3 part 2: %v\n", d3.D3P2(client.Day(3)))
|
||||
|
||||
fmt.Printf("day 4: %v\n", d4.D4(client.Day(4)))
|
||||
fmt.Printf("day 4 part 2: %v\n", d4.D4P2(client.Day(4)))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue