chore: add day13
All checks were successful
Go Bump / bump (push) Successful in 7s
Go Test / build (push) Successful in 33s

This commit is contained in:
xuu 2023-12-14 08:31:57 -07:00
parent 6fce822def
commit 142a8dc00f
Signed by: xuu
GPG Key ID: 8B3B0604F164E04F
6 changed files with 1555 additions and 0 deletions

15
day13/example.txt Normal file
View File

@ -0,0 +1,15 @@
#.##..##.
..#.##.#.
##......#
##......#
..#.##.#.
..##..##.
#.#.##.#.
#...##..#
#....#..#
..##..###
#####.##.
#####.##.
..##..###
#....#..#

7
day13/example00.txt Normal file
View File

@ -0,0 +1,7 @@
#.##..##.
..#.##.#.
##......#
##......#
..#.##.#.
..##..##.
#.#.##.#.

1301
day13/input.txt Normal file

File diff suppressed because it is too large Load Diff

11
day13/input07.txt Normal file
View File

@ -0,0 +1,11 @@
##.#.##.#
...#..#..
.##...#..
.##...#..
.#.#..#..
##.#.##.#
.#...####
..#.#..##
...#...##
.#....#.#
.#....#.#

179
day13/main.go Normal file
View File

@ -0,0 +1,179 @@
package main
import (
"bufio"
_ "embed"
"fmt"
"strings"
aoc "go.sour.is/advent-of-code-2023"
)
var log = aoc.Log
func main() { aoc.MustResult(aoc.Runner(run)) }
type result struct {
valuePT1 int
valuePT2 int
}
func (r result) String() string { return fmt.Sprintf("%#v", r) }
func run(scan *bufio.Scanner) (*result, error) {
maps := []Map{}
m := Map{}
r := &result{}
for scan.Scan() {
text := scan.Text()
if text == "" {
maps = append(maps, m)
m = Map{}
} else {
m = append(m, []rune(text))
}
}
maps = append(maps, m)
for _, m := range maps {
sum, sum2 := findSmudge(m)
if sum == -1 || sum2 == -1 {
mr := Map(aoc.Transpose(m))
Hsum, Hsum2 := findSmudge(mr)
if sum2 == -1 {
sum2 = Hsum2 * 100
}
if sum == -1 {
sum = Hsum * 100
}
}
r.valuePT1 += sum
r.valuePT2 += sum2
}
return r, nil
}
type Map [][]rune
func (m Map) String() string {
var buf strings.Builder
for i, row := range m {
if i == 0 {
fmt.Fprint(&buf, " ")
for j := range row {
fmt.Fprintf(&buf, "%d", j)
}
fmt.Fprint(&buf, "\n")
}
fmt.Fprintf(&buf, "%d ", i)
buf.WriteRune(' ')
buf.WriteString(string(row))
buf.WriteRune('\n')
}
buf.WriteRune('\n')
return buf.String()
}
// func findReflection(m Map) (int, bool) {
// candidates := make(map[int]bool)
// var candidateList []int
// for _, row := range m {
// for col := 1; col < len(row); col++ {
// if v, ok := candidates[col]; !ok || v {
// candidates[col], _ = reflects(row[:col], row[col:])
// }
// }
// candidateList = all(candidates)
// if len(candidateList) == 0 {
// return 0, false
// }
// }
// if len(candidateList) == 1 {
// return candidateList[0], true
// }
// return 0, false
// }
type level struct {
blips int
nequal int
fail bool
}
func findSmudge(m Map) (int, int) {
candidates := make(map[int]level)
for _, row := range m {
for col := 1; col < len(row); col++ {
candidate := candidates[col]
if candidate.fail {
continue
}
eq, bl := reflects(row[:col], row[col:])
if !eq {
candidate.nequal++
}
candidate.blips += bl
if candidate.nequal > 1 || candidate.blips > 1 {
candidate.fail = true
}
candidates[col] = candidate
}
}
a, b := -1, -1
for i, cand := range candidates {
if !cand.fail && cand.blips == 1 {
b = i
}
if !cand.fail && cand.blips == 0 {
a = i
}
}
return a, b
}
func reflects(a, b []rune) (bool, int) {
c := min(len(a), len(b))
a = append([]rune{}, a...)
b = append([]rune{}, b...)
aoc.Reverse(a)
a = a[:c]
b = b[:c]
blips := 0
for i := range a {
if a[i] != b[i] {
blips++
}
}
return blips == 0, blips
}
func all[T comparable](m map[T]bool) []T {
lis := make([]T, 0, len(m))
for k, v := range m {
if v {
lis = append(lis, k)
}
}
return lis
}

42
day13/main_test.go Normal file
View File

@ -0,0 +1,42 @@
package main
import (
"bufio"
"bytes"
"testing"
_ "embed"
"github.com/matryer/is"
)
//go:embed example.txt
var example []byte
//go:embed input.txt
var input []byte
func TestExample(t *testing.T) {
is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(example))
result, err := run(scan)
is.NoErr(err)
t.Log(result)
is.Equal(result.valuePT1, 405)
is.Equal(result.valuePT2, 400)
}
func TestSolution(t *testing.T) {
is := is.New(t)
scan := bufio.NewScanner(bytes.NewReader(input))
result, err := run(scan)
is.NoErr(err)
t.Log(result)
is.True(result.valuePT1 > 1704) // attempt 1
is.Equal(result.valuePT1, 30705)
is.Equal(result.valuePT2, 44615)
}