Skip to content

Commit

Permalink
refactoring and slight performance improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
samabcde committed Jul 7, 2024
1 parent 3c3bf40 commit eb32f47
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.samabcde.puzzlesolver.component.BlockPuzzle;
import com.samabcde.puzzlesolver.performance.PerformanceRecorder;
import com.samabcde.puzzlesolver.solve.priority.BlockComparator;
import com.samabcde.puzzlesolver.solve.priority.BlockPositionComparator;
import com.samabcde.puzzlesolver.solve.priority.BlockPriorityComparator;
import com.samabcde.puzzlesolver.solve.state.BlockPossiblePosition;
import com.samabcde.puzzlesolver.solve.state.BoardFillState;
Expand All @@ -14,7 +15,6 @@
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class BlockPuzzleSolver {
Expand Down Expand Up @@ -59,18 +59,6 @@ private void sortBlockPositions() {
}
}

private record BlockPositionComparator(BlockPuzzle blockPuzzle) implements Comparator<BlockPosition> {

@Override
public int compare(BlockPosition arg0, BlockPosition arg1) {
int compareIntersectScore = Integer.compare(arg0.getIntersectScore(blockPuzzle), arg1.getIntersectScore(blockPuzzle));
if (compareIntersectScore != 0) {
return compareIntersectScore;
}
return Integer.compare(arg0.id, arg1.id);
}
}

private Block getNextBlockToAdd() {
return this.getRemainingBlocks().getFirst();
}
Expand Down Expand Up @@ -134,7 +122,7 @@ private boolean isCurrentBoardSolvable(Block block) {
}
}
BoardFillState cloneBoardFillState = this.boardFillState.copy();
List<PossiblePositions> remainingBlockPossiblePositions = getRemainingBlocksPossiblePositions(cloneBoardFillState, remainingBlocks, this.blockPossiblePosition);
List<PossiblePositions> remainingBlockPossiblePositions = getRemainingBlocksPossiblePositions(remainingBlocks, this.blockPossiblePosition);
return isRemainingBlockPositionsSolvable(cloneBoardFillState, remainingBlockPossiblePositions);
}

Expand Down Expand Up @@ -196,7 +184,7 @@ private boolean isRemainingBlockPositionsSolvable(BoardFillState cloneBoardFillS
return true;
}

private List<PossiblePositions> getRemainingBlocksPossiblePositions(BoardFillState cloneBoardFillState, List<Block> remainingBlocks, BlockPossiblePosition cloneBlockPossiblePosition) {
private List<PossiblePositions> getRemainingBlocksPossiblePositions(List<Block> remainingBlocks, BlockPossiblePosition cloneBlockPossiblePosition) {
List<PossiblePositions> remainingBlocksPossiblePositions = new ArrayList<>();

boolean[] isBlocksSkippable = new boolean[blocks.size()];
Expand Down Expand Up @@ -224,7 +212,6 @@ private void placeNextBlockPosition(Block block) {
BlockPosition nextPossiblePosition = blockPossiblePosition.pollNextPossiblePosition(block);

blockPossiblePosition.placeBlockPosition(nextPossiblePosition)
.stream()
.forEach(boardFillState::removeCanFillBlockPosition);
boardFillState.placeBlockPosition(nextPossiblePosition);
solution.push(nextPossiblePosition);
Expand All @@ -234,7 +221,6 @@ private void takeLastBlockPosition() {
BlockPosition lastBlockPosition = solution.poll();

blockPossiblePosition.takeBlockPosition(lastBlockPosition)
.stream()
.forEach(boardFillState::addCanFillBlockPosition);
boardFillState.takeBlockPosition(lastBlockPosition);
}
Expand All @@ -248,7 +234,7 @@ private void resetAddedPosition(Block block) {
}

private void setAllBlockPositionsTried(Block block) {
this.blockPossiblePosition.resetAddedPositionPriority(block);
this.blockPossiblePosition.resetPlacedPositionPriority(block);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.samabcde.puzzlesolver.solve.priority;

import com.samabcde.puzzlesolver.component.BlockPosition;
import com.samabcde.puzzlesolver.component.BlockPuzzle;

import java.util.Comparator;

public record BlockPositionComparator(BlockPuzzle blockPuzzle) implements Comparator<BlockPosition> {

@Override
public int compare(BlockPosition arg0, BlockPosition arg1) {
int compareIntersectScore = Integer.compare(arg0.getIntersectScore(blockPuzzle), arg1.getIntersectScore(blockPuzzle));
if (compareIntersectScore != 0) {
return compareIntersectScore;
}
return Integer.compare(arg0.id, arg1.id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import com.samabcde.puzzlesolver.solve.state.BoardFillState;

import java.util.Comparator;
import java.util.Optional;

public class BlockPriorityComparator implements Comparator<Block> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,25 @@ public class BlockPossiblePosition {
private final BlockPuzzle blockPuzzle;
private final int[] possiblePositionCountOfBlocks;
private final int[] intersectionCountOfBlockPositions;
private final int[] addedPositionOfBlocks;
private final int[] placedPositionOfBlocks;
private Set<Integer> placedBlockIds = new HashSet<>();
// TODO add BlockCommonIntersection

public BlockPossiblePosition(BlockPuzzle blockPuzzle) {
this.blockPuzzle = blockPuzzle;
this.intersectionCountOfBlockPositions = new int[blockPuzzle.getPositionCount()];
List<Block> blocks = blockPuzzle.getBlocks();
this.addedPositionOfBlocks = new int[blocks.size()];
this.placedPositionOfBlocks = new int[blocks.size()];
this.possiblePositionCountOfBlocks = new int[blocks.size()];
for (Block block : blocks) {
this.possiblePositionCountOfBlocks[block.id] = block.getPositionIdTo() - block.getPositionIdFrom() + 1;
this.addedPositionOfBlocks[block.id] = -1;
this.placedPositionOfBlocks[block.id] = -1;
}
}

public boolean hasPossiblePosition(Block block) {
List<BlockPosition> blockPositions = block.getBlockPositions();
int positionPriorityFrom = this.getAddedPosition(block) + 1;
int positionPriorityFrom = this.getPlacedPosition(block) + 1;
int positionPriorityTo = blockPositions.size() - 1;

for (int i = positionPriorityFrom; i <= positionPriorityTo; i++) {
Expand All @@ -52,7 +52,7 @@ public BlockPosition pollNextPossiblePosition(Block block) {

for (int i = positionPriorityFrom; i <= positionPriorityTo; i++) {
if (isPossible(blockPositions.get(i))) {
setAddedPosition(block, i);
setPlacedPosition(block, i);
return blockPositions.get(i);
}
}
Expand Down Expand Up @@ -88,7 +88,7 @@ int getIntersectionCount(BlockPosition blockPosition) {
}

private boolean isPossible(BlockPosition blockPosition) {
return getIntersectionCount(blockPosition) == 0;
return intersectionCountOfBlockPositions[blockPosition.id] == 0;
}

public int incrementIntersectionCount(BlockPosition blockPosition) {
Expand Down Expand Up @@ -117,7 +117,7 @@ private void decrementPossiblePositionCount(Block block) {
this.possiblePositionCountOfBlocks[block.id]--;
}

public List<BlockPosition> placeBlockPosition(BlockPosition blockPosition) {
public Stream<BlockPosition> placeBlockPosition(BlockPosition blockPosition) {
placedBlockIds.add(blockPosition.getBlock().id);
List<Integer> intersectPositionIds = blockPosition.getIntersectPositionIds();
Stream.Builder<BlockPosition> builder = Stream.builder();
Expand All @@ -130,10 +130,10 @@ public List<BlockPosition> placeBlockPosition(BlockPosition blockPosition) {
builder.add(intersectBlockPosition);
}
}
return Stream.concat(builder.build(), blockPosition.getBlock().getBlockPositions().stream().filter(this::isPossible)).toList();
return Stream.concat(builder.build(), blockPosition.getBlock().getBlockPositions().stream().filter(this::isPossible));
}

public List<BlockPosition> takeBlockPosition(BlockPosition blockPosition) {
public Stream<BlockPosition> takeBlockPosition(BlockPosition blockPosition) {
placedBlockIds.remove(blockPosition.getBlock().id);
List<Integer> intersectPositionIds = blockPosition.getIntersectPositionIds();
Stream.Builder<BlockPosition> builder = Stream.builder();
Expand All @@ -145,28 +145,28 @@ public List<BlockPosition> takeBlockPosition(BlockPosition blockPosition) {
builder.add(intersectBlockPosition);
}
}
return Stream.concat(builder.build(), blockPosition.getBlock().getBlockPositions().stream().filter(this::isPossible)).toList();
return Stream.concat(builder.build(), blockPosition.getBlock().getBlockPositions().stream().filter(this::isPossible));
}

private boolean isPlaced(Block block) {
return this.placedBlockIds.contains(block.id);
}

// check which position is added
private int getAddedPosition(Block block) {
return this.addedPositionOfBlocks[block.id];
private int getPlacedPosition(Block block) {
return this.placedPositionOfBlocks[block.id];
}

private void setAddedPosition(Block block, int position) {
this.addedPositionOfBlocks[block.id] = position;
private void setPlacedPosition(Block block, int position) {
this.placedPositionOfBlocks[block.id] = position;
}

private int getBlockPriorityFrom(Block block) {
return getAddedPosition(block) + 1;
return getPlacedPosition(block) + 1;
}

public void resetAddedPositionPriority(Block block) {
setAddedPosition(block, -1);
public void resetPlacedPositionPriority(Block block) {
setPlacedPosition(block, -1);
}

}
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package com.samabcde.puzzlesolver.solve.state;

import com.samabcde.puzzlesolver.component.Block;
import com.samabcde.puzzlesolver.component.BlockPosition;
import com.samabcde.puzzlesolver.component.BlockPuzzle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class BoardFillState {
private static final Logger logger = LoggerFactory.getLogger(BoardFillState.class);
private final LinkedList<PointFillState> emptyPoints;
private boolean[] isCanFillPositionRemoved;
private final boolean[] isCanFillPositionRemoved;
private final List<PointFillState> pointFillStatesOrderByPosition;
private final BlockPuzzle blockPuzzle;

Expand Down

0 comments on commit eb32f47

Please sign in to comment.