Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
94
Task/Word-ladder/Java/word-ladder-1.java
Normal file
94
Task/Word-ladder/Java/word-ladder-1.java
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Set;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class WordLadder {
|
||||
private static int distance(String s1, String s2) {
|
||||
assert s1.length() == s2.length();
|
||||
return (int) IntStream.range(0, s1.length())
|
||||
.filter(i -> s1.charAt(i) != s2.charAt(i))
|
||||
.count();
|
||||
}
|
||||
|
||||
private static void wordLadder(Map<Integer, Set<String>> words, String fw, String tw) {
|
||||
wordLadder(words, fw, tw, 8);
|
||||
}
|
||||
|
||||
private static void wordLadder(Map<Integer, Set<String>> words, String fw, String tw, int limit) {
|
||||
if (fw.length() != tw.length()) {
|
||||
throw new IllegalArgumentException("From word and to word must have the same length");
|
||||
}
|
||||
|
||||
Set<String> ws = words.get(fw.length());
|
||||
if (ws.contains(fw)) {
|
||||
List<String> primeList = new ArrayList<>();
|
||||
primeList.add(fw);
|
||||
|
||||
PriorityQueue<List<String>> queue = new PriorityQueue<>((chain1, chain2) -> {
|
||||
int cmp1 = Integer.compare(chain1.size(), chain2.size());
|
||||
if (cmp1 == 0) {
|
||||
String last1 = chain1.get(chain1.size() - 1);
|
||||
int d1 = distance(last1, tw);
|
||||
|
||||
String last2 = chain2.get(chain2.size() - 1);
|
||||
int d2 = distance(last2, tw);
|
||||
|
||||
return Integer.compare(d1, d2);
|
||||
}
|
||||
return cmp1;
|
||||
});
|
||||
queue.add(primeList);
|
||||
|
||||
while (queue.size() > 0) {
|
||||
List<String> curr = queue.remove();
|
||||
if (curr.size() > limit) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String last = curr.get(curr.size() - 1);
|
||||
for (String word : ws) {
|
||||
if (distance(last, word) == 1) {
|
||||
if (word.equals(tw)) {
|
||||
curr.add(word);
|
||||
System.out.println(String.join(" -> ", curr));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!curr.contains(word)) {
|
||||
List<String> cp = new ArrayList<>(curr);
|
||||
cp.add(word);
|
||||
queue.add(cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.err.printf("Cannot turn `%s` into `%s`%n", fw, tw);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
Map<Integer, Set<String>> words = new HashMap<>();
|
||||
for (String line : Files.readAllLines(Path.of("unixdict.txt"))) {
|
||||
Set<String> wl = words.computeIfAbsent(line.length(), HashSet::new);
|
||||
wl.add(line);
|
||||
}
|
||||
|
||||
wordLadder(words, "boy", "man");
|
||||
wordLadder(words, "girl", "lady");
|
||||
wordLadder(words, "john", "jane");
|
||||
wordLadder(words, "child", "adult");
|
||||
wordLadder(words, "cat", "dog");
|
||||
wordLadder(words, "lead", "gold");
|
||||
wordLadder(words, "white", "black");
|
||||
wordLadder(words, "bubble", "tickle", 12);
|
||||
}
|
||||
}
|
||||
72
Task/Word-ladder/Java/word-ladder-2.java
Normal file
72
Task/Word-ladder/Java/word-ladder-2.java
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class WordLadder {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Map<Integer, List<String>> words = new HashMap<>();
|
||||
try (BufferedReader reader = new BufferedReader(new FileReader("unixdict.txt"))) {
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null)
|
||||
words.computeIfAbsent(line.length(), k -> new ArrayList<String>()).add(line);
|
||||
}
|
||||
wordLadder(words, "boy", "man");
|
||||
wordLadder(words, "girl", "lady");
|
||||
wordLadder(words, "john", "jane");
|
||||
wordLadder(words, "child", "adult");
|
||||
wordLadder(words, "cat", "dog");
|
||||
wordLadder(words, "lead", "gold");
|
||||
wordLadder(words, "white", "black");
|
||||
wordLadder(words, "bubble", "tickle");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if strings s1 and s2 differ by one character.
|
||||
private static boolean oneAway(String s1, String s2) {
|
||||
if (s1.length() != s2.length())
|
||||
return false;
|
||||
boolean result = false;
|
||||
for (int i = 0, n = s1.length(); i != n; ++i) {
|
||||
if (s1.charAt(i) != s2.charAt(i)) {
|
||||
if (result)
|
||||
return false;
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// If possible, print the shortest chain of single-character modifications that
|
||||
// leads from "from" to "to", with each intermediate step being a valid word.
|
||||
// This is an application of breadth-first search.
|
||||
private static void wordLadder(Map<Integer, List<String>> words, String from, String to) {
|
||||
List<String> w = words.get(from.length());
|
||||
if (w != null) {
|
||||
Deque<String> poss = new ArrayDeque<>(w);
|
||||
Deque<String> f = new ArrayDeque<String>();
|
||||
f.add(from);
|
||||
Deque<Deque<String>> queue = new ArrayDeque<>();
|
||||
queue.add(f);
|
||||
while (!queue.isEmpty()) {
|
||||
Deque<String> curr = queue.poll();
|
||||
for (Iterator<String> i = poss.iterator(); i.hasNext(); ) {
|
||||
String str = i.next();
|
||||
if (!oneAway(str, curr.getLast()))
|
||||
continue;
|
||||
if (to.equals(str)) {
|
||||
curr.add(to);
|
||||
System.out.println(String.join(" -> ", curr));
|
||||
return;
|
||||
}
|
||||
Deque<String> temp = new ArrayDeque<>(curr);
|
||||
temp.add(str);
|
||||
queue.add(temp);
|
||||
i.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.printf("%s into %s cannot be done.\n", from, to);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue