Day 16 solution
Following the formula for part 1 was straightforward enough, but finding the pattern for part 2 and deducing the shortcut formula took me a while. That first 0 1 propagate enough that by the time we get halfway through applying the formula, it's all 0s and 1s, so sort of like an addition with a mask on what numbers we're adding. Also, fun fact: changing the numberSet from an array of ints (my initial implementation) to an array of int8's (what's here now) reduced the memory footprint of the application substantially (from something like 50mb to closer to 8).
This commit is contained in:
104
days/16.go
Normal file
104
days/16.go
Normal file
@ -0,0 +1,104 @@
|
||||
package days
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
u "parnic.com/aoc2019/utilities"
|
||||
)
|
||||
|
||||
type Day16 struct {
|
||||
numberSet []int8
|
||||
}
|
||||
|
||||
func (d *Day16) Parse() {
|
||||
numberSequence := u.GetStringContents("16p")
|
||||
d.numberSet = make([]int8, len(numberSequence))
|
||||
for i, numRune := range numberSequence {
|
||||
d.numberSet[i] = int8(numRune - '0')
|
||||
}
|
||||
}
|
||||
|
||||
func (d Day16) Num() int {
|
||||
return 16
|
||||
}
|
||||
|
||||
func (d *Day16) Part1() string {
|
||||
transformed := make([]int8, len(d.numberSet))
|
||||
copy(transformed, d.numberSet)
|
||||
|
||||
transformPattern := []int8{0, 1, 0, -1}
|
||||
|
||||
phases := 100
|
||||
workingSet := make([]int8, len(transformed))
|
||||
for i := 0; i < phases; i++ {
|
||||
copy(workingSet, transformed)
|
||||
|
||||
// fmt.Printf("Phase %d. Input signal: %v\n", (i + 1), transformed)
|
||||
for destIdx := range transformed {
|
||||
repeated := 0
|
||||
patternIdx := 0
|
||||
workingVal := int64(0)
|
||||
for idx := range transformed {
|
||||
if repeated >= destIdx {
|
||||
repeated = 0
|
||||
patternIdx++
|
||||
if patternIdx == len(transformPattern) {
|
||||
patternIdx = 0
|
||||
}
|
||||
} else {
|
||||
repeated++
|
||||
}
|
||||
|
||||
// fmt.Printf("%d*%d", transformed[idx], transformPattern[patternIdx])
|
||||
// if idx < len(transformed)-1 {
|
||||
// fmt.Print(" + ")
|
||||
// }
|
||||
workingVal += int64(transformed[idx] * transformPattern[patternIdx])
|
||||
}
|
||||
|
||||
workingSet[destIdx] = int8(int64(math.Abs(float64(workingVal))) % 10)
|
||||
// fmt.Printf(" = %d\n", workingSet[destIdx])
|
||||
}
|
||||
|
||||
copy(transformed, workingSet)
|
||||
}
|
||||
|
||||
finalVal := 0
|
||||
for i := range transformed[0:8] {
|
||||
finalVal += int(transformed[i]) * int(math.Pow10(8-1-i))
|
||||
}
|
||||
return fmt.Sprintf("First 8 digits of the final output list: %s%d%s", u.TextBold, finalVal, u.TextReset)
|
||||
}
|
||||
|
||||
func (d *Day16) Part2() string {
|
||||
transformed := make([]int8, len(d.numberSet)*10000)
|
||||
for i := 0; i < 10000; i++ {
|
||||
copy(transformed[i*len(d.numberSet):(i*len(d.numberSet))+len(d.numberSet)], d.numberSet)
|
||||
}
|
||||
|
||||
finalMsgOffset := 0
|
||||
for i := 0; i < 7; i++ {
|
||||
finalMsgOffset += int(d.numberSet[i]) * int(math.Pow10(7-1-i))
|
||||
}
|
||||
|
||||
if finalMsgOffset < len(transformed)/2 {
|
||||
panic("offset must be in the back half of the message for this solution to work")
|
||||
}
|
||||
|
||||
phases := 100
|
||||
for p := 0; p < phases; p++ {
|
||||
rollingTotal := int8(0)
|
||||
for i := len(transformed) - 1; i >= finalMsgOffset; i-- {
|
||||
rollingTotal += transformed[i]
|
||||
rollingTotal = rollingTotal % 10
|
||||
transformed[i] = rollingTotal
|
||||
}
|
||||
}
|
||||
|
||||
finalVal := 0
|
||||
for i := range transformed[finalMsgOffset : finalMsgOffset+8] {
|
||||
finalVal += int(transformed[finalMsgOffset+i]) * int(math.Pow10(8-1-i))
|
||||
}
|
||||
return fmt.Sprintf("Embedded message in the final output list: %s%d%s", u.TextBold, finalVal, u.TextReset)
|
||||
}
|
1
inputs/16p.txt
Normal file
1
inputs/16p.txt
Normal file
@ -0,0 +1 @@
|
||||
59791875142707344554745984624833270124746225787022156176259864082972613206097260696475359886661459314067969858521185244807128606896674972341093111690401527976891268108040443281821862422244152800144859031661510297789792278726877676645835805097902853584093615895099152578276185267316851163313487136731134073054989870018294373731775466754420075119913101001966739563592696702233028356328979384389178001923889641041703308599918672055860556825287836987992883550004999016194930620165247185883506733712391462975446192414198344745434022955974228926237100271949068464343172968939069550036969073411905889066207300644632441054836725463178144030305115977951503567
|
1
inputs/16s1.txt
Normal file
1
inputs/16s1.txt
Normal file
@ -0,0 +1 @@
|
||||
12345678
|
1
inputs/16s2.txt
Normal file
1
inputs/16s2.txt
Normal file
@ -0,0 +1 @@
|
||||
80871224585914546619083218645595
|
1
inputs/16s3.txt
Normal file
1
inputs/16s3.txt
Normal file
@ -0,0 +1 @@
|
||||
19617804207202209144916044189917
|
1
inputs/16s4.txt
Normal file
1
inputs/16s4.txt
Normal file
@ -0,0 +1 @@
|
||||
69317163492948606335995924319873
|
Reference in New Issue
Block a user