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 (
|
||||
"bufio"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ReadLines(path string) (lines []string) {
|
||||
|
|
@ -18,3 +20,19 @@ func ReadLines(path string) (lines []string) {
|
|||
}
|
||||
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
|
||||
|
||||
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