mirror of
https://codeberg.org/cblanken/boggler.git
synced 2026-07-26 11:35:10 -04:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a80111072f | ||
|
|
fa01d442a5 | ||
|
|
733c1474b0 | ||
|
|
54f79c0afe | ||
|
|
9f364ee90e | ||
|
|
e219954ba6 | ||
|
|
f4accfe959 | ||
|
|
bc70b88bf7 | ||
|
|
21aab46b96 | ||
|
|
f18c30cb60 | ||
|
|
da915b723c | ||
|
|
d5a102713d | ||
|
|
c488263eea | ||
|
|
fe1f1c2b97 | ||
|
|
d2584686a3 | ||
|
|
8f75604d15 | ||
|
|
96da732dd9 | ||
|
|
ec53042d18 | ||
|
|
5c18a4aebf | ||
|
|
b197253d86 | ||
|
|
67f8c439b0 | ||
|
|
8c41ad212d | ||
|
|
94800909b4 | ||
|
|
f24b996411 | ||
|
|
e4df95cd08 | ||
|
|
0e9b120e94 | ||
|
|
276c27f1ce | ||
|
|
d30c44af3c |
+8
-1
@@ -1,2 +1,9 @@
|
|||||||
|
# Byte-compiled / optimized
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
|
||||||
|
# Distribution / packaging
|
||||||
|
dist/
|
||||||
|
|
||||||
|
# Env
|
||||||
.vscode
|
.vscode
|
||||||
__pycache__
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
Copyright © 2022 Cameron Blankenbuehler
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
@@ -2,8 +2,12 @@
|
|||||||
A solver for the popular word game Boggle.
|
A solver for the popular word game Boggle.
|
||||||
|
|
||||||
# Install
|
# Install
|
||||||
```bash
|
```console
|
||||||
$ git clone https://github.com/cblanken/boggler.git
|
pip install boggler
|
||||||
|
```
|
||||||
|
OR
|
||||||
|
```console
|
||||||
|
git clone https://github.com/cblanken/boggler.git
|
||||||
```
|
```
|
||||||
|
|
||||||
To use the script to solve a particular Boggle board configuration, you'll need to do a few things
|
To use the script to solve a particular Boggle board configuration, you'll need to do a few things
|
||||||
@@ -11,11 +15,11 @@ To use the script to solve a particular Boggle board configuration, you'll need
|
|||||||
|
|
||||||
Here is an example `board.csv`. Note the orientation of the board does not matter.
|
Here is an example `board.csv`. Note the orientation of the board does not matter.
|
||||||
```console
|
```console
|
||||||
$ cat boards/b1.csv
|
$ cat board.csv
|
||||||
s,a,i,p
|
y,e,o,s
|
||||||
l,qu,a,y
|
r,e,o,v
|
||||||
u,l,l,s
|
d,f,e,y
|
||||||
o,w,h,a
|
n,m,e,qu
|
||||||
```
|
```
|
||||||
2. Find a dictionary wordlist file or create your own
|
2. Find a dictionary wordlist file or create your own
|
||||||
|
|
||||||
@@ -394,3 +398,6 @@ quey : [(3, 3), (3, 2), (2, 3)]
|
|||||||
quem : [(3, 3), (3, 2), (3, 1)]
|
quem : [(3, 3), (3, 2), (3, 1)]
|
||||||
queme : [(3, 3), (3, 2), (3, 1), (2, 2)]
|
queme : [(3, 3), (3, 2), (3, 1), (2, 2)]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# License
|
||||||
|
The included [wordlists](src/boggler/wordlists) are covered by their respective licenses. All other files MIT © Cameron Blankenbuehler
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
'''Module to generate random Boggle boards for testing'''
|
|
||||||
from sys import argv
|
|
||||||
from random import randint, shuffle
|
|
||||||
from math import sqrt
|
|
||||||
|
|
||||||
def read_dice_file(path):
|
|
||||||
# TODO: Factor in 'qu' die face
|
|
||||||
'''Return list of die strings from file ignoring all comments (#)'''
|
|
||||||
with open(path, 'r+', encoding="utf-8") as file:
|
|
||||||
return [line.rstrip().split(',') for line in file.readlines() if line[0] != "#"]
|
|
||||||
|
|
||||||
def roll_die(die: str):
|
|
||||||
'''Return a face of the given die string to simulate rolling a die'''
|
|
||||||
return str(die[randint(0, len(die) - 1)])
|
|
||||||
|
|
||||||
def roll_dice(dice: list[str]):
|
|
||||||
'''Return a random roll for each die'''
|
|
||||||
return [ roll_die(die) for die in dice ]
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
if len(argv) != 2:
|
|
||||||
print('Usage: python3 board_randomizer.py <dice_file>')
|
|
||||||
else:
|
|
||||||
dice_strings = read_dice_file(argv[1])
|
|
||||||
shuffle(dice_strings)
|
|
||||||
rolls = roll_dice(dice_strings)
|
|
||||||
|
|
||||||
# Format dice rolls for boards file
|
|
||||||
board_size = int(sqrt(len(rolls)))
|
|
||||||
for i in range(0, len(dice_strings), board_size):
|
|
||||||
print(",".join(rolls[i:i+board_size]))
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
[build-system]
|
||||||
|
requires = ["hatchling"]
|
||||||
|
build-backend = "hatchling.build"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "boggler"
|
||||||
|
version = "2.0.1"
|
||||||
|
authors = [
|
||||||
|
{ name="Cameron Blankenbuehler", email="cameron.blankenbuehler@gmail.com" },
|
||||||
|
]
|
||||||
|
description = "Utilities for solving the Boggle word game."
|
||||||
|
readme="README.md"
|
||||||
|
license = { file="LICENSE" }
|
||||||
|
requires-python = ">=3.7"
|
||||||
|
classifiers = [
|
||||||
|
"Programming Language :: Python :: 3",
|
||||||
|
"License :: OSI Approved :: MIT License",
|
||||||
|
"Operating System :: POSIX :: Linux",
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.urls]
|
||||||
|
"Homepage" = "https://github.com/cblanken/boggler"
|
||||||
|
"Bug Tracker" = "https://github.com/cblanken/boggler/issues"
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
if [ -z $1 ] || [ -z $2 ]; then
|
|
||||||
echo "Usage: ./filter_prefix.sh WORDLIST OUT_DIR"
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
grep -P "^a" $1 > "$2/words_a.txt"
|
|
||||||
grep -P "^b" $1 > "$2/words_b.txt"
|
|
||||||
grep -P "^c" $1 > "$2/words_c.txt"
|
|
||||||
grep -P "^d" $1 > "$2/words_d.txt"
|
|
||||||
grep -P "^e" $1 > "$2/words_e.txt"
|
|
||||||
grep -P "^f" $1 > "$2/words_f.txt"
|
|
||||||
grep -P "^g" $1 > "$2/words_g.txt"
|
|
||||||
grep -P "^h" $1 > "$2/words_h.txt"
|
|
||||||
grep -P "^i" $1 > "$2/words_i.txt"
|
|
||||||
grep -P "^j" $1 > "$2/words_j.txt"
|
|
||||||
grep -P "^k" $1 > "$2/words_k.txt"
|
|
||||||
grep -P "^l" $1 > "$2/words_l.txt"
|
|
||||||
grep -P "^m" $1 > "$2/words_m.txt"
|
|
||||||
grep -P "^n" $1 > "$2/words_n.txt"
|
|
||||||
grep -P "^o" $1 > "$2/words_o.txt"
|
|
||||||
grep -P "^p" $1 > "$2/words_p.txt"
|
|
||||||
grep -P "^q" $1 > "$2/words_q.txt"
|
|
||||||
grep -P "^r" $1 > "$2/words_r.txt"
|
|
||||||
grep -P "^s" $1 > "$2/words_s.txt"
|
|
||||||
grep -P "^t" $1 > "$2/words_t.txt"
|
|
||||||
grep -P "^u" $1 > "$2/words_u.txt"
|
|
||||||
grep -P "^v" $1 > "$2/words_v.txt"
|
|
||||||
grep -P "^w" $1 > "$2/words_w.txt"
|
|
||||||
grep -P "^x" $1 > "$2/words_x.txt"
|
|
||||||
grep -P "^y" $1 > "$2/words_y.txt"
|
|
||||||
grep -P "^z" $1 > "$2/words_z.txt"
|
|
||||||
grep -P "^_" $1 > "$2/words__.txt"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
Executable
+48
@@ -0,0 +1,48 @@
|
|||||||
|
'''Module to generate random Boggle boards for testing'''
|
||||||
|
from sys import argv, stderr
|
||||||
|
from random import randint, shuffle
|
||||||
|
from math import sqrt, floor
|
||||||
|
from os import path
|
||||||
|
|
||||||
|
def read_dice_file(dice_path: str):
|
||||||
|
'''Return list of die strings from file ignoring all comments (#)'''
|
||||||
|
with open(path.abspath(dice_path), 'r+', encoding="utf-8") as file:
|
||||||
|
return [line.rstrip().split(',') for line in file.readlines() if line[0] != "#"]
|
||||||
|
|
||||||
|
def roll_die(die: str):
|
||||||
|
'''Return a face of the given die string to simulate rolling a die'''
|
||||||
|
return str(die[randint(0, len(die) - 1)])
|
||||||
|
|
||||||
|
def roll_dice(dice: list[str]):
|
||||||
|
'''Return a random roll for each die'''
|
||||||
|
return [ roll_die(die) for die in dice ]
|
||||||
|
|
||||||
|
def get_random_board(dice: list[str]):
|
||||||
|
shuffle(dice)
|
||||||
|
rolls = roll_dice(dice)
|
||||||
|
|
||||||
|
# Format dice rolls for boards file
|
||||||
|
board_size = int(floor(sqrt(len(rolls))))
|
||||||
|
board = []
|
||||||
|
for i in range(0, len(dice), board_size):
|
||||||
|
board.append(rolls[i:i+board_size])
|
||||||
|
return board
|
||||||
|
|
||||||
|
def get_random_board_csv(dice: list[str]):
|
||||||
|
board = get_random_board(dice)
|
||||||
|
board = [",".join(row) for row in board]
|
||||||
|
return board
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
if len(argv) != 2:
|
||||||
|
print('Usage: python3 board_randomizer.py <dice_file>')
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
dice = read_dice_file(path.abspath(argv[1]))
|
||||||
|
board = get_random_board_csv(dice)
|
||||||
|
for r in range(0, int(floor(sqrt(len(dice))))):
|
||||||
|
print(board[r])
|
||||||
|
except Exception as e:
|
||||||
|
print("Argument must be a valid file path!", file=stderr)
|
||||||
|
|
||||||
|
|
||||||
@@ -11,11 +11,13 @@ if __name__ == '__main__':
|
|||||||
board = read_boggle_file(Path(sys.argv[1]))
|
board = read_boggle_file(Path(sys.argv[1]))
|
||||||
if len(sys.argv) == 3:
|
if len(sys.argv) == 3:
|
||||||
boggle_board = BoggleBoard(board)
|
boggle_board = BoggleBoard(board)
|
||||||
print(boggle_board)
|
|
||||||
boggle_tree = build_full_boggle_tree(boggle_board, Path(sys.argv[2]))
|
|
||||||
elif len(sys.argv) == 4:
|
elif len(sys.argv) == 4:
|
||||||
try:
|
try:
|
||||||
boggle_board = BoggleBoard(board, int(sys.argv[3]))
|
boggle_board = BoggleBoard(board, int(sys.argv[3]))
|
||||||
|
except ValueError:
|
||||||
|
print("Invalid MAX_WORD_LENGTH. Please try again with a valid integer.")
|
||||||
|
sys.exit(1)
|
||||||
|
try:
|
||||||
boggle_tree = build_full_boggle_tree(boggle_board, Path(sys.argv[2]))
|
boggle_tree = build_full_boggle_tree(boggle_board, Path(sys.argv[2]))
|
||||||
|
|
||||||
print("\nBOARD")
|
print("\nBOARD")
|
||||||
Regular → Executable
+31
-14
@@ -2,6 +2,8 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from os import path
|
from os import path
|
||||||
from multiprocessing import Pool
|
from multiprocessing import Pool
|
||||||
|
import functools
|
||||||
|
import operator
|
||||||
|
|
||||||
class BoardCell:
|
class BoardCell:
|
||||||
'''Boggle Board cell'''
|
'''Boggle Board cell'''
|
||||||
@@ -197,9 +199,9 @@ class WordNode:
|
|||||||
|
|
||||||
class WordTree:
|
class WordTree:
|
||||||
'''A tree populated by WordNode(s) to complete words from a given root letter and wordlist'''
|
'''A tree populated by WordNode(s) to complete words from a given root letter and wordlist'''
|
||||||
def __init__(self, alphabet: str, root: WordNode, words: list[str] = None,
|
def __init__(self, alphabet: list, root: WordNode, words: list[str] = None,
|
||||||
max_word_len = 16) -> WordTree:
|
max_word_len = 16) -> WordTree:
|
||||||
self.__alphabet: str = alphabet
|
self.__alphabet: list = alphabet
|
||||||
self.__wordlist: list[str] = words
|
self.__wordlist: list[str] = words
|
||||||
self.__root: WordNode = root
|
self.__root: WordNode = root
|
||||||
self.__max_word_len: int = max_word_len
|
self.__max_word_len: int = max_word_len
|
||||||
@@ -216,7 +218,7 @@ class WordTree:
|
|||||||
self.__insert_word(word)
|
self.__insert_word(word)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def alphabet(self) -> str:
|
def alphabet(self) -> list:
|
||||||
'''Getter for alphabet property'''
|
'''Getter for alphabet property'''
|
||||||
return self.__alphabet
|
return self.__alphabet
|
||||||
|
|
||||||
@@ -278,7 +280,7 @@ class WordTree:
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
alpha_index = [x[0] for x in self.alphabet].index(letter)
|
alpha_index = self.alphabet.index(letter)
|
||||||
except ValueError: # letters not in given alphabet
|
except ValueError: # letters not in given alphabet
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -324,7 +326,7 @@ class WordTree:
|
|||||||
# TODO: return all possible paths, maybe create minature WordTree? Or just of list of paths.
|
# TODO: return all possible paths, maybe create minature WordTree? Or just of list of paths.
|
||||||
return curr_node
|
return curr_node
|
||||||
|
|
||||||
def build_boggle_tree(self, board: BoggleBoard, board_cell: BoardCell, subtree: WordTree, depth: int = 1) -> WordTree:
|
def build_boggle_tree(self, board: BoggleBoard, board_cell: BoardCell, subtree: WordTree, word_len: int = 0) -> WordTree:
|
||||||
'''Return subtree of board given a particular root (first letter).
|
'''Return subtree of board given a particular root (first letter).
|
||||||
|
|
||||||
Keyword arguments:
|
Keyword arguments:
|
||||||
@@ -334,6 +336,12 @@ class WordTree:
|
|||||||
subtree -- the partial tree passed to the next recursive step for generating branches
|
subtree -- the partial tree passed to the next recursive step for generating branches
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
if word_len > self.max_word_len or word_len >= board.max_word_len:
|
||||||
|
#print(f"MAX DEPTH REACHED! Depth = {depth}")
|
||||||
|
subtree.active_node = subtree.active_node.parent
|
||||||
|
self.active_node = self.active_node.parent
|
||||||
|
return
|
||||||
|
|
||||||
# TODO rework active_node refs for recursion so don't have to be reset to parent at every point of return
|
# TODO rework active_node refs for recursion so don't have to be reset to parent at every point of return
|
||||||
if self.active_node.is_word and len(self.active_node.children) == 0:
|
if self.active_node.is_word and len(self.active_node.children) == 0:
|
||||||
word_path = subtree.active_node.path[::-1]
|
word_path = subtree.active_node.path[::-1]
|
||||||
@@ -347,12 +355,6 @@ class WordTree:
|
|||||||
subtree.word_paths.append((subtree.active_node.get_word(board), word_path))
|
subtree.word_paths.append((subtree.active_node.get_word(board), word_path))
|
||||||
#print("2: WORD FOUND:", "".join([board.board[x].letters for x in word_path]), word_path)
|
#print("2: WORD FOUND:", "".join([board.board[x].letters for x in word_path]), word_path)
|
||||||
|
|
||||||
if depth >= self.max_word_len or depth >= board.max_word_len:
|
|
||||||
#print(f"MAX DEPTH REACHED! Depth = {depth}")
|
|
||||||
subtree.active_node = subtree.active_node.parent
|
|
||||||
self.active_node = self.active_node.parent
|
|
||||||
return
|
|
||||||
|
|
||||||
# Branch for each adjacent board cell
|
# Branch for each adjacent board cell
|
||||||
for cell in board_cell.adjacent_cells:
|
for cell in board_cell.adjacent_cells:
|
||||||
# Check dictionary and exclude nodes already in path
|
# Check dictionary and exclude nodes already in path
|
||||||
@@ -361,7 +363,7 @@ class WordTree:
|
|||||||
subtree.active_node.add_child_node(new_node)
|
subtree.active_node.add_child_node(new_node)
|
||||||
subtree.active_node = subtree.active_node.children[cell.letters] # update subtree pointer
|
subtree.active_node = subtree.active_node.children[cell.letters] # update subtree pointer
|
||||||
self.active_node = self.active_node.children[cell.letters] # update dictionary tree pointer
|
self.active_node = self.active_node.children[cell.letters] # update dictionary tree pointer
|
||||||
self.build_boggle_tree(board, board.board[cell.pos], subtree, depth=depth+1)
|
self.build_boggle_tree(board, board.board[cell.pos], subtree, word_len=word_len+len(board_cell.letters))
|
||||||
|
|
||||||
self.active_node = self.active_node.parent
|
self.active_node = self.active_node.parent
|
||||||
subtree.active_node = subtree.active_node.parent
|
subtree.active_node = subtree.active_node.parent
|
||||||
@@ -383,14 +385,22 @@ def build_full_boggle_tree(board: BoggleBoard, wordlist_path: str) -> dict[str,
|
|||||||
|
|
||||||
print("Reading in wordlists...")
|
print("Reading in wordlists...")
|
||||||
for letters in alphabet:
|
for letters in alphabet:
|
||||||
if letters[0] in index:
|
if letters == "":
|
||||||
|
# Skip wordlist read for blocks with empty string
|
||||||
|
index[""] = {}
|
||||||
|
continue
|
||||||
|
elif letters[0] in index:
|
||||||
index[letters] = index[letters[0]]
|
index[letters] = index[letters[0]]
|
||||||
continue
|
continue
|
||||||
|
|
||||||
filename = "words_" + letters[0] + ".txt"
|
filename = "words_" + letters[0] + ".txt"
|
||||||
print(f">> {letters}: {filename}")
|
try:
|
||||||
wordlist = read_wordlist(path.join(path.abspath(wordlist_path), filename))
|
wordlist = read_wordlist(path.join(path.abspath(wordlist_path), filename))
|
||||||
index[letters] = wordlist
|
index[letters] = wordlist
|
||||||
|
print(f">> {letters}: {filename}")
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f">> {letters}: -- Skipping -- no wordlist found for {letters}")
|
||||||
|
index[letters] = {}
|
||||||
|
|
||||||
print("Generating WordTrees...")
|
print("Generating WordTrees...")
|
||||||
params = [ [alphabet, board, cell, index[cell.letters] ] for cell in board.board.values()]
|
params = [ [alphabet, board, cell, index[cell.letters] ] for cell in board.board.values()]
|
||||||
@@ -410,3 +420,10 @@ def read_boggle_file(file):
|
|||||||
'''Return list of rows from Boggle board csv file'''
|
'''Return list of rows from Boggle board csv file'''
|
||||||
with open(file, 'r', encoding='utf-8') as file:
|
with open(file, 'r', encoding='utf-8') as file:
|
||||||
return [x.rstrip().split(',') for x in file.readlines()]
|
return [x.rstrip().split(',') for x in file.readlines()]
|
||||||
|
|
||||||
|
def find_paths_by_word(board_letters, dictionary_path, max_len):
|
||||||
|
'''Return list of paths by word'''
|
||||||
|
boggle_board = BoggleBoard(board_letters, max_len)
|
||||||
|
boggle_tree = build_full_boggle_tree(boggle_board, dictionary_path)
|
||||||
|
paths_by_word = functools.reduce(operator.iconcat, [x.word_paths for x in boggle_tree.values()], [])
|
||||||
|
return paths_by_word
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# Listed alphabetically
|
# Listed alphabetically
|
||||||
a,a,a,e,e,g
|
a,a,e,e,g,n
|
||||||
a,b,b,j,o,o
|
a,b,b,j,o,o
|
||||||
a,c,h,o,p,s
|
a,c,h,o,p,s
|
||||||
a,f,f,k,p,s
|
a,f,f,k,p,s
|
||||||
|
@@ -0,0 +1,27 @@
|
|||||||
|
# Listed alphabetically
|
||||||
|
a,a,a,f,r,s
|
||||||
|
a,a,e,e,e,e
|
||||||
|
a,a,f,i,r,s
|
||||||
|
a,d,e,n,n,n
|
||||||
|
a,e,e,e,e,m
|
||||||
|
a,e,e,g,m,u
|
||||||
|
a,e,g,m,n,n
|
||||||
|
a,f,i,r,s,y
|
||||||
|
an,er,he,in,qu,th
|
||||||
|
b,j,k,qu,x,z
|
||||||
|
c,c,e,n,s,t
|
||||||
|
c,e,i,i,l,t
|
||||||
|
c,e,i,l,p,t
|
||||||
|
c,e,i,p,s,t
|
||||||
|
d,d,h,n,o,t
|
||||||
|
d,h,h,l,n,o
|
||||||
|
d,h,l,n,o,r
|
||||||
|
d,l,o,h,h,r
|
||||||
|
e,i,i,i,t,t
|
||||||
|
e,m,o,t,t,t
|
||||||
|
e,n,s,s,s,u
|
||||||
|
f,i,p,r,s,y
|
||||||
|
g,o,r,r,v,w
|
||||||
|
i,k,l,qu,u,w
|
||||||
|
n,o,o,t,u,w
|
||||||
|
o,o,o,t,t,u
|
||||||
|
@@ -0,0 +1,82 @@
|
|||||||
|
# Made from 6x6 dice repeated to reach 9x9 (81) dice rolls
|
||||||
|
_,_,_,e,i,o
|
||||||
|
a,a,a,f,r,s
|
||||||
|
a,a,e,e,e,e
|
||||||
|
a,a,e,e,o,o
|
||||||
|
a,a,f,i,r,s
|
||||||
|
a,b,d,e,i,o
|
||||||
|
a,d,e,n,n,n
|
||||||
|
a,e,e,e,e,m
|
||||||
|
a,e,e,g,m,u
|
||||||
|
a,e,g,m,n,n
|
||||||
|
a,e,i,l,m,n
|
||||||
|
a,e,i,n,o,u
|
||||||
|
a,f,i,r,s,y
|
||||||
|
an,er,he,in,qu,th
|
||||||
|
b,b,b,j,j,z
|
||||||
|
c,c,e,n,s,t
|
||||||
|
c,d,d,l,n,n
|
||||||
|
c,e,e,i,t,t
|
||||||
|
c,e,i,p,s,t
|
||||||
|
c,f,g,n,u,w
|
||||||
|
d,d,h,n,o,t
|
||||||
|
d,h,h,l,o,r
|
||||||
|
d,h,h,n,o,w
|
||||||
|
d,h,l,n,o,r
|
||||||
|
e,h,i,l,r,s
|
||||||
|
e,i,i,l,s,t
|
||||||
|
e,i,l,p,s,t
|
||||||
|
e,m,o,t,t,t
|
||||||
|
e,n,s,s,s,u
|
||||||
|
g,o,r,r,v,w
|
||||||
|
h,i,r,s,t,v
|
||||||
|
h,o,p,r,s,t
|
||||||
|
i,p,r,s,y,y
|
||||||
|
j,k,qu,w,x,z
|
||||||
|
n,o,o,t,u,w
|
||||||
|
o,o,o,t,t,u
|
||||||
|
_,_,_,e,i,o
|
||||||
|
a,a,a,f,r,s
|
||||||
|
a,a,e,e,e,e
|
||||||
|
a,a,e,e,o,o
|
||||||
|
a,a,f,i,r,s
|
||||||
|
a,b,d,e,i,o
|
||||||
|
a,d,e,n,n,n
|
||||||
|
a,e,e,e,e,m
|
||||||
|
a,e,e,g,m,u
|
||||||
|
a,e,g,m,n,n
|
||||||
|
a,e,i,l,m,n
|
||||||
|
a,e,i,n,o,u
|
||||||
|
a,f,i,r,s,y
|
||||||
|
an,er,he,in,qu,th
|
||||||
|
b,b,b,j,j,z
|
||||||
|
c,c,e,n,s,t
|
||||||
|
c,d,d,l,n,n
|
||||||
|
c,e,e,i,t,t
|
||||||
|
c,e,i,p,s,t
|
||||||
|
c,f,g,n,u,w
|
||||||
|
d,d,h,n,o,t
|
||||||
|
d,h,h,l,o,r
|
||||||
|
d,h,h,n,o,w
|
||||||
|
d,h,l,n,o,r
|
||||||
|
e,h,i,l,r,s
|
||||||
|
e,i,i,l,s,t
|
||||||
|
e,i,l,p,s,t
|
||||||
|
e,m,o,t,t,t
|
||||||
|
e,n,s,s,s,u
|
||||||
|
g,o,r,r,v,w
|
||||||
|
h,i,r,s,t,v
|
||||||
|
h,o,p,r,s,t
|
||||||
|
i,p,r,s,y,y
|
||||||
|
j,k,qu,w,x,z
|
||||||
|
n,o,o,t,u,w
|
||||||
|
o,o,o,t,t,u
|
||||||
|
e,m,o,t,t,t
|
||||||
|
e,n,s,s,s,u
|
||||||
|
g,o,r,r,v,w
|
||||||
|
h,i,r,s,t,v
|
||||||
|
h,o,p,r,s,t
|
||||||
|
i,p,r,s,y,y
|
||||||
|
j,k,qu,w,x,z
|
||||||
|
n,o,o,t,u,w
|
||||||
|
o,o,o,t,t,u
|
||||||
|
Executable
+35
@@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
if [ -z $1 ] || [ -z $2 ]; then
|
||||||
|
echo "Usage: WORDLIST OUT_DIR"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
rg "(^a[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_a.txt"
|
||||||
|
rg "(^b[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_b.txt"
|
||||||
|
rg "(^c[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_c.txt"
|
||||||
|
rg "(^d[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_d.txt"
|
||||||
|
rg "(^e[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_e.txt"
|
||||||
|
rg "(^f[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_f.txt"
|
||||||
|
rg "(^g[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_g.txt"
|
||||||
|
rg "(^h[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_h.txt"
|
||||||
|
rg "(^i[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_i.txt"
|
||||||
|
rg "(^j[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_j.txt"
|
||||||
|
rg "(^k[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_k.txt"
|
||||||
|
rg "(^l[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_l.txt"
|
||||||
|
rg "(^m[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_m.txt"
|
||||||
|
rg "(^n[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_n.txt"
|
||||||
|
rg "(^o[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_o.txt"
|
||||||
|
rg "(^p[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_p.txt"
|
||||||
|
rg "(^q[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_q.txt"
|
||||||
|
rg "(^r[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_r.txt"
|
||||||
|
rg "(^s[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_s.txt"
|
||||||
|
rg "(^t[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_t.txt"
|
||||||
|
rg "(^u[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_u.txt"
|
||||||
|
rg "(^v[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_v.txt"
|
||||||
|
rg "(^w[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_w.txt"
|
||||||
|
rg "(^x[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_x.txt"
|
||||||
|
rg "(^y[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_y.txt"
|
||||||
|
rg "(^z[a-z]+).*$" -or '$1' $1 | sort | uniq > "$2/words_z.txt"
|
||||||
|
touch "$2/words__.txt"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user