56 lines
2.0 KiB
Java
56 lines
2.0 KiB
Java
package com.cleverthis.interview;
|
|
|
|
import java.util.Iterator;
|
|
import java.util.TreeSet;
|
|
import org.apache.commons.text.similarity.LevenshteinDistance;
|
|
|
|
/**
|
|
* This is a write-aware brute solver implementation that uses the levenshtein distance to sort passcode permutations
|
|
* into a tree. Walking the tree in-order (Likely a depth-first traversal internally) results in a naive nearest-neighbor
|
|
* optimization that generally performs well, but may perform poorly in some cases.
|
|
*
|
|
* This permutation optimization problem is NP-hard and a perfect brute-force solution has a worst-case running time that
|
|
* is super-polynomial. Heuristic solutions exist that have acceptable performance, and this is a more naive heuristic
|
|
* implementation.
|
|
*/
|
|
public class WriteAwareBruteSolver extends DumbBruteSolver {
|
|
|
|
private final TreeSet<IntegerLevenshtein> orderedTree;
|
|
private final Integer numpadSize;
|
|
|
|
public WriteAwareBruteSolver(int numpadSize) {
|
|
orderedTree = new TreeSet<IntegerLevenshtein>();
|
|
this.numpadSize = numpadSize;
|
|
|
|
Integer[] currentPermutation = new Integer[numpadSize];
|
|
for(int i = 0; i < numpadSize; i++) {
|
|
currentPermutation[i] = i;
|
|
}
|
|
|
|
boolean morePermutationsExist = true;
|
|
|
|
do {
|
|
IntegerLevenshtein levenshteinPermutation = new IntegerLevenshtein(numpadSize);
|
|
levenshteinPermutation.setIntegerData(currentPermutation);
|
|
orderedTree.add(levenshteinPermutation);
|
|
morePermutationsExist = this.calculateNextPermutation(currentPermutation, numpadSize);
|
|
} while(morePermutationsExist);
|
|
}
|
|
|
|
public void solve(PadlockAdapter padlockAdapter) {
|
|
int numpadSize = padlockAdapter.getNumpadSize();
|
|
|
|
Iterator<IntegerLevenshtein> iterator = orderedTree.iterator();
|
|
|
|
while(iterator.hasNext()) {
|
|
if(this.checkPermutation(iterator.next().getIntegerData(), padlockAdapter)) {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
public Integer getTreeSize() {
|
|
return this.orderedTree.size();
|
|
}
|
|
}
|