1
+ import static com .github .pareronia .aoc .IntegerSequence .Range .range ;
2
+ import static java .util .stream .Collectors .joining ;
1
3
import static java .util .stream .Collectors .toCollection ;
2
4
3
5
import java .util .ArrayList ;
4
6
import java .util .Arrays ;
5
- import java .util .HashMap ;
6
- import java .util .IntSummaryStatistics ;
7
7
import java .util .List ;
8
- import java .util .Map ;
9
- import java .util .Objects ;
8
+ import java .util .Set ;
9
+ import java .util .stream . IntStream ;
10
10
import java .util .stream .Stream ;
11
11
12
12
import com .github .pareronia .aoc .StringOps ;
13
13
import com .github .pareronia .aoc .solution .Sample ;
14
14
import com .github .pareronia .aoc .solution .Samples ;
15
15
import com .github .pareronia .aoc .solution .SolutionBase ;
16
16
17
- public class AoC2020_23 extends SolutionBase <List <Integer >, Long , Long > {
17
+ public class AoC2020_23 extends SolutionBase <List <Integer >, String , Long > {
18
18
19
19
private AoC2020_23 (final boolean debug ) {
20
20
super (debug );
@@ -35,92 +35,67 @@ protected List<Integer> parseInput(final List<String> inputs) {
35
35
return Arrays .stream (digits ).toList ();
36
36
}
37
37
38
- private Map <Integer , Cup > prepareCups (final List <Integer > labels ) {
39
- final Map <Integer , Cup > cups = new HashMap <>();
40
- final Integer first = labels .get (0 );
41
- final Integer last = labels .get (labels .size () - 1 );
42
- final Cup tail = new Cup (last , (Cup ) null );
43
- Cup prev = tail ;
44
- Cup cup ;
45
- for (int i = labels .size () - 2 ; i > 0 ; i --) {
46
- final Integer label = labels .get (i );
47
- cup = new Cup (label , prev );
48
- cups .put (label , cup );
49
- prev = cup ;
50
- }
51
- final Cup head = new Cup (first , prev );
52
- cups .put (first , head );
53
- tail .setNext (head );
54
- cups .put (last , tail );
55
- return cups ;
56
- }
57
-
58
- private Cup doMove (
59
- final Map <Integer , Cup > cups ,
60
- final Cup current ,
61
- final Integer size ,
62
- final Integer min ,
63
- final Integer max ) {
64
- final Cup p1 = current .getNext ();
65
- final Cup p2 = p1 .getNext ();
66
- final Cup p3 = p2 .getNext ();
67
- current .setNext (p3 .getNext ());
68
- final List <Integer > pickup
69
- = List .of (p1 .getLabel (), p2 .getLabel (), p3 .getLabel ());
70
- Integer d = current .getLabel () - 1 ;
71
- if (d < min ) {
72
- d = max ;
73
- }
38
+ private int [] prepareCups (final List <Integer > labels ) {
39
+ final int [] cups = new int [labels .size () + 1 ];
40
+ range (labels .size ()).forEach (i -> {
41
+ cups [labels .get (i )] = labels .get ((i + 1 ) % labels .size ());
42
+ });
43
+ return cups ;
44
+ }
45
+
46
+ private int doMove (
47
+ final int [] cups ,
48
+ final int current ,
49
+ final int min ,
50
+ final int max
51
+ ) {
52
+ final int c = current ;
53
+ final int p1 = cups [c ];
54
+ final int p2 = cups [p1 ];
55
+ final int p3 = cups [p2 ];
56
+ cups [c ] = cups [p3 ];
57
+ final Set <Integer > pickup = Set .of (p1 , p2 , p3 );
58
+ int d = c - 1 ;
59
+ if (d < min ) {
60
+ d = max ;
61
+ }
74
62
while (pickup .contains (d )) {
75
63
d --;
76
64
if (d < min ) {
77
65
d = max ;
78
66
}
79
67
}
80
- final Cup destination = cups .get (d );
81
- p3 .setNext (destination .getNext ());
82
- destination .setNext (p1 );
83
- return current .getNext ();
84
- }
85
-
68
+ cups [p3 ] = cups [d ];
69
+ cups [d ] = p1 ;
70
+ return cups [c ];
71
+ }
72
+
86
73
@ Override
87
- public Long solvePart1 (final List <Integer > labels ) {
88
- final Map <Integer , Cup > cups = prepareCups (labels );
89
- final int size = labels .size ();
90
- final IntSummaryStatistics stats
91
- = labels .stream ().mapToInt (Integer ::valueOf ).summaryStatistics ();
92
- final Integer min = stats .getMin ();
93
- final Integer max = stats .getMax ();
94
- Cup current = cups .get (labels .get (0 ));
74
+ public String solvePart1 (final List <Integer > labels ) {
75
+ final int [] cups = prepareCups (labels );
76
+ int current = labels .get (0 );
95
77
for (int i = 0 ; i < 100 ; i ++) {
96
- current = doMove (cups , current , size , min , max );
78
+ current = doMove (cups , current , 1 , 9 );
97
79
}
98
- Cup cup = cups .get (1 );
99
- final StringBuilder result = new StringBuilder ();
100
- while (cup .getNext ().getLabel () != 1 ) {
101
- result .append (cup .getNext ().getLabel ());
102
- cup = cup .getNext ();
103
- }
104
- return Long .valueOf (result .toString ());
80
+ return IntStream .iterate (cups [1 ], cup -> cups [cup ])
81
+ .takeWhile (cup -> cup != 1 )
82
+ .mapToObj (String ::valueOf )
83
+ .collect (joining ());
105
84
}
106
85
107
86
@ Override
108
87
public Long solvePart2 (final List <Integer > labels ) {
109
- final IntSummaryStatistics stats
110
- = labels .stream ().mapToInt (Integer ::valueOf ).summaryStatistics ();
111
- final Integer min = stats .getMin ();
112
- final Integer max = stats .getMax ();
113
- final List <Integer > newLabels = new ArrayList <>(labels );
114
- Stream .iterate (max + 1 , i -> i + 1 ).limit (1_000_000 - labels .size ())
88
+ final List <Integer > newLabels = new ArrayList <>(1_000_000 );
89
+ newLabels .addAll (labels );
90
+ Stream .iterate (10 , i -> i + 1 ).limit (1_000_000 - labels .size ())
115
91
.collect (toCollection (() -> newLabels ));
116
- final Map < Integer , Cup > cups = prepareCups (newLabels );
117
- Cup current = cups .get (newLabels . get ( 0 ) );
92
+ final int [] cups = prepareCups (newLabels );
93
+ int current = labels .get (0 );
118
94
for (int i = 0 ; i < 10_000_000 ; i ++) {
119
- current = doMove (cups , current , 1_000_000 , min , 1_000_000 );
95
+ current = doMove (cups , current , 1 , 1_000_000 );
120
96
}
121
- final Cup one = cups .get (1 );
122
- final long star1 = one .getNext ().getLabel ().longValue ();
123
- final long star2 = one .getNext ().getNext ().getLabel ().longValue ();
97
+ final long star1 = cups [1 ];
98
+ final long star2 = cups [cups [1 ]];
124
99
return star1 * star2 ;
125
100
}
126
101
@@ -133,54 +108,4 @@ public static void main(final String[] args) throws Exception {
133
108
}
134
109
135
110
private static final String TEST = "389125467" ;
136
-
137
-
138
- private static final class Cup {
139
- private final Integer label ;
140
- private Cup next ;
141
-
142
- public Cup (final Integer label , final Cup next ) {
143
- this .label = label ;
144
- this .next = next ;
145
- }
146
-
147
- public Integer getLabel () {
148
- return label ;
149
- }
150
-
151
- public Cup getNext () {
152
- return next ;
153
- }
154
-
155
- public void setNext (final Cup next ) {
156
- this .next = next ;
157
- }
158
-
159
- @ Override
160
- public String toString () {
161
- final StringBuilder builder = new StringBuilder ();
162
- builder .append ("Cup [label=" ).append (label ).append ("]" );
163
- return builder .toString ();
164
- }
165
-
166
- @ Override
167
- public boolean equals (final Object obj ) {
168
- if (this == obj ) {
169
- return true ;
170
- }
171
- if (obj == null ) {
172
- return false ;
173
- }
174
- if (getClass () != obj .getClass ()) {
175
- return false ;
176
- }
177
- final Cup other = (Cup ) obj ;
178
- return Objects .equals (label , other .label ) && Objects .equals (next , other .next );
179
- }
180
-
181
- @ Override
182
- public int hashCode () {
183
- return Objects .hash (label , next );
184
- }
185
- }
186
111
}
0 commit comments