package trees; // le jeu du Boggle // trouve tous les mots d'au moins 3 lettres que l'on peut faire // avec un tirage donné // suppose un dictionnaire (en majuscules et sans accents) // dans le fichier french-up.txt // exemple : java -cp bin trees.Boggle RHREYPCSWNSNTEGO // solutionne le tirage // RHRE // YPCS // WNSN // TEGO // et affiche 34 mots (en 195 ms) import java.io.File; import java.io.FileNotFoundException; import java.util.Collections; import java.util.HashSet; import java.util.Scanner; import java.util.Vector; public class Boggle { static String letters; static int count = 0; static HashSet<String> words = new HashSet<>(); public static void main(String[] args) throws FileNotFoundException { double start = System.currentTimeMillis(); Trie t = buildDict("french-up.txt"); // letters = args[0]; letters = "RHREYPCSWNSNTEGO"; assert letters.length() == 16; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) find(t, i, j, 0, ""); // on imprime les mots dans l'ordre alphabétique Vector<String> list = new Vector<>(words); Collections.sort(list); for (String w: list) System.out.println(w); System.out.println(words.size() + " words"); System.err.println((System.currentTimeMillis() - start) + " ms"); print(letters); } // cherche à partir de t et de la position i, j // mask = les lettres déjà utilisées // prefix = le mot formé par les lettres déjà utilisées // (si bien que prefix.length() + pop(mask) == 16) static void find(Trie t, int i, int j, int mask, String prefix) { int pos = 4 * i + j, bit = 1 << pos; if ((mask & bit) != 0) return; mask |= bit; char c = letters.charAt(pos); t = t.branch(c); if (t == null) return; prefix += c; if (t.contains("")) words.add(prefix); for (int di = -1; di <= 1; di++) for (int dj = -1; dj <= 1; dj++) if ((di != 0 || dj != 0) && validPos(i + di, j + dj)) find(t, i + di, j + dj, mask, prefix); } static boolean validPos(int i, int j) { return 0 <= i && i < 4 && 0 <= j && j < 4; } static Trie buildDict(String filename) throws FileNotFoundException { Scanner sc = new Scanner(new File(filename)); Trie t = new Trie(); while (sc.hasNext()) { String s = sc.next(); if (s.length() >= 3 && validWord(s)) t.add(s); } sc.close(); return t; } static boolean validWord(String s) { for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c < 'A' || c > 'Z') { return false; } } return true; } static void print(String s) { assert s.length() == 16; System.out.println("+----+"); for (int i = 0; i < 4; i++) System.out.println("|" + s.substring(4 * i, 4 * i + 4) + "|"); System.out.println("+----+"); } }