Trouver la plus petite période à partir d'un nombre> 1000 chiffres

10

Votre travail consiste à prendre ce numéro en entrée (bien qu'il devrait également fonctionner avec tout autre numéro):

18349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957

et trouver la plus petite période, qui est dans ce cas:

1834957034571097518349570345710975183495703457109751834957034571097518349570345710976

Bonne chance et amusez-vous bien!


Clarifications :

  • Le numéro d'entrée a au moins une période et une période partielle
  • La période commence toujours au début du numéro saisi
  • Période signifie dans ce cas une séquence de nombres qui se répète.
Michael Bolli
la source
quelle est la taille maximale du numéro d'entrée? si vous vouliez dire que 1000 est la taille maximale, vous êtes dans >le mauvais sens.
Level River St
@steveverrill: Non, il n'y a pas de taille maximale du numéro d'entrée en soi, mais limitons-le à 2 ^ 16 chiffres (parce que vous l'avez demandé).
Michael Bolli
3
Qu'est-ce qu'une période?
FUZxxl
@FUZxxl dans ce cas: une suite de nombres qui se répète.
Michael Bolli
3
Ce que vous demandez est clair, mais vous ne devriez vraiment pas l'appeler un point: en mathématiques, un point se réfère uniquement aux chiffres après le point décimal répété à l' infini plusieurs fois . Comme ci-contre, votre entrée de test est un entier et a un nombre fini de chiffres.
GOTO 0

Réponses:

4

CJam, 20 16 octets

Ll:Q{+_Q,*Q#!}=;

Lit à partir de STDIN. Essayez-le en ligne.

Le code ci-dessus nécessite une mémoire O (n 2 ) , où n est la longueur de l'entrée. Il va travailler avec 2 16 chiffres, aussi longtemps que vous avez assez de mémoire.

Cela peut être fixé au coût de cinq octets supplémentaires:

Ll:Q{+_Q,1$,/)*Q#!}=;

Exemple d'exécution

$ cjam <(echo 'Ll:Q{+_Q,*Q#!}=;') <<< 18349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957; echo
1834957034571097518349570345710975183495703457109751834957034571097518349570345710976
$ cjam <(echo 'Ll:Q{+_Q,*Q#!}=;') <<< 12345123451; echo
12345
$ cjam <(echo 'Ll:Q{+_Q,*Q#!}=;') <<< 1234512345; echo
12345
$ cjam <(echo 'Ll:Q{+_Q,*Q#!}=;') <<< 123451; echo
12345

Comment ça fonctionne

Pour l'entrée Q, l'idée est de répéter le premier caractère len (Q) fois et de vérifier si l'index de Q dans le résultat est 0. Si ce n'est pas le cas, répétez les deux premiers caractères len (Q) fois, etc.

L                   " Push L := [].                                                       ";
 l:Q                " Read one line from STDIN and save the result in Q.                  ";
    {        }=     " Find the first element q ∊ Q that yields a truthy value:            ";
     +              "   Execute L += [q].                                                 ";
      _Q,*Q#        "   Push (L * len(Q)).index(Q).                                       ";
            !       "   Compute the logical NOT of the index.                             ";
               ;    " Discard the last q. This leaves L on the stack.                     ";
Dennis
la source
8

Regex (saveur .NET), 23 22 octets

.+?(?=(.*$)(?<=^\1.*))

Cela correspondra à la période requise en tant que sous-chaîne.

Testez-le ici.

Comment ça marche?

# The regex will always find a match, so there's no need to anchor it to
# the beginning of the string - the match will start there anyway.
.+?        # Try matching periods from shortest to longest
(?=        # Lookahead to ensure that what we've matched is actually
           # a period. By using a lookahead, we ensure that this is
           # not part of the match.
  (.*$)    # Match and capture the remainder of the input in group 1.
  (?<=     # Use a lookahead to ensure that this remainder is the same
           # as the beginning of the input. .NET lookaheads are best
           # read from right to left (because that's how they are matched)
           # so you might want to read the next three lines from the 
           # bottom up.
    ^      # Make sure we can reach the beginning of the string.
    \1     # Match group 1.
    .*     # Skip some characters, because the capture won't cover the
           # entire string.
  )
)
Martin Ender
la source
1
Cela ne fonctionne cependant que si le point commence au début de la chaîne. C'est le cas ici, mais je ne vois pas cela dans les spécifications. Droite?
Tim Pietzcker du
1
@TimPietzcker Voir le commentaire / modification de OP sur la question: la période commence toujours au début de la chaîne.
Martin Ender
Regex Storm .Net semble également gérer .NET, et il ne nécessite pas Silverlight (non disponible sur la plupart des plates-formes).
Dennis
@Dennis Merci, je ne connaissais pas celui-là!
Martin Ender
1
@tolos C'est parce que vous ne vous assurez pas d'atteindre la fin de la chaîne comme ceci. Par conséquent, il utilisera simplement la première chose qui se répète. Par exemple aabaabaab, correspondra probablement aparce qu'il se répète. Je n'ai pas encore trouvé de moyen de le résoudre dans PCRE. Dennis a essayé une réponse maintenant supprimée, mais celle-ci n'a pas fonctionné non plus. Btw, vous n'avez pas besoin g.
Martin Ender
3

Python 60

s est la chaîne de chiffres

[s[:i]for i in range(len(s))if(s[:i]*len(s))[:len(s)]==s][0]

par exemple:

>>> s = '18349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957034571097518349570345710975183495703457109761834957034571097518349570345710975183495703457109751834957034571097518349570345710976183495703457109751834957034571097518349570345710975183495703457109751834957034571097618349570345710975183495703457109751834957'
>>> [s[:i]for i in range(len(s))if(s[:i]*len(s))[:len(s)]==s][0]
'1834957034571097518349570345710975183495703457109751834957034571097518349570345710976'
grignoteur
la source
1

Pyth , 14 caractères

hf}z*lzTm<zdUz

Explication:

implicit:      z = input()
h              head(
 f                  filter(lambda T:
  }z                                z in
    *lz                                  len(z) * 
       T                                          T,
  m                        map(lambda d:
   <zd                                  z[:d],
   Uz                                   range(len(d)))))

Essentiellement, il génère toutes les séquences initiales de l'entrée, se répète chacune une len(z)fois et voit si z, l'entrée, se trouve dans la chaîne résultante.


Ce n'est pas une réponse valide, mais une fonctionnalité a été récemment ajoutée à Pyth, après que la question a été posée, qui permet une solution à 12 caractères:

<zf}z*lz<zT1

Cela utilise le filtre sur la fonction entière.

isaacg
la source
0

Japt , 8 octets

å+ æ@¶îX

Essayez-le

-2 octets grâce à Shaggy!

Transpiled JS expliqué:

// U is the input string representation of the number
U
 // cumulative reduce using the '+' operator
 // the result is an array of strings length 1, 2, ..., N
 // all substrings start with the first character from input
 .å("+")
 // find the first match
 .æ(function(X, Y, Z) {
  // repeat the substring until it is as long as the input
  // and compare it to the input
  return U === U.î(X)
 })
dana
la source
1
8 octets:å+ æ@¶îX
Shaggy
Excellent :) J'ai déjà vu lancer un opérateur dans la fonction de réduction, mais je l'ai oublié.
dana
0

Java 8, 125 octets

Prend l'entrée sous forme de chaîne car il n'y a aucun moyen raisonnable de représenter un nombre de 1000+ chiffres en Java autre qu'une chaîne (pas de BigInteger s'il vous plaît).

s->{String o="";for(int i=0;java.util.Arrays.stream(s.split(o+=s.charAt(i++))).filter(b->!b.isEmpty()).count()>1;);return o;}

Essayez-le en ligne!

Benjamin Urquhart
la source
Vous pouvez remplacer Stringpar var. -3 octets
Adam
@Adam Java 8 cependant
Benjamin Urquhart
Oh, je n'ai pas vu ça.
Adam