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:])
|
size, subpacketlength := getSubpacketLength(stream[6], stream[7:])
|
||||||
for {
|
for {
|
||||||
consumed, subs := parsePackets(stream[7+size+parsed:])
|
consumed, subs := parsePackets(stream[7+size+parsed:])
|
||||||
|
if consumed == 0 {
|
||||||
|
return parsed + 7 + size, parsedPacket
|
||||||
|
}
|
||||||
parsedPacket.subPackets = append(parsedPacket.subPackets, subs)
|
parsedPacket.subPackets = append(parsedPacket.subPackets, subs)
|
||||||
parsed += consumed
|
parsed += consumed
|
||||||
if size == 11 && len(parsedPacket.subPackets) == subpacketlength {
|
if size == 11 && len(parsedPacket.subPackets) == subpacketlength {
|
||||||
return parsed + 7 + size, parsedPacket
|
return parsed + 7 + size, parsedPacket
|
||||||
|
|
||||||
} else if size == 15 && parsed > subpacketlength || consumed == 0 {
|
} else if size == 15 && parsed > subpacketlength {
|
||||||
return parsed + 7 + size, parsedPacket
|
return parsed + 7 + size, parsedPacket
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,10 +147,97 @@ func partOne() {
|
|||||||
fmt.Println(countVersions(parsedPacket))
|
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() {
|
func partTwo() {
|
||||||
scanner := makeScanner(false)
|
scanner := makeScanner(false)
|
||||||
|
|
||||||
for scanner.Scan() {
|
scanner.Scan()
|
||||||
// line := scanner.Text()
|
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