2021 Day 4
This commit is contained in:
parent
c13f4ca236
commit
739b9080ab
4 changed files with 185 additions and 0 deletions
|
|
@ -3,6 +3,8 @@ package aoc
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func ReadLines(path string) (lines []string) {
|
func ReadLines(path string) (lines []string) {
|
||||||
|
|
@ -18,3 +20,19 @@ func ReadLines(path string) (lines []string) {
|
||||||
}
|
}
|
||||||
return lines
|
return lines
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ReadFile(path string) string {
|
||||||
|
b, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(string(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
func MustInt(s string) int {
|
||||||
|
i, err := strconv.Atoi(s)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
|
|
||||||
148
2021/day4/main.go
Normal file
148
2021/day4/main.go
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
"github.com/jdkaplan/advent-of-code/aoc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type input struct {
|
||||||
|
numbers []int
|
||||||
|
boards []board
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseInput(text string) input {
|
||||||
|
sections := strings.Split(text, "\n\n")
|
||||||
|
var nums []int
|
||||||
|
for _, n := range strings.Split(sections[0], ",") {
|
||||||
|
nums = append(nums, aoc.MustInt(n))
|
||||||
|
}
|
||||||
|
var boards []board
|
||||||
|
for _, block := range sections[1:] {
|
||||||
|
b := newBoard()
|
||||||
|
for r, row := range strings.Split(block, "\n") {
|
||||||
|
for c, n := range strings.Fields(row) {
|
||||||
|
b.nums[r][c] = aoc.MustInt(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
boards = append(boards, b)
|
||||||
|
}
|
||||||
|
return input{numbers: nums, boards: boards}
|
||||||
|
}
|
||||||
|
|
||||||
|
type board struct {
|
||||||
|
nums *[5][5]int
|
||||||
|
marked *[5][5]bool
|
||||||
|
won bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBoard() board {
|
||||||
|
return board{
|
||||||
|
nums: &[5][5]int{},
|
||||||
|
marked: &[5][5]bool{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b board) String() string {
|
||||||
|
var s strings.Builder
|
||||||
|
for r, row := range b.nums {
|
||||||
|
for c, n := range row {
|
||||||
|
if b.marked[r][c] {
|
||||||
|
color.New(color.FgGreen, color.Bold).Fprintf(&s, "%2d ", n)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(&s, "%2d ", n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s.WriteRune('\n')
|
||||||
|
}
|
||||||
|
return s.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *board) call(x int) (win bool) {
|
||||||
|
if b.won {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for r, row := range b.nums {
|
||||||
|
for c, n := range row {
|
||||||
|
if n == x {
|
||||||
|
b.marked[r][c] = true
|
||||||
|
if b.win(r, c) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b board) win(r, c int) bool {
|
||||||
|
return b.winRow(r) || b.winCol(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b board) winRow(r int) bool {
|
||||||
|
for c := 0; c < 5; c++ {
|
||||||
|
if !b.marked[r][c] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b board) winCol(c int) bool {
|
||||||
|
for r := 0; r < 5; r++ {
|
||||||
|
if !b.marked[r][c] {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b board) score(x int) int {
|
||||||
|
var sum int
|
||||||
|
for r, row := range b.nums {
|
||||||
|
for c, n := range row {
|
||||||
|
if !b.marked[r][c] {
|
||||||
|
sum += n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return x * sum
|
||||||
|
}
|
||||||
|
|
||||||
|
func part1(text string) int {
|
||||||
|
inp := parseInput(text)
|
||||||
|
for _, n := range inp.numbers {
|
||||||
|
for _, b := range inp.boards {
|
||||||
|
if b.call(n) {
|
||||||
|
return b.score(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len(inp.numbers)
|
||||||
|
}
|
||||||
|
|
||||||
|
func part2(text string) int {
|
||||||
|
inp := parseInput(text)
|
||||||
|
var wins int
|
||||||
|
for _, n := range inp.numbers {
|
||||||
|
for i, b := range inp.boards {
|
||||||
|
if b.call(n) {
|
||||||
|
// Set on the original in inp, not the copy in b.
|
||||||
|
inp.boards[i].won = true
|
||||||
|
wins++
|
||||||
|
if wins == len(inp.boards) {
|
||||||
|
return b.score(n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return len(inp.numbers)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
text := aoc.ReadFile("./input/day4.txt")
|
||||||
|
fmt.Println(part1(text))
|
||||||
|
fmt.Println(part2(text))
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
module github.com/jdkaplan/advent-of-code
|
module github.com/jdkaplan/advent-of-code
|
||||||
|
|
||||||
go 1.17
|
go 1.17
|
||||||
|
|
||||||
|
require github.com/fatih/color v1.13.0
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/mattn/go-colorable v0.1.9 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
|
||||||
|
)
|
||||||
|
|
|
||||||
11
2021/go.sum
11
2021/go.sum
|
|
@ -0,0 +1,11 @@
|
||||||
|
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||||
|
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||||
|
github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
|
||||||
|
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||||
|
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||||
|
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||||
|
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||||
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
|
||||||
|
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
Loading…
Reference in a new issue