App Academy

Mastermind Solution Error

I was watching the Mastermind Solution Video (part.2) and discovered that the solution for num_near_matches is incorrect, even though it passes the rspec tests, as written.

(I looked back at the given solution and rspec tests for the Mastermind provided in the Alpha course, and they do not have this issue. This is just for the new Mastermind project in the Foundations course.)


def num_near_matches(guess_code)
_count = 0

_(0…guess_code.length).each do |i|
__if guess_code[i] != self[i] && self.pegs.include?(guess_code[i])
___count += 1
__end
_end

_count
end


if self.pegs = [“R”, “G”, “B”, “Y”] and guess_code = [“R”, “R”, “R”, “R”]
it returns ---- exact: 1, near: 3

it should return ---- exact: 1, near: 0
because the only “R” is accounted for in exact

another example

if self.pegs = [“R”, “G”, “B”, “B”] and guess_code = [“Y”, “R”, “R”, “R”]
it returns ---- exact: 0, near: 3

it should return ---- exact: 0, near: 1
because there is only one “R” in the solution, and it’s not in the exact position

final example

if self.pegs = [“R”, “G”, “B”, “Y”] and guess_code == [“Y”, “Y”, “R”, “R”]
it returns ---- exact: 0, near: 4

it should return ---- exact: 0, near: 2
near of 4 implies that the pegs solution is [“R”, “R”, “Y”, “Y”]. Both guess Y’s and both guess R’s would get counted, but the total number of each respectively is only 1, or 2 total.

The rspec test cases are written in just such a way that they omit a scenario where the guess has more pegs of a certain color than the solution.

3 Likes

Bump as it appears this has not been corrected as of 4/7/2021 for the App Academy Open material.

Unless I am misunderstanding the purpose of num_near_matches, I agree with this post on how the near matches should actually be evaluated.

Incorrect Spec
let (:code) { Code.new([“R”, “G”, “R”, “B”]) }
expect(code.num_near_matches(Code.new([“R”, “R”, “R”, “R”]))).to eq(2)

This trial case should equate to:
num_exact_matches = 2
num_near_matches = 0
The “R” at indices 0 and 2 are exact matches and the other two "R"s should not be considered near matches.

The given solution incorrectly outputs:
num_exact_matches = 2
num_near_matches = 2
This is incorrectly indicating that the two "R"s at indices 1 and 3 are near matches despite the exact matches already being accounted for.

I would suggest changing the solution to properly account for these scenarios.

1/08/2021
I spent literally 2hrs trying out stuff and got really frustrated, i decided to watch the video and i was like: “wait, i tried this…” and indeed i had, but it did not work, im just going to delet the rspec example that keeps on failing i guess, unless someone has a solution…

Can someone please share their correct num_near_matches method? I’m stuck on this part and the method in the video hasn’t been updated.

Thank you.

SOLUTION SPOILERS

I got it, here is a solution for anyone else that got stuck on this. It’s funny, this was the first time I gave up on something and resorted to the video since the beginning of the course, and it’s the first time the video has had an error (that I’ve noticed).

def num_near_matches(guess) # Code instance
code_hash = Hash.new(0)
count = 0

@pegs.each { |peg| code_hash[peg] += 1 }

guess.pegs.each do |peg|

  if code_hash.has_key?(peg) && code_hash[peg] > 0

    code_hash[peg] -= 1

    count += 1

  end

end

count - num_exact_matches(guess)

end

Ha, was just working on this today and noticed that too. Just saw the video and was like, “wait a minute… how the hell does that work for him?”

My solution wasn’t quite as clean as @reangity but works nonetheless. Essentially, I create 2 new arrays that has removed all exact matches. Then, iterate over the new “guess” array, and if it finds a near miss, “remove” from the array so it can’t be found again.

  def num_near_matches(code)
    near = 0
    self_pegs = []
    code_pegs = []

    code.pegs.each_with_index do |peg, i|
      if peg != self[i]
        self_pegs << self[i]
        code_pegs << peg
      end
    end

    code_pegs.each do |peg|
      if self_pegs.include?(peg)
        self_pegs[self_pegs.index(peg)] = 0
        near += 1
      end
    end

    near
  end

SOLUTION SPOILERS

This was the logic I was trying to implement. I assumed I had to make use of ‘num_exact_matches’ in ‘num_near_matches’ as we created the ‘num_exact_matches’ part first… kind of a hint.

However, I had to revert to the video too… then I was crazy confused so I signed up here looking for help. Really glad I’m not alone!

The official code solution is as follows:

def num_near_matches(guess_code)
    code_dup = self.pegs.dup
    guess_dup = guess_code.pegs.dup

    guess_dup.each_with_index do |peg, i|
      if peg == code_dup[i]
        code_dup[i] = nil
        guess_dup[i] = nil
      end
    end
    code_dup.delete(nil)
    guess_dup.delete(nil)

    count = 0
    guess_dup.each_with_index do |peg, i|
      if code_dup.include?(peg)
        count += 1
        code_dup.delete_at(code_dup.index(peg))
      end
    end
    count
  end