我目前正在Codewars上做5kyu的 "掌握你的质数:筛子与记忆 "卡塔。挑战给你一个前4个质数的缓存数组,你必须检查n(例如5)是否是该数组中的质数,如果是,返回true。如果有必要(例如,如果n = 143),你必须将质数添加到缓存数组中,并在到达n时停止,然后检查n是否在数组中(因此是一个质数)。
我的代码(如下)通过了检查是否为质数的测试。问题是他们扔进了一些奇怪的输入。
n = ($primes.size-5).abs<3 (测试期望为真)
n = ($primes.size-9).abs<3 (测试预期为真)
我的代码目前只有这2个输入失败。当我根据缓存数组当时的位置来评估它们时,它们都评估为false。我的方法中的第一行试图在n的值为false的情况下returntrue,我也用其他2种方式尝试过,目前没有任何效果。
令人沮丧的是,在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
创业板。如果你自己做质数测试,你就会明白为什么测试有意义。
该卡塔的测试,依次是
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]。我相信,卡塔试图验证你没有在备忘录中添加不必要的质数。出于某种原因,他们增加了一些回旋余地,所以你可以在备忘录中增加两个额外的质数,它仍然会通过。
接下来的测试更高级一些。29是质数,但我们同样不需要在备忘录中添加任何东西来检测。当我们检查已知质数的备忘录时,我们会检查它是否被2,5,和... 我们实际上已经完成了。5x5=25 小于29 但7x7=49 小于30 更大 比29大的素数。这意味着如果29被7或更大的质数除掉,它也会被比7小的质数除掉。 但我们已经检查了所有的小质数,它是 是不是 可除。因此29是质数。
同样的技巧也适用于53,因为我们在备忘录中已经有11,11x11>53。
529的最后一个检查与之前的检查类似。529=23x23,所以我们必须得到23,这是第9个质数。