Перестановки и сравнения массивов: содержит ли этот массив какой-либо из этих массивов?

Я просмотрел все SO для ответа на этот вопрос, и пока я нашел несколько подобных проблем, я просто не смог решить свою проблему.

Я создаю игру Mastermind. Прямо сейчас я работаю над алгоритмом для интеллектуального вычисления компьютера. Я читал об этом много, но, как человек, довольно новый для программирования, было немного сложно разработать этот алгоритм (я использую TDD).

secret_code = %w(blue blue orange orange)
guess = %w(orange blue red yellow)
valid_colors = %w(blue green orange purple red yellow)
possible_secret_codes = valid_colors.repeated_permutation(4).to_a

Я хочу исключить как можно больше возможных_секучих_кодов на основе обратной связи (оценка), которую я получаю после того, как сделал свое предположение.

Один потенциальный подход (простой, хотя и не самый эффективный) заключается в том, чтобы сначала сосредоточиться на поиске правильных четырех цветов, независимо от местоположения.

score = {exact: 1, close: 1}
total_score = score[:exact] + score[:close]
parts_of_secret_code = guess.repeated_permutation(total_score).to_a.uniq

parts_of_secret_code будет возвращать массив массивов. Мы можем быть уверены, что секретный код включает AT LEAST ONE из этих массивов. Я хочу исключить из возможных_secret_codes любой код, который не включает по крайней мере один из этих массивов.

Используя приведенную ниже информацию о примере (при условии, что я предоставил секретный код, предположив, что я предоставил, оценку, которую я предоставил, и т.д.), это то, что part_of_secret_code будет:

parts_of_secret_code = [["orange", "orange"],
                        ["orange", "blue"],
                        ["orange", "red"],
                        ["orange", "yellow"],
                        ["blue", "orange"],
                        ["blue", "blue"],
                        ["blue", "red"],
                        ["blue", "yellow"],
                        ["red", "orange"],
                        ["red", "blue"],
                        ["red", "red"],
                        ["red", "yellow"],
                        ["yellow", "orange"],
                        ["yellow", "blue"],
                        ["yellow", "red"],
                        ["yellow", "yellow"]]

Я хочу удалить коды, которые не имеют хотя бы одного из этих массивов. Выполнение этого сократит исходный список возможных_секументов (всего 1,296), который найден путем вызова repeat_permutation в массиве допустимых цветов (как я показал выше):

possible_secret_codes = valid_colors.repeated_permutation(4).to_a

Может ли кто-нибудь подумать о том, как это сделать? Я пробовал кучу вещей и не смог понять это.

Заранее благодарим за помощь и дайте мне знать, если я не предоставил достаточную информацию! (И я знаю, что название может быть странным... не было уверенно, как это сказать.)

Ответ 1

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

require 'set' 
possible_secret_codes.select do |ary|
  parts_of_secret_codes.any? {|part| part.to_set.subset? ary.to_set}
end

Что делает фрагмент кода, это select те массивы из possible_secret_codes, которые удовлетворяют условию

parts_of_secret_codes.any? {|part| part.to_set.subset? ary.to_set}

Условие выражает тот факт, что part является собственным подмножеством в ary.