Compare commits
10 Commits
8ec77c3b97
...
e9ee54b0d9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9ee54b0d9 | ||
|
|
91dcccf17f | ||
|
|
d2defd64e6 | ||
|
|
3ed3fb78f7 | ||
|
|
712cab8120 | ||
|
|
9878e51904 | ||
|
|
44b8be5a9e | ||
|
|
3cea8acd1f | ||
|
|
1c8af2a8aa | ||
|
|
55c6d5fa3b |
77
day14/day.go
Normal file
77
day14/day.go
Normal file
@ -0,0 +1,77 @@
|
||||
package day14
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"tools"
|
||||
)
|
||||
|
||||
func generateHashes(hashmap map[int][]byte, salt string, start, end int, stretch bool) map[int][]byte {
|
||||
for i := start; i <= end; i++ {
|
||||
thisSalt := salt + strconv.Itoa(i)
|
||||
if _, ok := hashmap[i]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if !stretch {
|
||||
hashmap[i] = []byte(fmt.Sprintf("%x", md5.Sum([]byte(thisSalt))))
|
||||
} else {
|
||||
hash := fmt.Sprintf("%x", md5.Sum([]byte(thisSalt)))
|
||||
for i := 0; i < 2016; i++ {
|
||||
hash = fmt.Sprintf("%x", md5.Sum([]byte(hash)))
|
||||
}
|
||||
hashmap[i] = []byte(hash)
|
||||
}
|
||||
}
|
||||
|
||||
return hashmap
|
||||
}
|
||||
|
||||
func getIndexForKeys(salt string, needKeys int, stretch bool) int {
|
||||
hashmap := make(map[int][]byte)
|
||||
|
||||
keyCount := 0
|
||||
index := -1
|
||||
for keyCount < needKeys {
|
||||
index++
|
||||
hashmap = generateHashes(hashmap, salt, index, index+1000, stretch)
|
||||
foundKey := false
|
||||
for i := 0; i < len(hashmap[index])-2; i++ {
|
||||
c := hashmap[index][i]
|
||||
if c == hashmap[index][i+1] && c == hashmap[index][i+2] {
|
||||
for j := 1; j <= 1000; j++ {
|
||||
hash := hashmap[index+j]
|
||||
for k := 1; k < len(hash)-5; k++ {
|
||||
if c != hash[k] {
|
||||
continue
|
||||
}
|
||||
if hash[k+1] == c && hash[k+2] == c && hash[k+3] == c && hash[k+4] == c {
|
||||
foundKey = true
|
||||
keyCount++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
if foundKey {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return index
|
||||
}
|
||||
|
||||
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
||||
salt := puzzle.GetInputArray()[0]
|
||||
|
||||
return getIndexForKeys(salt, 64, false)
|
||||
}
|
||||
|
||||
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
||||
salt := puzzle.GetInputArray()[0]
|
||||
|
||||
return getIndexForKeys(salt, 64, true)
|
||||
}
|
||||
70
day15/day.go
Normal file
70
day15/day.go
Normal file
@ -0,0 +1,70 @@
|
||||
package day15
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"tools"
|
||||
)
|
||||
|
||||
type Disc struct {
|
||||
posCount int
|
||||
initPos int
|
||||
}
|
||||
|
||||
func parseInput(inp []string, part2 bool) map[int]Disc {
|
||||
discs := make(map[int]Disc)
|
||||
parserRegex := regexp.MustCompile(".*has ([0-9]+) positions.*at position ([0-9]+).")
|
||||
for i, s := range inp {
|
||||
parts := parserRegex.FindStringSubmatch(s)
|
||||
pc, _ := strconv.Atoi(parts[1])
|
||||
ip, _ := strconv.Atoi(parts[2])
|
||||
discs[i] = Disc{pc, ip}
|
||||
if part2 {
|
||||
discs[i+1] = Disc{11, 0}
|
||||
}
|
||||
}
|
||||
|
||||
return discs
|
||||
}
|
||||
|
||||
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
||||
discs := parseInput(puzzle.GetInputArray(), false)
|
||||
|
||||
tIndex := -1
|
||||
for {
|
||||
tIndex++
|
||||
failed := false
|
||||
for i, d := range discs {
|
||||
if !((d.initPos+tIndex+i+1)%d.posCount == 0) {
|
||||
failed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !failed {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return tIndex
|
||||
}
|
||||
|
||||
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
||||
discs := parseInput(puzzle.GetInputArray(), true)
|
||||
|
||||
tIndex := -1
|
||||
for {
|
||||
tIndex++
|
||||
failed := false
|
||||
for i, d := range discs {
|
||||
if !((d.initPos+tIndex+i+1)%d.posCount == 0) {
|
||||
failed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !failed {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return tIndex
|
||||
}
|
||||
58
day16/day.go
Normal file
58
day16/day.go
Normal file
@ -0,0 +1,58 @@
|
||||
package day16
|
||||
|
||||
import (
|
||||
"tools"
|
||||
)
|
||||
|
||||
func expandState(state string) string {
|
||||
b := []rune(state)
|
||||
for i, j := 0, len(b)-1; i <= j; i, j = i+1, j-1 {
|
||||
x := b[j]
|
||||
if b[i] == 48 {
|
||||
b[j] = 49
|
||||
} else {
|
||||
b[j] = 48
|
||||
}
|
||||
if x == 48 {
|
||||
b[i] = 49
|
||||
} else {
|
||||
b[i] = 48
|
||||
}
|
||||
}
|
||||
|
||||
return state + "0" + string(b)
|
||||
}
|
||||
|
||||
func getCheckSum(state string) string {
|
||||
checksum := []byte(state)
|
||||
for len(checksum)%2 == 0 {
|
||||
var newsum []byte
|
||||
bytes := checksum
|
||||
for i := 0; i < len(bytes); i += 2 {
|
||||
newsum = append(newsum, 49-(bytes[i]+bytes[i+1])%2)
|
||||
}
|
||||
checksum = newsum
|
||||
}
|
||||
|
||||
return string(checksum)
|
||||
}
|
||||
|
||||
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
||||
state := puzzle.GetInputArray()[0]
|
||||
|
||||
for len(state) < 272 {
|
||||
state = expandState(state)
|
||||
}
|
||||
|
||||
return getCheckSum(state[:272])
|
||||
}
|
||||
|
||||
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
||||
state := puzzle.GetInputArray()[0]
|
||||
|
||||
for len(state) < 35651584 {
|
||||
state = expandState(state)
|
||||
}
|
||||
|
||||
return getCheckSum(state[:35651584])
|
||||
}
|
||||
74
day17/day.go
Normal file
74
day17/day.go
Normal file
@ -0,0 +1,74 @@
|
||||
package day17
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"math"
|
||||
"tools"
|
||||
)
|
||||
|
||||
func getMD5Sum(s string) string {
|
||||
return fmt.Sprintf("%x", md5.Sum([]byte(s)))
|
||||
}
|
||||
|
||||
type DirDelta struct {
|
||||
x int
|
||||
y int
|
||||
}
|
||||
|
||||
var dirDeltas = []DirDelta{{0, -1}, {0, 1}, {-1, 0}, {1, 0}}
|
||||
var dirs = []string{"U", "D", "L", "R"}
|
||||
var pathLen = math.MaxInt32
|
||||
var foundPath = ""
|
||||
|
||||
func findPath(passcode, path string, x, y int, findLongest bool) {
|
||||
doors := getMD5Sum(passcode + path)[:4]
|
||||
if !findLongest && len(path) >= pathLen {
|
||||
return
|
||||
}
|
||||
if x == 3 && y == 3 {
|
||||
if findLongest {
|
||||
if len(path) > pathLen {
|
||||
foundPath = path
|
||||
pathLen = len(path)
|
||||
}
|
||||
} else {
|
||||
if len(path) < pathLen {
|
||||
foundPath = path
|
||||
pathLen = len(path)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
for i, c := range doors {
|
||||
if x+dirDeltas[i].x < 0 || x+dirDeltas[i].x > 3 || y+dirDeltas[i].y < 0 || y+dirDeltas[i].y > 3 {
|
||||
// border case
|
||||
continue
|
||||
}
|
||||
|
||||
if c > 97 { // door open
|
||||
findPath(passcode, path+dirs[i], x+dirDeltas[i].x, y+dirDeltas[i].y, findLongest)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
||||
for _, passcode := range puzzle.GetInputArray() {
|
||||
pathLen = math.MaxInt32
|
||||
findPath(passcode, "", 0, 0, false)
|
||||
// fmt.Println("Passcode:", passcode, "Path:", foundPath)
|
||||
}
|
||||
|
||||
return foundPath
|
||||
}
|
||||
|
||||
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
||||
for _, passcode := range puzzle.GetInputArray() {
|
||||
pathLen = 0
|
||||
findPath(passcode, "", 0, 0, true)
|
||||
// fmt.Println("Passcode:", passcode, "Len:", len(foundPath), "Path:", foundPath)
|
||||
}
|
||||
|
||||
return len(foundPath)
|
||||
}
|
||||
41
day18/day.go
Normal file
41
day18/day.go
Normal file
@ -0,0 +1,41 @@
|
||||
package day18
|
||||
|
||||
import (
|
||||
"tools"
|
||||
)
|
||||
|
||||
func getGridFromInput(inp string) tools.GridToggle {
|
||||
grid := tools.NewGridToggle()
|
||||
for i, c := range inp {
|
||||
grid.Set(i, 0, c == '^')
|
||||
}
|
||||
return grid
|
||||
}
|
||||
|
||||
func calcTraps(grid tools.GridToggle, cols, rows int) tools.GridToggle {
|
||||
for row := 1; row < rows; row++ {
|
||||
for x := 0; x < cols; x++ {
|
||||
grid.Set(x, row,
|
||||
(grid.State(x-1, row-1) && grid.State(x, row-1) && !grid.State(x+1, row-1)) ||
|
||||
(!grid.State(x-1, row-1) && grid.State(x, row-1) && grid.State(x+1, row-1)) ||
|
||||
(grid.State(x-1, row-1) && !grid.State(x, row-1) && !grid.State(x+1, row-1)) ||
|
||||
(!grid.State(x-1, row-1) && !grid.State(x, row-1) && grid.State(x+1, row-1)))
|
||||
}
|
||||
}
|
||||
|
||||
return grid
|
||||
}
|
||||
|
||||
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
||||
inp := puzzle.GetInputString()
|
||||
width := len(inp)
|
||||
field := calcTraps(getGridFromInput(inp), width, 40)
|
||||
return (field.MaxX+1)*(field.MaxY+1) - field.GetOnCount()
|
||||
}
|
||||
|
||||
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
||||
inp := puzzle.GetInputString()
|
||||
width := len(inp)
|
||||
field := calcTraps(getGridFromInput(inp), width, 400000)
|
||||
return (field.MaxX+1)*(field.MaxY+1) - field.GetOnCount()
|
||||
}
|
||||
55
day19/day.go
Normal file
55
day19/day.go
Normal file
@ -0,0 +1,55 @@
|
||||
package day19
|
||||
|
||||
import (
|
||||
"math"
|
||||
"tools"
|
||||
)
|
||||
|
||||
func getNextIndex(m map[int]int, start, max int) int {
|
||||
index := start
|
||||
for {
|
||||
index++
|
||||
if index > max {
|
||||
index = 0
|
||||
}
|
||||
if _, ok := m[index]; ok {
|
||||
return index
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
||||
elfCount := puzzle.GetInputInt()
|
||||
elfs := make(map[int]int)
|
||||
for i := 0; i < elfCount; i++ {
|
||||
elfs[i] = 1
|
||||
}
|
||||
|
||||
index := 0
|
||||
for len(elfs) > 1 {
|
||||
nextIndex := getNextIndex(elfs, index, elfCount)
|
||||
delete(elfs, nextIndex)
|
||||
index = getNextIndex(elfs, nextIndex, elfCount)
|
||||
}
|
||||
|
||||
return index + 1
|
||||
}
|
||||
|
||||
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
||||
elfCount := puzzle.GetInputInt()
|
||||
var elfs []int
|
||||
for i := 0; i < elfCount; i++ {
|
||||
elfs = append(elfs, i+1)
|
||||
}
|
||||
|
||||
// Future optimization path?
|
||||
// 0..4; 0 eliminates 2 (index + floor(half), 1 eliminates 4 (1 + half(len)), 3 eliminates 1 (index + floor(half))
|
||||
// eliminate (1:?)2:1:2:1:...until len(2) (start with 1 for equal lens and 2 for unequal lens)
|
||||
for len(elfs) > 1 {
|
||||
half := int(math.Floor(float64(len(elfs) / 2)))
|
||||
elfs = append(elfs, elfs[0])
|
||||
elfs = append(elfs[1:half], elfs[half+1:]...)
|
||||
}
|
||||
|
||||
return elfs[0]
|
||||
}
|
||||
56
day20/day.go
Normal file
56
day20/day.go
Normal file
@ -0,0 +1,56 @@
|
||||
package day20
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"tools"
|
||||
)
|
||||
|
||||
func getBlacklistMap(inp []string) (map[int]int, []int) {
|
||||
ips := make(map[int]int)
|
||||
var lips []int
|
||||
for _, l := range inp {
|
||||
p := strings.Split(l, "-")
|
||||
i1, _ := strconv.Atoi(p[0])
|
||||
i2, _ := strconv.Atoi(p[1])
|
||||
ips[i1] = i2
|
||||
lips = append(lips, i1)
|
||||
}
|
||||
sort.Ints(lips)
|
||||
return ips, lips
|
||||
}
|
||||
|
||||
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
||||
ips, lips := getBlacklistMap(puzzle.GetInputArray())
|
||||
|
||||
index := 0
|
||||
for _, lip := range lips {
|
||||
if lip > index {
|
||||
break
|
||||
}
|
||||
if index >= lip && index <= ips[lip] {
|
||||
index = ips[lip] + 1
|
||||
}
|
||||
}
|
||||
|
||||
return index
|
||||
}
|
||||
|
||||
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
||||
ips, lips := getBlacklistMap(puzzle.GetInputArray())
|
||||
|
||||
cips := make(map[int]int)
|
||||
var minIp, maxIp = 0, 0
|
||||
for _, lip := range lips {
|
||||
if lip >= minIp && lip <= maxIp+1 {
|
||||
maxIp = tools.Max(ips[lip], maxIp)
|
||||
} else {
|
||||
minIp = lip
|
||||
maxIp = ips[lip]
|
||||
}
|
||||
cips[minIp] = maxIp
|
||||
}
|
||||
|
||||
return len(cips) - 1
|
||||
}
|
||||
114
day21/day.go
Normal file
114
day21/day.go
Normal file
@ -0,0 +1,114 @@
|
||||
package day21
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"tools"
|
||||
)
|
||||
|
||||
var revIndex = map[int]int{
|
||||
0: 1,
|
||||
1: 1,
|
||||
2: 6,
|
||||
3: 2,
|
||||
4: 7,
|
||||
5: 3,
|
||||
6: 8,
|
||||
7: 4,
|
||||
}
|
||||
|
||||
func scramble(s string, instr []string, reverse bool) string {
|
||||
sb := []byte(s)
|
||||
for _, inst := range instr {
|
||||
parts := strings.Split(inst, " ")
|
||||
if parts[0] == "swap" && parts[1] == "position" {
|
||||
x, _ := strconv.Atoi(parts[2])
|
||||
y, _ := strconv.Atoi(parts[5])
|
||||
sb[x], sb[y] = sb[y], sb[x]
|
||||
} else if parts[0] == "swap" && parts[1] == "letter" {
|
||||
x := bytes.Index(sb, []byte(parts[2]))
|
||||
y := bytes.Index(sb, []byte(parts[5]))
|
||||
sb[x], sb[y] = sb[y], sb[x]
|
||||
} else if parts[0] == "rotate" && parts[1] == "left" {
|
||||
x, _ := strconv.Atoi(parts[2])
|
||||
if reverse {
|
||||
sb = append(sb[len(sb)-(x%len(sb)):], sb[:len(sb)-(x%len(sb))]...)
|
||||
} else {
|
||||
sb = append(sb[x%len(sb):], sb[:x%len(sb)]...)
|
||||
}
|
||||
} else if parts[0] == "rotate" && parts[1] == "right" {
|
||||
x, _ := strconv.Atoi(parts[2])
|
||||
if reverse {
|
||||
sb = append(sb[x%len(sb):], sb[:x%len(sb)]...)
|
||||
} else {
|
||||
sb = append(sb[len(sb)-(x%len(sb)):], sb[:len(sb)-(x%len(sb))]...)
|
||||
}
|
||||
} else if parts[0] == "rotate" && parts[1] == "based" {
|
||||
var x int
|
||||
if reverse {
|
||||
x = bytes.Index(sb, []byte(parts[6]))
|
||||
x = revIndex[x]
|
||||
sb = append(sb[x%len(sb):], sb[:x%len(sb)]...)
|
||||
} else {
|
||||
x = bytes.Index(sb, []byte(parts[6]))
|
||||
if x >= 4 {
|
||||
x++
|
||||
}
|
||||
x++
|
||||
sb = append(sb[len(sb)-(x%len(sb)):], sb[:len(sb)-(x%len(sb))]...)
|
||||
}
|
||||
} else if parts[0] == "reverse" && parts[1] == "positions" {
|
||||
x, _ := strconv.Atoi(parts[2])
|
||||
y, _ := strconv.Atoi(parts[4])
|
||||
var ns []byte
|
||||
for i := 0; i < x; i++ {
|
||||
ns = append(ns, sb[i])
|
||||
}
|
||||
for i := y; i >= x; i-- {
|
||||
ns = append(ns, sb[i])
|
||||
}
|
||||
sb = append(ns, sb[y+1:]...)
|
||||
} else if parts[0] == "move" && parts[1] == "position" {
|
||||
x, _ := strconv.Atoi(parts[2])
|
||||
y, _ := strconv.Atoi(parts[5])
|
||||
if reverse {
|
||||
c := sb[y]
|
||||
sb = append(sb[:y], sb[y+1:]...)
|
||||
sb = append(sb[:x+1], sb[x:]...)
|
||||
sb[x] = c
|
||||
} else {
|
||||
c := sb[x]
|
||||
sb = append(sb[:x], sb[x+1:]...)
|
||||
sb = append(sb[:y+1], sb[y:]...)
|
||||
sb[y] = c
|
||||
}
|
||||
} else {
|
||||
fmt.Println("ERROR: unknown instruction:", inst)
|
||||
}
|
||||
}
|
||||
|
||||
return string(sb)
|
||||
}
|
||||
|
||||
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
||||
inp := puzzle.GetInputArray()
|
||||
startString := inp[0]
|
||||
password := scramble(startString, inp[1:], false)
|
||||
|
||||
return password
|
||||
}
|
||||
|
||||
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
||||
inp := puzzle.GetInputArray()
|
||||
var rinp []string
|
||||
for x := len(inp) - 1; x > 0; x-- {
|
||||
rinp = append(rinp, inp[x])
|
||||
}
|
||||
startString := "fbgdceah"
|
||||
//startString := "gfdhebac"
|
||||
password := scramble(startString, rinp, true)
|
||||
|
||||
return password
|
||||
}
|
||||
104
day23/day.go
Normal file
104
day23/day.go
Normal file
@ -0,0 +1,104 @@
|
||||
package day23
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"tools"
|
||||
)
|
||||
|
||||
func run(code []string, register map[string]int) map[string]int {
|
||||
index := 0
|
||||
for index < len(code) {
|
||||
//fmt.Println("Executing line", index, ":", code[index])
|
||||
instr := strings.Split(code[index], " ")
|
||||
switch instr[0] {
|
||||
case "cpy":
|
||||
value, err := strconv.Atoi(instr[1])
|
||||
if err != nil {
|
||||
register[instr[2]] = register[instr[1]]
|
||||
} else {
|
||||
register[instr[2]] = value
|
||||
}
|
||||
index++
|
||||
case "inc":
|
||||
register[instr[1]]++
|
||||
index++
|
||||
case "dec":
|
||||
register[instr[1]]--
|
||||
index++
|
||||
case "jnz":
|
||||
value, err := strconv.Atoi(instr[1])
|
||||
if err != nil {
|
||||
value = register[instr[1]]
|
||||
}
|
||||
if value == 0 {
|
||||
index++
|
||||
} else {
|
||||
jump, err := strconv.Atoi(instr[2])
|
||||
if err != nil {
|
||||
index += register[instr[2]]
|
||||
} else {
|
||||
index += jump
|
||||
}
|
||||
}
|
||||
case "tgl":
|
||||
toChange := index + register[instr[1]]
|
||||
if toChange < len(code) && toChange >= 0 {
|
||||
switch len(strings.Split(code[toChange], " ")) {
|
||||
case 2:
|
||||
if code[toChange][:3] == "inc" {
|
||||
code[toChange] = "dec" + code[toChange][3:]
|
||||
} else {
|
||||
code[toChange] = "inc" + code[toChange][3:]
|
||||
}
|
||||
case 3:
|
||||
if code[toChange][:3] == "jnz" {
|
||||
code[toChange] = "cpy" + code[toChange][3:]
|
||||
} else {
|
||||
code[toChange] = "jnz" + code[toChange][3:]
|
||||
}
|
||||
}
|
||||
}
|
||||
index++
|
||||
}
|
||||
/*
|
||||
fmt.Println("New registers", register)
|
||||
fmt.Println("New code", code)
|
||||
bufio.NewReader(os.Stdin).ReadBytes('\n')
|
||||
*/
|
||||
}
|
||||
|
||||
return register
|
||||
}
|
||||
|
||||
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
||||
register := map[string]int{
|
||||
"a": 7,
|
||||
"b": 0,
|
||||
"c": 0,
|
||||
"d": 0,
|
||||
}
|
||||
|
||||
register = run(puzzle.GetInputArray(), register)
|
||||
|
||||
return register["a"]
|
||||
}
|
||||
|
||||
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
||||
register := map[string]int{
|
||||
"a": 12,
|
||||
"b": 0,
|
||||
"c": 1,
|
||||
"d": 0,
|
||||
}
|
||||
|
||||
/*
|
||||
This could be optimized by closely looking at the input and finding the "inc x" loops
|
||||
and then replace them with multiplications.
|
||||
Also the code seems to resemble a factorial implementation which could lead to finding
|
||||
the solution without executing the code at all. Needs more analysis.
|
||||
*/
|
||||
register = run(puzzle.GetInputArray(), register)
|
||||
|
||||
return register["a"]
|
||||
}
|
||||
59
day24/day.go
Normal file
59
day24/day.go
Normal file
@ -0,0 +1,59 @@
|
||||
package day24
|
||||
|
||||
import (
|
||||
"math"
|
||||
"tools"
|
||||
)
|
||||
|
||||
func getInputGrid(inp []string) (tools.GridToggle, map[int]tools.Coordinate) {
|
||||
grid := tools.NewGridToggle()
|
||||
targets := make(map[int]tools.Coordinate)
|
||||
|
||||
for y, line := range inp {
|
||||
for x, c := range line {
|
||||
if c == '#' {
|
||||
grid.Set(x, y, tools.On)
|
||||
} else if c != '.' {
|
||||
targets[int(c-48)] = tools.Coordinate{X: x, Y: y}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return grid, targets
|
||||
}
|
||||
|
||||
func findShortestPathBetweenNodes(grid tools.GridToggle, targets map[int]tools.Coordinate, startNode int, alreadyVisited tools.Set, pathLen int, part2 bool) int {
|
||||
alreadyVisited.Add(startNode)
|
||||
minLen := math.MaxInt32
|
||||
for node, target := range targets {
|
||||
if alreadyVisited.Contains(node) {
|
||||
continue
|
||||
}
|
||||
thisLen := len(grid.GetPathAStar(targets[startNode], target, false)) - 1
|
||||
if alreadyVisited.Len() == len(targets)-1 {
|
||||
if part2 {
|
||||
return thisLen + pathLen + len(grid.GetPathAStar(target, targets[0], false)) - 1
|
||||
} else {
|
||||
return thisLen + pathLen
|
||||
}
|
||||
} else {
|
||||
thisLen = findShortestPathBetweenNodes(grid, targets, node, alreadyVisited.Copy(), thisLen, part2)
|
||||
if thisLen < minLen {
|
||||
minLen = thisLen
|
||||
}
|
||||
}
|
||||
}
|
||||
return minLen + pathLen
|
||||
}
|
||||
|
||||
func Part1(puzzle tools.AoCPuzzle) interface{} {
|
||||
grid, targets := getInputGrid(puzzle.GetInputArray())
|
||||
|
||||
return findShortestPathBetweenNodes(grid, targets, 0, tools.NewSet(), 0, false)
|
||||
}
|
||||
|
||||
func Part2(puzzle tools.AoCPuzzle) interface{} {
|
||||
grid, targets := getInputGrid(puzzle.GetInputArray())
|
||||
|
||||
return findShortestPathBetweenNodes(grid, targets, 0, tools.NewSet(), 0, true)
|
||||
}
|
||||
1
inputs/14_test
Normal file
1
inputs/14_test
Normal file
@ -0,0 +1 @@
|
||||
abc
|
||||
6
inputs/15
Normal file
6
inputs/15
Normal file
@ -0,0 +1,6 @@
|
||||
Disc #1 has 13 positions; at time=0, it is at position 1.
|
||||
Disc #2 has 19 positions; at time=0, it is at position 10.
|
||||
Disc #3 has 3 positions; at time=0, it is at position 2.
|
||||
Disc #4 has 7 positions; at time=0, it is at position 1.
|
||||
Disc #5 has 5 positions; at time=0, it is at position 3.
|
||||
Disc #6 has 17 positions; at time=0, it is at position 5.
|
||||
2
inputs/15_test
Normal file
2
inputs/15_test
Normal file
@ -0,0 +1,2 @@
|
||||
Disc #1 has 5 positions; at time=0, it is at position 4.
|
||||
Disc #2 has 2 positions; at time=0, it is at position 1.
|
||||
1
inputs/16_test
Normal file
1
inputs/16_test
Normal file
@ -0,0 +1 @@
|
||||
10000
|
||||
3
inputs/17_test
Normal file
3
inputs/17_test
Normal file
@ -0,0 +1,3 @@
|
||||
ihgpwlah
|
||||
kglvqrro
|
||||
ulqzkmiv
|
||||
1
inputs/18
Normal file
1
inputs/18
Normal file
@ -0,0 +1 @@
|
||||
^.^^^.^..^....^^....^^^^.^^.^...^^.^.^^.^^.^^..^.^...^.^..^.^^.^..^.....^^^.^.^^^..^^...^^^...^...^.
|
||||
1
inputs/18_test
Normal file
1
inputs/18_test
Normal file
@ -0,0 +1 @@
|
||||
.^^.^.^^^^
|
||||
1
inputs/19_test
Normal file
1
inputs/19_test
Normal file
@ -0,0 +1 @@
|
||||
5
|
||||
3
inputs/20_test
Normal file
3
inputs/20_test
Normal file
@ -0,0 +1,3 @@
|
||||
5-8
|
||||
0-2
|
||||
4-7
|
||||
101
inputs/21
Normal file
101
inputs/21
Normal file
@ -0,0 +1,101 @@
|
||||
abcdefgh
|
||||
reverse positions 1 through 6
|
||||
rotate based on position of letter a
|
||||
swap position 4 with position 1
|
||||
reverse positions 1 through 5
|
||||
move position 5 to position 7
|
||||
swap position 4 with position 0
|
||||
swap position 4 with position 6
|
||||
rotate based on position of letter a
|
||||
swap position 0 with position 2
|
||||
move position 5 to position 2
|
||||
move position 7 to position 1
|
||||
swap letter d with letter c
|
||||
swap position 5 with position 3
|
||||
reverse positions 3 through 7
|
||||
rotate based on position of letter d
|
||||
swap position 7 with position 5
|
||||
rotate based on position of letter f
|
||||
swap position 4 with position 1
|
||||
swap position 3 with position 6
|
||||
reverse positions 4 through 7
|
||||
rotate based on position of letter c
|
||||
move position 0 to position 5
|
||||
swap position 7 with position 4
|
||||
rotate based on position of letter f
|
||||
reverse positions 1 through 3
|
||||
move position 5 to position 3
|
||||
rotate based on position of letter g
|
||||
reverse positions 2 through 5
|
||||
rotate right 0 steps
|
||||
rotate left 0 steps
|
||||
swap letter f with letter b
|
||||
rotate based on position of letter h
|
||||
move position 1 to position 3
|
||||
reverse positions 3 through 6
|
||||
rotate based on position of letter h
|
||||
swap position 4 with position 3
|
||||
swap letter b with letter h
|
||||
swap letter a with letter h
|
||||
reverse positions 1 through 6
|
||||
swap position 3 with position 6
|
||||
swap letter e with letter d
|
||||
swap letter e with letter h
|
||||
swap position 1 with position 5
|
||||
rotate based on position of letter a
|
||||
reverse positions 4 through 5
|
||||
swap position 0 with position 4
|
||||
reverse positions 0 through 3
|
||||
move position 7 to position 2
|
||||
swap letter e with letter c
|
||||
swap position 3 with position 4
|
||||
rotate left 3 steps
|
||||
rotate left 7 steps
|
||||
rotate based on position of letter e
|
||||
reverse positions 5 through 6
|
||||
move position 1 to position 5
|
||||
move position 1 to position 2
|
||||
rotate left 1 step
|
||||
move position 7 to position 6
|
||||
rotate left 0 steps
|
||||
reverse positions 5 through 6
|
||||
reverse positions 3 through 7
|
||||
swap letter d with letter e
|
||||
rotate right 3 steps
|
||||
swap position 2 with position 1
|
||||
swap position 5 with position 7
|
||||
swap letter h with letter d
|
||||
swap letter c with letter d
|
||||
rotate based on position of letter d
|
||||
swap letter d with letter g
|
||||
reverse positions 0 through 1
|
||||
rotate right 0 steps
|
||||
swap position 2 with position 3
|
||||
rotate left 4 steps
|
||||
rotate left 5 steps
|
||||
move position 7 to position 0
|
||||
rotate right 1 step
|
||||
swap letter g with letter f
|
||||
rotate based on position of letter a
|
||||
rotate based on position of letter b
|
||||
swap letter g with letter e
|
||||
rotate right 4 steps
|
||||
rotate based on position of letter h
|
||||
reverse positions 3 through 5
|
||||
swap letter h with letter e
|
||||
swap letter g with letter a
|
||||
rotate based on position of letter c
|
||||
reverse positions 0 through 4
|
||||
rotate based on position of letter e
|
||||
reverse positions 4 through 7
|
||||
rotate left 4 steps
|
||||
swap position 0 with position 6
|
||||
reverse positions 1 through 6
|
||||
rotate left 2 steps
|
||||
swap position 5 with position 3
|
||||
swap letter b with letter d
|
||||
swap letter b with letter d
|
||||
rotate based on position of letter d
|
||||
rotate based on position of letter c
|
||||
rotate based on position of letter h
|
||||
move position 4 to position 7
|
||||
9
inputs/21_test
Normal file
9
inputs/21_test
Normal file
@ -0,0 +1,9 @@
|
||||
abcde
|
||||
swap position 4 with position 0
|
||||
swap letter d with letter b
|
||||
reverse positions 0 through 4
|
||||
rotate left 1 step
|
||||
move position 1 to position 4
|
||||
move position 3 to position 0
|
||||
rotate based on position of letter b
|
||||
rotate based on position of letter d
|
||||
26
inputs/23
Normal file
26
inputs/23
Normal file
@ -0,0 +1,26 @@
|
||||
cpy a b
|
||||
dec b
|
||||
cpy a d
|
||||
cpy 0 a
|
||||
cpy b c
|
||||
inc a
|
||||
dec c
|
||||
jnz c -2
|
||||
dec d
|
||||
jnz d -5
|
||||
dec b
|
||||
cpy b c
|
||||
cpy c d
|
||||
dec d
|
||||
inc c
|
||||
jnz d -2
|
||||
tgl c
|
||||
cpy -16 c
|
||||
jnz 1 c
|
||||
cpy 84 c
|
||||
jnz 71 d
|
||||
inc a
|
||||
inc d
|
||||
jnz d -2
|
||||
inc c
|
||||
jnz c -5
|
||||
7
inputs/23_test
Normal file
7
inputs/23_test
Normal file
@ -0,0 +1,7 @@
|
||||
cpy 2 a
|
||||
tgl a
|
||||
tgl a
|
||||
tgl a
|
||||
cpy 1 a
|
||||
dec a
|
||||
dec a
|
||||
39
inputs/24
Normal file
39
inputs/24
Normal file
@ -0,0 +1,39 @@
|
||||
#######################################################################################################################################################################################
|
||||
#...........#.....#...........#.#.......#.....#.#...............#.....#.....#.......#.......#.......#.....................#.........#.....#...#3......#...#.#.............#.......#...#
|
||||
#####.#.#.###.###.#####.#.#####.#.###.###.###.#.#.#.#.#.#.###.#.###.###.###.#.#######.#.#.#.###.###.#.#.#.#####.#.#.#####.###.#.#######.#############.#.#.#.#.#.#.###.#.#.#.#.###.#.#.#
|
||||
#...#.#.#.#.....#.#...#...#.....#.....#.#...#.........#.....................#.....#...#...#.......#.....#.#.........#.#.#.#.#.......................#...#...#.#.#.#.....#.#.........#.#
|
||||
#.#.#.#.#.#####.#.#.#.#.#.#.#.#.###.#.#.###.#.#.#.#.#.#########.#.###.###.#.#.###.###.#.#.#.#.###.#.#.#.#.#.#.#####.#.#.###.###.#######.#.#.#.###.#.###.#.#.#####.#####.#.#.###.#.#.#.#
|
||||
#.#.#...#.....#.#.....#...#.#...#.#...#.......#...........#...#...#...#.#.....#.#...#...........#.#.......#...#...#.#.........#...#.......#.#...#.....#...#.......#.#.#.............#.#
|
||||
#.#######.#.#.###.#.#.#####.#.#.#.#.###.#####.#.#.###.#.#.#.#.#.#.#.#.#.#.###.#.#.#.###.#######.#######.#.#.###.#.#.#.#.#.#.###.#.#.#.#.#.###.#.#####.#.#.#.#.#.#.#.#.#.###.#.#####.#.#
|
||||
#.#...#.....#.......#.......#.#.......#...#.#.....#.#.#.#.#.#.......#...#.....#.#.#.#.#.........#...#...#...#.......#...#...#.....#.....#...#.........#...#.#...#...#...#.........#.#.#
|
||||
#.#.#.#.###.###.#.#.#.###.###.#.#.###.#.#.#.#####.#.###.#.#####.#####.###.#.#.#.#.###.#.#.#.###.###.#.#.#.#.#.#####.#.###.#.#.###.#.#.#.#.###.###.#######.#.###.###.#.#######.#.#.#.#.#
|
||||
#.#...#...#...............#...#...#...#.#.........#.#...#...#.#...#.#.....#...#.#...#.#.#...#.#.#.#.#.....#...#...#.......#.#...#.........#.#.....#.#...#.....#.#...#.#2#.....#.......#
|
||||
#.#.#####.#########.#.###.#.#####.#.#.#.#######.#.###.#.#.#.#.###.#.#.###.#.###.#.#.#.#.#.###.###.#.#.#######.#.###.#.#.#.#.#.#.#.#####.###.#.###.#.#####.#.#.###.#.#.#.###.#.###.###.#
|
||||
#...#...........#.....#.......#...#0..........#...#.....#.#...#.#...#.#.#...#.#.......#.........#...#.#...#.#.#.......#...#.#.........#.#.....................#.#.#.#.....#.#.....#...#
|
||||
#.###.#.#.#.#.#.###.#.#.#.#.#.###.#.#.###.#.#.#.###.###.#.#####.#.#.#.#.###.#.#.###.#.#.###.###.#.#####.#.#.#.###.#.#######.#######.#.#.#.###.#.#.#.#.#.#######.#.#.#####.#.###.###.#.#
|
||||
#...#...#...#.#...........#...#.#.....#...#...#.....#.#.............#...#.........#...#.....#...#.......#...#.#.............#.........#...#.#.....#.#.........#.............#...#.....#
|
||||
#.#.#.###.#.###.#.#.#.###.#.###.#######.#.#.###.#.#.#.#.###.#.###.#.#.#.#.#####.#.#.#.#####.#.#####.#.#.#.#.###.###.#.###.###.###.#.#.#.###.#.#.###.#.#.###.#########.#####.#.#.#.#####
|
||||
#.#...#.#.......#...#.....#.....#...#...#.....#...#...#.........#.....#.#.........#.....#.....#.........#...#.#.....#.#...#...#.#.#...#.#...#.........#.#...#.........#.#.......#.....#
|
||||
#.#####.#.###.#.#.#.###.#.#.#.#.#.#.###.#.#.#.###.###.#.###.#.###.#.#.#.###.#.#####.###.#.#.#.#.#.#####.#.#.#.#.#.#.###.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.###.#.#.#.#.#.#.#.#.###.#.#.#
|
||||
#.....#...#...........#...#...........#.#.....#...#.....#...#.#.#.#...#.....#...#...#...............#...#.........#...#.....#...#.#...#.#...#.....#.....#.....#...#.#...#...#.#.......#
|
||||
###.###.#.#.#####.###.#####.#.###.#.#.#####.#.###.#.###.#.###.#.#.#.#.###.#.###.#.#.#.#.###.#.###.#.#.#.#.#.#.###.#.#.#.###.###.#.#.###.#########.#.#####.###########.#.###.###.#####.#
|
||||
#...#1#...#...#.......#...#...#.#...#...#...........#.#.......#.......#.#.........#.#...#...#...............#...#.....#.#...#.#.....#.........#...#.....#.#...#...#.....#.#.#.#...#...#
|
||||
#.###.###.#.#.#.#####.#.#.#.#.#.#.#####.#####.#.#####.#.#.#.#.###.#.#.#.###.#.###.#.###.#.#.#####.#.#.#####.#.#.###.#.###.#.#.#.#.#.#.#####.#.#.#.#.###.#.#.###.#.#.#.#.#.#.#.###.#.#.#
|
||||
#.....#.#.#.#.........#.#.#.....#.....#...#.....#...#.............#...#...#.....#...#.......#.......#.#.....#...#...#.#...#.....#.#...#.....#.#.#.#.#.#.#.......#...........#.#5#.....#
|
||||
#.###.#.#.###.###.###.#.#####.#.#.###.###.#.###.#############.#######.#.###.#.###.#.#####.#.#.#.#####.#.#.#####.#.#.#.#.#.#######.#.#.###########.#.#.#.#.#.#.#.#.#.###.#.#.#.#.#.###.#
|
||||
#.....#...#...................#.......#...#...#.#.....#.............#.....#...#.....#.......#.#.#.........#.........#.......#.......#...#.........#.#...#...#.....#.#.....#...#...#.#.#
|
||||
#.###.###.###########.###.#####.#####.###.#.#.#.#.#.#.###.#.###.#.#######.#.#.#.#.#.#.###.#.#.#####.#.#.#.#######.#.###.#.#.###.#.#.#.###.#####.#####.#.#.#.#.###.#.###.###########.#.#
|
||||
#.#.#.#...#...#.....#.....#.#.......#.....#.....#...........#.#...#.........#.#.#.#.....#.#.#...........#...#...#...#.......#...#.........#.....#.....#.....#.......#...#...#.#...#...#
|
||||
#.#.#.#.#.#########.#.#.###.#.#.###.###.#.#.#.###.#####.#.#.#.#.#.#.#######.#.#.#######.#.###.#.###.###.#.###.#.#.#.#######.#######.#.#.#.#####.#.###.#.#####.#.###.#.#.###.#.#######.#
|
||||
#.#...#...#.#...................#.#...#.#...#.......#.#...#.#...#.#.#.....#.#...#...#...#.#.............#.....#...........#.........#...#.#.#.....#.......#.......#.....#...#.#...#...#
|
||||
###.#.#.#.#.#.#.###.#.###.#####.#.#####.#.#.###.#.#.#.#####.#.###.#####.#.#.#.#.#.#.#.###.#.#.#####.###.#.###.#####.#.#.#.#####.###.#.#.#.#.#.#######.###.#.#.#########.###.#.#######.#
|
||||
#.....#...................#...#.#...#...#...........#.#.......#.#.....#.#.....#...........#.....#.........#.#...........#...#.....#...#.....#.............#.#.#.........#.#.#.#.......#
|
||||
#.#.#.#.#.###.#.#.#.#.#########.###.#.#.#.#########.#.#.#.#.#.#.###########.#.#.###.###.###.#.#.#.#.#.###.#.###.#.###.#.###.###.#.###.#.#.#####.#.#.#######.#.#.###.###.#.#.#.###.#####
|
||||
#...#.#.#....7#.#...#.#.........#.....#...#.#.......#.....#...........#.#...#.......#.#...#.#...#...........#...#.#...#.....#...#.#.#...........#...#.#...#...#4....#...#...#...#.....#
|
||||
###.#.#.###.#####.#.#.#.#.#.#.#.#.#.#.###.#.###.#.###.#######.#.#.###.#.#####.#.#####.###.#.###.#.#.#.#.#####.###.#.###.#.#.#.#.###.#.#.###.#.#.###.#.###.#########.#.###.#.#.#.#.#.#.#
|
||||
#.....#.#.#.......#.#.#.......#.#.#.............#...#.........#.......#.#.#...........#.....#.....#...#...#.#.....#...#.....#.#.#...#...#...#.....#...#...#.#...#...#.#.#.....#...#.#.#
|
||||
#.###.#.#.#########.#.#.#.#######.#.#.#.#.###.###.#####.#.#.#.#.#.###.#.#.#.#.#####.#.#.###.#.#.#.#.###.###.###.#.#.#######.#.#.###.#####.#.#.###.#.#.#####.###.#.#.###.#.#########.###
|
||||
#.......#...#...#...#...#.#...#...#.#.#...#.#...........#.........#...#.#.#.#.....#...#.....#.#.....#...#...#...#.#.#.#...#...#.#...#.....#...........#.#.........#.....#.#.#...#.....#
|
||||
#####.###.#####.#.#####.#######.#.#.#.###.#.#######.###.#####.###.#.#.#.#.#.#####.#####.###.###.###.#.#.###.#.#.#.###.#.#.###.#.#.#####.#.###.#.#.#.###.#.#.#.#.#.###.###.#.#.###.#.#.#
|
||||
#.....#.#.#.......#...#.#.#.....#.........#...#.....#6......#...#.#...........#.......#.............#...#...#...#...#.#...#...#...#.....#.........#.#...#.....#.#.#.......#...#.#.#...#
|
||||
#######################################################################################################################################################################################
|
||||
5
inputs/24_test
Normal file
5
inputs/24_test
Normal file
@ -0,0 +1,5 @@
|
||||
###########
|
||||
#0.1.....2#
|
||||
#.#######.#
|
||||
#4.......3#
|
||||
###########
|
||||
30
main.go
30
main.go
@ -13,6 +13,16 @@ import (
|
||||
"aoc2016/day10"
|
||||
"aoc2016/day12"
|
||||
"aoc2016/day13"
|
||||
"aoc2016/day14"
|
||||
"aoc2016/day15"
|
||||
"aoc2016/day16"
|
||||
"aoc2016/day17"
|
||||
"aoc2016/day18"
|
||||
"aoc2016/day19"
|
||||
"aoc2016/day20"
|
||||
"aoc2016/day21"
|
||||
"aoc2016/day23"
|
||||
"aoc2016/day24"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
@ -43,17 +53,17 @@ func initDayFunctions() {
|
||||
// 11: {1: day11.Part1, 2: day11.Part2},
|
||||
12: {1: day12.Part1, 2: day12.Part2},
|
||||
13: {1: day13.Part1, 2: day13.Part2},
|
||||
// 14: {1: day14.Part1, 2: day14.Part2},
|
||||
// 15: {1: day15.Part1, 2: day15.Part2},
|
||||
// 16: {1: day16.Part1, 2: day16.Part2},
|
||||
// 17: {1: day17.Part1, 2: day17.Part2},
|
||||
// 18: {1: day18.Part1, 2: day18.Part2},
|
||||
// 19: {1: day19.Part1, 2: day19.Part2},
|
||||
// 20: {1: day20.Part1, 2: day20.Part2},
|
||||
// 21: {1: day21.Part1, 2: day21.Part2},
|
||||
14: {1: day14.Part1, 2: day14.Part2},
|
||||
15: {1: day15.Part1, 2: day15.Part2},
|
||||
16: {1: day16.Part1, 2: day16.Part2},
|
||||
17: {1: day17.Part1, 2: day17.Part2},
|
||||
18: {1: day18.Part1, 2: day18.Part2},
|
||||
19: {1: day19.Part1, 2: day19.Part2},
|
||||
20: {1: day20.Part1, 2: day20.Part2},
|
||||
21: {1: day21.Part1, 2: day21.Part2},
|
||||
// 22: {1: day22.Part1, 2: day22.Part2},
|
||||
// 23: {1: day23.Part1, 2: day23.Part2},
|
||||
// 24: {1: day24.Part1, 2: day24.Part2},
|
||||
23: {1: day23.Part1, 2: day23.Part2},
|
||||
24: {1: day24.Part1, 2: day24.Part2},
|
||||
// 25: {1: day25.Part1, 2: day25.Part2},
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user