diff --git a/src/main/java/Solution.java b/src/main/java/Solution.java index 5615be4..ce8c564 100644 --- a/src/main/java/Solution.java +++ b/src/main/java/Solution.java @@ -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 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> filterGroup( List digits, IntFunction 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 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; + } + }