2024 Day 21 Complete
This commit is contained in:
parent
d0c04d1fdb
commit
06dada9c63
5
2024/day21/input
Normal file
5
2024/day21/input
Normal file
@ -0,0 +1,5 @@
|
||||
836A
|
||||
540A
|
||||
965A
|
||||
480A
|
||||
789A
|
162
2024/day21/main.go
Normal file
162
2024/day21/main.go
Normal file
@ -0,0 +1,162 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||
)
|
||||
|
||||
func main() {
|
||||
inp := h.StdinToStringSlice()
|
||||
dirPad := make(map[string]h.Coordinate)
|
||||
dirPad["A"] = h.Coordinate{X: 2, Y: 1}
|
||||
dirPad["^"] = h.Coordinate{X: 1, Y: 1}
|
||||
dirPad[">"] = h.Coordinate{X: 2, Y: 0}
|
||||
dirPad["v"] = h.Coordinate{X: 1, Y: 0}
|
||||
dirPad["<"] = h.Coordinate{X: 0, Y: 0}
|
||||
|
||||
numPad := make(map[string]h.Coordinate)
|
||||
numPad["A"] = h.Coordinate{X: 2, Y: 0}
|
||||
numPad["0"] = h.Coordinate{X: 1, Y: 0}
|
||||
numPad["1"] = h.Coordinate{X: 0, Y: 1}
|
||||
numPad["2"] = h.Coordinate{X: 1, Y: 1}
|
||||
numPad["3"] = h.Coordinate{X: 2, Y: 1}
|
||||
numPad["4"] = h.Coordinate{X: 0, Y: 2}
|
||||
numPad["5"] = h.Coordinate{X: 1, Y: 2}
|
||||
numPad["6"] = h.Coordinate{X: 2, Y: 2}
|
||||
numPad["7"] = h.Coordinate{X: 0, Y: 3}
|
||||
numPad["8"] = h.Coordinate{X: 1, Y: 3}
|
||||
numPad["9"] = h.Coordinate{X: 2, Y: 3}
|
||||
fmt.Println("# Part 1")
|
||||
fmt.Println(findOrders(inp, dirPad, numPad, 2))
|
||||
fmt.Println("")
|
||||
fmt.Println("# Part 2")
|
||||
fmt.Println(findOrders(inp, dirPad, numPad, 25))
|
||||
}
|
||||
|
||||
func parseNum(line string) int {
|
||||
var numLine string
|
||||
for i := range line {
|
||||
if line[i] >= '0' && line[i] <= '9' {
|
||||
numLine = numLine + string(line[i])
|
||||
}
|
||||
}
|
||||
var num int
|
||||
fmt.Sscanf(numLine, "%d", &num)
|
||||
return num
|
||||
}
|
||||
|
||||
// findOrders takes:
|
||||
//
|
||||
// inp: The codes that need to be input
|
||||
// dirPad: The direction pad description
|
||||
// numPad: The number pad description
|
||||
// bots: How many robots are operating directional pads between you and the numpad robot.
|
||||
func findOrders(inp []string, dirPad, numPad map[string]h.Coordinate, bots int) int {
|
||||
var count int
|
||||
cache := make(map[string][]int)
|
||||
for _, line := range inp {
|
||||
code := strings.Split(line, "")
|
||||
s := workPad(code, "A", numPad)
|
||||
wrk := workBots(s, bots, 1, cache, dirPad)
|
||||
count += parseNum(line) * wrk
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
func workPad(code []string, start string, pad map[string]h.Coordinate) []string {
|
||||
curr := pad[start]
|
||||
out := []string{}
|
||||
for _, c := range code {
|
||||
btn := pad[c]
|
||||
dist := btn.Sub(curr)
|
||||
var outV, outH []string
|
||||
for i := 0; i < h.Abs(dist.X); i++ {
|
||||
if dist.X >= 0 {
|
||||
outH = append(outH, ">")
|
||||
} else {
|
||||
outH = append(outH, "<")
|
||||
}
|
||||
}
|
||||
for i := 0; i < h.Abs(dist.Y); i++ {
|
||||
if dist.Y >= 0 {
|
||||
outV = append(outV, "^")
|
||||
} else {
|
||||
outV = append(outV, "v")
|
||||
}
|
||||
}
|
||||
_, isNumPad := pad["0"]
|
||||
if isNumPad {
|
||||
if curr.Y == 0 && btn.X == 0 {
|
||||
out = append(out, outV...)
|
||||
out = append(out, outH...)
|
||||
} else if (curr.X == 0 && btn.Y == 0) || dist.X < 0 {
|
||||
out = append(out, outH...)
|
||||
out = append(out, outV...)
|
||||
} else if dist.X >= 0 {
|
||||
out = append(out, outV...)
|
||||
out = append(out, outH...)
|
||||
}
|
||||
} else {
|
||||
if curr.X == 0 && btn.Y == 1 {
|
||||
out = append(out, outH...)
|
||||
out = append(out, outV...)
|
||||
} else if curr.Y == 1 && btn.X == 0 {
|
||||
out = append(out, outV...)
|
||||
out = append(out, outH...)
|
||||
} else if dist.X < 0 {
|
||||
out = append(out, outH...)
|
||||
out = append(out, outV...)
|
||||
} else if dist.X >= 0 {
|
||||
out = append(out, outV...)
|
||||
out = append(out, outH...)
|
||||
}
|
||||
}
|
||||
curr = btn
|
||||
out = append(out, "A")
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func workBots(inst []string, bots int, bot int, cache map[string][]int, dirPad map[string]h.Coordinate) int {
|
||||
cacheKey := strings.Join(inst, "")
|
||||
if v, ok := cache[cacheKey]; ok {
|
||||
if v[bot-1] != 0 {
|
||||
return v[bot-1]
|
||||
}
|
||||
} else {
|
||||
cache[cacheKey] = make([]int, bots)
|
||||
}
|
||||
s := workPad(inst, "A", dirPad)
|
||||
cache[cacheKey][0] = len(s)
|
||||
if bot == bots {
|
||||
return len(s)
|
||||
}
|
||||
sSteps := splitSteps(s)
|
||||
var count int
|
||||
for _, s := range sSteps {
|
||||
c := workBots(s, bots, bot+1, cache, dirPad)
|
||||
subCacheKey := strings.Join(s, "")
|
||||
if _, ok := cache[subCacheKey]; !ok {
|
||||
cache[subCacheKey] = make([]int, bots)
|
||||
}
|
||||
cache[subCacheKey][0] = c
|
||||
count += c
|
||||
}
|
||||
cache[cacheKey][bot-1] = count
|
||||
return count
|
||||
}
|
||||
|
||||
func splitSteps(s []string) [][]string {
|
||||
var out [][]string
|
||||
var c []string
|
||||
for _, char := range s {
|
||||
c = append(c, char)
|
||||
if char == "A" {
|
||||
out = append(out, c)
|
||||
c = []string{}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
5
2024/day21/testinput
Normal file
5
2024/day21/testinput
Normal file
@ -0,0 +1,5 @@
|
||||
029A
|
||||
980A
|
||||
179A
|
||||
456A
|
||||
379A
|
Loading…
Reference in New Issue
Block a user