This commit is contained in:
Karl Spickermann 2021-12-16 17:23:52 +01:00
parent 08c17309ad
commit d7099480b7

172
src/day16/day16.go Normal file
View File

@ -0,0 +1,172 @@
package main
import (
"fmt"
"os"
"strconv"
"strings"
)
type packageStruct struct {
version int64
typeID int64
operator string
value int64
subPackages []packageStruct
}
func main() {
args := os.Args[1:]
input := args[0]
binaryNumberString := parseHexToBit(input)
pack, _ := parsePackage(binaryNumberString)
fmt.Println(pack)
sum := int64(0)
sumVers(pack, &sum)
fmt.Println(sum)
fmt.Println(calculatePart2(pack))
}
func calculatePart2(pack packageStruct) int64 {
switch pack.typeID {
case 0:
sum := int64(0)
for _, p := range pack.subPackages {
sum += calculatePart2(p)
}
return sum
case 1:
sum := int64(1)
for _, p := range pack.subPackages {
sum *= calculatePart2(p)
}
return sum
case 2:
min := calculatePart2(pack.subPackages[0])
for _, p := range pack.subPackages {
valueOfSubPackage := calculatePart2(p)
if min > valueOfSubPackage {
min = valueOfSubPackage
}
}
return min
case 3:
max := calculatePart2(pack.subPackages[0])
for _, p := range pack.subPackages {
valueOfSubPackage := calculatePart2(p)
if max < valueOfSubPackage {
max = valueOfSubPackage
}
}
return max
case 5:
if calculatePart2(pack.subPackages[0]) > calculatePart2(pack.subPackages[1]) {
return 1
} else {
return 0
}
case 6:
if calculatePart2(pack.subPackages[0]) < calculatePart2(pack.subPackages[1]) {
return 1
} else {
return 0
}
case 7:
if calculatePart2(pack.subPackages[0]) == calculatePart2(pack.subPackages[1]) {
return 1
} else {
return 0
}
default:
return pack.value
}
}
func sumVers(pack packageStruct, sum *int64) {
*sum += pack.version
for _, p := range pack.subPackages {
sumVers(p, sum)
}
}
func parseHexToBit(hex string) string {
returnString := ""
for _, char := range hex {
number, _ := strconv.ParseInt(string(char), 16, 0)
returnString += padBinaryNumber(strconv.FormatInt(number, 2))
}
return returnString
}
func padBinaryNumber(binaryNumberString string) string {
if (len(binaryNumberString) % 4) > 0 {
amountPaddingZeros := 4 - (len(binaryNumberString) % 4)
binaryNumberString = strings.Repeat("0", amountPaddingZeros) + binaryNumberString
}
return binaryNumberString
}
func parsePackage(binaryNumberString string) (pack packageStruct, index int64) {
index = 0
pack.version, _ = strconv.ParseInt(binaryNumberString[:3], 2, 0)
pack.typeID, _ = strconv.ParseInt(binaryNumberString[3:6], 2, 0)
index += 6
if pack.typeID == 4 {
indexAdd := int64(0)
pack.value, indexAdd = parseLiteralValue(binaryNumberString[6:])
index += indexAdd
return
}
subPackages, indexAdd := parseOperator(binaryNumberString[6:])
pack.subPackages = subPackages
index += indexAdd
return
}
func parseLiteralValue(packageString string) (value int64, index int64) {
index = 0
number := ""
for {
number += packageString[index+1 : index+5]
if packageString[index] == '0' {
value, _ = strconv.ParseInt(number, 2, 0)
index += 5
return
}
index += 5
}
}
func parseOperator(packageString string) (packs []packageStruct, index int64) {
index = 1
lengthTypeID := packageString[0]
if lengthTypeID == '0' {
lengthSubPackets, _ := strconv.ParseInt(packageString[index+1:index+15], 2, 0)
index += 15
subPackageBinary := packageString[index : index+lengthSubPackets]
subPackageIndex := int64(0)
for subPackageIndex < lengthSubPackets {
pack, i := parsePackage(subPackageBinary[subPackageIndex:])
packs = append(packs, pack)
subPackageIndex += i
}
index += lengthSubPackets
return
}
if lengthTypeID == '1' {
neededSubPackets, _ := strconv.ParseInt(packageString[index+1:index+11], 2, 0)
index += 11
subPackageBinary := packageString[index:]
subPackageIndex := int64(0)
countSubPackets := int64(0)
for countSubPackets < neededSubPackets {
pack, i := parsePackage(subPackageBinary[subPackageIndex:])
packs = append(packs, pack)
subPackageIndex += i
countSubPackets++
}
index += subPackageIndex
return
}
return
}