1
+ import java .io .IOException ;
2
+ import java .nio .file .Files ;
3
+ import java .nio .file .Paths ;
4
+ import java .util .ArrayDeque ;
5
+ import java .util .ArrayList ;
6
+ import java .util .Arrays ;
7
+ import java .util .List ;
8
+
9
+ public class Main {
10
+
11
+ enum Compare {
12
+ LEFT (-1 ), RIGHT (1 ), BOTH (0 );
13
+
14
+ final int value ;
15
+
16
+ Compare (int value ) {
17
+ this .value = value ;
18
+ }
19
+ }
20
+
21
+ interface Node {
22
+ int size ();
23
+ }
24
+
25
+ record Pair (String left , String right ){}
26
+ static class ValueNode implements Node , Comparable <ValueNode > {
27
+ int value ;
28
+
29
+ ValueNode (int value ) {
30
+ this .value = value ;
31
+ }
32
+ @ Override
33
+ public int size () {
34
+ return 1 ;
35
+ }
36
+
37
+ public TreeNode asTreeNode () {
38
+ return new TreeNode (Arrays .asList (this ));
39
+ }
40
+
41
+ @ Override
42
+ public int compareTo (ValueNode other ) {
43
+ if (value < other .value )
44
+ return Compare .RIGHT .value ;
45
+ if (value > other .value )
46
+ return Compare .LEFT .value ;
47
+ return Compare .BOTH .value ;
48
+ }
49
+
50
+ @ Override
51
+ public String toString () {
52
+ return Integer .toString (value );
53
+ }
54
+ }
55
+
56
+ record TreeNode (List <Node > values ) implements Node {
57
+ @ Override
58
+ public int size () {
59
+ return values .size ();
60
+ }
61
+
62
+ public TreeNode subList () {
63
+ var result = new TreeNode (new ArrayList <>());
64
+ values .add (result );
65
+ return result ;
66
+ }
67
+
68
+ public void replaceLast (Main .ValueNode result ) {
69
+ values .remove (values .size ()-1 );
70
+ values .add (result );
71
+ }
72
+
73
+ public void updateLatestValue (int digit ) {
74
+ var valueNode = (ValueNode )values .get (values .size ()-1 );
75
+ valueNode .value = digit + (valueNode .value * 10 );
76
+ }
77
+
78
+ @ Override
79
+ public String toString () {
80
+ return values .toString ();
81
+ }
82
+ }
83
+
84
+
85
+ static TreeNode [] DIVIDER_PACKETS = {
86
+ new TreeNode (Arrays .asList (new ValueNode (2 ).asTreeNode ())), // "[[2]]"
87
+ new TreeNode (Arrays .asList (new ValueNode (6 ).asTreeNode ())) // "[[6]]"
88
+ };
89
+
90
+ public static void main (String [] args ) throws IOException {
91
+ var input = Files .lines (Paths .get ("2022/day13/src/main/resources/input.txt" )).toList ();
92
+ // var input = Files.lines(Paths.get("2022/day13/src/main/resources/test.txt")).toList();
93
+
94
+
95
+ var pairs = new ArrayList <TreeNode >();
96
+ for (int i =0 ; i < input .size (); i +=3 ) {
97
+ pairs .add (parseLine (input .get (i ).trim ()));
98
+ pairs .add (parseLine (input .get (i +1 ).trim ()));
99
+ }
100
+ pairs .sort ((a ,b ) -> -compareTo (a , b ));
101
+ int [] beforeIndexes = new int []{1 , 2 }; // 1 based index, +1 for [[2]] not in index
102
+
103
+ for (int i =0 ; i < pairs .size (); i ++) {
104
+ var pair = pairs .get (i );
105
+ for (int di =0 ; di < DIVIDER_PACKETS .length ; di ++){
106
+ boolean rightOrder = compareTo (pair , DIVIDER_PACKETS [di ]) != Compare .LEFT .value ;
107
+ if (rightOrder ) {
108
+ beforeIndexes [di ]++;
109
+ }
110
+ }
111
+ }
112
+ System .out .println ("\n Total: " + Arrays .toString (beforeIndexes ) + " => " + Arrays .stream (beforeIndexes ).reduce ((a ,b ) -> a *b ).getAsInt ());
113
+ }
114
+
115
+
116
+ static boolean rightOrder (String left , String right ) {
117
+ var leftNode = parseLine (left );
118
+ var rightNode = parseLine (right );
119
+
120
+ int outcome = compareTo (leftNode , rightNode );
121
+ return outcome != Compare .LEFT .value ;
122
+ }
123
+
124
+
125
+ static int compareTo (Node left , Node right ) {
126
+ // System.out.println(left + " vs " + right);
127
+
128
+ // ValueNode vs ValueNode
129
+ if (left instanceof ValueNode l && right instanceof ValueNode r ) {
130
+ return l .compareTo (r );
131
+ }
132
+
133
+ // TreeNode vs TreeNode
134
+ if (left instanceof TreeNode l && right instanceof TreeNode r ) {
135
+ return compareTo (l , r );
136
+ }
137
+
138
+ // if entry is value and tree then value as tree and retry
139
+ if (left instanceof ValueNode l ) {
140
+ return compareTo (l .asTreeNode (), right );
141
+ } else if (right instanceof ValueNode r ) {
142
+ return compareTo (left , r .asTreeNode ());
143
+ }
144
+ throw new IllegalStateException ("Invalid state for nodes" );
145
+ }
146
+
147
+ static int compareTo (TreeNode left , TreeNode right ) {
148
+ // foreach(node : tree) check(node)
149
+ // if left.isempty && right.isnotempty = OK
150
+ // if left.isnotempty && right.isempty = NOK
151
+ // if both.empty = check more
152
+ for (int i = 0 ; i < Math .min (left .size (), right .size ()); i ++) {
153
+ int cmp = compareTo (left .values .get (i ), right .values .get (i ));
154
+ if (cmp != 0 ) {
155
+ return cmp ;
156
+ }
157
+ }
158
+ return left .size () > right .size () ? Compare .LEFT .value :
159
+ left .size () < right .size () ? Compare .RIGHT .value : Compare .BOTH .value ;
160
+ }
161
+
162
+
163
+ static TreeNode parseLine (String line ) {
164
+ TreeNode result = new TreeNode (new ArrayList <>());
165
+ var stack = new ArrayDeque <TreeNode >();
166
+ var input = line .toCharArray ();
167
+ for (int i =0 ; i < input .length ; i ++) {
168
+ if (input [i ] == '[' ) {
169
+ if (stack .isEmpty ()) {
170
+ stack .push (result );
171
+ } else {
172
+ var newTree = stack .peek ().subList ();
173
+ stack .push (newTree );
174
+ }
175
+ } else if (input [i ] == ']' ) {
176
+ stack .pop ();
177
+ } else if (input [i ] == ',' ) {
178
+
179
+ } else if (Character .isDigit (input [i ])) {
180
+ if (Character .isDigit (input [i -1 ])) {
181
+ stack .peek ().updateLatestValue (Character .digit (input [i ], 10 ));
182
+ } else {
183
+ stack .peek ().values .add (new ValueNode (Character .digit (input [i ], 10 )));
184
+ }
185
+ }
186
+ }
187
+ return result ;
188
+ }
189
+
190
+ }
0 commit comments