Files
freeCodeCamp/curriculum/challenges/russian/08-coding-interview-prep/rosetta-code/factors-of-a-mersenne-number.russian.md

9.0 KiB
Raw Blame History

title, id, challengeType, forumTopicId, localeTitle
title id challengeType forumTopicId localeTitle
Factors of a Mersenne number 598eea87e5cf4b116c3ff81a 5 302264 Факторы числа Мерсенны

Description

Число Мерсенна - это число в виде 2 P -1.

Если P является простым, число Мерсенна может быть простым числом Мерсенна

(если P не является простым, число Мерсенна также не является простым).

При поиске простых чисел Мерсенна выгодно исключить экспоненты путем нахождения небольшого коэффициента перед началом потенциально длительного теста Lucas-Lehmer .

Существуют очень эффективные алгоритмы для определения того, делит ли число 2 P -1 (или, что то же самое, если 2 P mod (число) = 1).

Некоторые языки уже имеют встроенные реализации этой операции экспонента и мода (называемые modPow или аналогичные).

Ниже описано, как реализовать этот modPow самостоятельно:

Например, давайте вычислим 2 23 mod 47.

Преобразуйте экспонента 23 в двоичный код, вы получите 10111. Начиная с квадрата = 1, многократно меняйте его.

Удалите верхний бит экспоненты, и если это 1 умножить квадрат на основание экспоненции (2), тогда вычислите квадрат по модулю 47.

Используйте результат модуляции с последнего шага в качестве начального значения квадрата на следующем шаге:

Удалить необязательный

квадратный верхний бит умножается на 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.

(Чтобы увидеть это, вычтите 1 с обеих сторон: 2 23 -1 = 0 mod 47.)

Поскольку мы показали, что 47 является фактором, 2 23 -1 не является простым.

Дальнейшие свойства чисел Мерсенна позволяют нам еще больше усовершенствовать процесс.

Любой фактор q из 2 P -1 должен иметь вид 2kP + 1, k - положительное целое число или ноль. Кроме того, q должно быть 1 или 7 mod 8.

Наконец, любой потенциальный фактор q должен быть простым .

Как и в других алгоритмах пробного деления, алгоритм останавливается, когда 2kP + 1> sqrt (N).

Эти тесты на примитивность работают только на числа Мерсенна, где P является простым. Например, M 4 = 15 не дает никаких факторов, использующих эти методы, но факторы в 3 и 5, ни один из которых не соответствует 2kP + 1.

Задача:

Используя приведенный выше метод, найдите коэффициент 2 929 -1 (ака M929)

Задачи, связанные с данной темой: подсчет в факторах простых коэффициентов декомпозиции целочисленного сита примитивности Эратосфена методом пробного деления пробного факторинга числа чисел Мерсенна - целое число X в N простых порядков простых чисел с помощью Trial Division Computers в 1948 году: 2¹²⁷-1

Instructions

Using the above method find a factor of 2929-1 (aka M929)

Tests

tests:
  - text: <code>check_mersenne</code> is a function.
    testString: assert(typeof check_mersenne === 'function');
  - text: <code>check_mersenne(3)</code> should return a string.
    testString: assert(typeof check_mersenne(3) == 'string');
  - text: <code>check_mersenne(3)</code> should return "M3 = 2^3-1 is prime".
    testString: assert.equal(check_mersenne(3),"M3 = 2^3-1 is prime");
  - text: <code>check_mersenne(23)</code> should return "M23 = 2^23-1 is composite with factor 47".
    testString: assert.equal(check_mersenne(23),"M23 = 2^23-1 is composite with factor 47");
  - text: <code>check_mersenne(929)</code> should return "M929 = 2^929-1 is composite with factor 13007
    testString: assert.equal(check_mersenne(929),"M929 = 2^929-1 is composite with factor 13007");

Challenge Seed

function check_mersenne(p) {
  // Good luck!
}

Solution

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;
}