Рубиновые перестановки

#ruby #permutation #anagram #spelling

Вопрос:

Проще говоря, я хочу иметь ввод букв и вывод всех возможных комбинаций для заданного диапазона длин. например: диапазон длин 1 — 2 ввода a, b, c … выход a, b, c, aa, ab, ac, bb, ba, bc, cc, ca, cb

Я пытаюсь создать решатель для проверки анаграмм/орфографии, чтобы я мог «автоматизировать» игру NYT в орфографию. Итак, я хочу ввести буквы, указанные в моей программе, получить массив всех возможных комбинаций для определенной длины (у них минимальная длина слова 4), а затем проверить этот массив на массив всех английских слов. То, что у меня есть до сих пор, — это:

 letters = ["m","o","r"]
words = []

# Puts all the words into an array
File.open('en_words.txt') do |word|
   word.each_line.each do |line|
      words << line.strip
   end
end

class String
  def permutation(amp;block)
    arr = split(//)
    arr.permutation { |i| yield i.join }
  end
end

letters.join.permutation do |i|
  p "#{i}" if words.include?(i)
end

=>"mor"
=>"rom"
 

моя проблема с приведенным выше кодом заключается в том, что он останавливается
на количестве букв, которые я ему дал. Например, он не будет повторяться, чтобы вернуть «комнату» или «причал». Итак, то, что я пытаюсь сделать, — это получить более полный список комбинаций, а затем сверить их с моим списком слов.

Спасибо вам за вашу помощь.

Ответ №1:

Как насчет того, чтобы пойти в другую сторону? Проверять каждое слово, чтобы убедиться, что в нем используются только разрешенные буквы? Я попробовал это с помощью 3000 наиболее распространенных слов, и это сработало очень быстро.

 words = [..]
letters = [ "m", "o", "r" ]
words.each do |word|
  all_letters_valid = true
  word.chars.each do |char|
    unless letters.include?(char)
      all_letters_valid = false
      break
    end
  end
  if all_letters_valid
    puts word
  end
end
 

Если буквы могут повторяться, то нет конечного числа перестановок, так что такой подход не имеет смысла.

Предположение: только английские символы ascii

Комментарии:

1. Я думаю, что это отличная идея, но я не уверен, как сортировать по буквам. (Я немного новичок в кодировании)

2. @MarcAuciello зачем вам нужно их сортировать? Похоже, вышесказанного должно быть достаточно, чтобы написать функцию, которая принимает массив букв и возвращает список слов.

3. мои извинения. Вы правы. Я допустил ошибку и продолжал получать пустой массив в качестве вывода.

4. @MarcAuciello хорошие вещи! Пожалуйста, примите ответ, если на этот вопрос будет дан ответ (:

5. Я немного изменил его, чтобы убедиться, что во всех словах есть определенная буква.

Ответ №2:

Если цель не состоит в том, чтобы перекодировать комбинацию в образовательных целях :

В стандартной библиотеке ruby класс Array имеет комбинированный метод.

Вот примеры :

 letters = ["m","o","r"]

letters.combination(2).to_a
#  => [["m", "o"], ["m", "r"], ["o", "r"]]
 

У вас также есть волшебный метод перестановки :

 
letters.permutation(3).to_a
#  => [["m", "o", "r"], ["m", "r", "o"], ["o", "m", "r"], ["o", "r", "m"], ["r", "m", "o"], ["r", "o", "m"]] 

 

Если цель состоит в том, чтобы перекодировать методы тезисов. Может быть, вы сможете использовать их в качестве подтверждения. Например, путем подсчета элементов в вашем методе и в методе стандартной библиотеки.