use of common.datastore.OperationWithKey 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 common.datastore.OperationWithKey in project solution-finder by knewjade.
the class BuildUpStreamTest method buildUp1.
@Test
void buildUp1() {
// Create LockedReachable
int height = 4;
MinoFactory minoFactory = new MinoFactory();
MinoShifter minoShifter = new MinoShifter();
MinoRotation minoRotation = new MinoRotation();
LockedReachable reachable = new LockedReachable(minoFactory, minoShifter, minoRotation, height);
// Create OperationWithKey List
Field field = FieldFactory.createField("" + "____XXXXXX" + "____XXXXXX" + "____XXXXXX" + "____XXXXXX");
Operations operations = OperationInterpreter.parseToOperations("J,0,1,0;S,L,1,2;O,0,2,1;J,2,2,1");
List<MinoOperationWithKey> operationWithKeys = OperationTransform.parseToOperationWithKeys(field, operations, minoFactory, height);
// Create Pieces
Set<String> valid = new BuildUpStream(reachable, height).existsValidBuildPattern(field, operationWithKeys).map(op -> op.stream().map(OperationWithKey::getPiece).map(Piece::name).collect(Collectors.joining())).collect(Collectors.toSet());
// Assertion
assertThat(valid).hasSize(2).contains("JSOJ", "JOSJ");
}
use of common.datastore.OperationWithKey in project solution-finder by knewjade.
the class OperationWithKeyComparatorTest method compareDiffX.
@Test
void compareDiffX() throws Exception {
Randoms randoms = new Randoms();
MinoFactory minoFactory = new MinoFactory();
int x = randoms.nextInt(10);
int y = randoms.nextInt(20);
long deleteKey = 0L;
long usingKey = 1049600L;
OperationWithKey operationWithKey1 = new FullOperationWithKey(minoFactory.create(Piece.I, Rotate.Spawn), x, y, deleteKey, usingKey);
int newX = randoms.nextInt(10);
if (newX == x)
newX += 1;
Mino newMino = new MinoFactory().create(Piece.I, Rotate.Spawn);
OperationWithKey operationWithKey2 = createNewOperationWithKey(newMino, newX, y, deleteKey, usingKey);
// assert is not 0 & sign reversed
OperationWithKeyComparator comparator = new OperationWithKeyComparator();
assertThat(comparator.compare(operationWithKey1, operationWithKey2) * comparator.compare(operationWithKey2, operationWithKey1)).as(operationWithKey2.toString()).isLessThan(0);
}
use of common.datastore.OperationWithKey in project solution-finder by knewjade.
the class UseCSVPathOutput method output.
@Override
public void output(List<PathPair> pathPairs, Field field, SizedBit sizedBit) throws FinderExecuteException {
this.lastException = null;
outputLog("Found path = " + pathPairs.size());
AtomicInteger allCounter = new AtomicInteger();
Map<PieceCounter, List<PathPair>> groupingByClockCounter = pathPairs.parallelStream().collect(Collectors.groupingBy(pathPair -> {
List<OperationWithKey> operations = pathPair.getSampleOperations();
return new PieceCounter(operations.stream().map(OperationWithKey::getPiece));
}));
List<PathPair> emptyValidList = Collections.emptyList();
try (AsyncBufferedFileWriter writer = outputBaseFile.newAsyncWriter()) {
writer.writeAndNewLine("使用ミノ,対応地形数,対応ツモ数 (対パターン),テト譜,ツモ (対パターン)");
generator.blockCountersStream().parallel().map(blockCounter -> {
// カウンターをインクリメント
allCounter.incrementAndGet();
// 組み合わせ名を取得
String blockCounterName = blockCounter.getBlockStream().map(Piece::getName).collect(Collectors.joining());
// パフェ可能な地形を抽出
List<PathPair> valid = groupingByClockCounter.getOrDefault(blockCounter, emptyValidList);
// パフェ可能な地形数
int possibleSize = valid.size();
// パフェ可能な地形のテト譜を連結
String fumens = valid.stream().sorted(Comparator.comparing(PathPair::getPatternSize).reversed()).map(pathPair -> "v115@" + pathPair.getFumen()).collect(Collectors.joining(";"));
// 対応できるパターンを重複なく抽出
Set<LongPieces> possiblePatternSet = valid.stream().flatMap(PathPair::blocksStreamForPattern).collect(Collectors.toSet());
// 対応できるパターン数
int possiblePatternSize = possiblePatternSet.size();
// パターンを連結
String patterns = possiblePatternSet.stream().map(LongPieces::getPieces).map(blocks -> blocks.stream().map(Piece::getName).collect(Collectors.joining(""))).collect(Collectors.joining(";"));
return String.format("%s,%d,%d,%s,%s", blockCounterName, possibleSize, possiblePatternSize, fumens, patterns);
}).forEach(writer::writeAndNewLine);
writer.flush();
} catch (IOException e) {
throw new FinderExecuteException("Failed to output file", e);
}
outputLog("Found piece combinations = " + allCounter.get());
if (lastException != null)
throw new FinderExecuteException("Error to output file", lastException);
}
use of common.datastore.OperationWithKey in project solution-finder by knewjade.
the class PathCore method run.
List<PathPair> run(Field field, SizedBit sizedBit) throws ExecutionException, InterruptedException {
List<Result> candidates = searcher.toList();
int maxClearLine = sizedBit.getHeight();
return candidates.parallelStream().map(result -> {
LinkedList<MinoOperationWithKey> operations = result.getMemento().getSeparableMinoStream(sizedBit.getWidth()).map(SeparableMino::toMinoOperationWithKey).collect(Collectors.toCollection(LinkedList::new));
// 地形の中で組むことができるoperationsをすべてリスト化する
BuildUpStream buildUpStream2 = buildUpStreamThreadLocal.get();
List<List<MinoOperationWithKey>> validOperaions = buildUpStream2.existsValidBuildPatternDirectly(field, operations).collect(Collectors.toList());
// 地形の中で組むことができるものがないときはスキップ
if (validOperaions.isEmpty())
return PathPair.EMPTY_PAIR;
// 地形の中で組むことができるSetを作成
HashSet<LongPieces> piecesSolution = validOperaions.stream().map(operationWithKeys -> operationWithKeys.stream().map(OperationWithKey::getPiece)).map(LongPieces::new).collect(Collectors.toCollection(HashSet::new));
// 探索シーケンスの中で組むことができるSetを作成
HashSet<LongPieces> piecesPattern = getPiecesPattern(piecesSolution);
// 探索シーケンスの中で組むことができるものがないときはスキップ
if (piecesPattern.isEmpty())
return PathPair.EMPTY_PAIR;
// 探索シーケンスの中でテト譜にするoperationsを選択する
List<MinoOperationWithKey> operationsToUrl = validOperaions.stream().filter(o -> validPieces.contains(new LongPieces(o.stream().map(Operation::getPiece)))).findFirst().orElse(Collections.emptyList());
// 譜面の作成
String fumen = fumenParser.parse(operationsToUrl, field, maxClearLine);
return new PathPair(result, piecesSolution, piecesPattern, fumen, new ArrayList<>(operationsToUrl), validPieces);
}).filter(pathPair -> pathPair != PathPair.EMPTY_PAIR).collect(Collectors.toList());
}
Aggregations