diff --git a/src/main/java/rxjava/Solution.java b/src/main/java/rxjava/Solution.java index c8657a2..a7ddf98 100644 --- a/src/main/java/rxjava/Solution.java +++ b/src/main/java/rxjava/Solution.java @@ -6,7 +6,7 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; /** - * stream.Solution involving a Sukdoku Board, a SudokuVerifier, plus some RxJava processing. + * stream.Solution involving a SudokuVerifier, and some RxJava processing. **/ class Solution { diff --git a/src/main/java/rxjava/SudokuVerifier.java b/src/main/java/rxjava/SudokuVerifier.java index b623eae..d01ebc8 100644 --- a/src/main/java/rxjava/SudokuVerifier.java +++ b/src/main/java/rxjava/SudokuVerifier.java @@ -1,46 +1,79 @@ package rxjava; -import io.reactivex.rxjava3.annotations.NonNull; import io.reactivex.rxjava3.core.Observable; -import io.reactivex.rxjava3.core.Single; +import java.util.List; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import java.util.stream.Stream; public class SudokuVerifier { - @NonNull Observable digitObservable; + + List digitFields; public SudokuVerifier(Stream digitStream) { // Observable on the digit stream - digitObservable = Observable.fromStream(digitStream); - } - - public boolean isSolved() { AtomicInteger row = new AtomicInteger(1); AtomicInteger column = new AtomicInteger(0); - @NonNull Observable digitFieldObservable = digitObservable - .map(digit -> digitField(row, column, digit)); - @NonNull Observable filter = digitFieldObservable - .filter(digitField -> digitField.row == 1); - return isSolved(filter).blockingGet(); + digitFields = Observable.fromStream(digitStream) + .map(digit -> digitField(row, column, digit)) + .collect(Collectors.toList()) + .blockingGet(); } - @NonNull Single isSolved(@NonNull Observable filter) { - return filter - .map(digitField -> digitField.digit) - .distinct().count() - .map(count -> count == 9); + public boolean isSolved() { + // Filter for 9 rows, 9 columns, 9 squares + return digitsInBlockFilters() + .map(blockFilter -> blockFilter.distinct().count().blockingGet() == 9) + .all(solved -> solved).blockingGet(); } DigitField digitField(AtomicInteger row, AtomicInteger column, String digit) { - if (column.getAndIncrement() > 9) { + if (column.incrementAndGet() > 9) { row.getAndIncrement(); column.set(1); } return new DigitField(row.get(), column.get(), digit); } + Observable> digitsInBlockFilters() { + Stream> stream = Stream.of( + IntStream.rangeClosed(1, 9).boxed().map(row -> digitsInRowFilter(row)), + IntStream.rangeClosed(1, 9).boxed().map(column -> digitsInColumnFilter(column)), + digitsInSquareFilters() + ).flatMap(s -> s); + return Observable.fromStream(stream); + } + + Observable digitsInRowFilter(Integer row) { + return Observable.fromStream( + digitFields.stream() + .filter(digitField -> digitField.row == row) + .map(digitField -> digitField.digit)); + } + + Observable digitsInColumnFilter(Integer column) { + return Observable.fromStream( + digitFields.stream() + .filter(digitField -> digitField.column == column) + .map(digitField -> digitField.digit)); + } + + Stream> digitsInSquareFilters() { + return IntStream.rangeClosed(1, 3).boxed().flatMap( + squareRow -> IntStream.rangeClosed(1, 3).boxed().map( + squareColumn -> digitsInSquareFilter(squareRow, squareColumn))); + } + + Observable digitsInSquareFilter(Integer squareRow, Integer squareColumn) { + return Observable.fromStream( + digitFields.stream() + .filter(digitField -> digitField.isInSquare(squareRow, squareColumn)) + .map(digitField -> digitField.digit)); + } + static class DigitField { int row; int column; @@ -51,5 +84,12 @@ public class SudokuVerifier { this.column = column; this.digit = digit; } + + public boolean isInSquare(Integer squareRow, Integer squareColumn) { + return row >= squareRow * 3 - 2 + && row <= squareRow * 3 + && column >= squareColumn * 3 - 2 + && column <= squareColumn * 3; + } } } diff --git a/src/test/java/rxjava/SolutionTest.java b/src/test/java/rxjava/SolutionTest.java index 8ffee72..8061222 100644 --- a/src/test/java/rxjava/SolutionTest.java +++ b/src/test/java/rxjava/SolutionTest.java @@ -87,6 +87,6 @@ class SolutionTest { static void redirectStreams( final InputStream input, final PrintStream output, final PrintStream error ) { System.setIn( input ); System.setOut( output ); - System.setErr( error ); + //System.setErr( error ); } }