module RubyWordleSolver
Constants
- LPAD
- MAX_SUGGESTIONS
- NUM_LETTERS
- PROMPT
Public Class Methods
draw_decorated_border()
click to toggle source
# File lib/ruby-wordle/script-solver.rb, line 103 def self.draw_decorated_border puts; puts (' '.bg_green * 5 + ' '.bg_gray * 3 + ' '.bg_brown * 5 + ' '.bg_gray * 3) * 4; puts end
get_letters_known()
click to toggle source
# File lib/ruby-wordle/script-solver.rb, line 32 def self.get_letters_known puts puts "STEP 1".bold.bg_green + " Input " + "known letters".underline + " using alphabets and dots" puts LPAD + "Then press \"↵\" (Type \"quit↵\" to exit)" if @letters_known puts LPAD + "Last time: #{@letters_known.bg_green}" else puts LPAD + "Example: #{'s...h'.bg_green}" end letters_known = Readline.readline(LPAD + PROMPT, true).strip.downcase exit if letters_known == "quit" || letters_known == "q" unless /\A[a-z\.]{5}\z/ =~ letters_known puts LPAD + "Sorry,".red + " the input format is not right" letters_known = get_letters_known end letters_known end
get_letters_not_used()
click to toggle source
# File lib/ruby-wordle/script-solver.rb, line 79 def self.get_letters_not_used puts puts "STEP 3".bold.bg_gray + " Input " + "letters not used".underline + " in the word" puts LPAD + "Then press \"↵\" (Type \"quit↵\" to exit)" if @letters_not_used puts LPAD + "Last time: #{@letters_not_used.join.bg_gray}" else puts LPAD + "Example: #{'ieagh'.bg_gray}" end letters_not_used = Readline.readline(LPAD + PROMPT, true).strip.downcase exit if letters_not_used == "quit" || letters_not_used == "q" if letters_not_used.strip == "" array_letters_not_used = [] elsif /\A[a-z\s]+\z/ =~ letters_not_used array_letters_not_used = letters_not_used.split(//) else puts LPAD + "Sorry,".red + " the input format is not right" array_letters_not_used = get_letters_not_used end array_letters_not_used end
get_letters_used()
click to toggle source
# File lib/ruby-wordle/script-solver.rb, line 52 def self.get_letters_used puts puts "STEP 2".bold.bg_brown + " Input pairs of " + "a position and a letter".underline puts LPAD + "Then press \"↵\" (Type \"quit↵\" to exit)" if @letters_used puts LPAD + "Last time: #{@letters_used.map{|p, l| (p + 1).to_s + l}.join(' ').bg_brown}" else puts LPAD + "Example: #{'1g 2e 5a'.bg_brown}" end letters_used = Readline.readline(LPAD + PROMPT, true).strip.downcase exit if letters_used == "quit" || letters_used == "q" if letters_used.strip == "" array_letters_used = [] elsif /\A(?:[1-5][a-z][\s,]*)+\z/ =~ letters_used array_letters_used = [] letters_used.gsub(/\s+/, "").split(//).each_slice(2) do |k, v| array_letters_used << [k.to_i - 1, v] end else puts LPAD + "Sorry,".red + " the input format is not right" array_letters_used = get_letters_used end array_letters_used end
run_interactively()
click to toggle source
# File lib/ruby-wordle/script-solver.rb, line 154 def run_interactively draw_decorated_border @letters_known = get_letters_known @letters_used = get_letters_used @letters_not_used = get_letters_not_used results = solve_wordle(@letters_known, @letters_used, @letters_not_used) draw_decorated_border exit if results.size < 2 puts " ? ".bold.bg_magenta + " Press \"↵\" to continue." puts LPAD + "Type \"quit↵\" to exit." response = Readline.readline(LPAD + PROMPT, true).strip.downcase if response == "quit" || response == "q" exit else run_interactively end end
solve_wordle(letters_known, letters_used, letters_not_used, mode = :original, answer = nil)
click to toggle source
# File lib/ruby-wordle/script-solver.rb, line 107 def solve_wordle(letters_known, letters_used, letters_not_used, mode = :original, answer = nil) word_list = mode == :original ? @word_list : @word_list_basic indices_unknown_letters = (0 ... letters_known.length).find_all { |i| letters_known[i, 1] == '.' } word_list_a = word_list.select do |word| Regexp.compile(letters_known) =~ word end word_list_b = word_list_a.select do |word| word_letters = word.split(//) letters_in_candidate = word_letters.values_at(*indices_unknown_letters) - letters_used.map{|l| l[1]} cond1 = letters_used.all? do |position, letter| word_letters[position] != letter end cond2 = (letters_used.map{|l| l[1]} - word_letters).empty? cond3 = (letters_in_candidate - letters_not_used).size == letters_in_candidate.size cond1 && cond2 && cond3 end if answer word_list_b.delete(answer) reduced_list = word_list_b.sample(MAX_SUGGESTIONS - 1) reduced_list << answer else reduced_list = word_list_b.sample(MAX_SUGGESTIONS) end results = reduced_list.sort.map do |word| if @basic_word_uniq_list[word] mode == :original ? word.red.bold : word.red elsif @basic_word_list[word] mode == :original ? word.blue.bold : word.blue else word end end puts results.each_with_index do |word, i| if (i + 1) % 8 == 0 || results.size == i + 1 print word + "\n" else print word + " " end end word_list_b end
Private Instance Methods
run_interactively()
click to toggle source
# File lib/ruby-wordle/script-solver.rb, line 154 def run_interactively draw_decorated_border @letters_known = get_letters_known @letters_used = get_letters_used @letters_not_used = get_letters_not_used results = solve_wordle(@letters_known, @letters_used, @letters_not_used) draw_decorated_border exit if results.size < 2 puts " ? ".bold.bg_magenta + " Press \"↵\" to continue." puts LPAD + "Type \"quit↵\" to exit." response = Readline.readline(LPAD + PROMPT, true).strip.downcase if response == "quit" || response == "q" exit else run_interactively end end
solve_wordle(letters_known, letters_used, letters_not_used, mode = :original, answer = nil)
click to toggle source
# File lib/ruby-wordle/script-solver.rb, line 107 def solve_wordle(letters_known, letters_used, letters_not_used, mode = :original, answer = nil) word_list = mode == :original ? @word_list : @word_list_basic indices_unknown_letters = (0 ... letters_known.length).find_all { |i| letters_known[i, 1] == '.' } word_list_a = word_list.select do |word| Regexp.compile(letters_known) =~ word end word_list_b = word_list_a.select do |word| word_letters = word.split(//) letters_in_candidate = word_letters.values_at(*indices_unknown_letters) - letters_used.map{|l| l[1]} cond1 = letters_used.all? do |position, letter| word_letters[position] != letter end cond2 = (letters_used.map{|l| l[1]} - word_letters).empty? cond3 = (letters_in_candidate - letters_not_used).size == letters_in_candidate.size cond1 && cond2 && cond3 end if answer word_list_b.delete(answer) reduced_list = word_list_b.sample(MAX_SUGGESTIONS - 1) reduced_list << answer else reduced_list = word_list_b.sample(MAX_SUGGESTIONS) end results = reduced_list.sort.map do |word| if @basic_word_uniq_list[word] mode == :original ? word.red.bold : word.red elsif @basic_word_list[word] mode == :original ? word.blue.bold : word.blue else word end end puts results.each_with_index do |word, i| if (i + 1) % 8 == 0 || results.size == i + 1 print word + "\n" else print word + " " end end word_list_b end