rxjava solution - check rows, columns, and squares
This commit is contained in:
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);
|
AtomicInteger row = new AtomicInteger(1);
|
||||||
|
AtomicInteger column = new AtomicInteger(0);
|
||||||
|
digitFields = Observable.fromStream(digitStream)
|
||||||
|
.map(digit -> digitField(row, column, digit))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
.blockingGet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSolved() {
|
public boolean isSolved() {
|
||||||
AtomicInteger row = new AtomicInteger(1);
|
// Filter for 9 rows, 9 columns, 9 squares
|
||||||
AtomicInteger column = new AtomicInteger(0);
|
return digitsInBlockFilters()
|
||||||
@NonNull Observable<DigitField> digitFieldObservable = digitObservable
|
.map(blockFilter -> blockFilter.distinct().count().blockingGet() == 9)
|
||||||
.map(digit -> digitField(row, column, digit));
|
.all(solved -> solved).blockingGet();
|
||||||
@NonNull Observable<DigitField> filter = digitFieldObservable
|
|
||||||
.filter(digitField -> digitField.row == 1);
|
|
||||||
return isSolved(filter).blockingGet();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull Single<Boolean> isSolved(@NonNull Observable<DigitField> filter) {
|
|
||||||
return filter
|
|
||||||
.map(digitField -> digitField.digit)
|
|
||||||
.distinct().count()
|
|
||||||
.map(count -> count == 9);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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…
x
Reference in New Issue
Block a user