Oliver Eyton-Williams ee1e8abd87
feat(curriculum): restore seed + solution to Chinese (#40683)
* feat(tools): add seed/solution restore script

* chore(curriculum): remove empty sections' markers

* chore(curriculum): add seed + solution to Chinese

* chore: remove old formatter

* fix: update getChallenges

parse translated challenges separately, without reference to the source

* chore(curriculum): add dashedName to English

* chore(curriculum): add dashedName to Chinese

* refactor: remove unused challenge property 'name'

* fix: relax dashedName requirement

* fix: stray tag

Remove stray `pre` tag from challenge file.

Signed-off-by: nhcarrigan <nhcarrigan@gmail.com>

Co-authored-by: nhcarrigan <nhcarrigan@gmail.com>
2021-01-12 19:31:00 -07:00

5.3 KiB
Raw Blame History

id, title, challengeType, videoUrl, dashedName
id title challengeType videoUrl dashedName
598eea87e5cf4b116c3ff81a 梅森数的因素 5 factors-of-a-mersenne-number

--description--

梅森数是2 P -1形式的数字。

如果P是素数那么梅森数可能是梅森素数

如果P不是素数则梅森数也不是素数

在搜索梅森素数时,通过在开始可能冗长的Lucas-Lehmer检验之前找到一个小因子来消除指数是有利的。

有非常有效的算法来确定数字是否除以2 P -1或等效地如果2 P mod数字= 1

有些语言已经有了这个exponent-and-mod操作的内置实现称为modPow或类似的

以下是如何自己实现这个modPow

例如让我们计算2 23 mod 47。

将指数23转换为二进制得到10111.从square = 1开始重复平方。

卸下指数的最高位并且如果它是1 平方乘以由所述幂2的基础上然后计算平方模47。

在下一步中使用最后一步的模数结果作为square的初始值:

删除可选

方形顶部位乘以2 mod 47

------------ ------- ------------- ------

1 * 1 = 1 1 0111 1 * 2 = 2 2

2 * 2 = 4 0 111否4

4 * 4 = 16 1 11 16 * 2 = 32 32

32 * 32 = 1024 1 1 1024 * 2 = 2048 27

27 * 27 = 729 1 729 * 2 = 1458 1

由于2 23 mod 47 = 1,47是2 P -1的因子。

要看到这一点从两边减去12 23 -1 = 0 mod 47.

由于我们已经证明47是一个因子因此2 23 -1不是素数。

Mersenne数字的其他属性使我们能够进一步完善这一过程。

任何因子q为2 P -1必须是2kP + 1的形式k是正整数或零。此外q必须是1或7 mod 8。

最后任何潜在因素q必须是素数

与其他试验划分算法一样算法在2kP + 1> sqrtN时停止。

这些素性测试仅适用于P为素数的Mersenne数。例如M 4 = 15不使用这些技术产生因子而是产生3和5的因子两者都不符合2kP + 1。

任务:

使用上述方法找到因子2 929 -1又名M929

相关任务: 计数因素 素数分解 的整数的因素 埃拉托塞尼的筛 通过试验除法素性 梅森数的试验理 分区的整数X为N个素数 由审判庭素数的序列 在1948年计算机2¹²⁷-1

--hints--

check_mersenne是一个函数。

assert(typeof check_mersenne === 'function');

check_mersenne(3)应该返回一个字符串。

assert(typeof check_mersenne(3) == 'string');

check_mersenne(3)应该返回“M3 = 2 ^ 3-1是素数”。

assert.equal(check_mersenne(3), 'M3 = 2^3-1 is prime');

check_mersenne(23)应返回“M23 = 2 ^ 23-1与因子47复合”。

assert.equal(check_mersenne(23), 'M23 = 2^23-1 is composite with factor 47');

check_mersenne(929)应返回“M929 = 2 ^ 929-1与因子13007复合

assert.equal(
  check_mersenne(929),
  'M929 = 2^929-1 is composite with factor 13007'
);

--seed--

--seed-contents--

function check_mersenne(p) {

}

--solutions--

function check_mersenne(p){
    function isPrime(value){
      for (let i=2; i < value; i++){
        if (value % i == 0){
          return false;
        }
        if (value % i != 0){
          return true;
         }
      }
    }

    function trial_factor(base, exp, mod){
      let square, bits;
      square = 1;
      bits = exp.toString(2).split('');
      for (let i=0,ln=bits.length; i<ln; i++){
        square = Math.pow(square, 2) * (bits[i] == 1 ? base : 1) % mod;
      }
      return (square == 1);
    }

    function mersenne_factor(p){
      let limit, k, q;
      limit = Math.sqrt(Math.pow(2,p) - 1);
      k = 1;
      while ((2*k*p - 1) < limit){
        q = 2*k*p + 1;
        if (isPrime(q) && (q % 8 == 1 || q % 8 == 7) && trial_factor(2,p,q)){
          return q; // q is a factor of 2**p-1
        }
        k++;
      }
      return null;
    }
  let f, result;
  result="M"+p+" = 2^"+p+"-1 is ";
  f = mersenne_factor(p);
  result+=f == null ? "prime" : "composite with factor "+f;
  return result;
}