1
1
package dev .linl33 .adventofcode .year2022 ;
2
2
3
+ import jdk .incubator .vector .FloatVector ;
4
+ import jdk .incubator .vector .VectorOperators ;
5
+ import jdk .incubator .vector .VectorSpecies ;
3
6
import org .jetbrains .annotations .NotNull ;
4
7
5
8
import java .io .BufferedReader ;
6
9
7
10
public class Day11 extends AdventSolution2022 <Long , Long > {
11
+ private static final VectorSpecies <Float > SPECIES = FloatVector .SPECIES_PREFERRED ;
12
+
8
13
private static final int MAX_ITEMS = 50 ;
9
14
private static final int PART_1_ROUNDS = 20 ;
10
15
private static final int PART_2_ROUNDS = 10_000 ;
@@ -89,14 +94,19 @@ public Long part2(@NotNull BufferedReader reader) throws Exception {
89
94
var input = reader .lines ().toArray (String []::new );
90
95
var monkeyCount = (input .length + 1 ) / 7 ;
91
96
92
- var items = new int [MAX_ITEMS ];
97
+ if (monkeyCount > SPECIES .length ()) {
98
+ // shouldn't happen, don't want to handle it
99
+ throw new IllegalArgumentException ();
100
+ }
101
+
102
+ var items = new float [MAX_ITEMS ];
93
103
var itemsPosition = new int [MAX_ITEMS ];
94
104
var itemsPointer = 0 ;
95
105
96
- var offsets = new int [ monkeyCount * monkeyCount ];
97
- var multipliers = new int [ monkeyCount * monkeyCount ];
106
+ var offsets = new float [ monkeyCount ];
107
+ var multipliers = new float [ monkeyCount ];
98
108
99
- var moduli = new int [monkeyCount ];
109
+ var moduli = new float [monkeyCount ];
100
110
var trueValues = new int [monkeyCount ];
101
111
var falseValues = new int [monkeyCount ];
102
112
@@ -121,49 +131,46 @@ public Long part2(@NotNull BufferedReader reader) throws Exception {
121
131
var op = input [i + 2 ].charAt (23 );
122
132
if (op == '+' ) {
123
133
var opVal = Integer .parseInt (input [i + 2 ], 25 , input [i + 2 ].length (), 10 );
124
- offsets [m * monkeyCount ] = opVal ;
125
- multipliers [m * monkeyCount ] = 1 ;
134
+ offsets [m ] = opVal ;
135
+ multipliers [m ] = 1 ;
126
136
} else {
127
137
if (input [i + 2 ].charAt (25 ) == 'o' ) {
128
138
// handle new = old * old
129
139
squareMonkey = m ;
130
140
} else {
131
141
var opVal = Integer .parseInt (input [i + 2 ], 25 , input [i + 2 ].length (), 10 );
132
- multipliers [m * monkeyCount ] = opVal ;
142
+ multipliers [m ] = opVal ;
133
143
}
134
144
}
135
145
}
136
146
137
- for (int i = 0 ; i < offsets .length ; i ++) {
138
- var monkeyIndex = (i / monkeyCount ) * monkeyCount ;
139
- var modulus = moduli [i % monkeyCount ];
140
- offsets [i ] = offsets [monkeyIndex ] % modulus ;
141
- multipliers [i ] = multipliers [monkeyIndex ] % modulus ;
142
- }
143
-
144
147
var inspectionCounts = new int [monkeyCount ];
145
- var worries = new int [monkeyCount ];
146
148
147
- for (int i = 0 ; i < itemsPointer ; i ++) {
148
- var item = items [i ];
149
- for (int m = 0 ; m < monkeyCount ; m ++) {
150
- worries [m ] = item % moduli [m ];
151
- }
149
+ var mask = SPECIES .indexInRange (0 , monkeyCount );
150
+ var modV = FloatVector .fromArray (SPECIES , moduli , 0 , mask );
152
151
152
+ for (int i = 0 ; i < itemsPointer ; i ++) {
153
+ var worriesVector = FloatVector .broadcast (SPECIES , items [i ]);
153
154
var pos = itemsPosition [i ];
155
+
154
156
for (int round = 0 ; round < PART_2_ROUNDS ; round ++) {
155
157
inspectionCounts [pos ]++;
156
- if (pos == squareMonkey ) {
157
- for (int j = 0 , mulIndex = squareMonkey * monkeyCount ; j < monkeyCount ; j ++, mulIndex ++) {
158
- multipliers [mulIndex ] = worries [j ] % moduli [j ];
159
- }
160
- }
161
-
162
- for (int m = 0 , opIndex = pos * monkeyCount ; m < monkeyCount ; m ++, opIndex ++) {
163
- worries [m ] = (worries [m ] * multipliers [opIndex ] + offsets [opIndex ]) % moduli [m ];
164
- }
165
158
166
- var posNext = worries [pos ] == 0 ? trueValues [pos ] : falseValues [pos ];
159
+ worriesVector = worriesVector
160
+ .fma (
161
+ pos == squareMonkey ? worriesVector : FloatVector .broadcast (SPECIES , multipliers [pos ]),
162
+ FloatVector .broadcast (SPECIES , offsets [pos ])
163
+ );
164
+
165
+ // compute mod with using a - (a/d) * d
166
+ var tmp = worriesVector
167
+ .div (modV )
168
+ .convert (VectorOperators .F2I , 0 )
169
+ .convert (VectorOperators .I2F , 0 )
170
+ .mul (modV );
171
+ worriesVector = worriesVector .sub (tmp );
172
+
173
+ var posNext = worriesVector .test (VectorOperators .IS_DEFAULT ).laneIsSet (pos ) ? trueValues [pos ] : falseValues [pos ];
167
174
if (posNext > pos ) {
168
175
round --;
169
176
}
@@ -175,8 +182,8 @@ public Long part2(@NotNull BufferedReader reader) throws Exception {
175
182
}
176
183
177
184
private static long calculateLevel (int [] inspectionCounts ) {
178
- var highest = -1L ;
179
- var secondHighest = -1L ;
185
+ var highest = -1 ;
186
+ var secondHighest = -1 ;
180
187
for (int value : inspectionCounts ) {
181
188
if (value > secondHighest ) {
182
189
if (value < highest ) {
@@ -188,6 +195,6 @@ private static long calculateLevel(int[] inspectionCounts) {
188
195
}
189
196
}
190
197
191
- return highest * secondHighest ;
198
+ return Math . multiplyFull ( highest , secondHighest ) ;
192
199
}
193
200
}
0 commit comments