2021 Day 16 Complete
This commit is contained in:
parent
5aaf7163dc
commit
e91157fca7
1
2021/day16/input
Normal file
1
2021/day16/input
Normal file
@ -0,0 +1 @@
|
|||||||
|
E0529D18025800ABCA6996534CB22E4C00FB48E233BAEC947A8AA010CE1249DB51A02CC7DB67EF33D4002AE6ACDC40101CF0449AE4D9E4C071802D400F84BD21CAF3C8F2C35295EF3E0A600848F77893360066C200F476841040401C88908A19B001FD35CCF0B40012992AC81E3B980553659366736653A931018027C87332011E2771FFC3CEEC0630A80126007B0152E2005280186004101060C03C0200DA66006B8018200538012C01F3300660401433801A6007380132DD993100A4DC01AB0803B1FE2343500042E24C338B33F5852C3E002749803B0422EC782004221A41A8CE600EC2F8F11FD0037196CF19A67AA926892D2C643675A0C013C00CC0401F82F1BA168803510E3942E969C389C40193CFD27C32E005F271CE4B95906C151003A7BD229300362D1802727056C00556769101921F200AC74015960E97EC3F2D03C2430046C0119A3E9A3F95FD3AFE40132CEC52F4017995D9993A90060729EFCA52D3168021223F2236600ECC874E10CC1F9802F3A71C00964EC46E6580402291FE59E0FCF2B4EC31C9C7A6860094B2C4D2E880592F1AD7782992D204A82C954EA5A52E8030064D02A6C1E4EA852FE83D49CB4AE4020CD80272D3B4AA552D3B4AA5B356F77BF1630056C0119FF16C5192901CEDFB77A200E9E65EAC01693C0BCA76FEBE73487CC64DEC804659274A00CDC401F8B51CE3F8803B05217C2E40041A72E2516A663F119AC72250A00F44A98893C453005E57415A00BCD5F1DD66F3448D2600AC66F005246500C9194039C01986B317CDB10890C94BF68E6DF950C0802B09496E8A3600BCB15CA44425279539B089EB7774DDA33642012DA6B1E15B005C0010C8C917A2B880391160944D30074401D845172180803D1AA3045F00042630C5B866200CC2A9A5091C43BBD964D7F5D8914B46F040
|
240
2021/day16/main.go
Normal file
240
2021/day16/main.go
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
inp := h.StdinToString()
|
||||||
|
var arg string
|
||||||
|
if len(os.Args) > 1 {
|
||||||
|
arg = os.Args[1]
|
||||||
|
}
|
||||||
|
|
||||||
|
p := ParsePacket(inp)
|
||||||
|
if arg == "--json" {
|
||||||
|
fmt.Println(p.Json())
|
||||||
|
} else {
|
||||||
|
fmt.Println("# Part 1")
|
||||||
|
fmt.Println("Version Sum:", CalculateVersionSum(p))
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println("# Part 2")
|
||||||
|
fmt.Println("Value:", p.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func CalculateVersionSum(p *Packet) int {
|
||||||
|
sum := p.version
|
||||||
|
for s := range p.packets {
|
||||||
|
sum += CalculateVersionSum(p.packets[s])
|
||||||
|
}
|
||||||
|
return sum
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
PacketTypeSum = iota
|
||||||
|
PacketTypeProduct
|
||||||
|
PacketTypeMin
|
||||||
|
PacketTypeMax
|
||||||
|
PacketTypeLiteral
|
||||||
|
PacketTypeGreater
|
||||||
|
PacketTypeLess
|
||||||
|
PacketTypeEqual
|
||||||
|
|
||||||
|
LengthTypeBits = 0
|
||||||
|
LengthTypeSubPackets = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
type Packet struct {
|
||||||
|
version int
|
||||||
|
packetType int
|
||||||
|
|
||||||
|
value int
|
||||||
|
|
||||||
|
// Operator
|
||||||
|
lengthTypeId int
|
||||||
|
subLength int
|
||||||
|
|
||||||
|
// Sub-packets
|
||||||
|
packets []*Packet
|
||||||
|
|
||||||
|
binaryString string
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParsePacket(inp string) *Packet {
|
||||||
|
var bin string
|
||||||
|
for i := 0; i < len(inp); i += 2 {
|
||||||
|
if len(inp) >= i+2 {
|
||||||
|
bin += fmt.Sprintf("%08b", HexToByte(inp[i:i+2]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ParseBinaryPacket(bin)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseBinaryPacket(inp string) *Packet {
|
||||||
|
p := Packet{
|
||||||
|
binaryString: inp,
|
||||||
|
}
|
||||||
|
// Parse the version
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
p.version = p.version << 1
|
||||||
|
if p.binaryString[i] == '1' {
|
||||||
|
p.version |= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := 3; i < 6; i++ {
|
||||||
|
p.packetType = p.packetType << 1
|
||||||
|
if p.binaryString[i] == '1' {
|
||||||
|
p.packetType |= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if p.packetType == PacketTypeLiteral {
|
||||||
|
p.parseLiteral()
|
||||||
|
} else {
|
||||||
|
p.parseOperator()
|
||||||
|
}
|
||||||
|
return &p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packet) parseLiteral() {
|
||||||
|
// The bits for the literal start at bit 7
|
||||||
|
// Every 5 bits is a chunk of the literal
|
||||||
|
ptr := 6
|
||||||
|
more := true
|
||||||
|
for more {
|
||||||
|
more = (p.binaryString[ptr] == '1')
|
||||||
|
ptr++
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
p.value = p.value << 1
|
||||||
|
if p.binaryString[ptr] == '1' {
|
||||||
|
p.value |= 1
|
||||||
|
}
|
||||||
|
ptr++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.binaryString = p.binaryString[:ptr]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Packet) parseOperator() {
|
||||||
|
ptr := 6
|
||||||
|
p.lengthTypeId = int(p.binaryString[ptr] - '0')
|
||||||
|
ptr++
|
||||||
|
if p.lengthTypeId == LengthTypeBits {
|
||||||
|
for i := 0; i < 15; i++ {
|
||||||
|
p.subLength = p.subLength << 1
|
||||||
|
if p.binaryString[ptr] == '1' {
|
||||||
|
p.subLength |= 1
|
||||||
|
}
|
||||||
|
ptr++
|
||||||
|
}
|
||||||
|
length := p.subLength
|
||||||
|
for length > 0 {
|
||||||
|
sp := ParseBinaryPacket(p.binaryString[ptr:])
|
||||||
|
p.packets = append(p.packets, sp)
|
||||||
|
ptr += len(sp.binaryString)
|
||||||
|
length -= len(sp.binaryString)
|
||||||
|
}
|
||||||
|
p.binaryString = p.binaryString[:ptr]
|
||||||
|
} else if p.lengthTypeId == LengthTypeSubPackets {
|
||||||
|
for i := 0; i < 11; i++ {
|
||||||
|
p.subLength = p.subLength << 1
|
||||||
|
if p.binaryString[ptr] == '1' {
|
||||||
|
p.subLength |= 1
|
||||||
|
}
|
||||||
|
ptr++
|
||||||
|
}
|
||||||
|
length := p.subLength
|
||||||
|
for length > 0 {
|
||||||
|
sp := ParseBinaryPacket(p.binaryString[ptr:])
|
||||||
|
p.packets = append(p.packets, sp)
|
||||||
|
ptr += len(sp.binaryString)
|
||||||
|
length--
|
||||||
|
}
|
||||||
|
p.binaryString = p.binaryString[:ptr]
|
||||||
|
}
|
||||||
|
switch p.packetType {
|
||||||
|
case PacketTypeSum:
|
||||||
|
for _, sp := range p.packets {
|
||||||
|
p.value += sp.value
|
||||||
|
}
|
||||||
|
case PacketTypeProduct:
|
||||||
|
p.value = 1
|
||||||
|
for _, sp := range p.packets {
|
||||||
|
p.value *= sp.value
|
||||||
|
}
|
||||||
|
case PacketTypeMin:
|
||||||
|
p.value = h.MAX_INT
|
||||||
|
for _, sp := range p.packets {
|
||||||
|
if sp.value < p.value {
|
||||||
|
p.value = sp.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case PacketTypeMax:
|
||||||
|
p.value = h.MIN_INT
|
||||||
|
for _, sp := range p.packets {
|
||||||
|
if sp.value > p.value {
|
||||||
|
p.value = sp.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case PacketTypeGreater:
|
||||||
|
if len(p.packets) == 2 && (p.packets[0].value > p.packets[1].value) {
|
||||||
|
p.value = 1
|
||||||
|
} else {
|
||||||
|
p.value = 0
|
||||||
|
}
|
||||||
|
case PacketTypeLess:
|
||||||
|
if len(p.packets) == 2 && (p.packets[0].value < p.packets[1].value) {
|
||||||
|
p.value = 1
|
||||||
|
} else {
|
||||||
|
p.value = 0
|
||||||
|
}
|
||||||
|
case PacketTypeEqual:
|
||||||
|
if len(p.packets) == 2 && (p.packets[0].value == p.packets[1].value) {
|
||||||
|
p.value = 1
|
||||||
|
} else {
|
||||||
|
p.value = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Packet) Json() string {
|
||||||
|
ret := fmt.Sprintf("{\"version\":%d, \"type\":%d, \"value\":%d,", p.version, p.packetType, p.value)
|
||||||
|
ret += "\"packets\":["
|
||||||
|
for i := range p.packets {
|
||||||
|
ret += fmt.Sprintf("%s", p.packets[i].String())
|
||||||
|
if i < len(p.packets)-1 {
|
||||||
|
ret += ","
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret += fmt.Sprintf("],\"binary\":\"%s\"}", p.binaryString)
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Packet) String() string {
|
||||||
|
if p.packetType == PacketTypeLiteral {
|
||||||
|
return fmt.Sprintf("%d", p.value)
|
||||||
|
} else {
|
||||||
|
return p.Json()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func HexToByte(h string) byte {
|
||||||
|
var b byte
|
||||||
|
for i := range h {
|
||||||
|
var wrk byte
|
||||||
|
if h[i] >= '0' && h[i] <= '9' {
|
||||||
|
wrk = byte(h[i] - '0')
|
||||||
|
} else if h[i] >= 'A' && h[i] <= 'F' {
|
||||||
|
wrk = byte(h[i]-'A') + 10
|
||||||
|
}
|
||||||
|
if i == 0 {
|
||||||
|
b = wrk << 4
|
||||||
|
} else {
|
||||||
|
b |= wrk
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
1
2021/day16/packet_literal2021
Normal file
1
2021/day16/packet_literal2021
Normal file
@ -0,0 +1 @@
|
|||||||
|
D2FE28
|
1
2021/day16/packet_literal2021_cruft
Normal file
1
2021/day16/packet_literal2021_cruft
Normal file
@ -0,0 +1 @@
|
|||||||
|
D2FE28FEDCBA987654321
|
1
2021/day16/packet_operator0
Normal file
1
2021/day16/packet_operator0
Normal file
@ -0,0 +1 @@
|
|||||||
|
38006F45291200
|
1
2021/day16/packet_operator0_cruft
Normal file
1
2021/day16/packet_operator0_cruft
Normal file
@ -0,0 +1 @@
|
|||||||
|
38006F45291200FEDCBA0987654321
|
1
2021/day16/packet_operator1
Normal file
1
2021/day16/packet_operator1
Normal file
@ -0,0 +1 @@
|
|||||||
|
EE00D40C823060
|
1
2021/day16/test.json
Normal file
1
2021/day16/test.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"version":0, "type":1, "binary":"00000100000000000101101011000011001110001001",'packets':[6,9]}
|
1
2021/day16/testinput1
Normal file
1
2021/day16/testinput1
Normal file
@ -0,0 +1 @@
|
|||||||
|
8A004A801A8002F478
|
1
2021/day16/testinput2
Normal file
1
2021/day16/testinput2
Normal file
@ -0,0 +1 @@
|
|||||||
|
620080001611562C8802118E34
|
1
2021/day16/testinput3
Normal file
1
2021/day16/testinput3
Normal file
@ -0,0 +1 @@
|
|||||||
|
C0015000016115A2E0802F182340
|
1
2021/day16/testinput4
Normal file
1
2021/day16/testinput4
Normal file
@ -0,0 +1 @@
|
|||||||
|
A0016C880162017C3686B18A3D4780
|
Loading…
Reference in New Issue
Block a user