1- import java .util .ArrayList ;
2- import java .util .List ;
3- import java .util .Objects ;
4- import java .util .Optional ;
1+ import java .util .*;
52
63public class PiecingItTogether {
74 private final double epsilon = 1e-6 ;
85
9- public PartialJigsawInformation getCompleteInformation (PartialJigsawInformation input ) {
10- Integer rows = input .getRows ().orElse ( null ) ;
11- Integer cols = input .getColumns ().orElse ( null ) ;
12- Integer pieces = input .getPieces ().orElse ( null ) ;
13- Integer border = input .getBorder ().orElse ( null ) ;
14- Integer inside = input .getInside ().orElse ( null ) ;
15- Double aspect = input .getAspectRatio ().orElse ( null ) ;
6+ public JigsawInfo getCompleteInformation (JigsawInfo input ) {
7+ Integer rows = input .getRows ().isPresent () ? input . getRows (). getAsInt () : null ;
8+ Integer cols = input .getColumns ().isPresent () ? input . getColumns (). getAsInt () : null ;
9+ Integer pieces = input .getPieces ().isPresent () ? input . getPieces (). getAsInt () : null ;
10+ Integer border = input .getBorder ().isPresent () ? input . getBorder (). getAsInt () : null ;
11+ Integer inside = input .getInside ().isPresent () ? input . getInside (). getAsInt () : null ;
12+ Double aspect = input .getAspectRatio ().isPresent () ? input . getAspectRatio (). getAsDouble () : null ;
1613 String format = input .getFormat ().orElse (null );
1714
1815 // Final information to be compared with the original input to detect inconsistencies
19- PartialJigsawInformation result = null ;
16+ JigsawInfo result = null ;
2017
2118 // Check format and aspect ratio don't contradict each other or set aspect if format is square
2219 if (format != null && aspect != null ) {
@@ -77,7 +74,7 @@ public PartialJigsawInformation getCompleteInformation(PartialJigsawInformation
7774 checkConsistencyOrThrow (result , input );
7875 return result ;
7976 } else if (inside != null && inside == 0 ) {
80- List <PartialJigsawInformation > validGuesses = new ArrayList <>();
77+ List <JigsawInfo > validGuesses = new ArrayList <>();
8178
8279 for (int fixed : List .of (1 , 2 )) {
8380 tryGuessWithFixedSide (fixed , true , aspect , input ).ifPresent (validGuesses ::add ); // rows = fixed
@@ -99,7 +96,7 @@ public PartialJigsawInformation getCompleteInformation(PartialJigsawInformation
9996 }
10097
10198 // Brute force as a last resort
102- List <PartialJigsawInformation > validGuesses = new ArrayList <>();
99+ List <JigsawInfo > validGuesses = new ArrayList <>();
103100
104101 // Brute-force using pieces
105102 if (pieces != null ) {
@@ -220,14 +217,22 @@ private Optional<Integer> calculateOtherSide(int knownSide, boolean isRowKnown,
220217 return Optional .empty ();
221218 }
222219
223- private PartialJigsawInformation fromRowsAndCols (int rows , int cols ) {
220+ private JigsawInfo fromRowsAndCols (int rows , int cols ) {
224221 int pieces = rows * cols ;
225222 int border = (rows == 1 || cols == 1 ) ? pieces : 2 * (rows + cols - 2 );
226223 int inside = pieces - border ;
227224 double aspect = (double ) cols / rows ;
228225 String format = getFormatFromAspect (aspect );
229226
230- return new PartialJigsawInformation (pieces , border , inside , rows , cols , aspect , format );
227+ return new JigsawInfo .Builder ()
228+ .pieces (pieces )
229+ .border (border )
230+ .inside (inside )
231+ .rows (rows )
232+ .columns (cols )
233+ .aspectRatio (aspect )
234+ .format (format )
235+ .build ();
231236 }
232237
233238 /**
@@ -239,7 +244,7 @@ private PartialJigsawInformation fromRowsAndCols(int rows, int cols) {
239244 * @param input the original partial input with possibly known values
240245 * @throws IllegalArgumentException if any known value in the input conflicts with the computed result
241246 */
242- public void checkConsistencyOrThrow (PartialJigsawInformation computed , PartialJigsawInformation input ) {
247+ public void checkConsistencyOrThrow (JigsawInfo computed , JigsawInfo input ) {
243248 if (!valuesMatch (computed .getPieces (), input .getPieces ()) || !valuesMatch (computed .getBorder (), input .getBorder ()) || !valuesMatch (computed .getInside (), input .getInside ()) || !valuesMatch (computed .getRows (), input .getRows ()) || !valuesMatch (computed .getColumns (), input .getColumns ()) || !valuesMatch (computed .getAspectRatio (), input .getAspectRatio ()) || !valuesMatch (computed .getFormat (), input .getFormat ())) {
244249 throw new IllegalArgumentException ("Contradictory data" );
245250 }
@@ -255,14 +260,14 @@ public void checkConsistencyOrThrow(PartialJigsawInformation computed, PartialJi
255260 * @param input the original input to check for consistency
256261 * @return an Optional containing a valid inferred configuration, or empty if the guess is invalid
257262 */
258- private Optional <PartialJigsawInformation > tryGuessWithFixedSide (int fixed , boolean isRowFixed , double aspect , PartialJigsawInformation input ) {
263+ private Optional <JigsawInfo > tryGuessWithFixedSide (int fixed , boolean isRowFixed , double aspect , JigsawInfo input ) {
259264 try {
260265 int other = isRowFixed ? roundIfClose (fixed * aspect ) : roundIfClose (fixed / aspect );
261266
262267 int rows = isRowFixed ? fixed : other ;
263268 int cols = isRowFixed ? other : fixed ;
264269
265- PartialJigsawInformation guess = fromRowsAndCols (rows , cols );
270+ JigsawInfo guess = fromRowsAndCols (rows , cols );
266271 checkConsistencyOrThrow (guess , input );
267272 return Optional .of (guess );
268273 } catch (IllegalArgumentException ignored ) {
@@ -279,9 +284,9 @@ private Optional<PartialJigsawInformation> tryGuessWithFixedSide(int fixed, bool
279284 * @param input the original input to check for consistency
280285 * @return an Optional containing a valid configuration, or empty if inconsistent
281286 */
282- private Optional <PartialJigsawInformation > tryGuess (int rows , int cols , PartialJigsawInformation input ) {
287+ private Optional <JigsawInfo > tryGuess (int rows , int cols , JigsawInfo input ) {
283288 try {
284- PartialJigsawInformation guess = fromRowsAndCols (rows , cols );
289+ JigsawInfo guess = fromRowsAndCols (rows , cols );
285290 checkConsistencyOrThrow (guess , input );
286291 return Optional .of (guess );
287292 } catch (IllegalArgumentException ignored ) {
@@ -306,4 +311,20 @@ private <T> boolean valuesMatch(Optional<T> a, Optional<T> b) {
306311
307312 return true ;
308313 }
314+
315+ private boolean valuesMatch (OptionalInt a , OptionalInt b ) {
316+ if (a .isPresent () && b .isPresent ()) {
317+ return a .getAsInt () == b .getAsInt ();
318+ }
319+
320+ return true ;
321+ }
322+
323+ private boolean valuesMatch (OptionalDouble a , OptionalDouble b ) {
324+ if (a .isPresent () && b .isPresent ()) {
325+ return Double .compare (a .getAsDouble (), b .getAsDouble ()) == 0 ;
326+ }
327+
328+ return true ;
329+ }
309330}
0 commit comments