use of searcher.pack.SeparableMinos in project solution-finder by knewjade.
the class ConnectionsToStreamCallable method parseWhenNext.
private Stream<RecursiveMinoField> parseWhenNext(ColumnField outerColumnField, SeparableMino currentMino, RecursiveMinoFields minoFields) {
SeparableMinos separableMinos = calculator.getSeparableMinos();
int index = separableMinos.toIndex(currentMino);
return minoFields.recursiveStream().filter(minoField -> minoField.getMaxIndex() <= index).map(minoField -> {
// outerで、最終的に使用されるブロック と すでに使っているブロックが重ならないことを確認
ColumnField lastOuterField = minoField.getOuterField();
if (!lastOuterField.canMerge(outerColumnField))
return null;
OperationWithKey currentOperations = currentMino.toMinoOperationWithKey();
long currentDeleteKey = currentOperations.getNeedDeletedKey();
long currentUsingKey = currentOperations.getUsingKey();
// いま置こうとしているミノと、それまでの結果に矛盾があるか確認
boolean isContradiction = currentDeleteKey != 0L && minoField.getOperationsStream().anyMatch(operationWithKey -> {
long deletedKey = operationWithKey.getNeedDeletedKey();
long usingKey = operationWithKey.getUsingKey();
return (currentUsingKey & deletedKey) != 0L && (usingKey & currentDeleteKey) != 0L;
});
// 矛盾があるときはスキップ
if (isContradiction)
return null;
// 使用されるブロックを算出
ColumnField usingBlock = lastOuterField.freeze(calculator.getHeight());
usingBlock.merge(outerColumnField);
return new RecursiveMinoField(currentMino, minoField, usingBlock, separableMinos);
}).filter(Objects::nonNull);
}
use of searcher.pack.SeparableMinos in project solution-finder by knewjade.
the class ConnectionsToStreamCallable method over.
private Stream<RecursiveMinoField> over(ColumnField columnField, ColumnField outerColumnField, List<SeparableMino> minos, SeparableMinos separableMinos, RecursiveMinoField result) {
Stream.Builder<RecursiveMinoField> builder = Stream.builder();
builder.accept(result);
StreamColumnFieldConnections connections = new StreamColumnFieldConnections(minos, columnField, calculator.getSizedBit());
Stream<RecursiveMinoField> stream = connections.getConnectionStream().filter(connection -> {
ColumnField nextOuterField = connection.getOuterField();
SeparableMino mino = connection.getMino();
return // 次に埋めるべき場所を埋めてある
!needFilledField.canMerge(mino.getField()) && // 次のフィールドの制限範囲と重なっていない
nextOuterField.canMerge(limitOuterField) && // 次のフィールドにあるブロックと重なっていない
nextOuterField.canMerge(outerColumnField);
}).flatMap(connection -> {
// 使用されるブロックを算出
ColumnField usingBlock = connection.getOuterField().freeze(calculator.getHeight());
usingBlock.merge(outerColumnField);
RecursiveMinoField t = new RecursiveMinoField(connection.getMino(), result, usingBlock, separableMinos);
List<SeparableMino> allMinos = separableMinos.getMinos();
List<SeparableMino> minos2 = allMinos.subList(separableMinos.toIndex(connection.getMino()) + 1, allMinos.size());
return over(connection.getInnerField(), usingBlock, minos2, separableMinos, t);
});
return Stream.concat(Stream.of(result), stream);
}
use of searcher.pack.SeparableMinos in project solution-finder by knewjade.
the class ConnectionsToStreamCallable method parseWhenFilled.
private Stream<RecursiveMinoField> parseWhenFilled(ColumnField columnField, ColumnField outerColumnField, Field wallField, SeparableMino currentMino) {
// これからブロックをおく場所以外を、すでにブロックで埋めたフィールドを作成
Field freeze = wallField.freeze(calculator.getHeight());
Field invertedOuterField = calculator.parseInvertedOuterField(outerColumnField);
freeze.merge(invertedOuterField);
// 置くブロック以外がすでに埋まっていると仮定したとき、正しく接着できる順があるか確認
SeparableMinos separableMinos = calculator.getSeparableMinos();
RecursiveMinoField result = new RecursiveMinoField(currentMino, outerColumnField.freeze(calculator.getHeight()), separableMinos);
// 次に埋めるべき場所がないときは結果をそのまま返す
if (needFilledField.isPerfect()) {
return Stream.of(result);
}
// 現在のフィールドに埋めるべきところがないが、次以降のフィールドに残っている場合をケアする
List<SeparableMino> allMinos = separableMinos.getMinos();
return over(columnField, outerColumnField, allMinos, separableMinos, result);
}
use of searcher.pack.SeparableMinos in project solution-finder by knewjade.
the class BuildUpStreamTest method randomLong.
@Test
@LongTest
void randomLong() throws ExecutionException, InterruptedException {
// Initialize
Randoms randoms = new Randoms();
MinoFactory minoFactory = new MinoFactory();
MinoShifter minoShifter = new MinoShifter();
MinoRotation minoRotation = new MinoRotation();
// Define size
int height = 4;
int basicWidth = 3;
SizedBit sizedBit = new SizedBit(basicWidth, height);
SeparableMinos separableMinos = SeparableMinos.createSeparableMinos(minoFactory, minoShifter, sizedBit);
// Create basic solutions
TaskResultHelper taskResultHelper = new Field4x10MinoPackingHelper();
LockedReachableThreadLocal lockedReachableThreadLocal = new LockedReachableThreadLocal(minoFactory, minoShifter, minoRotation, height);
Predicate<ColumnField> memorizedPredicate = (columnField) -> true;
OnDemandBasicSolutions basicSolutions = new OnDemandBasicSolutions(separableMinos, sizedBit, memorizedPredicate);
AtomicInteger counter = new AtomicInteger();
for (int count = 0; count < 10; count++) {
// Create field
int numOfMinos = randoms.nextIntClosed(7, 9);
Field field = randoms.field(height, numOfMinos);
// Search
List<InOutPairField> inOutPairFields = InOutPairField.createInOutPairFields(basicWidth, height, field);
SolutionFilter solutionFilter = createRandomSolutionFilter(randoms, sizedBit, lockedReachableThreadLocal, field);
PerfectPackSearcher searcher = new PerfectPackSearcher(inOutPairFields, basicSolutions, sizedBit, solutionFilter, taskResultHelper);
Optional<Result> resultOptional = searcher.findAny();
// If found solution
resultOptional.ifPresent(result -> {
counter.incrementAndGet();
LinkedList<MinoOperationWithKey> operationWithKeys = result.getMemento().getSeparableMinoStream(basicWidth).map(SeparableMino::toMinoOperationWithKey).collect(Collectors.toCollection(LinkedList::new));
// Create Pieces
LockedReachable reachable = lockedReachableThreadLocal.get();
Set<List<MinoOperationWithKey>> valid = new BuildUpStream(reachable, height).existsValidBuildPattern(field, operationWithKeys).collect(Collectors.toSet());
PermutationIterable<MinoOperationWithKey> permutations = new PermutationIterable<>(operationWithKeys, operationWithKeys.size());
for (List<MinoOperationWithKey> permutation : permutations) {
boolean canBuild = BuildUp.cansBuild(field, permutation, height, reachable);
if (canBuild) {
assertThat(valid).as(FieldView.toString(field)).contains(permutation);
} else {
assertThat(valid).as(FieldView.toString(field)).doesNotContain(permutation);
}
}
});
}
System.out.println(counter);
}
use of searcher.pack.SeparableMinos in project solution-finder by knewjade.
the class BuildUpStreamTest method randomShort.
@Test
void randomShort() throws ExecutionException, InterruptedException {
// Initialize
Randoms randoms = new Randoms();
MinoFactory minoFactory = new MinoFactory();
MinoShifter minoShifter = new MinoShifter();
MinoRotation minoRotation = new MinoRotation();
// Define size
int height = 4;
int basicWidth = 3;
SizedBit sizedBit = new SizedBit(basicWidth, height);
SeparableMinos separableMinos = SeparableMinos.createSeparableMinos(minoFactory, minoShifter, sizedBit);
// Create basic solutions
TaskResultHelper taskResultHelper = new Field4x10MinoPackingHelper();
LockedReachableThreadLocal lockedReachableThreadLocal = new LockedReachableThreadLocal(minoFactory, minoShifter, minoRotation, height);
Predicate<ColumnField> memorizedPredicate = (columnField) -> true;
OnDemandBasicSolutions basicSolutions = new OnDemandBasicSolutions(separableMinos, sizedBit, memorizedPredicate);
AtomicInteger counter = new AtomicInteger();
for (int count = 0; count < 10000; count++) {
// Create field
int numOfMinos = randoms.nextInt(1, 7);
Field field = randoms.field(height, numOfMinos);
// Search
List<InOutPairField> inOutPairFields = InOutPairField.createInOutPairFields(basicWidth, height, field);
SolutionFilter solutionFilter = createRandomSolutionFilter(randoms, sizedBit, lockedReachableThreadLocal, field);
PerfectPackSearcher searcher = new PerfectPackSearcher(inOutPairFields, basicSolutions, sizedBit, solutionFilter, taskResultHelper);
Optional<Result> resultOptional = searcher.findAny();
// If found solution
resultOptional.ifPresent(result -> {
counter.incrementAndGet();
LinkedList<MinoOperationWithKey> operationWithKeys = result.getMemento().getSeparableMinoStream(basicWidth).map(SeparableMino::toMinoOperationWithKey).collect(Collectors.toCollection(LinkedList::new));
// Create Pieces
LockedReachable reachable = lockedReachableThreadLocal.get();
Set<List<MinoOperationWithKey>> valid = new BuildUpStream(reachable, height).existsValidBuildPattern(field, operationWithKeys).collect(Collectors.toSet());
PermutationIterable<MinoOperationWithKey> permutations = new PermutationIterable<>(operationWithKeys, operationWithKeys.size());
for (List<MinoOperationWithKey> permutation : permutations) {
boolean canBuild = BuildUp.cansBuild(field, permutation, height, reachable);
if (canBuild) {
assertThat(valid).as(FieldView.toString(field)).contains(permutation);
} else {
assertThat(valid).as(FieldView.toString(field)).doesNotContain(permutation);
}
}
});
}
System.out.println(counter);
}
Aggregations