tests all pass, but I'm parsing the real input tree slightly wrong
This commit is contained in:
parent
374dd4a9b7
commit
d1c2f5eb90
96
16/main.go
96
16/main.go
@ -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))
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user