Why does Ruby include? evaluate to nil?
So, I'm a total nuby working through http://www.rubykoans.com/ and I'm stuck on about_scoring_project.rb. This is my stab at the score method.
def score(dice)
score = 0;
if dice.respond_to?("include?") then
# add 1000 points if rolled 3 ones
score += 1000 if dice.include?([1, 1, 1])
# add 100 points times die face value if rolled 3 of a number between 2 and 6
(2...6).each do |die|
score += die*100 if dice.include?([die, die, die])
# award points for each 1 or 5 not a part of a set of 3
leftovers = dice - [1,1,1]
leftovers -= [5,5,5]
leftovers.each do |leftover|
score += 100 if leftover == 1
score += 50 if leftover == 5
end
end
end
score
end
class AboutScoringAssignment < EdgeCase::Koan
def test_score_examples
assert_equal 1150, score([1,1,1,5,1])
assert_equal 0, score([2,3,4,6,2])
assert_equal 350, score([3,4,5,3,3])
assert_equal 250, score([1,5,1,2,4])
end
end
In the call to score from the first assert_equal, I would expect dice.include?([1,1,1]) to evaluate to true, but it's evaluating to nil (and score is returning 0 instead of 1开发者_Go百科150).
I tried this separately...
require 'test/unit'
class EnumerableTests < Test::Unit::TestCase
def test_include
my_enumerable = [1,1,1,5,1]
assert true, my_enumerable.include?([1,1,1])
end
end
...and the test passes, so I don't know why I'm getting nil in my score method.
Anybody see what I'm doing wrong?
Minor nitpick: Array#include?
always returns true
or false
, never nil
.
To answer your question: x.include?(y)
tests whether y
is an element of x
, not whether it's a subarray.
[1,1,1,5,1].include?([1,1,1])
returns false
because [1,1,1]
is not an element of the array [1,1,1,5,1]
. [[1,1,1],[5,1]].include?([1,1,1]))
would return true
.
There is no method in ruby that checks whether an array is a subarray of a another array, but you can easily write it as arr1.each_cons(arr2.size).include?(arr2)
(needs require 'enumerator'
in 1.8.6). This is O(arr1.size*arr2.size)
though.
If you want it in O(arr1.size + arr2.size)
, you can implement the Knuth-Morris-Pratt algorithm (which is meant to find substrings, but works equally well for finding subarrays as they are essentially the same thing).
I think you misunderstand what Array#include?
does. It searches for its argument as an element of the array, not as a subsequence. Your test_include
will always pass, because you give the assert
function true
as its first argument. You should either use assert_equal
with these arguments or (preferably) just get rid of the first argument.
精彩评论