You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
2.4 KiB
Java
81 lines
2.4 KiB
Java
package reactivestreams;
|
|
|
|
import java.util.concurrent.Flow;
|
|
import java.util.concurrent.SubmissionPublisher;
|
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
import java.util.stream.IntStream;
|
|
import java.util.stream.Stream;
|
|
|
|
public class SudokuVerifier implements Flow.Subscriber<Boolean> {
|
|
|
|
Stream<String> digitStream;
|
|
SubmissionPublisher<String> digitPublisher;
|
|
AtomicInteger finished = new AtomicInteger(0);
|
|
AtomicBoolean solved = new AtomicBoolean(true);
|
|
|
|
public SudokuVerifier(Stream<String> digitStream) {
|
|
this.digitStream = digitStream;
|
|
// Setup publisher to emit the digitStream
|
|
digitPublisher = new SubmissionPublisher<>();
|
|
// Setup row and column checking subscribers
|
|
IntStream.rangeClosed(1, 9).boxed()
|
|
.forEach(i -> rowCheckerAndColumnChecker(digitPublisher, i));
|
|
// Setup square checking subscribers
|
|
IntStream.rangeClosed(1, 3).boxed()
|
|
.forEach(squareRow -> {
|
|
IntStream.rangeClosed(1, 3).boxed()
|
|
.forEach(squareColumn -> subscribeBlockChecker(digitPublisher, new SquareChecker(squareRow, squareColumn)));
|
|
});
|
|
}
|
|
|
|
public boolean isSolved() {
|
|
// Make publisher emit each digit
|
|
digitStream.forEach(digitPublisher::submit);
|
|
digitPublisher.close();
|
|
// Wait for checking subscribers to finish
|
|
while (finished.get() < digitPublisher.getSubscribers().size() && solved.get()) {
|
|
try {
|
|
Thread.sleep(5);
|
|
} catch (InterruptedException ex) {
|
|
System.out.println(ex.fillInStackTrace());
|
|
}
|
|
}
|
|
return solved.get();
|
|
}
|
|
|
|
private void rowCheckerAndColumnChecker(SubmissionPublisher<String> digitPublisher, Integer i) {
|
|
subscribeBlockChecker(digitPublisher, new RowChecker(i));
|
|
subscribeBlockChecker(digitPublisher, new ColumnChecker(i));
|
|
}
|
|
|
|
private void subscribeBlockChecker(SubmissionPublisher<String> digitPublisher, DigitBlockChecker blockChecker) {
|
|
digitPublisher.subscribe(blockChecker);
|
|
blockChecker.subscribe(this);
|
|
}
|
|
|
|
@Override
|
|
public void onSubscribe(Flow.Subscription subscription) {
|
|
subscription.request(1); // 1 Boolean result from the block checker
|
|
}
|
|
|
|
@Override
|
|
public void onNext(Boolean solved) {
|
|
if (! solved) {
|
|
this.solved.compareAndSet(true, false);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onError(Throwable throwable) {
|
|
System.err.println(throwable.fillInStackTrace());
|
|
solved.compareAndSet(true, false);
|
|
finished.incrementAndGet();
|
|
}
|
|
|
|
@Override
|
|
public void onComplete() {
|
|
finished.incrementAndGet();
|
|
}
|
|
}
|