-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconsultant.rb
80 lines (66 loc) · 2.46 KB
/
consultant.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# frozen_string_literal: true
require_relative './colorable'
# A helper for the CodeBreaker that knows how to pick a next guess
class Consultant < CodeMaker
include Colorable
POSSIBLE_PEG_SCORES = [
[0, 0], [0, 1], [0, 2], [0, 3], [0, 4],
[1, 0], [1, 1], [1, 2], [1, 3], [2, 0],
[2, 1], [2, 2],
[3, 0],
[4, 0]
].freeze
def initialize; end
def possibilities_to_keep(remaining_possibilities, guess, feedback)
remaining_possibilities.select do |possibility|
colors(feedback) == colors(determine_peg_correctness(guess, possibility))
end
end
def all_possible_peg_feedback
POSSIBLE_PEG_SCORES.map do |score|
colored_pegs = score[0]
white_pegs = score[1]
peg_container = []
colored_pegs.times { peg_container.push Key.new(:r) }
white_pegs.times { peg_container.push Key.new(:w) }
peg_container
end
end
def minimum_score_for_guess(guess, remaining_possibilities)
all_possible_peg_feedback.map do |feedback|
remaining_possibilities.count - possibilities_to_keep(remaining_possibilities, guess, feedback).count
end.min
end
def build_info_hash(unused_guesses, remaining_possibilities)
unused_guesses.each_with_object({}) do |guess, results|
results[guess] = [
minimum_score_for_guess(guess, remaining_possibilities),
remaining_possibilities.include?(guess)
]
end
end
def find_next_guess(unused_guesses, remaining_possibilities)
processed_guesses = build_info_hash unused_guesses, remaining_possibilities
set_of_minimum_scores = processed_guesses.values.map { |result| result[0] }
maximum_from_minimum_scores = set_of_minimum_scores.max
best_guess processed_guesses, maximum_from_minimum_scores
end
def find_optimal_guess(processed_guesses, maximum_from_minimum_scores)
processed_guesses.find do |_pattern, value|
score = value[0]
included_in_set = value[1]
score == maximum_from_minimum_scores && included_in_set
end
end
def find_smallest_numeric_guess(processed_guesses, maximum_from_minimum_scores)
processed_guesses.find do |_pattern, value|
score = value[0]
score == maximum_from_minimum_scores
end
end
def best_guess(processed_guesses, maximum_from_minimum_scores)
optimal_guess = find_optimal_guess(processed_guesses, maximum_from_minimum_scores) ||
find_smallest_numeric_guess(processed_guesses, maximum_from_minimum_scores)
optimal_guess[0]
end
end