Вступление
Рассмотрим последовательность целых чисел f, определенную следующим образом:
- f (2) = 2
- Если n нечетное простое число, то f (n) = (f (n-1) + f (n + 1)) / 2
- Если n = p · q является составным, то f (n) = f (p) · f (q)
Нетрудно понять, что f (n) = n для каждого n ≥ 2 , и, таким образом, вычисление f не будет очень интересной задачей. Давайте сделаем поворот к определению: наполовину первый случай и двойной второй случай. Мы получаем новую последовательность g, определенную следующим образом:
- г (2) = 1
- Если n нечетное простое число, то g (n) = g (n-1) + g (n + 1)
- Если n = p · q составное, то g (n) = g (p) · g (q)
Задание
Ваша задача - взять целое число n ≥ 2 в качестве входных данных и вывести g (n) в качестве выходных. Вам не нужно беспокоиться о переполнении целых чисел, но вы должны быть в состоянии правильно вычислить g (1025) = 81 , и ваш алгоритм теоретически должен работать для произвольно больших входных данных.
Вы можете написать полную программу или функцию. Побеждает самое низкое число байтов.
пример
Выше я утверждал, что g (1025) = 81 , поэтому давайте вычислим его вручную. Первичная факторизация 1025 дает
1025 = 5*5*41 => g(1025) = g(5)*g(5)*g(41)
Поскольку 41 простое число, мы получаем
g(41) = g(40) + g(42)
Далее мы вычисляем простые факторизации 40 и 42 :
40 = 2*2*2*5 => g(40) = g(2)*g(2)*g(2)*g(5) = g(5)
42 = 2*3*7 => g(42) = g(2)*g(3)*g(7) = g(3)*g(7)
Для этих небольших простых чисел мы получаем
g(3) = g(2) + g(4) = 1 + 1 = 2
g(5) = g(4) + g(6) = 1 + 2 = 3
g(7) = g(6) + g(8) = 2 + 1 = 3
Это означает, что
g(41) = g(40) + g(42) = g(5) + g(3)*g(7) = 3 + 2*3 = 9
и
g(1025) = g(5)*g(5)*g(41) = 3*3*9 = 81
Контрольные примеры
Вот значения g до 50 .
2 -> 1
3 -> 2
4 -> 1
5 -> 3
6 -> 2
7 -> 3
8 -> 1
9 -> 4
10 -> 3
11 -> 5
12 -> 2
13 -> 5
14 -> 3
15 -> 6
16 -> 1
17 -> 5
18 -> 4
19 -> 7
20 -> 3
21 -> 6
22 -> 5
23 -> 7
24 -> 2
25 -> 9
26 -> 5
27 -> 8
28 -> 3
29 -> 9
30 -> 6
31 -> 7
32 -> 1
33 -> 10
34 -> 5
35 -> 9
36 -> 4
37 -> 11
38 -> 7
39 -> 10
40 -> 3
41 -> 9
42 -> 6
43 -> 11
44 -> 5
45 -> 12
46 -> 7
47 -> 9
48 -> 2
49 -> 9
50 -> 9
15, 21, 25, 29, 33, 41
, и еще куча, но я не могу найти реальный образец того, почему.)a(2*n) = a(n)
, иa(2*n+1) = a(n) + a(n+1)
держится, если2*n+1
простое число. Для многих других нечетных чисел последовательности, вероятно, совпадают по совпадению.Ответы:
Haskell, 69 байт
Пример использования:
(#2) 1025
->81
Параметр
a
считается до тех пор, пока он не разделитсяx
или не достигнетx
(т.x
Е. Будет простым). Это на один байт короче, чтобы проверятьa > x
и добавлять дополнительное условие (a < x
) к проверке модуля вместо проверкиa == x
, потому что первое связываетсяa
сx+1
, что помогает в рекурсивном вызове. Для сравнения:источник
Желе , 18 байт
Попробуйте онлайн!
Это в основном просто прямой перевод спецификации. (Подумав немного об этом, я подозреваю, что если есть закрытая формула для нахождения последовательности, это будет больше байтов, чем прямой подход.)
объяснение
У нас есть две взаимно рекурсивные функции. Вот вспомогательная функция (которая вычисляет g (n) для простого n ):
А вот основная программа, которая вычисляет g (n) для любого n :
Понятно, что если мы вызываем основную программу по простому числу, все не работает, кроме
Ç
, поэтому в этом случае возвращается g (n) . Остальная часть программы обрабатывает поведение для составного n .источник
JavaScript (ES6), 59 байт
Тестовое задание
Показать фрагмент кода
источник
Python 2,
8569 байтисточник
Желе , 13 байт
Попробуйте онлайн!
Как это устроено
источник
Clojure, 126 байт
Ура! Это почти вдвое дольше, чем ответ Python!
Разрушенный и объяснение:
источник
(.indexOf (for [...] ...) x)
!(t 1025)
, может быть, этоif
было задумано:when
? Но потомnth
из пустого списка выбрасываетIndexOutOfBoundsException
.Mathematica, 83 байта
Безымянная рекурсивная функция одного положительного целочисленного аргумента, возвращающего целое число. Не все так коротко, в конце концов.
Tr[#0/@({#-1,#+1}/2)]
(в случае, когда вход простое) вызывает функцию для обоих членов упорядоченной пары{(#-1)/2,(#+1)/2}
и добавляет результаты; это нормально, так как функция имеет то же значение в(#-1)/2
и#-1
, например. Точно так же1##&@@#0/@Divisors@#~Part~{2,-2}
вызывает функцию на втором наименьшем делителе#
и его дополнительном делителе (делителе второго наибольшего) и умножает ответы вместе.источник
#0
в этом ответе .Clojure, 120 байт
Пользы
:when
получить делителиn
,F
этоnil
если такой делитель не найден (n
первична).источник
Python 2 , 62 байта
Попробуйте онлайн!
источник