Objectif
Étant donné l'entrée r
et n
trouver les premiers n
nombres naturels x
tels que si nous tournons le premier chiffre au dernier endroit que nous obtenons x/r
.
Vous pouvez supposer cela 2 <= r <= 9
et 1 <= n <= 65535
.
Vous pouvez écrire un programme qui accepte les entrées de stdin ou des arguments de ligne de commande; ou vous pouvez écrire une fonction qui prend r
et n
comme paramètres. Cependant, la sortie devrait être stdout. La sortie doit être une ligne par valeur de x
, formatée x/r=y
en ordre croissant x
.
Votre solution doit être capable de gérer tous les cas valides en une minute sur un ordinateur de bureau raisonnable.
Cas de test
Entrée: 4 5
Sortie:
102564/4=25641
205128/4=51282
307692/4=76923
410256/4=102564
512820/4=128205
Entrée: 5 1
Sortie:714285/5=142857
Il s'agit de code-golf, donc le moins d'octets est gagnant. La réponse gagnante sera acceptée dans 4 semaines (2014-09-19).
Les crédits pour cette question vont à mon collègue, qui m'a permis de poster cette question ici :)
la source
gprof
, un cas d'entrée pour mon programme passe moins d'une demi-seconde dans mon code, mais prend environ 80 secondes au total, ce qui, je suppose, doit principalement bloquer la sortie.printf
.Réponses:
Haskell,
182179Deuxième version, probablement plus jouable au golf, mais avec un "bon" algorithme cette fois. En particulier, il se termine en quelques minutes avec
r=4
etn=65535
, mais là encore, mon ordinateur n'est ni raisonnable ni un ordinateur de bureau, il est donc probable que cela reste en une minute sur d'autres machines.Il est basé sur l'idée que
x=10^k*a + m
, où son premier chiffre0≤a≤9
est déplacé à la fin pour obteniry=10*m+a
. Un peu de mathématiques révèle quem
peut être obtenu commea*(10^k-r)/(10*r-1)
, donc nous Numérisez simplementa
sur[1..9]
pour chaquek
de 0 à l' infini, et conserver et imprimer les premiersn
résultats pour lesquels l'expression ci - dessus pourm
fait partie intégrante.Le
fromIntegral
est nécessaire car laread
création d'une liste avec l'n
un de ses éléments dansmain
, en combinaison avec l'utilisation den
intake
, forceraitr
àInt
travers, ce qui entraîne des débordements désagréables avec les grands nombres en question. J'aurais pu utilisergenericTake
, mais cela nécessite unimport
.Ce code a également l'avantage d'être presque trivial pour s'étendre à des bases autres que 10.
L'entrée est lue
stdin
, les deux valeurs peuvent être séparées par n'importe quel espace.la source
r = 5; n = 65535
en une minute?y`mod`10
parmod y10
, qui est un caractère plus courtPure Bash (pas d'utilitaires externes), 80 octets
Notez que bash ne fait que de l'arithmétique entière et non en virgule flottante, nous vérifions donc si
x == y * r
au lieu dex / r == y
. De plus, la multiplication devrait généralement être plus rapide. Pourtant, cela est loin de répondre à l'exigence de performance.Production:
la source
C 468
(Certains sauts de ligne non comptés dans le nombre d'octets ont été ajoutés ci-dessus pour éliminer les barres de défilement. Oui, le saut de ligne final est compté.)
Attend des arguments sur la ligne de commande et suppose que la sortie standard accepte ASCII. Le temps d'exécution est O (nombre d'octets en sortie) = O (n * n).
Non, je ne peux pas utiliser
printf
. Cela prend trop de temps et pousse le programme au-delà de la limite des minutes sur mon bureau. En l'état, certains cas de test prennent environ 30 secondes.L'algorithme traite la sortie comme des chaînes, et non comme des nombres, car elles deviennent rapidement énormes et il existe de forts schémas dans la sortie.
Assez peu golfé:
Preuve
que le programme résout le problème:
(Dans la preuve, prenez tous les opérateurs et fonctions pour être les vraies fonctions mathématiques, pas les opérations informatiques qui les rapprochent.
^
Dénote l'exponentiation, pas le xor au niveau du bit.)Pour plus de clarté, je vais utiliser une fonction
ToDec
pour décrire le processus ordinaire d'écriture d'un nombre sous la forme d'une séquence de chiffres décimaux. Sa gamme est l'ensemble de tuples ordonnés sur{0...9}
. Par exemple,Pour un entier positif
n
, définissezL(n)
comme étant le nombre de chiffres dans la représentation décimale den
; ou,Pour un entier positif
k
et un entier non négatifn
avecL(n)<k
, définissezRep_k(n)
comme étant le nombre réel obtenu en ajoutant des zéros devant les chiffres décimaux den
, si nécessaire pour obtenir lek
total des chiffres, puis en répétant à l'infini cesk
chiffres après le point décimal. Par exempleLa multiplication
Rep_k(n) * 10^k
donne les chiffres d'n
avant la virgule décimale et les chiffres (remplis de zéro)n
infiniment répétés après la virgule décimale. DoncÉtant donné un entier positif
r
, supposonsx
une solution au problème, etoù
x_1 != 0
etk = L(x)
.Pour être une solution,
x
est un multiple der
, etL'application de la
Rep_k
fonction donne une belle équation:En utilisant sa forme fermée d'en haut,
x_1
doit être dans l'ensemble{1 ... 9}
.r
a été spécifié pour être dans l'ensemble{2 ... 9}
. Maintenant, la seule question est: pour quelles valeursk
la formule ci-dessusx
donne-t-elle un entier positif? Nous considérerons chaque valeur possibler
individuellement.Quand
r
= 2, 3, 6, 8 ou 9,10r-1
est respectivement 19, 29, 59, 79 ou 89. Dans tous les cas, le dénominateurp = 10r-1
est premier. Dans le numérateur, seul10^k-1
peut être un multiple dep
, ce qui se produit lorsqueL'ensemble des solutions est fermé sous addition et sous soustraction qui n'aboutit pas à un nombre négatif. Ainsi, l'ensemble comprend tous les multiples d'un facteur commun, qui est également la solution la moins positive pour
k
.Quand
r = 4
et10r-1 = 39
; ou quandr = 7
et10r-1 = 69
, le dénominateur est 3 fois un nombre premier différentp=(10r-1)/3
.10^k-1
est toujours un multiple de 3, et là encore aucun autre facteur du numérateur ne peut être un multiple dep
, donc encore une fois le problème se réduit àet encore une fois les solutions sont tous les multiples de la solution la moins positive pour
k
.[Pas terminé...]
la source
Python -
9190Voici un premier coup:
Edit: Ok, c'est probablement un moyen de ralentir pour respecter le délai de 1 minute requis pour les numéros 65K.
la source
JavaScript - 145
non golfé:
la source
(5,4)
. La raison pour laquelle cela ne fonctionnera pas est que les chiffres deviennent très importants. a) Beaucoup plus grand qu'un nombre dans JS peut représenter avec précision et b) beaucoup trop grand car il serait possible de parcourir tous les nombres pour y arriver.Python 3 -
223179 octetsImplémentation Python de la solution de TheSpanishInquisition:
Courir:
python3 <whatever you named it>.py
Production:
Résultats:
https://oeis.org/A092697 est la première valeur pour chaque r.
Il semble que seules certaines valeurs de k produisent des réponses, et que l'intervalle soit régulier. Par exemple pour r = 4:
Les intervalles sont:
Cela forme https://oeis.org/A094224 .
En utilisant ces valeurs, une version plus efficace peut être construite:
Cependant, je ne peux pas (encore) prouver que cela continue mathématiquement.
Résultats pour r = 5:
la source
9 65535
?unsigned long long
pour cela et le rendre multicœur pour le faire en une minute.unsigned long long
c'est 64 bits, ce n'est pas assez grand.