introduction
Considérons une séquence d'entiers f définie comme suit:
- f (2) = 2
- Si n est un nombre impair impair, alors f (n) = (f (n-1) + f (n + 1)) / 2
- Si n = p · q est composite, alors f (n) = f (p) · f (q)
Il n'est pas très difficile de voir que f (n) = n pour chaque n ≥ 2 , et donc calculer f ne serait pas un défi très intéressant. Faisons un tour à la définition: divisez par deux le premier cas et doublez le deuxième. On obtient une nouvelle séquence g définie comme suit:
- g (2) = 1
- Si n est un nombre impair impair, alors g (n) = g (n-1) + g (n + 1)
- Si n = p · q est composite, alors g (n) = g (p) · g (q)
La tâche
Votre tâche consiste à prendre un entier n ≥ 2 en entrée et à produire g (n) en sortie. Vous n'avez pas à vous soucier du débordement d'entier, mais vous devriez pouvoir calculer correctement g (1025) = 81 , et votre algorithme devrait théoriquement fonctionner pour des entrées arbitrairement grandes.
Vous pouvez écrire un programme complet ou une fonction. Le nombre d'octets le plus bas gagne.
Exemple
J'ai affirmé ci-dessus que g (1025) = 81 , alors calculons-le à la main. La factorisation de 1025 donne
1025 = 5*5*41 => g(1025) = g(5)*g(5)*g(41)
Puisque 41 est premier, nous obtenons
g(41) = g(40) + g(42)
Ensuite, nous calculons les factorisations premières de 40 et 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)
Pour ces petits nombres premiers, nous obtenons
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
Cela signifie que
g(41) = g(40) + g(42) = g(5) + g(3)*g(7) = 3 + 2*3 = 9
et
g(1025) = g(5)*g(5)*g(41) = 3*3*9 = 81
Cas de test
Voici les valeurs de g jusqu'à 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
, et beaucoup plus, mais je ne trouve aucun motif réel pour expliquer pourquoi.)a(2*n) = a(n)
eta(2*n+1) = a(n) + a(n+1)
tient si2*n+1
est premier. Pour de nombreux autres nombres impairs, les séquences s'accordent probablement par coïncidence.Réponses:
Haskell, 69 octets
Exemple d'utilisation:
(#2) 1025
->81
Le paramètre
a
est compté jusqu'à ce qu'il se divisex
ou qu'il atteignex
(c'estx
-à- dire qu'il est premier). Il est un octet plus court pour testera > x
et ajouter une autre condition (a < x
) au test de module au lieu de testera == x
, car le premier se liea
àx+1
, ce qui aide à l'appel récursif. Comparer:la source
Gelée , 18 octets
Essayez-le en ligne!
Il s'agit essentiellement d'une traduction directe de la spécification. (Après y avoir réfléchi un peu, je soupçonne que s'il existe une formule fermée pour trouver la séquence, ce serait plus d'octets que l'approche directe.)
Explication
Nous avons deux fonctions mutuellement récursives. Voici la fonction d'assistance (qui calcule g (n) pour le premier n ):
Et voici le programme principal, qui calcule g (n) pour tout n :
De toute évidence, si nous appelons le programme principal sur un nombre premier, tout est un no-op sauf le
Ç
, donc il renvoie g (n) dans ce cas. Le reste du programme gère le comportement du composite n .la source
JavaScript (ES6), 59 octets
Tester
Afficher l'extrait de code
la source
Python 2,
8569 octetsla source
Gelée , 13 octets
Essayez-le en ligne!
Comment ça fonctionne
la source
Clojure, 126 octets
Yay! C'est presque deux fois plus longtemps que la réponse Python!
Non golfé et une explication:
la source
(.indexOf (for [...] ...) x)
!(t 1025)
, peut-être queif
c'était prévu:when
? Mais alorsnth
de liste vide jetteIndexOutOfBoundsException
.Mathematica, 83 octets
Fonction récursive sans nom d'un argument entier positif, renvoyant un entier. Pas si court, finalement.
Tr[#0/@({#-1,#+1}/2)]
(dans le cas où l'entrée est principale) appelle la fonction sur les deux membres de la paire ordonnée{(#-1)/2,(#+1)/2}
et ajoute les résultats; c'est bien puisque la fonction a la même valeur à(#-1)/2
et#-1
, par exemple. De même,1##&@@#0/@Divisors@#~Part~{2,-2}
appelle la fonction sur le deuxième plus petit diviseur#
et son diviseur complémentaire (le deuxième diviseur) et multiplie les réponses ensemble.la source
#0
dans cette réponse .Clojure, 120 octets
Utilisations
:when
pour obtenir diviseursn
,F
estnil
si aucun diviseur est trouvé (n
est premier).la source
Python 2 , 62 octets
Essayez-le en ligne!
la source