use of searcher.pack.memento.SolutionFilter in project solution-finder by knewjade.
the class EasyPath method calculate.
public List<Result> calculate(Field initField, int width, int height) throws ExecutionException, InterruptedException {
assert !initField.existsAbove(height);
// SRS: SizedBit=widthxheight, TaskResultHelper=4x10, BasicSolutions=Mapped
SizedBit sizedBit = new SizedBit(width, height);
List<InOutPairField> inOutPairFields = InOutPairField.createInOutPairFields(sizedBit, initField);
// Create
BasicSolutions basicSolutions = createMappedBasicSolutions(sizedBit);
TaskResultHelper taskResultHelper = new Field4x10MinoPackingHelper();
// Assert
SolutionFilter solutionFilter = createSRSSolutionFilter(sizedBit, initField);
// パフェ手順の列挙
PerfectPackSearcher searcher = new PerfectPackSearcher(inOutPairFields, basicSolutions, sizedBit, solutionFilter, taskResultHelper);
return searcher.toList();
}
use of searcher.pack.memento.SolutionFilter in project solution-finder by knewjade.
the class SetupEntryPoint method run.
@Override
public void run() throws FinderException {
output("# Setup Field");
// Setup init field
Field initField = settings.getInitField();
Verify.field(initField);
// Setup need filled field
Field needFilledField = settings.getNeedFilledField();
Verify.needFilledField(needFilledField);
// Setup not filled field
Field notFilledField = settings.getNotFilledField();
// Setup max height
int maxHeight = settings.getMaxHeight();
Verify.maxClearLineUnder10(maxHeight);
// Setup reserved blocks
BlockField reservedBlocks = settings.getReservedBlock();
if (settings.isReserved()) {
Verify.reservedBlocks(reservedBlocks);
for (int y = maxHeight - 1; 0 <= y; y--) {
StringBuilder builder = new StringBuilder();
for (int x = 0; x < 10; x++) {
if (reservedBlocks.getBlock(x, y) != null)
builder.append(reservedBlocks.getBlock(x, y).getName());
else if (!initField.isEmpty(x, y))
builder.append('X');
else if (!needFilledField.isEmpty(x, y))
builder.append('*');
else if (!notFilledField.isEmpty(x, y))
builder.append('_');
else
builder.append('.');
}
output(builder.toString());
}
} else {
for (int y = maxHeight - 1; 0 <= y; y--) {
StringBuilder builder = new StringBuilder();
for (int x = 0; x < 10; x++) {
if (!initField.isEmpty(x, y))
builder.append('X');
else if (!needFilledField.isEmpty(x, y))
builder.append('*');
else if (!notFilledField.isEmpty(x, y))
builder.append('_');
else
builder.append('.');
}
output(builder.toString());
}
}
// Setup min depth
// 最低でも必要なミノ数
int minDepth = Verify.minDepth(needFilledField);
output();
// ========================================
// Output user-defined
DropType dropType = settings.getDropType();
output("# Initialize / User-defined");
output("Max height: " + maxHeight);
output("Drop: " + dropType.name().toLowerCase());
output("Searching patterns:");
// Setup patterns
List<String> patterns = settings.getPatterns();
PatternGenerator generator = Verify.patterns(patterns, minDepth);
// Output patterns
for (String pattern : patterns) output(" " + pattern);
// Setup output file
MyFile base = new MyFile(settings.getOutputBaseFilePath());
base.mkdirs();
base.verify();
output();
// ========================================
// Setup core
output("# Initialize / System");
int core = Runtime.getRuntime().availableProcessors();
// Output system-defined
output("Version = " + FinderConstant.VERSION);
output("Available processors = " + core);
output("Need Pieces = " + minDepth);
output();
// ========================================
output("# Search");
output(" -> Stopwatch start");
Stopwatch stopwatch = Stopwatch.createStartedStopwatch();
// Initialize
MinoFactory minoFactory = new MinoFactory();
MinoShifter minoShifter = new MinoShifter();
ColorConverter colorConverter = new ColorConverter();
SizedBit sizedBit = decideSizedBitSolutionWidth(maxHeight);
TaskResultHelper taskResultHelper = new BasicMinoPackingHelper();
SolutionFilter solutionFilter = new ForPathSolutionFilter(generator, maxHeight);
ThreadLocal<BuildUpStream> buildUpStreamThreadLocal = createBuildUpStreamThreadLocal(dropType, maxHeight);
OneFumenParser fumenParser = new OneFumenParser(minoFactory, colorConverter);
// ミノリストの作成
long deleteKeyMask = getDeleteKeyMask(notFilledField, maxHeight);
SeparableMinos separableMinos = SeparableMinos.createSeparableMinos(minoFactory, minoShifter, sizedBit, deleteKeyMask);
// 絶対に置かないブロック
List<InOutPairField> inOutPairFields = InOutPairField.createInOutPairFields(sizedBit, notFilledField);
// 絶対に置く必要があるブロック
ArrayList<BasicSolutions> basicSolutions = new ArrayList<>();
List<ColumnField> needFillFields = InOutPairField.createInnerFields(sizedBit, needFilledField);
{
Field freeze = needFilledField.freeze(sizedBit.getHeight());
for (ColumnField innerField : needFillFields) {
// 最小限の部分だけを抽出する
Field freeze1 = freeze.freeze(sizedBit.getHeight());
for (int y = 0; y < sizedBit.getHeight(); y++) {
int width = sizedBit.getWidth();
for (int x = 0; x < width; x++) freeze1.removeBlock(x, y);
for (int x = width + 3; x < 10; x++) freeze1.removeBlock(x, y);
}
OnDemandBasicSolutions solutions = new OnDemandBasicSolutions(separableMinos, sizedBit, innerField.getBoard(0), freeze1);
basicSolutions.add(solutions);
freeze.slideLeft(sizedBit.getWidth());
}
}
// 探索
SetupPackSearcher searcher = new SetupPackSearcher(inOutPairFields, basicSolutions, sizedBit, solutionFilter, taskResultHelper, needFillFields);
List<Result> results = getResults(initField, sizedBit, buildUpStreamThreadLocal, searcher);
output(" Found solution = " + results.size());
stopwatch.stop();
output(" -> Stopwatch stop : " + stopwatch.toMessage(TimeUnit.MILLISECONDS));
output();
// ========================================
output("# Output file");
HTMLBuilder<FieldHTMLColumn> htmlBuilder = new HTMLBuilder<>("Setup result");
results.parallelStream().forEach(result -> {
List<MinoOperationWithKey> operationWithKeys = result.getMemento().getSeparableMinoStream(sizedBit.getWidth()).map(SeparableMino::toMinoOperationWithKey).collect(Collectors.toList());
Field allField = initField.freeze(maxHeight);
Operations operations = OperationTransform.parseToOperations(allField, operationWithKeys, sizedBit.getHeight());
List<? extends Operation> operationList = operations.getOperations();
for (Operation operation : operationList) {
Mino mino = minoFactory.create(operation.getPiece(), operation.getRotate());
int x = operation.getX();
int y = operation.getY();
allField.put(mino, x, y);
}
// 譜面の作成
String encode = fumenParser.parse(operationWithKeys, initField, maxHeight);
String name = operationWithKeys.stream().map(OperationWithKey::getPiece).map(Piece::getName).collect(Collectors.joining());
String link = String.format("<a href='http://fumen.zui.jp/?v115@%s' target='_blank'>%s</a>", encode, name);
String line = String.format("<div>%s</div>", link);
htmlBuilder.addColumn(new FieldHTMLColumn(allField, maxHeight), line);
});
ArrayList<FieldHTMLColumn> columns = new ArrayList<>(htmlBuilder.getRegisteredColumns());
columns.sort(Comparator.comparing(FieldHTMLColumn::getTitle).reversed());
try (BufferedWriter bufferedWriter = base.newBufferedWriter()) {
for (String line : htmlBuilder.toList(columns, true)) {
bufferedWriter.write(line);
bufferedWriter.newLine();
}
bufferedWriter.flush();
} catch (IOException e) {
throw new FinderExecuteException(e);
}
output();
// ========================================
output("# Finalize");
output("done");
}
use of searcher.pack.memento.SolutionFilter in project solution-finder by knewjade.
the class OperationTransformTest method randomParse.
@Test
@LongTest
void randomParse() throws Exception {
// 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);
for (int count = 0; count < 100; count++) {
// Create field
int numOfMinos = randoms.nextInt(6, 10);
Field field = randoms.field(height, numOfMinos);
// Search
List<InOutPairField> inOutPairFields = InOutPairField.createInOutPairFields(basicWidth, height, field);
SolutionFilter solutionFilter = new SRSValidSolutionFilter(field, lockedReachableThreadLocal, sizedBit);
PerfectPackSearcher searcher = new PerfectPackSearcher(inOutPairFields, basicSolutions, sizedBit, solutionFilter, taskResultHelper);
Optional<Result> resultOptional = searcher.findAny();
OperationWithKeyComparator<MinoOperationWithKey> operationWithKeyComparator = new OperationWithKeyComparator<>();
ListComparator<MinoOperationWithKey> comparator = new ListComparator<>(operationWithKeyComparator);
BuildUpStream buildUpStream = new BuildUpStream(lockedReachableThreadLocal.get(), height);
// If found solution
resultOptional.ifPresent(result -> {
List<MinoOperationWithKey> list = result.getMemento().getSeparableMinoStream(basicWidth).map(SeparableMino::toMinoOperationWithKey).collect(Collectors.toList());
Optional<List<MinoOperationWithKey>> validOption = buildUpStream.existsValidBuildPattern(field, list).findAny();
validOption.ifPresent(operationWithKeys -> {
Operations operations = OperationTransform.parseToOperations(field, operationWithKeys, height);
List<MinoOperationWithKey> actual = OperationTransform.parseToOperationWithKeys(field, operations, minoFactory, height);
assertThat(comparator.compare(operationWithKeys, actual)).as("%s%n%s%n %s", FieldView.toString(field, height), OperationWithKeyInterpreter.parseToString(operationWithKeys), OperationWithKeyInterpreter.parseToString(actual)).isEqualTo(0);
});
});
}
}
use of searcher.pack.memento.SolutionFilter in project solution-finder by knewjade.
the class BasicMinoPackingHelper method fixResult.
@Override
public Stream<Result> fixResult(PackSearcher searcher, long innerFieldBoard, MinoFieldMemento nextMemento) {
SizedBit sizedBit = searcher.getSizedBit();
SolutionFilter solutionFilter = searcher.getSolutionFilter();
long fillBoard = sizedBit.getFillBoard();
long board = innerFieldBoard & fillBoard;
int resultIndex = searcher.getLastIndex() + 1;
ColumnSmallField nextInnerField = ColumnFieldFactory.createField(board);
if (searcher.isFilled(nextInnerField, resultIndex)) {
if (solutionFilter.testLast(nextMemento))
return Stream.of(createResult(nextMemento));
return Stream.empty();
} else {
ColumnSmallField over = ColumnFieldFactory.createField(innerFieldBoard & ~fillBoard);
MinoFields minoFields = searcher.getSolutions(resultIndex).parse(nextInnerField);
return minoFields.stream().filter(minoField -> over.canMerge(minoField.getOuterField())).map(nextMemento::concat).filter(solutionFilter::testLast).map(this::createResult);
}
}
use of searcher.pack.memento.SolutionFilter in project solution-finder by knewjade.
the class BuildUpTest method randomShortByPacking.
@Test
void randomShortByPacking() 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 = new AllPassedSolutionFilter();
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));
LockedReachable reachable = lockedReachableThreadLocal.get();
boolean exists = BuildUp.existsValidBuildPattern(field, operationWithKeys, height, reachable);
if (exists) {
// cansBuildでtrueとなるものがあることを確認
Optional<List<MinoOperationWithKey>> valid = StreamSupport.stream(new PermutationIterable<>(operationWithKeys, operationWithKeys.size()).spliterator(), false).filter(combination -> BuildUp.cansBuild(field, combination, height, lockedReachableThreadLocal.get())).findAny();
assertThat(valid.isPresent()).as(FieldView.toString(field) + OperationWithKeyInterpreter.parseToString(operationWithKeys)).isTrue();
// checksKeyは必ずtrueとなる
assertThat(BuildUp.checksKey(operationWithKeys, 0L, height)).as(FieldView.toString(field) + OperationWithKeyInterpreter.parseToString(operationWithKeys)).isTrue();
// existsValidByOrderは必ずtrueになる
assert valid.isPresent();
List<MinoOperationWithKey> keys = valid.get();
List<Piece> pieces = keys.stream().map(OperationWithKey::getPiece).collect(Collectors.toList());
assertThat(BuildUp.existsValidByOrder(field, keys.stream(), pieces, height, reachable)).isTrue();
} else {
// cansBuildですべてがfalseとなることを確認
boolean noneMatch = StreamSupport.stream(new PermutationIterable<>(operationWithKeys, operationWithKeys.size()).spliterator(), false).noneMatch(combination -> BuildUp.cansBuild(field, combination, height, lockedReachableThreadLocal.get()));
assertThat(noneMatch).as(FieldView.toString(field) + OperationWithKeyInterpreter.parseToString(operationWithKeys)).isTrue();
// existsValidByOrderは必ずfalseになる
List<Piece> pieces = operationWithKeys.stream().map(OperationWithKey::getPiece).collect(Collectors.toList());
assertThat(BuildUp.existsValidByOrder(field, operationWithKeys.stream(), pieces, height, reachable)).isFalse();
}
});
}
System.out.println(counter);
}
Aggregations