package rxjava; import io.reactivex.rxjava3.annotations.NonNull; import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Single; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Stream; public class SudokuVerifier { @NonNull Observable digitObservable; 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(); } @NonNull Single isSolved(@NonNull Observable filter) { return filter .map(digitField -> digitField.digit) .distinct().count() .map(count -> count == 9); } DigitField digitField(AtomicInteger row, AtomicInteger column, String digit) { if (column.getAndIncrement() > 9) { row.getAndIncrement(); column.set(1); } return new DigitField(row.get(), column.get(), digit); } static class DigitField { int row; int column; String digit; public DigitField(int row, int column, String digit) { this.row = row; this.column = column; this.digit = digit; } } }