Skip to content

Commit

Permalink
add list.closet_to, element.difference
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Sep 20, 2016
1 parent 2531693 commit 64f020b
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 3 deletions.
1 change: 0 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument></compilerArgument>
</configuration>
</plugin>
</plugins>
Expand Down
17 changes: 17 additions & 0 deletions src/main/java/net/aufdemrand/denizencore/objects/Element.java
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,23 @@ public String run(Attribute attribute, dObject object) {
// ELEMENT CHECKING ATTRIBUTES
/////////////////

// <--[tag]
// @attribute <el@element.difference[<element>]>
// @returns Element(Number)
// @group element checking
// @description
// Returns a number representing the difference between the two elements. (Uses Levenshtein logic).
// -->
registerTag("difference", new TagRunnable() {
@Override
public String run(Attribute attribute, dObject object) {
String element = ((Element) object).element;
String two = attribute.getContext(1);
return new Element(CoreUtilities.getLevenshteinDistance(element, two))
.getAttribute(attribute.fulfill(1));
}
});

// <--[tag]
// @attribute <el@element.contains_any_case_sensitive_text[<element>|...]>
// @returns Element(Boolean)
Expand Down
25 changes: 23 additions & 2 deletions src/main/java/net/aufdemrand/denizencore/objects/dList.java
Original file line number Diff line number Diff line change
Expand Up @@ -1558,7 +1558,7 @@ public String run(Attribute attribute, dObject object) {
// type of object that is fulfilling this attribute.
// -->

registerTag("type", new TagRunnable() { // TODO: ???
registerTag("type", new TagRunnable() {
@Override
public String run(Attribute attribute, dObject object) {
return new Element("List").getAttribute(attribute.fulfill(1));
Expand All @@ -1577,7 +1577,7 @@ public String run(Attribute attribute, dObject object) {
// "two|three|one", "three|two|one", OR "three|one|two" - different each time!
// -->

registerTag("random", new TagRunnable() { // TODO: ???
registerTag("random", new TagRunnable() {
@Override
public String run(Attribute attribute, dObject object) {
dList obj = (dList) object;
Expand Down Expand Up @@ -1605,6 +1605,27 @@ public String run(Attribute attribute, dObject object) {
}
});

// <--[tag]
// @attribute <li@list.closest_to[<text>]>
// @returns Element
// @description
// Returns the item in the list that seems closest to the given value.
// Particularly useful for command handlers, "<li@c1|c2|c3|[...].closet_to[<argument>]>" to get the best option as "did you mean" suggestion.
// For example, "<li@dance|quit|spawn.closest_to[spwn]>" returns "spawn".
// Be warned that this will always return /something/, excluding the case of an empty list, which will return an empty element.
// Uses the logic of tag "el@element.difference"!
// You can use that tag to add an upper limit on how different the strings can be.
// -->

registerTag("closest_to", new TagRunnable() {
@Override
public String run(Attribute attribute, dObject object) {
return new Element(CoreUtilities.getClosestOption((dList) object, attribute.getContext(1)))
.getAttribute(attribute.fulfill(1));
}
});



/////////////////
// dObject attributes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,73 @@ else if (arg == argc) {
}
return x == data2.length;
}

public static String getClosestOption(List<String> strs, String opt) {
int minDist = Integer.MAX_VALUE;
opt = CoreUtilities.toLowerCase(opt);
String closest = "";
for (String cmd : strs) {
String comp = CoreUtilities.toLowerCase(cmd);
int distance = getLevenshteinDistance(opt, comp);
if (minDist > distance) {
minDist = distance;
closest = comp;
}
}

return closest;
}

public static int getLevenshteinDistance(String s, String t) {
if (s == null || t == null) {
throw new IllegalArgumentException("Strings must not be null");
}

int n = s.length(); // length of s
int m = t.length(); // length of t

if (n == 0) {
return m;
}
else if (m == 0) {
return n;
}

int p[] = new int[n + 1]; // 'previous' cost array, horizontally
int d[] = new int[n + 1]; // cost array, horizontally
int _d[]; // placeholder to assist in swapping p and d

// indexes into strings s and t
int i; // iterates through s
int j; // iterates through t

char t_j; // jth character of t

int cost; // cost

for (i = 0; i <= n; i++) {
p[i] = i;
}

for (j = 1; j <= m; j++) {
t_j = t.charAt(j - 1);
d[0] = j;

for (i = 1; i <= n; i++) {
cost = s.charAt(i - 1) == t_j ? 0 : 1;
// minimum of cell to the left+1, to the top+1, diagonally left
// and up +cost
d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1] + cost);
}

// copy current distance counts to 'previous row' distance counts
_d = p;
p = d;
d = _d;
}

// our last action in the above loop was to switch d and p, so p now
// actually has the most recent cost counts
return p[n];
}
}

0 comments on commit 64f020b

Please sign in to comment.