Trouvez la répétition de la représentation décimale!


12

Dans ce défi il y a 2 ans, nous avons trouvé la période d'une fraction unitaire ( 1/n where n is a natural number).

Maintenant, votre tâche consiste à écrire un programme / une fonction pour trouver la répétition d'une fraction d'unité.

La répétition est la partie de l'expansion décimale qui se répète à l'infini, comme:

  • La représentation décimale de 1/6est 0.16666..., puis la répétition est 6.
  • La représentation décimale de 1/11est 0.090909..., puis la répétition est 09.
  • La représentation décimale de 1/28est 0.0357142857142857142857..., puis la répétition est 571428.

Spécifications

  • Entrez dans n'importe quel format raisonnable.
  • Sortez le repetend en décimal, chaîne ou liste .
  • Pour 1/7( 0.142857142857...), vous devez produire à la 142857place de 428571.
  • Pour 1/13( 0.076923076923076923...), vous devez produire à la 076923place de 76923.
  • Pas de force brute, s'il vous plaît.

Cas de test

Input    Output
1        0
2        0
3        3
7        142857
13       076923
17       0588235294117647
28       571428
70       142857
98       102040816326530612244897959183673469387755
9899     000101020305081321345590463683200323264976260228305889483786241034447924032730578846348115971310233356904737852308313971108192746742095161127386604707546216789574704515607637135064147893726639054449944438832205273259925244974239822204263056874431760783917567431053641781998181634508536215779371653702394181230427315890493989291847661379937367410849580765733912516415799575714718658450348520052530558642287099707041115264168097787655318719062531568845337912920497019901

Notation

C'est du . La solution la plus courte en octets gagne.

Aucune réponse ne serait acceptée, car le but n'est pas de trouver la langue capable de produire la solution la plus courte, mais la solution la plus courte dans chaque langue.

Classement



1
Comment décidez-vous que la répétition pour 13 est 076923 et non 769230?
aditsu quitte car SE est EVIL le

@aditsu Parce que ce 1/13n'est 0.076923076923...pas le cas0.769230769230...
Leaky Nun

3
Déclarant ouvertement que vous n'accepterez jamais une réponse en fait à peu près un catalogue. Ne dites rien et n'acceptez jamais de réponse.
Dennis

1
Vous pouvez ajouter un extrait de pile pour afficher la solution la plus courte pour chaque langue.
aditsu quitte car SE est EVIL

Réponses:


5

Java, 150 octets:

String p(int n){int a=1,p;String r="";for(;n%10<1;n/=10);for(;n%2<1;n/=2)a*=5;for(;n%5<1;n/=5)a*=2;for(p=a%=n;;){p*=10;r+=p/n;if(a==(p%=n))return r;}}

Espaces ajoutés:

String p(int n){
    int a=1,p;
    String r="";
    for(;n%10<1;n/=10);
    for(;n%2<1;n/=2)
        a*=5;
    for(;n%5<1;n/=5)
        a*=2;
    for(p=a%=n;;){
        p*=10;
        r+=p/n;
        if(a==(p%=n))
            return r;
    }
}

Programme complet non golfé:

import java.util.Scanner;

public class A036275 {
    public static String period(int a,int n){
        if(n%10==0) return period(a,n/10);
        if(n%2==0) return period(a*5,n/2);
        if(n%5==0) return period(a*2,n/5);
        a %= n;
        int pow = a;
        String period = "";
        while(true){
            pow *= 10;
            period += pow/n;
            pow %= n;
            if(pow == a){
                return period;
            }
        }
    }
    public static String period(int n){
        return period(1,n);
    }
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        sc.close();
        System.out.println(period(n));
    }
}

for(;;)serait moins d'octets que while(2<3)si tout en étant également une boucle infinie! (et moins d'octets que while(1)aussi @Maltysen)
Marv

@Marv Comment aurais-je pu oublier ça? Merci!
Leaky Nun

Mettez les déclarations pour aet rdans les boucles for. Économise des octets!
CalculatorFeline

1
@CatsAreFluffy Cela les rendrait inaccessibles ...
Leaky Nun

3

CJam, 26

riL{_XW$%A*:X|X@-}g_X#>\f/

Essayez-le en ligne

Explication:

Le programme construit une série de dividendes impliqués dans le calcul de l'expansion décimale, jusqu'à ce qu'il trouve un dividende qu'il a vu auparavant. Ensuite, il prend tous les dividendes en commençant par celui-ci, et les divise par n pour obtenir les chiffres de la répétition.

ri       read the input and convert to integer (n)
L        push an empty array (will add the dividends to it)
{…}g     do … while
  _      copy the current array of dividends
  X      push the latest dividend (initially 1 by default)
  W$     copy n from the bottom of the stack
  %A*    calculate X mod n and multiply by 10
  :X     store in X (this is the next dividend)
  |      perform set union with the array of dividends
  X@     push X and bring the old array to the top
  -      set difference; it is empty iff the old array already contained X
          this becomes the do-while loop condition
_X#      duplicate the array of dividends and find the position of X
>        take all dividends from that position
\f/      swap the array with n and divide all dividends by n

3

Python 3.5, 79 74 73 70 octets

f=lambda n,t=1,q=[],*d:q[(*d,t).index(t):]or f(n,t%n*10,q+[t//n],*d,t)

Économisé 3 octets en gardant une trace des dividendes, une idée que j'ai prise de la réponse CJam de @ aditsu .

Testez - le sur repl.it .


2

Gelée , 12 10 octets

%³×⁵
1ÇÐḶ:

Économisé 2 octets en gardant une trace des dividendes, une idée que j'ai prise de la réponse CJam de @ aditsu .

Essayez-le en ligne!

Comment ça fonctionne

%³×⁵     Helper link. Argument: d (dividend)

%³       Yield the remainder of the division of d by n.
  ×⁵     Multiply by 10.


1ÇÐḶ:    Main link. Argument: n

1        Yield 1 (initial dividend).
 ÇÐḶ     Apply the helper link until its results are no longer unique.
         Yield the loop, i.e., everything from the first repeated result
         up to and including the last unique one.
    :    Divide each dividend by n.

1

Langue GameMaker, 152 octets

Basé sur la réponse de Kenny

n=argument0;a=1r=0while(n mod 2<1){a*=5n/=2}while(n mod 5<1){a*=2n/=5}a=a mod n;p=a;while(1){p*=10r=r*10+p/n;r=r mod $5f5e107;p=p mod n;if(a=p)return r}

Je viens de trouver un bogue dans mon approche et de le corriger, alors peut-être auriez-vous besoin de le mettre à jour également.
Leaky Nun

1

Java, 122

String f(int n){String r="";int x=1,a[]=new
int[n*10];while(a[x]++<1)x=x%n*10;do{r+=x/n;x=x%n*10;}while(a[x]<2);return r;}

Similaire à ma solution CJam.


1

Perl 6 , 37 octets

{(1.FatRat/$_).base-repeating[1]||~0}
~0 max (1.FatRat/*).base-repeating[1]

Si vous ne vous souciez pas que cela ne fonctionne qu'avec des dénominateurs qui tiennent dans un entier 64 bits, vous pouvez supprimer l'appel de méthode à .FatRat.

Explication:

# return 「"0"」 if 「.base-repeating」 would return 「""」
~0

# 「&infix<max>」 returns the numerically largest value
# or it's first value if they are numerically equal
max

(
  # turn 1 into a FatRat so it will work
  # with denominators of arbitrary size
  1.FatRat

  # divided by
  /

  # the input
  *

# get the second value from calling the
# method 「.base-repeating」
).base-repeating[1]

Tester:

#! /usr/bin/env perl6
use v6.c;
use Test;

my &code = ~0 max (1.FatRat/*).base-repeating[1];
# stupid highlighter */
# Perl has never had // or /* */ comments

my @tests = (
  1    => '0',
  2    => '0',
  3    => '3',
  6    => '6',
  7    => '142857',
  11   => '09',
  13   => '076923',
  17   => '0588235294117647',
  28   => '571428',
  70   => '142857',
  98   => '102040816326530612244897959183673469387755',
  9899 => '000101020305081321345590463683200323264976260228305889483786241034447924032730578846348115971310233356904737852308313971108192746742095161127386604707546216789574704515607637135064147893726639054449944438832205273259925244974239822204263056874431760783917567431053641781998181634508536215779371653702394181230427315890493989291847661379937367410849580765733912516415799575714718658450348520052530558642287099707041115264168097787655318719062531568845337912920497019901',
);

plan +@tests;

for @tests -> $_ ( :key($input), :value($expected) ) {
  is code($input), $expected, "1/$input";
}
1..12
ok 1 - 1/1
ok 2 - 1/2
ok 3 - 1/3
ok 4 - 1/6
ok 5 - 1/7
ok 6 - 1/11
ok 7 - 1/13
ok 8 - 1/17
ok 9 - 1/28
ok 10 - 1/70
ok 11 - 1/98
ok 12 - 1/9899


0

PHP, 169 octets

$d=$argv[2];$a[]=$n=$argv[1];while($n%$d&&!$t){$n*=10;$r[]=$n/$d^0;$t=in_array($n%=$d,$a);$a[]=$n;}if($t)echo join(array_slice($r,array_search(end($a),$a),count($a)-1));
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.