tests all pass, but I'm parsing the real input tree slightly wrong

This commit is contained in:
David 2021-12-20 19:02:26 -05:00
parent 374dd4a9b7
commit d1c2f5eb90
2 changed files with 118 additions and 3 deletions

View File

@ -111,12 +111,15 @@ func parsePackets(stream []uint8) (int, packet) {
size, subpacketlength := getSubpacketLength(stream[6], stream[7:])
for {
consumed, subs := parsePackets(stream[7+size+parsed:])
if consumed == 0 {
return parsed + 7 + size, parsedPacket
}
parsedPacket.subPackets = append(parsedPacket.subPackets, subs)
parsed += consumed
if size == 11 && len(parsedPacket.subPackets) == subpacketlength {
return parsed + 7 + size, parsedPacket
} else if size == 15 && parsed > subpacketlength || consumed == 0 {
} else if size == 15 && parsed > subpacketlength {
return parsed + 7 + size, parsedPacket
}
}
@ -144,10 +147,97 @@ func partOne() {
fmt.Println(countVersions(parsedPacket))
}
func solve(p packet) int {
switch p.typeID {
case 0: // sum
if len(p.subPackets) == 1 {
return solve(p.subPackets[0])
} else {
acc := 0
for _, v := range p.subPackets {
acc += solve(v)
}
return acc
}
case 1: // product
if len(p.subPackets) == 1 {
return solve(p.subPackets[0])
} else {
acc := solve(p.subPackets[0])
for _, v := range p.subPackets[1:] {
acc *= solve(v)
}
return acc
}
case 2: // min
if len(p.subPackets) == 1 {
return solve(p.subPackets[0])
} else {
acc := solve(p.subPackets[0])
for _, v := range p.subPackets[1:] {
t := solve(v)
if t < acc {
acc = t
}
}
return acc
}
case 3: // max
if len(p.subPackets) == 1 {
return solve(p.subPackets[0])
} else {
acc := solve(p.subPackets[0])
for _, v := range p.subPackets[1:] {
t := solve(v)
if t > acc {
acc = t
}
}
return acc
}
case 4: // number
return p.encodedNumber
case 5: // >
if len(p.subPackets) != 2 {
panic(fmt.Sprintf("recevied type 5 packet with %d subpackets", len(p.subPackets)))
}
if solve(p.subPackets[0]) > solve(p.subPackets[1]) {
return 1
} else {
return 0
}
case 6: // <
if len(p.subPackets) != 2 {
panic(fmt.Sprintf("recevied type 6 packet with %d subpackets", len(p.subPackets)))
}
if solve(p.subPackets[0]) < solve(p.subPackets[1]) {
return 1
} else {
return 0
}
case 7: // ==
if len(p.subPackets) != 2 {
panic(fmt.Sprintf("recevied type 7 packet with %d subpackets", len(p.subPackets)))
}
if solve(p.subPackets[0]) == solve(p.subPackets[1]) {
return 1
} else {
return 0
}
default:
panic("unknown packet type")
}
}
func partTwo() {
scanner := makeScanner(false)
for scanner.Scan() {
// line := scanner.Text()
scanner.Scan()
line := scanner.Text()
stream := []uint8{}
for _, hex := range line {
stream = append(stream, hexMap[hex]...)
}
_, parsedPacket := parsePackets(stream)
fmt.Println(solve(parsedPacket))
}

View File

@ -59,3 +59,28 @@ func TestCases(t *testing.T) {
}
}
}
func TestSolving(t *testing.T) {
inputs := map[string]int{
"C200B40A82": 3,
"04005AC33890": 54,
"880086C3E88112": 7,
"CE00C43D881120": 9,
"D8005AC2A8F0": 1,
"F600BC2D8F": 0,
"9C005AC2F8F0": 0,
"9C0141080250320F1802104A08": 1,
}
for c, r := range inputs {
stream := []uint8{}
for _, hex := range c {
stream = append(stream, hexMap[hex]...)
}
_, parsedPacket := parsePackets(stream)
if r != solve(parsedPacket) {
t.Log(c, solve(parsedPacket))
t.Fail()
}
}
}