Skip to content

Instantly share code, notes, and snippets.

@dchelimsky
Created October 31, 2009 22:53
Show Gist options
  • Save dchelimsky/223293 to your computer and use it in GitHub Desktop.
Save dchelimsky/223293 to your computer and use it in GitHub Desktop.
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
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
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment