@@ -7,49 +7,29 @@ namespace AdventOfCode.Y2021.Day16;
7
7
[ ProblemName ( "Packet Decoder" ) ]
8
8
class Solution : Solver {
9
9
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
+ } ;
23
29
}
24
30
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 ( ) ;
53
33
54
34
Input GetInput ( string input ) => new Input (
55
35
( from ch in input
@@ -58,74 +38,62 @@ from bit in bits
58
38
select bit - '0' ) . ToList ( )
59
39
) ;
60
40
61
- Packet Parse ( Input input ) {
41
+ Packet GetPacket ( Input input ) {
62
42
var version = input . ReadInt ( 3 ) ;
63
43
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 ) {
84
44
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 ) {
86
56
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 ) ) ;
90
60
}
91
-
92
61
} 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 ) ) ;
95
64
}
96
65
97
- return new Operator ( version , type , packets . ToArray ( ) ) ;
66
+ return new Packet ( version , type , payload , packets . ToArray ( ) ) ;
98
67
}
99
-
100
68
}
101
69
102
70
class Input {
103
- private List < int > numbers ;
71
+ private List < int > bits ;
104
72
private int ptr ;
73
+
105
74
public Input ( List < int > numbers ) {
106
- this . numbers = numbers ;
75
+ this . bits = numbers ;
107
76
}
108
77
109
78
public bool Any ( ) {
110
- return ptr < numbers . Count ( ) ;
79
+ return ptr < bits . Count ( ) ;
111
80
}
81
+
112
82
public Input ReadInput ( int n ) {
113
- var sub = numbers . GetRange ( ptr , n ) . ToList ( ) ;
83
+ var sub = bits . GetRange ( ptr , n ) . ToList ( ) ;
114
84
var res = new Input ( sub ) ;
115
85
ptr += n ;
116
86
return res ;
117
87
}
118
88
119
89
public int ReadInt ( int n ) {
120
90
var res = 0 ;
121
- foreach ( var bit in numbers . GetRange ( ptr , n ) ) {
91
+ foreach ( var bit in bits . GetRange ( ptr , n ) ) {
122
92
res = res * 2 + bit ;
123
93
}
124
94
ptr += n ;
125
95
return res ;
126
96
}
127
97
}
128
98
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