-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdewordle.sh
executable file
·99 lines (84 loc) · 2.73 KB
/
dewordle.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#!/usr/bin/env bash
set -o errexit
set -o nounset
set -o pipefail
DOWNLOAD_CMD=() # auto-selected in script
GREP_CMD=(grep --extended-regexp --ignore-case)
WORDS_FILE="${HOME}/.dewordle-words"
WORDS_URL='https://users.cs.duke.edu/~ola/ap/linuxwords'
#
# Display usage
#
# In case of no arguments or any dashed option specified.
#
if [ $# -eq 0 ] || [[ " ${*} " =~ [[:space:]](-.*)[[:space:]] ]]; then
echo
echo "Usage: $0 POSITIONS [ALPHABET [LETTERS]]"
echo
echo 'POSITIONS -- pattern of letters with positions we are sure'
echo 'ALPHABET -- set of possible letters to check; default is: a-z'
echo 'LETTERS -- confirmed letters, with unknown positions; default empty'
echo
echo 'NOTE: For POSITION, a regular expression is expected with dots (.)'
echo ' representing any character; for first run just try: .....'
echo
echo 'NOTE: For ALPHABET, a negative set can be given, e.g. ^abc means'
echo ' that none of letters a, b or c should be part of the string.'
echo
exit 1
fi
#
# Input arguments
#
POSITIONS="${1}"
ALPHABET="${2:-a-z}"
LETTERS="${3:-}"
#
# Fetch words file
#
# If specified WORDS_FILE does not exist in file system, download it using
# wget or curl. The file content is filtered for 5-letters long words only
# and with letters additionally converted to lowercase for convenience.
#
if [ ! -f "${WORDS_FILE}" ]; then
if [ "${#DOWNLOAD_CMD[@]}" -eq 0 ] && ( command -v 'wget' &> /dev/null ); then
DOWNLOAD_CMD=(wget --quiet --output-document=-)
fi
if [ "${#DOWNLOAD_CMD[@]}" -eq 0 ] && ( command -v 'curl' &> /dev/null ); then
DOWNLOAD_CMD=(curl --silent)
fi
if [ "${#DOWNLOAD_CMD[@]}" -eq 0 ]; then
echo 'ERROR: Could not find wget or curl.'
echo 'Please install one of these before proceeding.'
exit 2
fi
"${DOWNLOAD_CMD[@]}" "${WORDS_URL}" \
| grep -E '^.....$' \
| tr '[:upper:]' '[:lower:]' \
| sort --unique \
> "${WORDS_FILE}"
fi
#
# Helper function for filtering strings with specified letters
#
# Recursively extracts letter by letter from a given string argument, then
# selects from standard input only the lines that contain the extracted letter.
# When no more letters, finishes with displaying the remaining standard input.
#
function filter_for_letters() {
local letters="${1:-}"
local n="${#letters}"
if [ "${n}" -eq 0 ]; then
cat
else
local letter="${letters:0:1}"
local remaining="${letters:1}"
"${GREP_CMD[@]}" "${letter}" | filter_for_letters "${remaining}"
fi
}
#
# Find matching words
#
"${GREP_CMD[@]}" "^[${ALPHABET}]{5}$" "${WORDS_FILE}" \
| "${GREP_CMD[@]}" "${POSITIONS}" \
| filter_for_letters "${LETTERS}"