Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
317
Task/Zebra-puzzle/Java/zebra-puzzle-3.java
Normal file
317
Task/Zebra-puzzle/Java/zebra-puzzle-3.java
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
package zebra;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class Puzzle {
|
||||
private static final ArrayList<Integer> orders = new ArrayList<>(5);
|
||||
private static final ArrayList<String> nations = new ArrayList<>(5);
|
||||
private static final ArrayList<String> animals = new ArrayList<>(5);
|
||||
private static final ArrayList<String> drinks = new ArrayList<>(5);
|
||||
private static final ArrayList<String> cigarettes = new ArrayList<>(5);
|
||||
private static final ArrayList<String> colors = new ArrayList<>(5);
|
||||
private static PuzzleSet<LineOfPuzzle> puzzleTable;
|
||||
static
|
||||
{
|
||||
// House orders
|
||||
orders.add(1);
|
||||
orders.add(2);
|
||||
orders.add(3);
|
||||
orders.add(4);
|
||||
orders.add(5);
|
||||
// Man nations
|
||||
nations.add("English");
|
||||
nations.add("Danish");
|
||||
nations.add("German");
|
||||
nations.add("Swedesh");
|
||||
nations.add("Norwegian");
|
||||
//Animals
|
||||
animals.add("Zebra");
|
||||
animals.add("Horse");
|
||||
animals.add("Birds");
|
||||
animals.add("Dog");
|
||||
animals.add("Cats");
|
||||
//Drinks
|
||||
drinks.add("Coffee");
|
||||
drinks.add("Tea");
|
||||
drinks.add("Beer");
|
||||
drinks.add("Water");
|
||||
drinks.add("Milk");
|
||||
//Smokes
|
||||
cigarettes.add("Pall Mall");
|
||||
cigarettes.add("Blend");
|
||||
cigarettes.add("Blue Master");
|
||||
cigarettes.add("Prince");
|
||||
cigarettes.add("Dunhill");
|
||||
//Colors
|
||||
colors.add("Red");
|
||||
colors.add("Green");
|
||||
colors.add("White");
|
||||
colors.add("Blue");
|
||||
colors.add("Yellow");
|
||||
}
|
||||
|
||||
public static void main (String[] args){
|
||||
boolean validLine=true;
|
||||
puzzleTable = new PuzzleSet<>();
|
||||
|
||||
//Rules
|
||||
LineOfPuzzle rule2 = new LineOfPuzzle(null, "English", "Red", null, null, null);
|
||||
LineOfPuzzle rule3 = new LineOfPuzzle(null, "Swedesh", null, "Dog", null, null);
|
||||
LineOfPuzzle rule4 = new LineOfPuzzle(null, "Danish", null, null, "Tea", null);
|
||||
LineOfPuzzle rule6 = new LineOfPuzzle(null, null, "Green", null, "Coffee", null);
|
||||
LineOfPuzzle rule7 = new LineOfPuzzle(null, null, null, "Birds", null, "Pall Mall");
|
||||
LineOfPuzzle rule8 = new LineOfPuzzle(null, null, "Yellow", null, null, "Dunhill");
|
||||
LineOfPuzzle rule9 = new LineOfPuzzle(3, null, null, null, "Milk", null);
|
||||
LineOfPuzzle rule10 = new LineOfPuzzle(1, "Norwegian", null, null, null, null);
|
||||
LineOfPuzzle rule13 = new LineOfPuzzle(null, null, null, null, "Beer", "Blue Master");
|
||||
LineOfPuzzle rule14 = new LineOfPuzzle(null, "German", null, null, null, "Prince");
|
||||
LineOfPuzzle rule15 = new LineOfPuzzle(2, null, "Blue", null, null, null);
|
||||
|
||||
PuzzleSet<LineOfPuzzle> ruleSet = new PuzzleSet<>();
|
||||
ruleSet.add(rule2);
|
||||
ruleSet.add(rule3);
|
||||
ruleSet.add(rule4);
|
||||
ruleSet.add(rule6);
|
||||
ruleSet.add(rule7);
|
||||
ruleSet.add(rule8);
|
||||
ruleSet.add(rule9);
|
||||
ruleSet.add(rule10);
|
||||
ruleSet.add(rule13);
|
||||
ruleSet.add(rule14);
|
||||
ruleSet.add(rule15);
|
||||
|
||||
//Creating all possible combination of a puzzle line.
|
||||
//The maximum number of lines is 5^^6 (15625).
|
||||
//Each combination line is checked against a set of knowing facts, thus
|
||||
//only a small number of line result at the end.
|
||||
for (Integer orderId : Puzzle.orders) {
|
||||
for (String nation : Puzzle.nations) {
|
||||
for (String color : Puzzle.colors) {
|
||||
for (String animal : Puzzle.animals) {
|
||||
for (String drink : Puzzle.drinks) {
|
||||
for (String cigarette : Puzzle.cigarettes) {
|
||||
LineOfPuzzle pzlLine = new LineOfPuzzle(orderId,
|
||||
nation,
|
||||
color,
|
||||
animal,
|
||||
drink,
|
||||
cigarette);
|
||||
// Checking against a set of knowing facts
|
||||
if (ruleSet.accepts(pzlLine)){
|
||||
// Adding rules of neighbors
|
||||
if (cigarette.equalsIgnoreCase("Blend")
|
||||
&& (animal.equalsIgnoreCase("Cats")
|
||||
|| drink.equalsIgnoreCase("Water")))
|
||||
validLine = false;
|
||||
|
||||
if (cigarette.equalsIgnoreCase("Dunhill")
|
||||
&& animal.equalsIgnoreCase("Horse"))
|
||||
validLine = false;
|
||||
|
||||
if (validLine){
|
||||
puzzleTable.add(pzlLine);
|
||||
|
||||
//set neighbors constraints
|
||||
if (color.equalsIgnoreCase("Green")){
|
||||
pzlLine.setRightNeighbor(new LineOfPuzzle(null, null, "White", null, null, null));
|
||||
}
|
||||
if (color.equalsIgnoreCase("White")){
|
||||
pzlLine.setLeftNeighbor(new LineOfPuzzle(null, null, "Green", null, null, null));
|
||||
}
|
||||
//
|
||||
if (animal.equalsIgnoreCase("Cats")
|
||||
&& !cigarette.equalsIgnoreCase("Blend") ){
|
||||
pzlLine.addUndefindedNeighbor(new LineOfPuzzle(null, null, null, null, null, "Blend"));
|
||||
}
|
||||
if (cigarette.equalsIgnoreCase("Blend")
|
||||
&& !animal.equalsIgnoreCase("Cats")){
|
||||
pzlLine.addUndefindedNeighbor(new LineOfPuzzle(null, null, null, "Cats", null, null));
|
||||
}
|
||||
//
|
||||
if (drink.equalsIgnoreCase("Water")
|
||||
&& !animal.equalsIgnoreCase("Cats")
|
||||
&& !cigarette.equalsIgnoreCase("Blend")){
|
||||
pzlLine.addUndefindedNeighbor(new LineOfPuzzle(null, null, null, null, null, "Blend"));
|
||||
}
|
||||
|
||||
if (cigarette.equalsIgnoreCase("Blend")
|
||||
&& !drink.equalsIgnoreCase("Water")){
|
||||
pzlLine.addUndefindedNeighbor(new LineOfPuzzle(null, null, null, null, "Water", null));
|
||||
}
|
||||
//
|
||||
if (animal.equalsIgnoreCase("Horse")
|
||||
&& !cigarette.equalsIgnoreCase("Dunhill")){
|
||||
pzlLine.addUndefindedNeighbor(new LineOfPuzzle(null, null, null, null, null, "Dunhill"));
|
||||
}
|
||||
if (cigarette.equalsIgnoreCase("Dunhill")
|
||||
&& !animal.equalsIgnoreCase("Horse")){
|
||||
pzlLine.addUndefindedNeighbor(new LineOfPuzzle(null, null, null, "Horse", null, null));
|
||||
}
|
||||
}
|
||||
validLine = true;
|
||||
}
|
||||
} //cigarette end
|
||||
} //drinks end
|
||||
} //animal end
|
||||
} //color end
|
||||
} //nations end
|
||||
} //order end
|
||||
|
||||
System.out.println("After general rule set validation, remains "+
|
||||
puzzleTable.size() + " lines.");
|
||||
|
||||
for (Iterator<LineOfPuzzle> it = puzzleTable.iterator(); it.hasNext();){
|
||||
validLine=true;
|
||||
|
||||
LineOfPuzzle lineOfPuzzle = it.next();
|
||||
|
||||
if (lineOfPuzzle.hasLeftNeighbor()){
|
||||
LineOfPuzzle neighbor = lineOfPuzzle.getLeftNeighbor();
|
||||
if (neighbor.getOrder()<1 || neighbor.getOrder()>5){
|
||||
validLine=false;
|
||||
it.remove();
|
||||
|
||||
}
|
||||
}
|
||||
if (validLine && lineOfPuzzle.hasRightNeighbor()){
|
||||
LineOfPuzzle neighbor = lineOfPuzzle.getRightNeighbor();
|
||||
if (neighbor.getOrder()<1 || neighbor.getOrder()>5){
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("After removing out of bound neighbors, remains " +
|
||||
puzzleTable.size() + " lines.");
|
||||
|
||||
//Setting left and right neighbors
|
||||
for (Iterator<LineOfPuzzle> it = puzzleTable.iterator(); it.hasNext();) {
|
||||
LineOfPuzzle puzzleLine = it.next();
|
||||
|
||||
if (puzzleLine.hasUndefNeighbors()){
|
||||
for (Iterator<LineOfPuzzle> it1 = puzzleLine.getUndefNeighbors().iterator(); it1.hasNext();) {
|
||||
LineOfPuzzle leftNeighbor = it1.next();
|
||||
LineOfPuzzle rightNeighbor = leftNeighbor.clone();
|
||||
|
||||
//make it left neighbor
|
||||
leftNeighbor.setOrder(puzzleLine.getOrder()-1);
|
||||
if (puzzleTable.contains(leftNeighbor)){
|
||||
if (puzzleLine.hasLeftNeighbor())
|
||||
puzzleLine.getLeftNeighbor().merge(leftNeighbor);
|
||||
else
|
||||
puzzleLine.setLeftNeighbor(leftNeighbor);
|
||||
}
|
||||
rightNeighbor.setOrder(puzzleLine.getOrder()+1);
|
||||
if (puzzleTable.contains(rightNeighbor)){
|
||||
if (puzzleLine.hasRightNeighbor())
|
||||
puzzleLine.getRightNeighbor().merge(rightNeighbor);
|
||||
else
|
||||
puzzleLine.setRightNeighbor(rightNeighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int iteration=1;
|
||||
int lastSize=0;
|
||||
|
||||
//Recursively validate against neighbor rules
|
||||
while (puzzleTable.size()>5 && lastSize != puzzleTable.size()) {
|
||||
lastSize = puzzleTable.size();
|
||||
puzzleTable.clearLineCountFlags();
|
||||
|
||||
recursiveSearch(null, puzzleTable, -1);
|
||||
|
||||
ruleSet.clear();
|
||||
// Assuming we'll get at leas one valid line each iteration, we create
|
||||
// a set of new rules with lines which have no more then one instance of same OrderId.
|
||||
for (int i = 1; i < 6; i++) {
|
||||
if (puzzleTable.getLineCountByOrderId(i)==1)
|
||||
ruleSet.addAll(puzzleTable.getSimilarLines(new LineOfPuzzle(i, null, null, null, null, null)));
|
||||
}
|
||||
|
||||
for (Iterator<LineOfPuzzle> it = puzzleTable.iterator(); it.hasNext();) {
|
||||
LineOfPuzzle puzzleLine = it.next();
|
||||
|
||||
if (!ruleSet.accepts(puzzleLine))
|
||||
it.remove();
|
||||
}
|
||||
//
|
||||
System.out.println("After " + iteration + " recursive iteration, remains "
|
||||
+ puzzleTable.size() + " lines");
|
||||
iteration+=1;
|
||||
}
|
||||
|
||||
// Print the results
|
||||
System.out.println("-------------------------------------------");
|
||||
if (puzzleTable.size()==5){
|
||||
for (Iterator<LineOfPuzzle> it = puzzleTable.iterator(); it.hasNext();) {
|
||||
LineOfPuzzle puzzleLine = it.next();
|
||||
System.out.println(puzzleLine.getWholeLine());
|
||||
}
|
||||
}else
|
||||
System.out.println("Sorry, solution not found!");
|
||||
}
|
||||
|
||||
// Recursively checks the input set to ensure each line has right neighbor.
|
||||
// Neighbors can be of three type, left, right or undefined.
|
||||
// Direction: -1 left, 0 undefined, 1 right
|
||||
private static boolean recursiveSearch(LineOfPuzzle pzzlNodeLine,
|
||||
PuzzleSet puzzleSet, int direction){
|
||||
boolean validLeaf = false;
|
||||
boolean hasNeighbor = false;
|
||||
PuzzleSet<LineOfPuzzle> puzzleSubSet = null;
|
||||
|
||||
for (Iterator<LineOfPuzzle> it = puzzleSet.iterator(); it.hasNext();) {
|
||||
LineOfPuzzle pzzlLeafLine = it.next();
|
||||
validLeaf = false;
|
||||
|
||||
hasNeighbor = pzzlLeafLine.hasNeighbor(direction);
|
||||
|
||||
if (hasNeighbor){
|
||||
puzzleSubSet = puzzleTable.getSimilarLines(pzzlLeafLine.getNeighbor(direction));
|
||||
if (puzzleSubSet != null){
|
||||
if (pzzlNodeLine !=null)
|
||||
validLeaf = puzzleSubSet.contains(pzzlNodeLine);
|
||||
else
|
||||
validLeaf = recursiveSearch(pzzlLeafLine, puzzleSubSet, -1*direction);
|
||||
}
|
||||
else
|
||||
validLeaf = false;
|
||||
}
|
||||
|
||||
if (!validLeaf && pzzlLeafLine.hasNeighbor(-1*direction)){
|
||||
hasNeighbor = true;
|
||||
if (hasNeighbor){
|
||||
puzzleSubSet = puzzleTable.getSimilarLines(pzzlLeafLine.getNeighbor(-1*direction));
|
||||
if (puzzleSubSet != null){
|
||||
if (pzzlNodeLine !=null)
|
||||
validLeaf = puzzleSubSet.contains(pzzlNodeLine);
|
||||
else
|
||||
validLeaf = recursiveSearch(pzzlLeafLine, puzzleSubSet, direction);
|
||||
}
|
||||
else
|
||||
validLeaf = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (pzzlNodeLine != null && validLeaf)
|
||||
return validLeaf;
|
||||
|
||||
if (pzzlNodeLine == null && hasNeighbor && !validLeaf){
|
||||
it.remove();
|
||||
}
|
||||
|
||||
if (pzzlNodeLine == null){
|
||||
if (hasNeighbor && validLeaf){
|
||||
puzzleSet.riseLineCountFlags(pzzlLeafLine.getOrder());
|
||||
}
|
||||
if (!hasNeighbor){
|
||||
puzzleSet.riseLineCountFlags(pzzlLeafLine.getOrder());
|
||||
}
|
||||
}
|
||||
}
|
||||
return validLeaf;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue