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.
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