forked from code-clash/sudoku-verifier
elegant stream solution
parent
863825ad1a
commit
8bd7d827a8
@ -1,20 +1,59 @@
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.math.*;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.stream.*;
|
||||
|
||||
/**
|
||||
* Template code to help you parse the standard input
|
||||
* according to the problem statement.
|
||||
**/
|
||||
class Solution {
|
||||
|
||||
private static final int SIZE = 9;
|
||||
private static final int BLOCK_SIZE = 3;
|
||||
|
||||
public static void main( String[] args ) {
|
||||
Scanner in = new Scanner( System.in );
|
||||
// read values with in.next...() methods
|
||||
|
||||
// code your solution here
|
||||
var digits = new Scanner( System.in ).tokens()
|
||||
.map( Integer::valueOf )
|
||||
.collect( Collectors.toList() );
|
||||
|
||||
// Write result with System.out.println()
|
||||
System.out.println( "value" );
|
||||
System.out.println( checkSudoku( digits ));
|
||||
}
|
||||
|
||||
/**
|
||||
* The basic idea is to split the digits into groups that can be verified by the same logic over and over again.
|
||||
* The code will create 27 groups - 9 lines, 9 rows and 9 blocks - and checks for all digits in each group.
|
||||
*/
|
||||
private static boolean checkSudoku( List<Integer> digits ) {
|
||||
return Stream.of(
|
||||
filterGroup( digits, Solution::byLine ),
|
||||
filterGroup( digits, Solution::byRow ),
|
||||
filterGroup( digits, Solution::byBlock )
|
||||
).flatMap( Collection::stream )
|
||||
.allMatch( Solution::checkAllDigits );
|
||||
}
|
||||
|
||||
/**
|
||||
* Splitting is done with a grouping function that calculates the group number for a grid index.
|
||||
*/
|
||||
private static Collection<List<Integer>> filterGroup( List<Integer> digits, IntFunction<Integer> grpFunc ) {
|
||||
var group = IntStream.range( 0, digits.size() ).boxed()
|
||||
.collect( Collectors.groupingBy( grpFunc::apply, Collectors.mapping( digits::get, Collectors.toList() )));
|
||||
return group.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if every digit from 1 to 9 is present in each group.
|
||||
*/
|
||||
private static boolean checkAllDigits( List<Integer> group ) {
|
||||
return group.stream().distinct().count() == SIZE;
|
||||
}
|
||||
|
||||
private static int byLine( int index ) {
|
||||
return index / SIZE;
|
||||
}
|
||||
|
||||
private static int byRow( int index ) {
|
||||
return index % SIZE;
|
||||
}
|
||||
|
||||
private static int byBlock( int index ) {
|
||||
return byRow( index ) / BLOCK_SIZE + ( index / ( SIZE * BLOCK_SIZE )) * BLOCK_SIZE;
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue