【问题标题】:Overcoming The Boolean Input Tests in the Codewars Kata: "Master your primes: sieve with memoization" - Ruby克服 Codewars Kata 中的布尔输入测试:“掌握你的素数:使用记忆筛选”-Ruby
【发布时间】:2020-08-06 17:39:33
【问题描述】:

我目前正在 Codewars 上做 5kyu“掌握你的素数:用记忆筛选”kata。挑战 为您提供前 4 个素数的缓存数组,您必须检查 n(例如 5)是否是该数组中的素数,如果是,则返回 true。如有必要(例如,如果 n = 143),您必须将素数添加到缓存数组并在达到 n 时停止,然后检查 n 是否在数组中(因此是素数)。

我的代码(如下)正在通过检查是否为素数的测试。问题是他们抛出了一些奇怪的输入:

n = ($primes.size-5).abs

n = ($primes.size-9).abs

我的代码目前只有这 2 个输入失败。当我根据当时缓存数组的位置评估它们时,它们都评估为假。我方法中的第一行尝试返回 如果 n 的值为 false,则为 true,我也尝试了其他 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

【问题讨论】:

  • 看看那个kata的讨论,有很多类似的抱怨。看来kata写得不好。
  • 确实写得不好,但人们已经完成了。

标签: ruby primes memoization boolean-expression sieve


【解决方案1】:

您应该在不使用 prime gem 的情况下解决这个 kata。如果您自己进行主要测试,您就会明白为什么这些测试有意义。

该 Kata 的测试按顺序是

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 个素数。

【讨论】:

  • 谢谢,我明天试试!
  • 好的,所以我不了解您的解决方案是您使用什么系统来检查输入是否为素数? (例如,11 x 13 是从哪里来的?)其次,在什么条件下我们在备忘录中添加质数?我现在能够通过基本测试,但是在大量测试后它们无法通过长度检查。我添加了很少的素数,它说。预期 17000,得到 16。我加起来每个 n(uniq)的 sqrt,它说预期 9,得到 22000。顺便说一句,我今天学习了埃拉托色尼筛法,我有不知道应该如何在这个 kata 中使用它,如果必须的话。
  • 我认为您应该使用稍微不同的筛子。如果你有一个所有素数
猜你喜欢
  • 2023-01-17
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
  • 2021-10-09
  • 1970-01-01
  • 2011-11-14
  • 2021-12-08
  • 2020-04-06
相关资源
最近更新 更多