AoC Day 13, Parts 1 and 2 (Solved)

This commit is contained in:
🐙PiperYxzzy
2023-12-13 08:20:44 +02:00
parent 40e94bec64
commit 72b4d8c16c
4 changed files with 1696 additions and 0 deletions

202
2023/13/code.go Normal file
View File

@@ -0,0 +1,202 @@
package main
import (
"strings"
"github.com/jpillora/puzzler/harness/aoc"
)
func main() {
aoc.Harness(run)
}
// on code change, run will be executed 4 times:
// 1. with: false (part1), and example input
// 2. with: true (part2), and example input
// 3. with: false (part1), and user input
// 4. with: true (part2), and user input
// the return value of each run is printed to stdout
func run(part2 bool, input string) any {
// when you're ready to do part 2, remove this "not implemented" block
grids := make([][][]rune, 0)
thisGrid := make([][]rune, 0)
for _, l := range strings.Split(input, "\n") {
if l == "" {
grids = append(grids, thisGrid)
thisGrid = make([][]rune, 0)
continue
}
thisGridLine := make([]rune, 0)
for _, r := range strings.Split(l, "") {
thisGridLine = append(thisGridLine, rune(r[0]))
}
thisGrid = append(thisGrid, thisGridLine)
}
if part2 {
sum := 0
for _, g := range grids {
cv, ch := calcReflectionRemainder(g, -1, -1)
found := false
calcGrid:
for v := range g {
for h := range g[v] {
//fmt.Printf("Smudging [%v, %v]...", v, h)
if g[v][h] == '.' {
// try fix the smudge!
g[v][h] = '#'
nv, nh := calcReflectionRemainder(g, cv, ch)
newVal := -1
if nv != -1 {
newVal = (nv + 1) * 100
} else if nh != -1 {
newVal = nh + 1
}
//fmt.Printf(" (%v)\n", newVal)
if newVal != -1 {
// We've found it!
sum += newVal
found = true
break calcGrid
}
g[v][h] = '.'
} else {
// try fix the smudge!
g[v][h] = '.'
nv, nh := calcReflectionRemainder(g, cv, ch)
newVal := -1
if nv != -1 {
newVal = (nv + 1) * 100
} else if nh != -1 {
newVal = nh + 1
}
//fmt.Printf(" (%v)\n", newVal)
if newVal != -1 {
// We've found it!
//fmt.Printf("Found new: %v\n", newVal)
sum += newVal
found = true
break calcGrid
}
g[v][h] = '#'
}
}
}
if !found {
panic("No new")
}
}
return sum
}
// solve part 1 here
p := 0
for _, g := range grids {
//fmt.Printf("Doing %v\n", g)
pv, ph := calcReflectionRemainder(g, -1, -1)
if pv != -1 {
p += (pv + 1) * 100
} else if ph != -1 {
p += ph + 1
} else {
panic("Could not find")
}
}
return p
}
func calcReflectionRemainder(grid [][]rune, exclV int, exclH int) (int, int) {
// Try horizontal
for v := 0; v < len(grid)-1; v++ {
if v == exclV {
continue
}
mirror := true
m1:
for h := 0; h < len(grid[v])-1; h++ {
if grid[v][h] != grid[v+1][h] {
mirror = false
break m1
}
}
if mirror {
// Confirm a mirror
lhs := v
rhs := v + 1
confirmedMirror := true
m2:
for lhs >= 0 && rhs < len(grid) {
for h := 0; h < len(grid[lhs]); h++ {
if grid[lhs][h] != grid[rhs][h] {
confirmedMirror = false
break m2
}
}
lhs -= 1
rhs += 1
}
if confirmedMirror {
//fmt.Printf("Found at horiz %v-%v\n", v, v+1)
return v, -1
}
}
}
// Else try vertical
for h := 0; h < len(grid[0])-1; h++ {
if h == exclH {
continue
}
mirror := true
m3:
for v := 0; v < len(grid)-1; v++ {
if grid[v][h] != grid[v][h+1] {
mirror = false
break m3
}
}
if mirror {
// Confirm a mirror
uhs := h
bhs := h + 1
confirmedMirror := true
m4:
for uhs >= 0 && bhs < len(grid[0]) {
for v := 0; v < len(grid); v++ {
if grid[v][uhs] != grid[v][bhs] {
confirmedMirror = false
break m4
}
}
uhs -= 1
bhs += 1
}
if confirmedMirror {
//fmt.Printf("Found at vert %v-%v\n", h, h+1)
return -1, h
}
}
}
return -1, -1
}