Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
samabcde committed Jun 30, 2024
1 parent ae6af93 commit 13b109f
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ public class BlockPosition implements Comparable<BlockPosition> {
public final int id;
private final Block block;
private final Position position;
private final int[] canFillPoints;
private Intersection intersection;

private int intersectScore = Integer.MIN_VALUE;
private int[] canFillPoints;

private int priority;

void initializeIntersection(int positionCount) {
Expand All @@ -27,7 +28,7 @@ public int[] getCanFillPoints() {
}

public boolean canFill(PointFillState point) {
return Arrays.binarySearch(canFillPoints, point.getPosition()) > -1;
return canFill(point.getPosition());
}

public boolean canFill(int position) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ public class BlockPuzzle {
private final BlockPosition[] blockPositionsById;
private final List<Block> blocks;

public int getBlockIdByBlockPositionId(int blockPositionId) {
return this.blockPositionsById[blockPositionId].getBlock().id;
}

public int getPositionCount() {
return positionCount;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ public Solution solve() {
if (isAllBlockTried()) {
break;
}
takeLastBlockPosition();
resetAddedPosition(block);
takeLastBlockPosition();
}
if (iterateCount % 200000 == 0) {
logger.info("iterate{}", iterateCount);
Expand All @@ -117,7 +117,7 @@ public Solution solve() {
}

private boolean isCurrentBoardSolvable(Block block) {
if (!this.blockPossiblePosition.hasPossiblePosition(block, boardFillState)) {
if (!this.blockPossiblePosition.hasPossiblePosition(block)) {
return false;
}
List<Block> remainingBlocks = getRemainingBlocks();
Expand All @@ -128,7 +128,7 @@ private boolean isCurrentBoardSolvable(Block block) {
return false;
}
for (Block remainingBlock : remainingBlocks) {
if (!blockPossiblePosition.hasPossiblePosition(remainingBlock, boardFillState)) {
if (!blockPossiblePosition.hasPossiblePosition(remainingBlock)) {
return false;
}
}
Expand Down Expand Up @@ -200,9 +200,7 @@ private List<PossiblePositions> getRemainingBlocksPossiblePositions(BoardFillSta

boolean[] isBlocksSkippable = new boolean[blocks.size()];
for (Block remainingBlock : remainingBlocks) {
if (isBlocksSkippable[remainingBlock.id]
// && possibleBlockPositions.hasNoCommonIntersect()
) {
if (isBlocksSkippable[remainingBlock.id]) {
continue;
}
PossiblePositions possibleBlockPositions = cloneBlockPossiblePosition
Expand All @@ -217,61 +215,27 @@ private List<PossiblePositions> getRemainingBlocksPossiblePositions(BoardFillSta
return remainingBlocksPossiblePositions;
}

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

private boolean isAllBlockTried() {
return solution.isEmpty();
}

private void takeLastBlockPosition() {
BlockPosition lastBlockPosition = solution.poll();

List<Integer> intersectPositionIds = lastBlockPosition.getIntersectPositionIds();
for (Integer intersectPositionId : intersectPositionIds) {
BlockPosition intersectBlockPosition = blockPuzzle.getBlockPositionById(intersectPositionId);
int intersectCount = blockPossiblePosition.decrementIntersectionCount(intersectBlockPosition);
if (intersectCount > 0) {
continue;
}

boolean isInSolution = solution.containsBlock(intersectBlockPosition.getBlock());

if (!isInSolution) {
boardFillState.addCanFillBlockPosition(intersectBlockPosition);
}
}

for (BlockPosition blockPosition : lastBlockPosition.getBlock().getBlockPositions()) {
if (blockPossiblePosition.isPossible(blockPosition)) {
boardFillState.addCanFillBlockPosition(blockPosition);
}
}
boardFillState.takeBlockPosition(lastBlockPosition);
}

private void placeNextBlockPosition(Block block) {
BlockPosition nextPossiblePosition = blockPossiblePosition.pollNextPossiblePosition(block);

List<Integer> intersectPositionIds = nextPossiblePosition.getIntersectPositionIds();
for (Integer intersectPositionId : intersectPositionIds) {
BlockPosition intersectBlockPosition = blockPuzzle.getBlockPositionById(intersectPositionId);
int intersectCount = blockPossiblePosition.incrementIntersectionCount(intersectBlockPosition);
if (intersectCount == 1) {
boolean isInSolution = solution.containsBlock(intersectBlockPosition.getBlock());
if (!isInSolution) {
boardFillState.removeCanFillBlockPosition(intersectBlockPosition);
}
}
}
solution.push(nextPossiblePosition);
for (BlockPosition blockPosition : nextPossiblePosition.getBlock().getBlockPositions()) {
if (blockPossiblePosition.isPossible(blockPosition)) {
boardFillState.removeCanFillBlockPosition(blockPosition);
}
}
blockPossiblePosition.placeBlockPosition(nextPossiblePosition)
.stream()
.forEach(boardFillState::removeCanFillBlockPosition);
boardFillState.placeBlockPosition(nextPossiblePosition);
solution.push(nextPossiblePosition);
}

private void takeLastBlockPosition() {
BlockPosition lastBlockPosition = solution.poll();

blockPossiblePosition.takeBlockPosition(lastBlockPosition)
.stream()
.forEach(boardFillState::addCanFillBlockPosition);
boardFillState.takeBlockPosition(lastBlockPosition);
}

private boolean isSolved() {
Expand All @@ -281,4 +245,9 @@ private boolean isSolved() {
private void resetAddedPosition(Block block) {
setAllBlockPositionsTried(block);
}

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

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@
import com.samabcde.puzzlesolver.component.BlockPosition;
import com.samabcde.puzzlesolver.component.BlockPuzzle;

import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.stream.Stream;

public class BlockPossiblePosition {
private final BlockPuzzle blockPuzzle;
private final int[] possiblePositionCountOfBlocks;
private final int[] intersectionCountOfBlockPositions;
private final int[] addedPositionOfBlocks;
// 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()];
Expand All @@ -23,16 +28,16 @@ public BlockPossiblePosition(BlockPuzzle blockPuzzle) {
}
}

public boolean hasPossiblePosition(Block block, BoardFillState boardFillState) {
public boolean hasPossiblePosition(Block block) {
List<BlockPosition> blockPositions = block.getBlockPositions();
int positionPriorityFrom = this.getAddedPositionOfBlocks()[block.id] + 1;
int positionPriorityTo = blockPositions.size() - 1;

for (int i = positionPriorityFrom; i <= positionPriorityTo; i++) {
if (this.getIntersectionCountOfBlockPositions()[blockPositions.get(i).id] > 0) {
if (this.getIntersectionCount(blockPositions.get(i)) > 0) {
continue;
}
if (this.getPossiblePositionCountOfBlocks()[block.id] == 0) {
if (this.getPossiblePositionCount(block) == 0) {
throw new IllegalStateException("intersection count is 0 but possible position count is also 0");
}
return true;
Expand Down Expand Up @@ -87,7 +92,7 @@ int getIntersectionCount(BlockPosition blockPosition) {
return getIntersectionCountOfBlockPositions()[blockPosition.id];
}

public boolean isPossible(BlockPosition blockPosition) {
private boolean isPossible(BlockPosition blockPosition) {
return getIntersectionCount(blockPosition) == 0;
}

Expand All @@ -110,6 +115,37 @@ public int decrementIntersectionCount(BlockPosition blockPosition) {
return getIntersectionCount(blockPosition);
}

public List<BlockPosition> placeBlockPosition(BlockPosition blockPosition) {
List<Integer> intersectPositionIds = blockPosition.getIntersectPositionIds();
Stream.Builder<BlockPosition> builder = Stream.builder();
for (Integer intersectPositionId : intersectPositionIds) {
BlockPosition intersectBlockPosition = blockPuzzle.getBlockPositionById(intersectPositionId);
int intersectCount = this.incrementIntersectionCount(intersectBlockPosition);
// from possible to not possible
if (intersectCount == 1 && !isPlaced(intersectBlockPosition.getBlock())) {
builder.add(intersectBlockPosition);
}
}
return Stream.concat(builder.build(), blockPosition.getBlock().getBlockPositions().stream().filter(this::isPossible)).toList();
}

public List<BlockPosition> takeBlockPosition(BlockPosition blockPosition) {
List<Integer> intersectPositionIds = blockPosition.getIntersectPositionIds();
Stream.Builder<BlockPosition> builder = Stream.builder();
for (Integer intersectPositionId : intersectPositionIds) {
BlockPosition intersectBlockPosition = blockPuzzle.getBlockPositionById(intersectPositionId);
int intersectCount = this.decrementIntersectionCount(intersectBlockPosition);
if (intersectCount == 0 && !isPlaced(intersectBlockPosition.getBlock())) {
builder.add(intersectBlockPosition);
}
}
return Stream.concat(builder.build(), blockPosition.getBlock().getBlockPositions().stream().filter(this::isPossible)).toList();
}

private boolean isPlaced(Block block) {
return this.addedPositionOfBlocks[block.id] != -1;
}

// check which position is added
private int[] getAddedPositionOfBlocks() {
return addedPositionOfBlocks;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public List<PointFillState> getOneBlockCanFillEmptyPoints() {
public void placeBlockPosition(BlockPosition blockPosition) {
for (int canFillPoint : blockPosition.getCanFillPoints()) {
pointFillStatesOrderByPosition.get(canFillPoint).setIsFilled(true);
emptyPoints.remove(pointFillStatesOrderByPosition.get(canFillPoint));
emptyPoints.removeFirstOccurrence(pointFillStatesOrderByPosition.get(canFillPoint));
}
}

Expand All @@ -67,7 +67,6 @@ public void removeCanFillBlockPosition(BlockPosition blockPosition) {
}
}


public void takeBlockPosition(BlockPosition blockPosition) {
for (int canFillPoint : blockPosition.getCanFillPoints()) {
pointFillStatesOrderByPosition.get(canFillPoint).setIsFilled(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,28 +56,6 @@ public boolean canOnlyFillByWeight1Block() {
return canFillBlockCount > 0 && canFillBlockCount == canFillBlockWeight;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + position;
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PointFillState other = (PointFillState) obj;
if (position != other.position)
return false;
return true;
}

public int getPosition() {
return position;
}
Expand Down Expand Up @@ -135,7 +113,28 @@ public void removeCanFillBlockPosition(BlockPosition canFillBlockPosition) {
canFillPositionCountGt1BlockCount--;
}
canFillBlockPositionCount--;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + position;
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PointFillState other = (PointFillState) obj;
if (position != other.position)
return false;
return true;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,27 +22,25 @@ public void getIntersectionCount() {
@Test
public void incrementIntersectionCount() {
BlockPuzzle blockPuzzle = new BlockPuzzle(new Dimension(1, 1), new String[]{"1"});
BoardFillState boardFillState = new BoardFillState(blockPuzzle);
BlockPossiblePosition blockPossiblePosition = new BlockPossiblePosition(blockPuzzle);
Block block = blockPuzzle.getBlocks().get(0);
BlockPosition blockPosition = block.getBlockPositions().get(0);
assertEquals(1, blockPossiblePosition.incrementIntersectionCount(blockPosition));
assertEquals(1, blockPossiblePosition.getIntersectionCount(blockPosition));
assertEquals(0, blockPossiblePosition.getPossiblePositionCount(block));
assertFalse(blockPossiblePosition.hasPossiblePosition(block, boardFillState));
assertFalse(blockPossiblePosition.hasPossiblePosition(block));
}

@Test
public void decrementIntersectionCount() {
BlockPuzzle blockPuzzle = new BlockPuzzle(new Dimension(1, 2), new String[]{"1", "1"});
BoardFillState boardFillState = new BoardFillState(blockPuzzle);
BlockPossiblePosition blockPossiblePosition = new BlockPossiblePosition(blockPuzzle);
Block block = blockPuzzle.getBlocks().get(0);
BlockPosition blockPosition = block.getBlockPositions().get(0);
blockPossiblePosition.incrementIntersectionCount(blockPosition);
assertEquals(0, blockPossiblePosition.decrementIntersectionCount(blockPosition));
assertEquals(0, blockPossiblePosition.getIntersectionCount(blockPosition));
assertEquals(2, blockPossiblePosition.getPossiblePositionCount(block));
assertTrue(blockPossiblePosition.hasPossiblePosition(block, boardFillState));
assertTrue(blockPossiblePosition.hasPossiblePosition(block));
}
}

0 comments on commit 13b109f

Please sign in to comment.