dchelimsky (owner)

Revisions

gist: 223293 Download_button fork
public
Public Clone URL: git://gist.github.com/223293.git
Embed All Files: show embed
marker.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
module Codebreaker
  class Marker
 
    EXACT_MATCH_INDICATOR = 'b'
    COLOR_MATCH_INDICATOR = 'w'
 
    def self.mark(secret, guess)
      marker = self.new(secret)
      marker.guess(guess)
      marker.mark
    end
 
    def initialize(secret)
      @secret = secret
    end
 
    def guess(guess)
      @guess = guess
    end
 
    def exact_match_count
      [@guess, @secret].transpose.count {|a,b| a == b}
    end
 
    def color_match_count
      shared_frequencies.values.inject {|sum,count| sum+=count; sum}
    end
 
   def shared_frequencies
      (@secret & @guess).inject({}) do |frequencies,color|
        frequencies[color] = [
          @guess.count(color),
          @secret.count(color)
        ].min
        frequencies
      end
    end
 
    def mark
      [EXACT_MATCH_INDICATOR]*exact_match_count + [COLOR_MATCH_INDICATOR]*(color_match_count - exact_match_count)
    end
 
  end
end
marker_spec.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
require 'spec_helper'
 
module Codebreaker
  describe Marker do
    context "class methods" do
      describe "#mark" do
        it "returns the mark for the submitted secret and guess" do
          Marker.mark(%w[r y g c], %w[r y g c]).should == %w[b b b b]
        end
      end
    end
 
    let(:marker) {Marker.new(%w[r g y c])}
 
    context "with all 4 colors correct in the correct places" do
      before(:each) do
        marker.guess %w[r g y c]
      end
 
      it "marks the guess with bbbb" do
        marker.mark.should == %w[b b b b]
      end
 
      it "returns 4 from #exact_match_count" do
        marker.exact_match_count.should == 4
      end
 
      it "returns 4 from #color_match_count" do
        marker.color_match_count.should == 4
      end
    end
 
    context "with all 4 colors correct, 2 in the correct places" do
      before(:each) do
        marker.guess %w[r g c y]
      end
 
      it "marks the guess with bbww" do
        marker.mark.should == %w[b b w w]
      end
 
      it "returns 2 from #exact_match_count" do
        marker.exact_match_count.should == 2
      end
 
      it "returns 4 from #color_match_count" do
        marker.color_match_count.should == 4
      end
    end
 
    context "with all 4 colors correct, 1 in the correct place" do
      before(:each) do
        marker.guess %w[y r g c]
      end
 
      it "marks the guess with bwww" do
        marker.mark.should == %w[b w w w]
      end
 
      it "returns 1 from #exact_match_count" do
        marker.exact_match_count.should == 1
      end
 
      it "returns 4 from #color_match_count" do
        marker.color_match_count.should == 4
      end
    end
 
    context "with three colors correct in the correct places" do
      before(:each) do
        marker.guess %w[r g y w]
      end
 
      it "marks the guess with bbb" do
        marker.mark.should == %w[b b b]
      end
 
      it "returns 3 from #exact_match_count" do
        marker.exact_match_count.should == 3
      end
 
      it "returns 3 from #color_match_count" do
        marker.color_match_count.should == 3
      end
    end
 
    context "with duplicates in the guess that match a peg in the code" do
      context "by color and position" do
        before(:each) do
          marker.guess %w[r g y y]
        end
 
        it "adds a single b to the mark for that color" do
          marker.mark.should == %w[b b b]
        end
 
        it "only accounts for the dup once in #exact_match_count" do
          marker.exact_match_count.should == 3
        end
 
        it "only accounts for the dup once in #color_match_count" do
          marker.color_match_count.should == 3
        end
      end
 
      context "by color only" do
        before(:each) do
          marker.guess %w[y y w y]
        end
 
        it "adds a single w to the mark for that color" do
          marker.mark.should == %w[w]
        end
 
        it "does not account for the dup at all in #exact_match_count" do
          marker.exact_match_count.should == 0
        end
 
        it "only accounts for the dup once in #color_match_count" do
          marker.color_match_count.should == 1
        end
      end
    end
 
    context "with duplications in the guess and code" do
      it "correctly accounts for the dups" do
        marker = Marker.new(%w[r r y g])
        marker.guess(%w[r r y g])
        marker.mark.should == %w[b b b b]
      end
    end
  end
end
 
output.txt #
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
Codebreaker::Marker
  class methods
    #mark
      returns the mark for the submitted secret and guess
  with all 4 colors correct in the correct places
    marks the guess with bbbb
    returns 4 from #exact_match_count
    returns 4 from #color_match_count
  with all 4 colors correct, 2 in the correct places
    marks the guess with bbww
    returns 2 from #exact_match_count
    returns 4 from #color_match_count
  with all 4 colors correct, 1 in the correct place
    marks the guess with bwww
    returns 1 from #exact_match_count
    returns 4 from #color_match_count
  with three colors correct in the correct places
    marks the guess with bbb
    returns 3 from #exact_match_count
    returns 3 from #color_match_count
  with duplicates in the guess that match a peg in the code
    by color and position
      adds a single b to the mark for that color
      only accounts for the dup once in #exact_match_count
      only accounts for the dup once in #color_match_count
    by color only
      adds a single w to the mark for that color
      does not account for the dup at all in #exact_match_count
      only accounts for the dup once in #color_match_count
  with duplications in the guess and code
    correctly accounts for the dups