wordle_decoder 0.1.3 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile.lock +1 -1
- data/LICENSE.md +11 -1
- data/Rakefile +2 -2
- data/bin/wordle_decoder +4 -1
- data/lib/wordle_decoder/guess.rb +6 -17
- data/lib/wordle_decoder/version.rb +1 -1
- data/lib/wordle_decoder/word.rb +1 -1
- data/lib/wordle_decoder/word_position.rb +18 -2
- data/lib/wordle_decoder/word_search.rb +1 -1
- data/lib/wordle_decoder/wordle_share.rb +22 -15
- data/lib/wordle_decoder.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2aaa74ed4dcd02533ea8a1930192aa9922c493fedaae4f54ef451c398d5b8d10
|
4
|
+
data.tar.gz: 26695283d3b9052b51e74041a2dcb119eef6b2146eb2c455a30b43fa0f2faee8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4beb10037a3cf7d88b0304a679042bd5cfb5afed1f55cc9d6e2409899494b953e4f3e1e85c308736a8aad14b8ccef825e01bbbdeda5122707c20dd0c1a1328fd
|
7
|
+
data.tar.gz: f7deb6c6ff1213f4db2e96cdd3550299a1658a5b8954154939341c542e7e9c96383d53b3558a4c6e9d3181327c55d9b540026ce881350400ec8e74a21b7aa724
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.1.6] - 2022-03-20
|
4
|
+
|
5
|
+
- Updated license - [58dd8f5](https://github.com/mattruzicka/wordle_decoder/commit/58dd8f50eb1d115236c2b14a25b39e598e6955ec)
|
6
|
+
|
7
|
+
## [0.1.5] - 2022-03-20
|
8
|
+
|
9
|
+
- Support high contrast mode - https://github.com/mattruzicka/wordle_decoder/issues/4
|
10
|
+
- Fix edge case where words were being falsey considered impossible when containing more than one of the same letter which is in the answer - https://github.com/mattruzicka/wordle_decoder/issues/3
|
11
|
+
- Found some old notes/TODOs I took while on a walk and forgot about - [4201916](https://github.com/mattruzicka/wordle_decoder/commit/4201916b47f84ba7ee851db938b8dba36eb64236)
|
12
|
+
|
13
|
+
## [0.1.4] - 2022-03-06
|
14
|
+
|
15
|
+
- Deal with weird input chars - https://github.com/mattruzicka/wordle_decoder/issues/2
|
16
|
+
|
3
17
|
## [0.1.3] - 2022-03-05
|
4
18
|
|
5
19
|
- Support shortcode emojis - https://github.com/mattruzicka/wordle_decoder/pull/1
|
data/Gemfile.lock
CHANGED
data/LICENSE.md
CHANGED
@@ -1 +1,11 @@
|
|
1
|
-
|
1
|
+
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. To view a copy of this license, visit [http://creativecommons.org/licenses/by-nc-sa/4.0/](http://creativecommons.org/licenses/by-nc-sa/4.0/) or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
|
2
|
+
|
3
|
+
I spent a decent amount of time on this thing and I'd hate to see someone slap some ads on top of it without at least contacting (and paying) me. If you do have a way to make money off this weird little project, awesome! I want some!
|
4
|
+
|
5
|
+
Also, I've only ever used the standard MIT license, so I thought it'd be interesting to try something different.
|
6
|
+
|
7
|
+
Feel free to open an issue or contact me directly with questions.
|
8
|
+
|
9
|
+
Thanks,
|
10
|
+
|
11
|
+
[@mattruzicka](https://twitter.com/mattruzicka)
|
data/Rakefile
CHANGED
@@ -20,7 +20,7 @@ task default: %i[test rubocop]
|
|
20
20
|
task :create_word_search_files do
|
21
21
|
sorted_words = load_words_sorted_by_frequency
|
22
22
|
most_common_words = sorted_words.pop(3_000)
|
23
|
-
most_common_words, less_common_words = most_common_words.partition { |r| r.
|
23
|
+
most_common_words, less_common_words = most_common_words.partition { |r| r.chars.uniq.count == 5 }
|
24
24
|
File.write(lib_path("most_common_words.txt"), most_common_words.join("\n"))
|
25
25
|
File.write(lib_path("less_common_words.txt"), less_common_words.join("\n"))
|
26
26
|
File.write(lib_path("least_common_words.txt"), sorted_words.join("\n"))
|
@@ -29,7 +29,7 @@ end
|
|
29
29
|
task :output_most_common_letters do
|
30
30
|
words = load_wordle_words("allowed_answers.txt")
|
31
31
|
words.concat load_wordle_words("allowed_guesses.txt")
|
32
|
-
letter_count_tally = words.flat_map { _1.
|
32
|
+
letter_count_tally = words.flat_map { _1.chars }.tally
|
33
33
|
letter_count_tally = letter_count_tally.sort_by { -_2 }
|
34
34
|
puts letter_count_tally.first(10).map { _1.first }.join(" ")
|
35
35
|
end
|
data/bin/wordle_decoder
CHANGED
@@ -134,9 +134,12 @@ salutations = ["Maybe some of those are your words!",
|
|
134
134
|
"What lovely words you have!",
|
135
135
|
"I hope my words were as good as yours!",
|
136
136
|
"Please enjoy the rest of your day!",
|
137
|
+
"I hope that what I'm lacking in precision is made up in personality.",
|
138
|
+
"I see your love of the game.",
|
139
|
+
"Wanna exchange five letter words?",
|
137
140
|
"I may not be positive about your words, but I am about you!",
|
138
141
|
"Thank you for spending time with me!",
|
139
142
|
"I enjoyed our time together!"].freeze
|
140
143
|
|
141
144
|
puts CLI::UI.fmt("\n\n #{salutations.sample}\n " \
|
142
|
-
|
145
|
+
"{{blue:https://github.com/mattruzicka/wordle_decoder}}}}\n\n")
|
data/lib/wordle_decoder/guess.rb
CHANGED
@@ -9,19 +9,19 @@ class WordleDecoder
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def score
|
12
|
-
@score ||=
|
12
|
+
@score ||= best_words_with_scores.sum(&:last)
|
13
13
|
end
|
14
14
|
|
15
15
|
def word_scores
|
16
|
-
@word_scores ||=
|
16
|
+
@word_scores ||= best_words_with_scores.map(&:last)
|
17
17
|
end
|
18
18
|
|
19
19
|
def words
|
20
|
-
@words ||=
|
20
|
+
@words ||= best_words_with_scores.map { |w, _s| w.to_s }
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
@
|
23
|
+
def best_words_with_scores
|
24
|
+
@best_words_with_scores ||= select_best_words_with_scores
|
25
25
|
end
|
26
26
|
|
27
27
|
def inspect
|
@@ -30,18 +30,7 @@ class WordleDecoder
|
|
30
30
|
|
31
31
|
private
|
32
32
|
|
33
|
-
|
34
|
-
# Greatly penalize words that have multiple of the same black letters
|
35
|
-
# Greatly penalize words that have the same black letters as any seen word
|
36
|
-
# Greatly penalize words that have the same yellow letter/index pair as any seen word
|
37
|
-
# Reward words that have yellow letters that match yellow letters in seen words, but in different positions
|
38
|
-
# Reward words that have yellow letters that match green letters in seen words
|
39
|
-
# Penalize words that have yellow letters that don't appear in seen words
|
40
|
-
# Penalize words that have green letters that don't appear in seen words
|
41
|
-
# Rewards words based on commonality
|
42
|
-
# Reward/penalize words based on line indexes and common letters
|
43
|
-
#
|
44
|
-
def select_words_with_scores
|
33
|
+
def select_best_words_with_scores
|
45
34
|
selected_words = [@start_word]
|
46
35
|
selected_word_scores = [@start_word.score]
|
47
36
|
seen_black_chars = @start_word.black_chars
|
data/lib/wordle_decoder/word.rb
CHANGED
@@ -5,7 +5,9 @@ class WordleDecoder
|
|
5
5
|
EMOJI_HINT_CHARS = { "⬛" => "b",
|
6
6
|
"⬜" => "b",
|
7
7
|
"🟨" => "y",
|
8
|
-
"
|
8
|
+
"🟦" => "y",
|
9
|
+
"🟩" => "g",
|
10
|
+
"🟧" => "g" }.freeze
|
9
11
|
|
10
12
|
def initialize(hint_line, line_index, answer_chars)
|
11
13
|
@hint_chars = normalize_hint_chars(hint_line)
|
@@ -143,7 +145,21 @@ class WordleDecoder
|
|
143
145
|
end
|
144
146
|
|
145
147
|
def impossible_words(commonality)
|
146
|
-
WordSearch.chars_at_index(@answer_chars, @index, commonality)
|
148
|
+
words = WordSearch.chars_at_index(@answer_chars, @index, commonality)
|
149
|
+
reject_possible_words_where_letter_appears_multiple_times_and_is_in_answer!(words)
|
150
|
+
words
|
151
|
+
end
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
def reject_possible_words_where_letter_appears_multiple_times_and_is_in_answer!(words)
|
156
|
+
words.reject! do |word|
|
157
|
+
chars = word.chars
|
158
|
+
index_char = chars[@index]
|
159
|
+
chars.each_with_index.any? do |char, idx|
|
160
|
+
char == index_char && idx != @index && @answer_chars.include?(char)
|
161
|
+
end
|
162
|
+
end
|
147
163
|
end
|
148
164
|
end
|
149
165
|
end
|
@@ -3,11 +3,27 @@
|
|
3
3
|
class WordleDecoder
|
4
4
|
class WordleShare
|
5
5
|
ANSWER_LINES = ["🟩🟩🟩🟩🟩",
|
6
|
-
"
|
7
|
-
":large_green_square:" * 5].freeze
|
6
|
+
"🟧🟧🟧🟧🟧"].freeze
|
8
7
|
|
9
|
-
def self.final_line?(
|
10
|
-
|
8
|
+
def self.final_line?(input_line)
|
9
|
+
line = normalize_wordle_line(input_line.strip)
|
10
|
+
ANSWER_LINES.include?(line)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.normalize_wordle_line(line)
|
14
|
+
line = translate_emoji_shortcodes(line)
|
15
|
+
line.each_grapheme_cluster.map { |cluster| cluster.codepoints.first }.pack("U*")
|
16
|
+
end
|
17
|
+
|
18
|
+
SHORTCODES_TO_EMOJIS = { ":black_large_square:" => "⬛",
|
19
|
+
":white_large_square:" => "⬜",
|
20
|
+
":large_green_square:" => "🟩",
|
21
|
+
":large_yellow_square:" => "🟨",
|
22
|
+
":large_orange_square:" => "🟧",
|
23
|
+
":large_blue_square:" => "🟦" }.freeze
|
24
|
+
|
25
|
+
def self.translate_emoji_shortcodes(line)
|
26
|
+
SHORTCODES_TO_EMOJIS.reduce(line) { |acc, (key, val)| acc.gsub(key, val) }
|
11
27
|
end
|
12
28
|
|
13
29
|
NEEDS_HELP_INPUTS = %w[help what wordle wat ? man okay yes no test].freeze
|
@@ -62,7 +78,7 @@ class WordleDecoder
|
|
62
78
|
end
|
63
79
|
|
64
80
|
def answer_chars
|
65
|
-
@answer_chars ||= answer&.strip&.
|
81
|
+
@answer_chars ||= answer&.strip&.chars
|
66
82
|
end
|
67
83
|
|
68
84
|
def hint_lines
|
@@ -102,20 +118,11 @@ class WordleDecoder
|
|
102
118
|
|
103
119
|
def parse_wordle_lines!
|
104
120
|
input_lines.filter_map do |line|
|
105
|
-
line =
|
121
|
+
line = self.class.normalize_wordle_line(line)
|
106
122
|
line if line.each_char.all? { |c| VALID_HINT_CHARS.include?(c) }
|
107
123
|
end
|
108
124
|
end
|
109
125
|
|
110
|
-
SHORTCODES_TO_EMOJIS = { ":black_large_square:" => "⬛",
|
111
|
-
":white_large_square:" => "⬜",
|
112
|
-
":large_green_square:" => "🟩",
|
113
|
-
":large_yellow_square:" => "🟨" }.freeze
|
114
|
-
|
115
|
-
def translate_emoji_shortcodes(line)
|
116
|
-
SHORTCODES_TO_EMOJIS.reduce(line) { |acc, (key, val)| acc.gsub(key, val) }
|
117
|
-
end
|
118
|
-
|
119
126
|
def parse_input_lines!
|
120
127
|
case input
|
121
128
|
when String
|
data/lib/wordle_decoder.rb
CHANGED
@@ -36,7 +36,7 @@ class WordleDecoder
|
|
36
36
|
|
37
37
|
def to_terminal
|
38
38
|
str = +"\n"
|
39
|
-
best_guess.
|
39
|
+
best_guess.best_words_with_scores.reverse_each do |word, guess_score|
|
40
40
|
str << " #{word.to_terminal} #{word.confidence_score(guess_score)}\n"
|
41
41
|
end
|
42
42
|
str << " {{green:#{@wordle_share.answer}}}\n"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wordle_decoder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Ruzicka
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cli-ui
|
@@ -55,10 +55,11 @@ files:
|
|
55
55
|
- sig/wordle_decoder.rbs
|
56
56
|
homepage: https://github.com/mattruzicka/wordle_decoder
|
57
57
|
licenses:
|
58
|
-
- CC-BY-NC-SA-
|
58
|
+
- CC-BY-NC-SA-4.0
|
59
59
|
metadata:
|
60
60
|
homepage_uri: https://github.com/mattruzicka/wordle_decoder
|
61
61
|
source_code_uri: https://github.com/mattruzicka/wordle_decoder
|
62
|
+
rubygems_mfa_required: 'true'
|
62
63
|
post_install_message:
|
63
64
|
rdoc_options: []
|
64
65
|
require_paths:
|