Skip to content

Commit c0f527a

Browse files
committed
day 16
1 parent 98d2cf5 commit c0f527a

File tree

1 file changed

+47
-79
lines changed

1 file changed

+47
-79
lines changed

2021/Day16/Solution.cs

Lines changed: 47 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -7,49 +7,29 @@ namespace AdventOfCode.Y2021.Day16;
77
[ProblemName("Packet Decoder")]
88
class Solution : Solver {
99

10-
public object PartOne(string input) {
11-
12-
var packet = Parse(GetInput(input));
13-
int rec(Packet p) {
14-
if (p is Literal) {
15-
return p.version;
16-
} else if (p is Operator) {
17-
return p.version + (p as Operator).packets.Select(rec).Sum();
18-
} else {
19-
throw new Exception();
20-
}
21-
}
22-
return rec(packet);
10+
public object PartOne(string input) =>
11+
GetTotalVersion(GetPacket(GetInput(input)));
12+
13+
public object PartTwo(string input) =>
14+
Evaluate(GetPacket(GetInput(input)));
15+
16+
long Evaluate(Packet packet) {
17+
var parts = packet.packets.Select(Evaluate).ToArray();
18+
return packet.type switch {
19+
0 => parts.Sum(),
20+
1 => parts.Aggregate(1L, (acc, x) => acc * x),
21+
2 => parts.Min(),
22+
3 => parts.Max(),
23+
4 => packet.payload,
24+
5 => parts[0] > parts[1] ? 1 : 0,
25+
6 => parts[0] < parts[1] ? 1 : 0,
26+
7 => parts[0] == parts[1] ? 1 : 0,
27+
_ => throw new Exception()
28+
};
2329
}
2430

25-
26-
public object PartTwo(string input) {
27-
var packet = Parse(GetInput(input));
28-
long rec(Packet p) {
29-
if (p is Literal) {
30-
return (p as Literal).value;
31-
} else if (p is Operator) {
32-
var op = p as Operator;
33-
var parts = op.packets.Select(rec).ToArray();
34-
switch (op.type) {
35-
case 0:
36-
return parts.Sum();
37-
case 1:
38-
return parts.Aggregate(1L, (acc, x) => acc * x);
39-
case 2: return parts.Min();
40-
case 3: return parts.Max();
41-
case 5: return parts[0] > parts[1] ? 1 : 0;
42-
case 6: return parts[0] < parts[1] ? 1 : 0;
43-
case 7: return parts[0] == parts[1] ? 1 : 0;
44-
default: throw new Exception();
45-
}
46-
} else {
47-
throw new Exception();
48-
}
49-
}
50-
return rec(packet);
51-
52-
}
31+
int GetTotalVersion(Packet packet) =>
32+
packet.version + packet.packets.Select(GetTotalVersion).Sum();
5333

5434
Input GetInput(string input) => new Input(
5535
(from ch in input
@@ -58,74 +38,62 @@ from bit in bits
5838
select bit - '0').ToList()
5939
);
6040

61-
Packet Parse(Input input) {
41+
Packet GetPacket(Input input) {
6242
var version = input.ReadInt(3);
6343
var type = input.ReadInt(3);
64-
return
65-
type == 0x4 ?
66-
ParseLiteral(version, type, input) :
67-
ParseOperator(version, type, input);
68-
}
69-
70-
Packet ParseLiteral(int version, int type, Input input) {
71-
var value = 0L;
72-
while (true) {
73-
var last = input.ReadInt(1) == 0;
74-
value <<= 4;
75-
value += input.ReadInt(4);
76-
if (last) {
77-
break;
78-
}
79-
}
80-
return new Literal(version, type, value);
81-
}
82-
83-
Packet ParseOperator(int version, int type, Input input) {
8444
var packets = new List<Packet>();
85-
if (input.ReadInt(1) == 0) {
45+
var payload = 0L;
46+
47+
if (type == 0x4) {
48+
while (true) {
49+
var isLast = input.ReadInt(1) == 0;
50+
payload = payload * 16 + input.ReadInt(4);
51+
if (isLast) {
52+
break;
53+
}
54+
}
55+
} else if (input.ReadInt(1) == 0) {
8656
var length = input.ReadInt(15);
87-
var subInput = input.ReadInput(length);
88-
while (subInput.Any()) {
89-
packets.Add(Parse(subInput));
57+
var subPackages = input.ReadInput(length);
58+
while (subPackages.Any()) {
59+
packets.Add(GetPacket(subPackages));
9060
}
91-
9261
} else {
93-
var length = input.ReadInt(11);
94-
packets = Enumerable.Range(0, length).Select(x => Parse(input)).ToList();
62+
var packetCount = input.ReadInt(11);
63+
packets.AddRange(from _ in Enumerable.Range(0, packetCount) select GetPacket(input));
9564
}
9665

97-
return new Operator(version, type, packets.ToArray());
66+
return new Packet(version, type, payload, packets.ToArray());
9867
}
99-
10068
}
10169

10270
class Input {
103-
private List<int> numbers;
71+
private List<int> bits;
10472
private int ptr;
73+
10574
public Input(List<int> numbers) {
106-
this.numbers = numbers;
75+
this.bits = numbers;
10776
}
10877

10978
public bool Any() {
110-
return ptr < numbers.Count();
79+
return ptr < bits.Count();
11180
}
81+
11282
public Input ReadInput(int n) {
113-
var sub = numbers.GetRange(ptr, n).ToList();
83+
var sub = bits.GetRange(ptr, n).ToList();
11484
var res = new Input(sub);
11585
ptr += n;
11686
return res;
11787
}
11888

11989
public int ReadInt(int n) {
12090
var res = 0;
121-
foreach (var bit in numbers.GetRange(ptr, n)) {
91+
foreach (var bit in bits.GetRange(ptr, n)) {
12292
res = res * 2 + bit;
12393
}
12494
ptr += n;
12595
return res;
12696
}
12797
}
12898

129-
record Packet(int version, int type);
130-
record Literal(int version, int type, long value) : Packet(version, type);
131-
record Operator(int version, int type, Packet[] packets) : Packet(version, type);
99+
record Packet(int version, int type, long payload, Packet[] packets);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy