Skip to content

Commit 319b733

Browse files
committed
Add comments
1 parent d876559 commit 319b733

File tree

2 files changed

+76
-63
lines changed

2 files changed

+76
-63
lines changed

Diff for: 2021/16/main.go

+74-63
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,52 @@ func main() {
1313
fmt.Printf("Part 2: %d\n", part2(util.RelativeFile("input"))) // 13476220616073
1414
}
1515

16-
type parser struct {
16+
func part1(file string) int64 {
17+
data, err := hex.DecodeString(util.ReadLinesStrings(file)[0])
18+
util.Check(err)
19+
p := Parser{data: data}
20+
p.ReadNumSubPackets(1)
21+
return p.sumVersionNums
22+
}
23+
24+
func part2(file string) int64 {
25+
return evalExpression(util.ReadLinesStrings(file)[0])
26+
}
27+
28+
func evalExpression(text string) int64 {
29+
data, err := hex.DecodeString(text)
30+
util.Check(err)
31+
p := Parser{data: data}
32+
var out []int64
33+
out, _ = p.ReadNumSubPackets(1)
34+
return out[0]
35+
}
36+
37+
// Parser holds data for parsing the Buoyancy Interchange Transmission System (BITS) expression.
38+
type Parser struct {
1739
data []byte
1840
pos int
1941
sumVersionNums int64
2042
}
2143

22-
func (p *parser) ReadLiteral() (int64, bool) {
44+
func (p *Parser) Chomp(ln int) (int64, bool) {
45+
i := bits.GetAsInt(p.data, p.pos, ln)
46+
p.pos += ln
47+
return i, (len(p.data)*8)-1 > p.pos
48+
}
49+
50+
// ReadVersion reads the 3 bits at the start of the expression. These are only useful for part 1 of day 16.
51+
func (p *Parser) ReadVersion() (int64, bool) {
52+
return p.Chomp(3)
53+
}
54+
55+
// ReadMode reads the 3 bits of the mode at the head of an expression (after the version).
56+
func (p *Parser) ReadMode() (int64, bool) {
57+
return p.Chomp(3)
58+
}
59+
60+
// ReadLiteral reads a single literal value.
61+
func (p *Parser) ReadLiteral() (int64, bool) {
2362
var ok bool
2463
var read int64
2564
val := int64(0)
@@ -36,21 +75,45 @@ func (p *parser) ReadLiteral() (int64, bool) {
3675
return val, ok
3776
}
3877

39-
func (p *parser) Chomp(ln int) (int64, bool) {
40-
i := bits.GetAsInt(p.data, p.pos, ln)
41-
p.pos += ln
42-
return i, (len(p.data)*8)-1 > p.pos
78+
// ReadNested begins to parse a sub-packet chunk.
79+
// If the length type id is 0 - read packets until the total number of bits has been reached
80+
// If the length type id is 1 - read the specified number of packets
81+
func (p *Parser) ReadNested() ([]int64, bool) {
82+
lengthTypeId, _ := p.Chomp(1)
83+
if lengthTypeId == 0 {
84+
// Total number of bits
85+
totalNumberOfBits, _ := p.Chomp(15)
86+
return p.ReadSubPacketsOfLength(int(totalNumberOfBits))
87+
} else {
88+
numberOfPackets, _ := p.Chomp(11)
89+
return p.ReadNumSubPackets(numberOfPackets)
90+
}
4391
}
4492

45-
func (p *parser) ReadVersion() (int64, bool) {
46-
return p.Chomp(3)
93+
// ReadNumSubPackets reads the specified number of sub-packets
94+
func (p *Parser) ReadNumSubPackets(num int64) ([]int64, bool) {
95+
var out []int64
96+
for i := int64(0); i < num; i++ {
97+
o, _ := p.ReadSubPacket()
98+
out = append(out, o)
99+
}
100+
return out, true
47101
}
48102

49-
func (p *parser) ReadMode() (int64, bool) {
50-
return p.Chomp(3)
103+
// ReadSubPacketsOfLength reads sub-packets limited to the number of bits
104+
func (p *Parser) ReadSubPacketsOfLength(lim int) ([]int64, bool) {
105+
var out []int64
106+
lim = p.pos + lim
107+
for p.pos < lim {
108+
o, _ := p.ReadSubPacket()
109+
out = append(out, o)
110+
}
111+
return out, true
51112
}
52113

53-
func (p *parser) ReadSub() (int64, bool) {
114+
// ReadSubPacket reads a single sub-packet. However, since a sub-packet can have more sub-packets it is recursive via
115+
// ReadNested calls back to itself.
116+
func (p *Parser) ReadSubPacket() (int64, bool) {
54117
var out int64
55118
var ok bool
56119
v, _ := p.ReadVersion()
@@ -121,55 +184,3 @@ func (p *parser) ReadSub() (int64, bool) {
121184

122185
return out, ok
123186
}
124-
125-
func (p *parser) ReadNested() ([]int64, bool) {
126-
lengthTypeId, _ := p.Chomp(1)
127-
if lengthTypeId == 0 {
128-
// Total number of bits
129-
totalNumberOfBits, _ := p.Chomp(15)
130-
return p.ReadBits(int(totalNumberOfBits))
131-
} else {
132-
numberOfPackets, _ := p.Chomp(11)
133-
return p.ReadNumSubPackets(numberOfPackets)
134-
}
135-
}
136-
137-
func (p *parser) ReadNumSubPackets(num int64) ([]int64, bool) {
138-
var out []int64
139-
for i := int64(0); i < num; i++ {
140-
o, _ := p.ReadSub()
141-
out = append(out, o)
142-
}
143-
return out, true
144-
}
145-
146-
func (p *parser) ReadBits(lim int) ([]int64, bool) {
147-
var out []int64
148-
lim = p.pos + lim
149-
for p.pos < lim {
150-
o, _ := p.ReadSub()
151-
out = append(out, o)
152-
}
153-
return out, true
154-
}
155-
156-
func part1(file string) int64 {
157-
data, err := hex.DecodeString(util.ReadLinesStrings(file)[0])
158-
util.Check(err)
159-
p := parser{data: data}
160-
p.ReadNumSubPackets(1)
161-
return p.sumVersionNums
162-
}
163-
164-
func part2(file string) int64 {
165-
return evalExpression(util.ReadLinesStrings(file)[0])
166-
}
167-
168-
func evalExpression(text string) int64 {
169-
data, err := hex.DecodeString(text)
170-
util.Check(err)
171-
p := parser{data: data}
172-
var out []int64
173-
out, _ = p.ReadNumSubPackets(1)
174-
return out[0]
175-
}

Diff for: util/bits/bits.go

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package bits
22

33
var lookup = []int64{0b0, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF}
44

5+
// https://stackoverflow.com/a/3847525
6+
57
func GetAsInt(bytes []byte, offset int, ln int) int64 {
68
byteIndex := offset / 8
79
bitIndex := offset % 8

0 commit comments

Comments
 (0)