Écrivez une fonction qui prend un seul entier positif n et renvoie la période de la représentation décimale de 1 / n .
Cas de test:
1 -> 1 # 1/1 = 1.0000...... = 1._0
2 -> 1 # 1/2 = 0.5000...... = 0.5_0
3 -> 1 # 1/3 = 0.3333...... = 0._3
7 -> 6 # 1/7 = 0.14285714.. = 0._142857
13 -> 6
14 -> 6
123 -> 5
345 -> 22
654 -> 108
12345 -> 822
67890 -> 120
C'est du code-golf . Les modules intégrés ou bibliothèques qui renvoient directement la période ne sont pas autorisés. Les nombres jusqu'à au moins 100 000 devraient fonctionner dans un délai raisonnable (au plus plusieurs minutes).
code-golf
number-theory
Howard
la source
la source
1.00000000000000000000000000000000000
Réponses:
APL, 19 caractères / octets *
Nars2000 . La version précédente était erronée sur certains chiffres, cela devrait être correct. Je l'ai vérifié manuellement sur tous les numéros jusqu'à 50.
Encore une fois, le mérite revient à Ben Reich pour l'idée de regarder la période de
10^i (mod x)
Vue éclatée
Exemples
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
*: APL peut être écrit dans son propre jeu de caractères à un octet (hérité) qui mappe les symboles APL aux valeurs supérieures de 128 octets. Par conséquent, aux fins de la notation, un programme de N caractères qui utilise uniquement des caractères ASCII et des symboles APL peut être considéré comme long de N octets.
la source
20
. Pouvez-vous vérifier?4
semble que cela donnerait aussi la mauvaise réponse, car10 != 100 (mod 4)
.GolfScript (
4227)Temps de référence: 5 secondes. Code de référence:
Nous remercions Ben Reich pour l'idée centrale de regarder la période de
10^i (mod x)
.Explication
La période
p
est définie comme le plus petit entier positif tel que pour tout suffisamment grandi
nous avonsfrac(10^i * 1/x) = frac(10^(i+p) * 1/x)
. Nous pouvons simplifier cela légèrementfrac(10^i / x) = frac(10^(i+p) / x)
. Maintenant,frac(a / x) = frac(b / x)
IFFa == b (mod x)
, donc nous cherchons le plus petit entier positif tel que pour tout suffisamment grandi
:10^i == 10^(i+p) (mod x)
.Supposons
10^i == 10^(i+p) (mod x)
. Alors10^(i+1) == 10 * 10^i == 10 * 10^(i+p) == 10^(i+p+1) (mod x)
; donc une fois que nous obtenons une répétition, nous sommes dans un cycle incassable.Il n'y a que
x
des valeurs distinctes(mod x)
, donc par le principe du pigeonhole nous devons obtenir une répétition dans les premièresx + 1
valeurs de10^i (mod x)
.Le code ci-dessus consiste donc à calculer les
x + 2
valeurs de10^i (mod x)
*. Ensuite, le dernier est garanti comme une répétition, et en inversant la liste et en la recherchant, je peux trouver l'occurrence la plus récente. De plus, parce que je ne fais qu'une seule recherche, c'est le temps pseudo-linéaire.* L'extra est de gérer le cas spécial
x = 1
, parce que je ne réduis pas10^0 (mod x)
et donc je chercherais un0
po[1]
.la source
Golfscript - 26 octets
Edit: mis à jour pour sortir
1
si la décimale se termine, plutôt que la longueur de la représentation décimale.Une version assez efficace. La valeur 67890 s'exécute en environ 10 secondes et 99991 environ 20 secondes. C'est un peu plus lent qu'auparavant (environ la moitié de la vitesse), car la plage itérée a été doublée, la première moitié étant ignorée.
Alternative, également 26 octets
Celui-ci fonctionne en itérant sur la chaîne
"\n"*(2*i+1)
, oùi
est la valeur transmise à la fonction. La valeur transmise au bloc à chaque fois est la valeur ordinale de"\n"
, qui est 10 .C'est
)^^
un peu une solution de contournement. Lorsque vous annulez un caractère d'une chaîne, le résultat est la valeur ordinale du caractère supprimé, comme mentionné ci-dessus. Cependant, l'ajout de cette valeur ajoutera la représentation sous forme de chaîne de ce nombre, plutôt que le caractère - un comportement assez asymétrique, et à mon avis, un défaut de conception. Si vous vouliez vraiment le faire, la première chaîne ne coûterait qu'un octet.Une copie supplémentaire de la valeur finale est déjà sur la pile, donc je supprime à nouveau la valeur finale
)
, la xor avec la chaîne, puis la xor à nouveau, afin que tous les caractères ajoutés ou supprimés par le premier xor soient restaurés. Siint op string
étaient traités comme un caractère, plutôt que sa représentation sous forme de chaîne,)^^
pourraient être remplacés par|
.Notez que tandis que les chaînes (qui dans Golfscript sont stockées sous forme de tableau d'ints) afficheront la valeur de chaque caractère mod 256 , les valeurs de chaque caractère peuvent elles-mêmes être en dehors de cette plage. Lors du test d'unicité (via des opérations définies) ou de confinement (via
?
), c'est la valeur réelle qui est comparée, plutôt que la valeur d'affichage.Un fichier patch pour l' interpréteur Golfscript actuel :
Ce qui précède n'affectera que le comportement de
string op int
(et vice versa), oùop
est l'un des+-|&^
. Tout le reste n'est pas affecté, y compris le comportement deGint`
.La solution suivante de 24 octets deviendrait alors valide:
Et cela corrige également beaucoup d'autres solutions de contournement vraiment laides .
Python - 48 octets
Pas la solution la plus efficace, mais raisonnable pour des valeurs inférieures à 100 000 .
FWIW, l'élément central est identique à ma solution pour Générer des nombres cycliques en décimal .
Une version plus efficace du même code ( 70 octets ):
La valeur 99991 prend moins d'une seconde.
la source
or
le tableau sur une chaîne vide. Étant donné qu'il s'agit d'une opération définie, tous les doublons sont supprimés au préalable..|
.string int +
casserait beaucoup de programmes. Je ne sais pas combien de fois les autres opérations sont utilisées sur cette paire de types.[]+''+
vs''+
. Append int, en tant que char, à la chaîne:[]++
vs+
. Apend int, comme représentation de chaîne, à chaîne:+
vs`+
. Dans son implémentation actuelle,int''+
est synonyme deint`
, ce qui semble inutile vu la verbosité d'avoir à contraindre au tableau, puis à contraindre à une chaîne si vous voulez le caractère ascii.GolfScript,
484746Merci à @PeterTaylor d'avoir coupé deux caractères.
J'ai essayé d'utiliser J, mais cela m'a donné toutes sortes de résultats étranges.
Testez en ligne
Cela divise fondamentalement 2 et 5 du nombre (2 et 5 sont les facteurs premiers de 10, et leurs inverses se terminent et remplissent l'algorithme), puis le plus petit entier n tel que le nombre résultant divise 10 ^ n - 1 est la période.
la source
{...}:d;...d
vous, enregistrez 1 personnage avec...{...}:d~
f
sur la pile, je remarque que vous le faites aussi. Vous devriez vraiment ajouter un;
pour faire apparaître la fonction pour une comparaison équitable avec d'autres langues.int array ,)\;
peut être raccourcieint array +,
.Perl, 52 caractères
Il s'agit d'une mise en œuvre simple de l'approche directe. (Heureusement, l'approche directe est également assez efficace: grâce à l'arithmétique modulo, les mathématiques n'ont jamais à traiter un nombre supérieur à 10 fois la valeur d'entrée.)
Comme le défi spécifiait une fonction, je me suis senti obligé de (re) initialiser mes variables, ce que je ne prendrais pas la peine de faire pour un programme complet. De même,
~~
dans l'instruction finale est inutile si la fonction peut être certaine qu'elle sera invoquée dans un contexte scalaire.la source
20
là où elle donne le mauvais résultat.Clojure,
102, 117, 115, 106non formaté:
formaté:
Le temps de course varie avec la période. Presque instantané sur mon ordinateur pour les valeurs d'échantillon.
Fondamentalement, cela calcule le résultat de la soustraction après chaque étape de la division longue. Un cycle est détecté si à tout moment ce nombre est le même que celui qui a été calculé avant lui.
la source
20
. Pouvez-vous vérifier?(non concurrent) Pyth
Utilise l' algorithme tortue-et-lièvre ( plus d'informations ).
Regardez-le passer tous les tests.
la source