我目前正在Codewars上做5kyu"掌握你的素数:记忆筛"卡塔。挑战给您一个由前4个素数组成的缓存数组,您必须检查n(例如5(是否是该数组中的素数,如果是,则返回true。如果必要(例如,如果n=143(,您必须将素数添加到缓存的数组中,并在达到n时停止,然后检查n是否在数组中(因此素数是一个数字(。
我的代码(下面(通过了检查是否素数的测试。问题是他们输入了一些奇怪的输入:
n=($primes.size-5(.abs<3(测试预期为真(
n=($primes.size-9(.abs<3(测试预期为真(
我的代码目前只失败了这两个输入。当我根据缓存数组当时的位置对它们进行求值时,它们的求值结果都为false。我的方法中的第一行尝试返回true如果n的值为false,我也用了另外两种方法,到目前为止都不起作用。
令人沮丧的是,在kata的描述中根本没有提到这些令人惊讶的测试。据我所知,输入会问"$primes长度减去5(以及后面的9(的绝对值是否小于3?">
如果我错了,请有人向我解释,这些输入意味着什么,以及我如何改进我的代码以通过这些测试(和kata(。
require "prime"
$primes = [2,3,5,7]
def is_prime(n)
return true if n.class == FalseClass
return true if n <= $primes.max && $primes.include?(n)
($primes.max+1..n).each do |p|
next if !p.prime?
$primes << p
end
$primes.include?(n) ? true : false
end
您应该在不使用prime
gem的情况下解决这个卡塔。如果你自己做初级测试,你就会明白为什么这些测试是有意义的。
卡塔的测试,按顺序,是
Test.assert_equals(is_prime(1),false)
Test.assert_equals(is_prime(2),true)
Test.assert_equals(is_prime(5),true)
Test.assert_equals(is_prime(143),false)
Test.assert_equals(($primes.size-5).abs<3,true)
Test.assert_equals(is_prime(-1),false)
Test.assert_equals(is_prime(29),true)
Test.assert_equals(is_prime(53),true)
Test.assert_equals(is_prime(529),false)
Test.assert_equals(($primes.size-9).abs<3,true)
测试1、2和5可以在不修改备忘录的情况下完成,但143是素数测试可能涉及在备忘录中添加更多素数的第一个数字。143=11x13,因此在这一点上,一个绝对最小的备忘录只包括[2,3,5,7,11]。我相信kata试图验证你没有在备忘录中添加不必要的素数。出于某种原因,他们增加了一些回旋余地,这样你就可以在备忘录中有两个额外的素数,它仍然会通过
接下来的测试稍微先进一点。29是最好的,但我们不必在备忘录中添加任何内容来检测它。当我们浏览已知素数的备忘录时,我们将检查它是否可以被2、5和…整除。。。实际上我们已经结束了。5x5=25小于29,但7x7=49大于29。这意味着,如果29可以被7或更大的素数整除,它也可以被比7更小的素数整整除。但我们已经检查了所有较小的素数,它是不可分割的。因此29是素数。
同样的技术适用于53,因为我们在备忘录中已经有了11,11x11>53。
529的最后一次检查与前一次类似。529=23x23,所以我们必须得到23,这是第9个素数。