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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7f99c89b38bbf201f3cc823ce9cb134d952b2b58a9fd0832f92bfab41e63bd01
4
- data.tar.gz: bcd052c478b24f5e0b5d360007688f04edd0c5fd47c8870f426759168fe4cc97
3
+ metadata.gz: 2aaa74ed4dcd02533ea8a1930192aa9922c493fedaae4f54ef451c398d5b8d10
4
+ data.tar.gz: 26695283d3b9052b51e74041a2dcb119eef6b2146eb2c455a30b43fa0f2faee8
5
5
  SHA512:
6
- metadata.gz: 9641a6f0cce9a39b9b137a72ef8e7fc9cf0cb310ca658c2182cfe9aa3c8c66916ccacfcd76ea57236c8fd3b7e25182b9833433453f25acadbd31e35f4ca1a037
7
- data.tar.gz: 6f39d15f60434b8a88a30c018b9860198c3d7080566a937cabd0d2d152232e599fb10e7b0a85969e405651c67c8cc65a681fcd0c5eaaf248d7aef1f58b075cd5
6
+ metadata.gz: 4beb10037a3cf7d88b0304a679042bd5cfb5afed1f55cc9d6e2409899494b953e4f3e1e85c308736a8aad14b8ccef825e01bbbdeda5122707c20dd0c1a1328fd
7
+ data.tar.gz: f7deb6c6ff1213f4db2e96cdd3550299a1658a5b8954154939341c542e7e9c96383d53b3558a4c6e9d3181327c55d9b540026ce881350400ec8e74a21b7aa724
data/.rubocop.yml CHANGED
@@ -1,5 +1,6 @@
1
1
  AllCops:
2
2
  TargetRubyVersion: 2.6
3
+ NewCops: enable
3
4
 
4
5
  Style/StringLiterals:
5
6
  Enabled: true
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
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- wordle_decoder (0.1.3)
4
+ wordle_decoder (0.1.5)
5
5
  cli-ui (~> 1.5)
6
6
 
7
7
  GEM
data/LICENSE.md CHANGED
@@ -1 +1,11 @@
1
- https://creativecommons.org/licenses/by-nc-sa/2.0/legalcode
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.split("").uniq.count == 5 }
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.split("") }.tally
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
- "{{blue:https://github.com/mattruzicka/wordle_decoder}}}}\n\n")
145
+ "{{blue:https://github.com/mattruzicka/wordle_decoder}}}}\n\n")
@@ -9,19 +9,19 @@ class WordleDecoder
9
9
  end
10
10
 
11
11
  def score
12
- @score ||= words_with_scores.sum(&:last)
12
+ @score ||= best_words_with_scores.sum(&:last)
13
13
  end
14
14
 
15
15
  def word_scores
16
- @word_scores ||= words_with_scores.map(&:last)
16
+ @word_scores ||= best_words_with_scores.map(&:last)
17
17
  end
18
18
 
19
19
  def words
20
- @words ||= words_with_scores.map { |w, _s| w.to_s }
20
+ @words ||= best_words_with_scores.map { |w, _s| w.to_s }
21
21
  end
22
22
 
23
- def words_with_scores
24
- @words_with_scores ||= select_words_with_scores
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class WordleDecoder
4
- VERSION = "0.1.3"
4
+ VERSION = "0.1.6"
5
5
  end
@@ -23,7 +23,7 @@ class WordleDecoder
23
23
  end
24
24
 
25
25
  def chars
26
- @chars ||= @word_str.split("")
26
+ @chars ||= @word_str.chars
27
27
  end
28
28
 
29
29
  COMMON_LETTERS = %w[s e a o r i l t n].freeze
@@ -5,7 +5,9 @@ class WordleDecoder
5
5
  EMOJI_HINT_CHARS = { "⬛" => "b",
6
6
  "⬜" => "b",
7
7
  "🟨" => "y",
8
- "🟩" => "g" }.freeze
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
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
3
+ require "json"
4
4
 
5
5
  class WordleDecoder
6
6
  class WordSearch
@@ -3,11 +3,27 @@
3
3
  class WordleDecoder
4
4
  class WordleShare
5
5
  ANSWER_LINES = ["🟩🟩🟩🟩🟩",
6
- "ggggg",
7
- ":large_green_square:" * 5].freeze
6
+ "🟧🟧🟧🟧🟧"].freeze
8
7
 
9
- def self.final_line?(input_lines)
10
- ANSWER_LINES.any? { input_lines.include?(_1) }
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&.split("")
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 = translate_emoji_shortcodes(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
@@ -36,7 +36,7 @@ class WordleDecoder
36
36
 
37
37
  def to_terminal
38
38
  str = +"\n"
39
- best_guess.words_with_scores.reverse_each do |word, guess_score|
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.3
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-06 00:00:00.000000000 Z
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-2.0
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: