Day16
This commit is contained in:
parent
08c17309ad
commit
d7099480b7
|
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user