use of common.datastore.PieceCounter in project solution-finder by knewjade.
the class PatternCSVPathOutput method output.
@Override
public void output(List<PathPair> pathPairs, Field field, SizedBit sizedBit) throws FinderExecuteException {
this.lastException = null;
outputLog("Found path = " + pathPairs.size());
AtomicInteger validCounter = new AtomicInteger();
AtomicInteger allCounter = new AtomicInteger();
try (AsyncBufferedFileWriter writer = outputBaseFile.newAsyncWriter()) {
writer.writeAndNewLine("ツモ,対応地形数,使用ミノ,未使用ミノ,テト譜");
generator.blocksStream().parallel().map(blocks -> {
// シーケンス名を取得
String sequenceName = blocks.blockStream().map(Piece::getName).collect(Collectors.joining());
// パフェ可能な地形を抽出
List<PathPair> valid = pathPairs.stream().filter(pathPair -> {
HashSet<? extends Pieces> buildBlocks = pathPair.blocksHashSetForPattern();
return buildBlocks.contains(blocks);
}).collect(Collectors.toList());
// パフェ可能な地形数
int possibleSize = valid.size();
// パフェ可能ならカウンターをインクリメント
allCounter.incrementAndGet();
if (0 < possibleSize)
validCounter.incrementAndGet();
// パフェ可能な地形のテト譜を連結
String fumens = valid.stream().sorted(Comparator.comparing(PathPair::getPatternSize).reversed()).map(pathPair -> "v115@" + pathPair.getFumen()).collect(Collectors.joining(";"));
// 使うミノ一覧を抽出
Set<PieceCounter> usesSet = valid.stream().map(PathPair::getBlockCounter).collect(Collectors.toSet());
String uses = usesSet.stream().map(blockCounter -> {
return blockCounter.getBlockStream().sorted().map(Piece::getName).collect(Collectors.joining());
}).collect(Collectors.joining(";"));
// 残せるミノ一覧を抽出
PieceCounter orderPieceCounter = new PieceCounter(blocks.blockStream());
String noUses = usesSet.stream().map(orderPieceCounter::removeAndReturnNew).distinct().map(blockCounter -> {
return blockCounter.getBlockStream().sorted().map(Piece::getName).collect(Collectors.joining());
}).collect(Collectors.joining(";"));
return String.format("%s,%d,%s,%s,%s", sequenceName, possibleSize, uses, noUses, fumens);
}).forEach(writer::writeAndNewLine);
writer.flush();
} catch (IOException e) {
throw new FinderExecuteException("Failed to output file", e);
}
outputLog("");
outputLog("perfect clear percent");
outputLog(String.format(" -> success = %.2f%% (%d/%d)", 100.0 * validCounter.get() / allCounter.get(), validCounter.get(), allCounter.get()));
if (lastException != null)
throw new FinderExecuteException("Error to output file", lastException);
}
use of common.datastore.PieceCounter 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.PieceCounter in project solution-finder by knewjade.
the class PackSearcherComparingParityBasedTest method compareCount.
private void compareCount(int width, int height, List<TestData> testDataList) throws InterruptedException, ExecutionException {
SizedBit sizedBit = new SizedBit(width, height);
SeparableMinos separableMinos = createSeparableMinos(sizedBit);
BasicSolutionsCalculator calculator = new BasicSolutionsCalculator(separableMinos, sizedBit);
Map<ColumnField, RecursiveMinoFields> calculate = calculator.calculate();
for (TestData data : testDataList) {
// 準備
List<Piece> usingPieces = data.getPieces();
int popCount = usingPieces.size();
Field initField = createSquareEmptyField(height, popCount);
// packで探索
Set<PieceCounter> pieceCounters = Collections.singleton(new PieceCounter(usingPieces));
SolutionFilter solutionFilter = createUsingBlockAndValidKeyMementoFilter(initField, sizedBit, pieceCounters);
BasicSolutions basicSolutions = new MappedBasicSolutions(calculate, solutionFilter);
long packCounter = calculateSRSValidCount(sizedBit, basicSolutions, initField, solutionFilter);
System.out.println(usingPieces);
assertThat(packCounter).isEqualTo(data.getCount());
}
}
use of common.datastore.PieceCounter in project solution-finder by knewjade.
the class ParityBasedPackSearcher method search.
public Stream<List<MinoOperationWithKey>> search(List<Piece> usingPieces) {
// 準備
MinoFactory minoFactory = new MinoFactory();
PositionLimitParser positionLimitParser = new PositionLimitParser(minoFactory, maxClearLine);
LockedReachableThreadLocal threadLocal = new LockedReachableThreadLocal(maxClearLine);
ParityField parityField = new ParityField(field);
PieceCounter pieceCounter = new PieceCounter(usingPieces);
ColumnParityLimitation limitation = new ColumnParityLimitation(pieceCounter, parityField, maxClearLine);
return limitation.enumerate().parallelStream().map(EstimateBuilder::create).flatMap(Collection::stream).flatMap(deltaLimitedMinos -> parseToSortedFullLimitedMinoStream(positionLimitParser, deltaLimitedMinos)).limit(// parallelでの並列数をリセットする(同時実行数を増やす)
Long.MAX_VALUE).flatMap(sets -> new CrossBuilder(sets, field, maxClearLine).create().stream()).filter(operationWithKeys -> BuildUp.existsValidBuildPattern(verifyField, operationWithKeys, maxClearLine, threadLocal.get()));
}
use of common.datastore.PieceCounter in project solution-finder by knewjade.
the class CombinationIterableTest method iteratorRandomBlockCount.
@Test
void iteratorRandomBlockCount() throws Exception {
Randoms randoms = new Randoms();
ArrayList<Piece> allPieces = Lists.newArrayList(Iterables.concat(Piece.valueList(), Piece.valueList()));
for (int pop = 1; pop <= 14; pop++) {
CombinationIterable<Piece> iterable = new CombinationIterable<>(allPieces, pop);
Set<PieceCounter> sets = StreamSupport.stream(iterable.spliterator(), false).map(PieceCounter::new).collect(Collectors.toSet());
// ランダムに組み合わせを選択し、必ず列挙したセットの中にあることを確認
for (int count = 0; count < 10000; count++) {
List<Piece> combinations = randoms.sample(allPieces, pop);
PieceCounter pieceCounter = new PieceCounter(combinations);
assertThat(pieceCounter).isIn(sets);
}
}
}
Aggregations