This commit is contained in:
onyx-and-iris 2023-12-14 03:44:14 +00:00
parent 8b61fa2011
commit 0fc0c49387
8 changed files with 253 additions and 0 deletions

3
day-13/go.mod Normal file
View File

@ -0,0 +1,3 @@
module github.com/onyx-and-iris/aoc2023/day-13
go 1.21.5

33
day-13/image.go Normal file
View File

@ -0,0 +1,33 @@
package main
type imgs struct {
img []img
}
func newImages() imgs {
return imgs{img: make([]img, 0)}
}
type img struct {
raw []string
}
func newImg() img {
return img{raw: make([]string, 0)}
}
func (i img) transposed() []string {
transposed := []string{}
for x := 0; x < len(i.raw[0]); x++ {
buf := ""
for j := len(i.raw) - 1; j >= 0; j-- {
buf += string(i.raw[j][x])
}
transposed = append(transposed, buf)
}
return transposed
}
var images imgs

10
day-13/makefile Normal file
View File

@ -0,0 +1,10 @@
TEST="test.txt"
INPUT="input.txt"
test:
cat $(TEST) | go run .
run:
cat $(INPUT) | go run .
all: test

62
day-13/one.go Normal file
View File

@ -0,0 +1,62 @@
package main
import (
"strings"
log "github.com/sirupsen/logrus"
)
// findReflection returns the reflection point for an image
func findReflection(image []string) (int, bool) {
walkToEdge := func(lower, upper int) bool {
for lower >= 0 && upper < len(image) && strings.Compare(image[lower], image[upper]) == 0 {
lower--
upper++
}
lower++
return (lower == 0 || upper == len(image))
}
for i := 0; i < len(image)-1; i++ {
if strings.Compare(image[i], image[i+1]) == 0 {
log.Debug("start point: ", image[i], " vs ", image[i+1])
if walkToEdge(i, i+1) {
return i, true
}
}
}
return 0, false
}
// horizontalReflection returns the reflection point of a horizontal mirror
func horizontalReflection(image img, fn func(image []string) (int, bool)) (int, bool) {
n, ok := fn(image.raw)
return n, ok
}
// verticalReflection returns the reflection point of a vertical mirror
func verticalReflection(image img, fn func(image []string) (int, bool)) (int, bool) {
n, ok := fn(image.transposed())
return n, ok
}
// one returns a calculation based on reflection points for all images.
func one(lines []string) int {
parselines(lines)
sum := 0
for _, image := range images.img {
log.Debug("checking for horizontal reflection")
n, ok := horizontalReflection(image, findReflection)
if ok {
sum += 100 * (n + 1)
}
log.Debug("checking for vertical reflection")
n, ok = verticalReflection(image, findReflection)
if ok {
sum += (n + 1)
}
}
return sum
}

19
day-13/one_test.go Normal file
View File

@ -0,0 +1,19 @@
package main
import (
"testing"
"github.com/go-playground/assert"
)
func TestCompare(t *testing.T) {
//t.Skip("skipping test")
img := newImg()
img.raw = []string{"#.##", "..#.", "##.."}
expected := []string{"#.#", "#..", ".##", "..#"}
t.Run("Should flip the image ninety degrees rightwards", func(t *testing.T) {
assert.Equal(t, expected, img.transposed())
})
}

21
day-13/solution.go Normal file
View File

@ -0,0 +1,21 @@
package main
import (
"fmt"
log "github.com/sirupsen/logrus"
)
func init() {
log.SetLevel(log.InfoLevel)
}
func main() {
lines := readlines()
ans := one(lines)
fmt.Printf("solution one: %d\n", ans)
ans = two(lines)
fmt.Printf("solution two: %d\n", ans)
}

48
day-13/two.go Normal file
View File

@ -0,0 +1,48 @@
package main
import (
log "github.com/sirupsen/logrus"
)
// findReflectionWithDifference returns the reflection point for an image with one smudge
func findReflectionWithDifference(image []string) (int, bool) {
walkToEdge := func(lower, upper int) bool {
diffs := 0
for lower >= 0 && upper < len(image) {
n := numDiffs(image[lower], image[upper])
log.Debug(n, " difference(s) found at line ", lower)
diffs += n
lower--
upper++
}
lower++
return diffs == 1
}
for i := 0; i < len(image)-1; i++ {
log.Debug("start point: ", image[i], " vs ", image[i+1])
if walkToEdge(i, i+1) {
return i, true
}
}
return 0, false
}
// two returns a calculation based on reflection points for all images with one smudge
func two(lines []string) int {
sum := 0
for _, image := range images.img {
log.Debug("checking for horizontal reflection")
n, ok := horizontalReflection(image, findReflectionWithDifference)
if ok {
sum += 100 * (n + 1)
}
log.Debug("checking for vertical reflection")
n, ok = verticalReflection(image, findReflectionWithDifference)
if ok {
sum += (n + 1)
}
}
return sum
}

57
day-13/util.go Normal file
View File

@ -0,0 +1,57 @@
package main
import (
"bufio"
"log"
"os"
)
// readlines reads lines from stdin.
// it returns them as an array of strings
func readlines() []string {
lines := []string{}
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
lines = append(lines, scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
return lines
}
// parselines stores each image into an images struct
func parselines(lines []string) {
addImage := func(i int) int {
image := newImg()
for ; i < len(lines); i++ {
if len(lines[i]) == 0 {
break
}
image.raw = append(image.raw, lines[i])
}
images.img = append(images.img, image)
return i
}
images = newImages()
for i := 0; i < len(lines); i++ {
next := addImage(i)
i = next
}
}
// numDiffs returns the number of difference between two strings
func numDiffs(a, b string) int {
diff := 0
for i := range a {
if a[i] != b[i] {
diff++
}
}
return diff
}