wordle_decoder 0.1.1 → 0.1.4

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: 19def1e6b5fe6f2513d21327fd4862c0a4e3db8d01775463633f9bd2eec03dd0
4
- data.tar.gz: 9a6e2f43a258eb186359491e5090f811ab27792cc945a93eca0ab5b714080af8
3
+ metadata.gz: 1b287c675238c8e02b76dd2fcb7c6811837831e2245954a9465a2f1d6634ecb5
4
+ data.tar.gz: 1d0f11cdd67b6443ebc6362daf666e82006c361b23a9847ee8c1a3020eeea1ad
5
5
  SHA512:
6
- metadata.gz: 0de9cbfba9ec0edaca95e4259e21efc79566979e9874841e4c1bd7a9f4462e60a41db6bf4881f15baca5d466b66a0043f74dcad2b2f2b2815b0c07f43373fc49
7
- data.tar.gz: 378f8d47d3b8a1043c197e3feb1652fdb8398102b51bfb690788a70cad7a1a2f3cccdfe12fcbd5b8051e39c52ff3a6bad1c632e98bf0579309ae3c93dd5d2305
6
+ metadata.gz: 4dcdc6aa0b31fd576fc973bd35ff7681ae4e054009d62f81afa00a25088e06e81e4c128068de5c524d4e30668b49bd0847e2354f5f614e80fab0e48a7c56c75d
7
+ data.tar.gz: d414927380ff8e1832c7eb70b1e9f632dc41357d586f1f9674cda5f8161e0d6e2c3ff393677b45fab47155d2b56dac1f6edf4a446003da4b4b2fdbf2399af6aa
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,9 @@
1
1
  ## [Unreleased]
2
2
 
3
- ## [0.1.0] - 2022-02-22
3
+ ## [0.1.4] - 2022-03-06
4
4
 
5
- - Initial release
5
+ - Deal with weird input chars - https://github.com/mattruzicka/wordle_decoder/issues/2
6
+
7
+ ## [0.1.3] - 2022-03-05
8
+
9
+ - 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.0)
4
+ wordle_decoder (0.1.3)
5
5
  cli-ui (~> 1.5)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,19 +1,36 @@
1
1
  # Wordle Decoder
2
2
 
3
- It guesses your guesses based on all those little 🟨, 🟩, and ⬛ emojis that we now love to share.
3
+ It guesses your guesses based on all those little square emojis that we now love to share.
4
4
 
5
- Given your Wordle share text, with some degree of confidence, the decoder will spit back the five-letter words it thinks you played.
5
+ Given your Wordle share, the decoder will spit back the five-letter words it thinks you played with some degree of confidence.
6
6
 
7
7
  ## Installation
8
8
 
9
+ Have Ruby 2.7 or later installed, then run the following at the command line:
10
+
9
11
  $ gem install wordle_decoder
10
12
 
11
13
  ## Usage
12
14
 
13
- After entering the below at the command line, you should be prompted to enter your Wordle share and the Wordle word of the day.
15
+ After installing the gem, run `wordle_decoder` at the command line like so:
14
16
 
15
17
  $ wordle_decoder
16
18
 
17
- ## Examples
19
+ You'll be prompted to share your wordle. Go ahead and paste in your wordle share text. The share text should look something like this:
20
+
21
+ ```
22
+ Wordle 258 3/6
23
+
24
+ ⬛⬛🟨⬛🟨
25
+ ⬛🟩🟩🟩⬛
26
+ 🟩🟩🟩🟩🟩
27
+ ```
28
+ You'll then be prompted to confirm the word of the day, or if it couldn't figure it out, you'll be asked for it. After that, it'll _try_ to guess your guesses.
29
+
30
+ ## Why?
31
+
32
+ I wasn't sure if something like this was possible and thought it'd be a fun project to build. It does a pretty good job, at least some of the time... I built an excuse to play Wordle.
33
+
34
+ Enjoy,
18
35
 
19
- TODO...
36
+ [@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
@@ -8,16 +8,28 @@ require "cli/ui"
8
8
 
9
9
  CLI::UI::StdoutRouter.enable
10
10
 
11
- print CLI::UI.fmt("\n\n Share your Wordle:\n\n {{blue:>}} ")
11
+ print CLI::UI.fmt("\n Share your wordle:\n\n{{blue:>}} ")
12
12
 
13
13
  input_lines = []
14
14
  until WordleDecoder::WordleShare.final_line?(input_line = gets)
15
15
  input_lines << input_line
16
+ if WordleDecoder::WordleShare.exit_program?(input_line)
17
+ puts "\n Goodbye!\n\n"
18
+ return
19
+ elsif WordleDecoder::WordleShare.needs_help?(input_line)
20
+ help_text = WordleDecoder::WordleShare.help_to_terminal
21
+ input_lines << "\n"
22
+ input_lines << help_text
23
+ input_lines << "\n"
24
+ print CLI::UI.fmt(help_text)
25
+ elsif input_lines.all? { |l| l.strip.empty? }
26
+ print CLI::UI.fmt("{{blue:>}} ")
27
+ end
16
28
  end
17
29
  input_lines << input_line
18
30
 
19
- clear_pasted_text_lines = input_lines.reverse_each.map { |line| "\033[A\r #{" " * line.length}" }
20
- clear_pasted_text_lines << "\033[A\r"
31
+ clear_pasted_text_lines = input_lines.reverse_each.map { |line| "\033[A\r #{" " * line.length}" }
32
+ clear_pasted_text_lines << "\033[A\r "
21
33
  puts clear_pasted_text_lines.join
22
34
 
23
35
  wordle_share = WordleDecoder::WordleShare.new(input_lines)
@@ -47,78 +59,84 @@ CLI::UI::Spinner.spin("Acting like I'm doing something.") do |spinner|
47
59
  end
48
60
  spinner.update_title("Fine, I'll do it")
49
61
 
50
- decoder.to_terminal
51
- spinner.update_title("\r I decoded your hints!}}")
62
+ if decoder.best_guess
63
+ spinner.update_title("\r I decoded your wordle hints!}}")
64
+ else
65
+ no_guess_messages = ["You stumped me!", "Are you messing with me?", "Are you sure that was the word of the day?"]
66
+ spinner.update_title("\r 🤨 #{no_guess_messages.sample}}}")
67
+ end
68
+ end
69
+
70
+ if decoder.best_guess
71
+ puts CLI::UI.fmt("\n {{blue:{{underline:Guesses}} {{underline:Confidence}}}}")
72
+ puts CLI::UI.fmt(decoder.to_terminal)
52
73
  end
53
74
 
54
- puts CLI::UI.fmt("\n\n {{blue:{{underline:Guesses}} {{underline:Confidence}}}}")
55
- puts CLI::UI.fmt(decoder.to_terminal)
56
-
57
- comments = ["Maybe some of those are your words!",
58
- "I tried!",
59
- "How'd I do?",
60
- "Did I get it?",
61
- "I'm also guessing you're great!",
62
- "Don't spill your coffee.",
63
- "Shout out to friends for sending me their wordles.",
64
- "Shout out to https://www.youtube.com/watch?v=v68zYyaEmEA for word frequency source.",
65
- "I hope you had a great time.",
66
- "Hope to see you again.",
67
- "Was great guessing you.",
68
- "Thinking about heading to sleep.",
69
- "Sometimes I just throw out mostly random stuff.",
70
- "I didn't mean to offend.",
71
- "I try not to be random...",
72
- "I'm open source :)",
73
- "I'd fork you to make me better.",
74
- "TLDR: Another programmer played wordle.",
75
- "How was I with my words?",
76
- "I'm written in Ruby and bite like a python.",
77
- "Here's an emoji ❤️",
78
- "🤔 🤨 🧐",
79
- "All my thinking to you.",
80
- "I've learned about wordle and your people.",
81
- "I'm not learning anything at the moment.",
82
- "I wish I had time to machine learn you ;)",
83
- "No, you have a great personality!",
84
- "This one might be weird, if it's your first.",
85
- "Is my strategy as good as yours?",
86
- "I'm biased, but so are you!",
87
- "I'd love to learn your strategy ;)",
88
- "I'd grow neurons for you.",
89
- "How well can you play without me guessing?",
90
- "If you're seeing this, we probably know each other.",
91
- "I hope things aren't getting too weird.",
92
- "❤️ ❤️ ❤️",
93
- "No, you're great!",
94
- "Do you decode often?",
95
- "All the best five-letter words to you!",
96
- "My friends call me the wordle decoder.",
97
- "Everything I am is written.",
98
- "May my written code speak truly.",
99
- "Who guessed better?",
100
- "No excuse, but my thoughts are in a constant array.",
101
- "Your words complete me.",
102
- "Like peering into a soul.",
103
- "I hope I didn't embarass myself.",
104
- "I hope I didn't embarrass myself.",
105
- "I hope I didn't embaras myself.",
106
- "Can you decode my five letter word?",
107
- "Sometimes I'm off by one...",
108
- "Something's fishy...",
109
- "Did you put something on me?",
110
- "I'm only wrong about five letter words...",
111
- "Your words are beautiful.",
112
- "You make this wordle a better place!",
113
- "What in the wordle was I thinking?",
114
- "Those words you gave me were so good.",
115
- "I truly enjoyed those words, thank you!",
116
- "What lovely words you have!",
117
- "I hope my words were as good as yours!",
118
- "Please enjoy the rest of your day!",
119
- "I may not be positive about your words, but I am about you!",
120
- "Thank you for spending time with me!",
121
- "I enjoyed our time together!"].freeze
122
-
123
- puts CLI::UI.fmt("\n #{comments.sample}\n " \
124
- "{{blue:https://github.com/mattruzicka/wordle_decoder}}}}\n\n")
75
+ salutations = ["Maybe some of those are your words!",
76
+ "I tried!",
77
+ "How'd I do?",
78
+ "Did I get it?",
79
+ "I'm also guessing you're great!",
80
+ "Don't spill your coffee.",
81
+ "Shout out to friends for sending me their wordles.",
82
+ "Shout out to https://www.youtube.com/watch?v=v68zYyaEmEA for word frequency source.",
83
+ "I hope you had a great time.",
84
+ "Hope to see you again.",
85
+ "Was great guessing you.",
86
+ "Thinking about heading to sleep.",
87
+ "Sometimes I just throw out mostly random stuff.",
88
+ "I didn't mean to offend.",
89
+ "I try not to be random...",
90
+ "I'm open source :)",
91
+ "I'd fork you to make me better.",
92
+ "TLDR: Another programmer played wordle.",
93
+ "How was I with my words?",
94
+ "I'm written in Ruby and bite like a python.",
95
+ "Here's an emoji ❤️",
96
+ "🤔 🤨 🧐",
97
+ "All my thinking to you.",
98
+ "I've learned about wordle and your people.",
99
+ "I'm not learning anything at the moment.",
100
+ "I wish I had time to machine learn you ;)",
101
+ "No, you have a great personality!",
102
+ "This one might be weird, if it's your first.",
103
+ "Is my strategy as good as yours?",
104
+ "I'm biased, but so are you!",
105
+ "I'd love to learn your strategy ;)",
106
+ "I'd grow neurons for you.",
107
+ "How well can you play without me guessing?",
108
+ "If you're seeing this, we probably know each other.",
109
+ "I hope things aren't getting too weird.",
110
+ "❤️ ❤️ ❤️",
111
+ "No, you're great!",
112
+ "Do you decode often?",
113
+ "All the best five-letter words to you!",
114
+ "My friends call me the wordle decoder.",
115
+ "Everything I am is written.",
116
+ "May my written code speak truly.",
117
+ "Who guessed better?",
118
+ "No excuse, but my thoughts are in a constant array.",
119
+ "Your words complete me.",
120
+ "Like peering into a soul.",
121
+ "I hope I didn't embarass myself.",
122
+ "I hope I didn't embarrass myself.",
123
+ "I hope I didn't embaras myself.",
124
+ "Can you decode my five letter word?",
125
+ "Sometimes I'm off by one...",
126
+ "Something's fishy...",
127
+ "Did you put something on me?",
128
+ "I'm only wrong about five letter words...",
129
+ "Your words are beautiful.",
130
+ "You make this wordle a better place!",
131
+ "What in the wordle was I thinking?",
132
+ "Those words you gave me were so good.",
133
+ "I truly enjoyed those words, thank you!",
134
+ "What lovely words you have!",
135
+ "I hope my words were as good as yours!",
136
+ "Please enjoy the rest of your day!",
137
+ "I may not be positive about your words, but I am about you!",
138
+ "Thank you for spending time with me!",
139
+ "I enjoyed our time together!"].freeze
140
+
141
+ puts CLI::UI.fmt("\n\n #{salutations.sample}\n " \
142
+ "{{blue:https://github.com/mattruzicka/wordle_decoder}}}}\n\n")
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class WordleDecoder
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.4"
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
@@ -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
@@ -2,12 +2,31 @@
2
2
 
3
3
  class WordleDecoder
4
4
  class WordleShare
5
- ANSWER_LINES = ["🟩🟩🟩🟩🟩", "ggggg"].freeze
5
+ ANSWER_LINES = ["🟩🟩🟩🟩🟩",
6
+ "ggggg",
7
+ ":large_green_square:" * 5].freeze
6
8
 
7
9
  def self.final_line?(input_lines)
8
10
  ANSWER_LINES.any? { input_lines.include?(_1) }
9
11
  end
10
12
 
13
+ NEEDS_HELP_INPUTS = %w[help what wordle wat ? man okay yes no test].freeze
14
+
15
+ def self.needs_help?(input)
16
+ NEEDS_HELP_INPUTS.include?(input.strip.downcase)
17
+ end
18
+
19
+ EXIT_PROGRAM_INPUTS = %w[exit no nvm].freeze
20
+
21
+ def self.exit_program?(input)
22
+ EXIT_PROGRAM_INPUTS.include?(input.strip)
23
+ end
24
+
25
+ def self.help_to_terminal
26
+ "\n {{italic:Copy and paste those 🟨, 🟩, and ⬛" \
27
+ " emojis from your wordle share.}} \n\n{{blue:>}} "
28
+ end
29
+
11
30
  def self.wordle_answers
12
31
  @wordle_answers ||= load_worldle_ansers
13
32
  end
@@ -36,12 +55,14 @@ class WordleDecoder
36
55
 
37
56
  def find_answer
38
57
  title_line = input_lines.detect { |line| line.match?(GAME_DAY_REGEX) }
58
+ return unless title_line
59
+
39
60
  game_day = title_line.match(GAME_DAY_REGEX).captures.first&.to_i
40
61
  self.answer = self.class.wordle_answers[game_day]
41
62
  end
42
63
 
43
64
  def answer_chars
44
- @answer_chars ||= answer&.strip&.split("")
65
+ @answer_chars ||= answer&.strip&.chars
45
66
  end
46
67
 
47
68
  def hint_lines
@@ -80,11 +101,26 @@ class WordleDecoder
80
101
  VALID_HINT_CHARS = WordPosition::EMOJI_HINT_CHARS.to_a.flatten.uniq
81
102
 
82
103
  def parse_wordle_lines!
83
- input_lines.select do |line|
84
- line.each_char.all? { |c| VALID_HINT_CHARS.include?(c) }
104
+ input_lines.filter_map do |line|
105
+ line = normalize_wordle_line(line)
106
+ line if line.each_char.all? { |c| VALID_HINT_CHARS.include?(c) }
85
107
  end
86
108
  end
87
109
 
110
+ def normalize_wordle_line(line)
111
+ line = translate_emoji_shortcodes(line)
112
+ line.each_grapheme_cluster.map { |cluster| cluster.codepoints.first }.pack("U*")
113
+ end
114
+
115
+ SHORTCODES_TO_EMOJIS = { ":black_large_square:" => "⬛",
116
+ ":white_large_square:" => "⬜",
117
+ ":large_green_square:" => "🟩",
118
+ ":large_yellow_square:" => "🟨" }.freeze
119
+
120
+ def translate_emoji_shortcodes(line)
121
+ SHORTCODES_TO_EMOJIS.reduce(line) { |acc, (key, val)| acc.gsub(key, val) }
122
+ end
123
+
88
124
  def parse_input_lines!
89
125
  case input
90
126
  when String
@@ -14,10 +14,6 @@ class WordleDecoder
14
14
  @wordle_share = wordle_share
15
15
  end
16
16
 
17
- def to_terminal
18
- @to_terminal ||= format_to_terminal
19
- end
20
-
21
17
  def best_guess
22
18
  @best_guess ||= guesses.first
23
19
  end
@@ -38,6 +34,14 @@ class WordleDecoder
38
34
  lines.join("\n")
39
35
  end
40
36
 
37
+ def to_terminal
38
+ str = +"\n"
39
+ best_guess.words_with_scores.reverse_each do |word, guess_score|
40
+ str << " #{word.to_terminal} #{word.confidence_score(guess_score)}\n"
41
+ end
42
+ str << " {{green:#{@wordle_share.answer}}}\n"
43
+ end
44
+
41
45
  private
42
46
 
43
47
  def initialize_and_sort_guesses
@@ -55,12 +59,4 @@ class WordleDecoder
55
59
  WordPosition.new(line, index, @wordle_share.answer_chars)
56
60
  end
57
61
  end
58
-
59
- def format_to_terminal
60
- str = +"\n"
61
- best_guess.words_with_scores.reverse_each do |word, guess_score|
62
- str << " #{word.to_terminal} #{word.confidence_score(guess_score)}\n"
63
- end
64
- str << " {{green:#{@wordle_share.answer}}}\n\n"
65
- end
66
62
  end
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.1
4
+ version: 0.1.4
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-05 00:00:00.000000000 Z
11
+ date: 2022-03-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cli-ui
@@ -24,7 +24,7 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.5'
27
- description: Given your Wordle share text, with some degree of confidence, the decoder
27
+ description: Given your Wordle share text, with some degree of confidence,the decoder
28
28
  will spit back the five-letter words it thinks you played.
29
29
  email:
30
30
  executables:
@@ -59,6 +59,7 @@ licenses:
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: