问题
I've looked all over SO for an answer to this, and while I've found a few similar problems, I just haven't been able to solve my problem.
I'm building a Mastermind game. Right now I'm working on the algorithm for an intelligent computer guess. I've read about this a lot, but as someone fairly new to programming, it's been a bit of a challenge to develop this algorithm (I'm using 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
I want to eliminate as many possible_secret_codes as I can based on the feedback (the score) I receive after making my guess.
One potential approach (simple, albeit not the most efficient) is to first focus on finding the correct four colors, regardless of location.
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 is going to return an array of arrays. We can be certain that the secret code includes AT LEAST ONE of those arrays. I want to eliminate from the possible_secret_codes any code that does not include at least one of those arrays.
Using the example information I provided (assuming the secret code I provided, the guess I provided, the score I provided, etc.), this is what parts_of_secret_code would be:
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"]]
I want to eliminate codes that do not have at least one of those arrays. Doing this will cut down the original list of possible_secret_codes (1,296 total) that is found by calling repeated_permutation on the array of valid colors (as I showed above):
possible_secret_codes = valid_colors.repeated_permutation(4).to_a
Can anyone think of a way to do that? I've tried a bunch of things and haven't been able to figure it out.
Thanks in advance for the help and let me know if I didn't provide enough information! (And I know that title might be odd...wasn't sure how to word it.)
回答1:
"I want to eliminate codes that do not have at least one of those arrays."
require 'set'
possible_secret_codes.select do |ary|
parts_of_secret_codes.any? {|part| part.to_set.subset? ary.to_set}
end
What the code snippet does is to select
those arrays from possible_secret_codes
that satisfy the condition
parts_of_secret_codes.any? {|part| part.to_set.subset? ary.to_set}
The condition expresses the fact that part
is a proper subset of ary
.
来源:https://stackoverflow.com/questions/12062970/array-permutations-and-comparisons-does-this-array-contain-any-of-these-arrays