0
0
Fork 0

rxjava solution - check rows, columns, and squares

paul
paul 5 years ago
parent d9386f7ae5
commit 31a0bee25b

@ -6,7 +6,7 @@ import java.util.stream.Stream;
import java.util.stream.StreamSupport; 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 { class Solution {

@ -1,46 +1,79 @@
package rxjava; package rxjava;
import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable; 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.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream; import java.util.stream.Stream;
public class SudokuVerifier { public class SudokuVerifier {
@NonNull Observable<String> digitObservable;
List<DigitField> digitFields;
public SudokuVerifier(Stream<String> digitStream) { public SudokuVerifier(Stream<String> digitStream) {
// Observable on the digit stream // Observable on the digit stream
digitObservable = Observable.fromStream(digitStream);
}
public boolean isSolved() {
AtomicInteger row = new AtomicInteger(1); AtomicInteger row = new AtomicInteger(1);
AtomicInteger column = new AtomicInteger(0); AtomicInteger column = new AtomicInteger(0);
@NonNull Observable<DigitField> digitFieldObservable = digitObservable digitFields = Observable.fromStream(digitStream)
.map(digit -> digitField(row, column, digit)); .map(digit -> digitField(row, column, digit))
@NonNull Observable<DigitField> filter = digitFieldObservable .collect(Collectors.toList())
.filter(digitField -> digitField.row == 1); .blockingGet();
return isSolved(filter).blockingGet();
} }
@NonNull Single<Boolean> isSolved(@NonNull Observable<DigitField> filter) { public boolean isSolved() {
return filter // Filter for 9 rows, 9 columns, 9 squares
.map(digitField -> digitField.digit) return digitsInBlockFilters()
.distinct().count() .map(blockFilter -> blockFilter.distinct().count().blockingGet() == 9)
.map(count -> count == 9); .all(solved -> solved).blockingGet();
} }
DigitField digitField(AtomicInteger row, AtomicInteger column, String digit) { DigitField digitField(AtomicInteger row, AtomicInteger column, String digit) {
if (column.getAndIncrement() > 9) { if (column.incrementAndGet() > 9) {
row.getAndIncrement(); row.getAndIncrement();
column.set(1); column.set(1);
} }
return new DigitField(row.get(), column.get(), digit); return new DigitField(row.get(), column.get(), digit);
} }
Observable<Observable<String>> digitsInBlockFilters() {
Stream<Observable<String>> 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<String> digitsInRowFilter(Integer row) {
return Observable.fromStream(
digitFields.stream()
.filter(digitField -> digitField.row == row)
.map(digitField -> digitField.digit));
}
Observable<String> digitsInColumnFilter(Integer column) {
return Observable.fromStream(
digitFields.stream()
.filter(digitField -> digitField.column == column)
.map(digitField -> digitField.digit));
}
Stream<Observable<String>> digitsInSquareFilters() {
return IntStream.rangeClosed(1, 3).boxed().flatMap(
squareRow -> IntStream.rangeClosed(1, 3).boxed().map(
squareColumn -> digitsInSquareFilter(squareRow, squareColumn)));
}
Observable<String> digitsInSquareFilter(Integer squareRow, Integer squareColumn) {
return Observable.fromStream(
digitFields.stream()
.filter(digitField -> digitField.isInSquare(squareRow, squareColumn))
.map(digitField -> digitField.digit));
}
static class DigitField { static class DigitField {
int row; int row;
int column; int column;
@ -51,5 +84,12 @@ public class SudokuVerifier {
this.column = column; this.column = column;
this.digit = digit; 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;
}
} }
} }

@ -87,6 +87,6 @@ class SolutionTest {
static void redirectStreams( final InputStream input, final PrintStream output, final PrintStream error ) { static void redirectStreams( final InputStream input, final PrintStream output, final PrintStream error ) {
System.setIn( input ); System.setIn( input );
System.setOut( output ); System.setOut( output );
System.setErr( error ); //System.setErr( error );
} }
} }

Loading…
Cancel
Save