¡Encuentra la repetición de la representación decimal!


12

En este desafío hace 2 años, encontramos el período de una fracción unitaria ( 1/n where n is a natural number).

Ahora, su tarea es escribir un programa / función para encontrar la repetición de una fracción unitaria.

La repetición es la parte de la expansión decimal que se repite infinitamente, como:

  • La representación decimal de 1/6es 0.16666..., luego la repetición es 6.
  • La representación decimal de 1/11es 0.090909..., luego la repetición es 09.
  • La representación decimal de 1/28es 0.0357142857142857142857..., luego la repetición es 571428.

Especificaciones

  • Entrada en cualquier formato razonable.
  • Salida de la repetición en decimal, cadena o lista .
  • Para 1/7( 0.142857142857...), debe generar en 142857lugar de 428571.
  • Para 1/13( 0.076923076923076923...), debe generar en 076923lugar de 76923.
  • Sin fuerza bruta, por favor.

Casos de prueba

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

Puntuación

Este es el . La solución más corta en bytes gana.

No se aceptará ninguna respuesta, porque el objetivo no es encontrar el idioma capaz de producir la solución más corta, sino la solución más corta en cada idioma.

Tabla de clasificación



1
¿Cómo decide que la repetición para 13 es 076923 y no 769230?
Aditsu renunció porque SE es MAL

@aditsu Porque no 1/13es0.076923076923...0.769230769230...
Leaky Nun

3
Declarar abiertamente que nunca aceptará una respuesta hace que sea un catálogo. Simplemente no digas nada y nunca aceptes una respuesta.
Dennis

1
Puede agregar un fragmento de pila para mostrar la solución más corta para cada idioma.
Aditsu se retiró porque SE es MAL

Respuestas:


5

Java, 150 bytes:

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;}}

Espacio en blanco agregado:

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;
    }
}

Ungolfed, programa completo:

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(;;)¡Sería menos bytes que while(2<3)aunque también es un bucle infinito! (y menos bytes que while(1)también @Maltysen)
Marv

@ Marv ¿Cómo podría haber olvidado eso? ¡Gracias!
Leaky Nun

Ponga las declaraciones para ay ren los bucles for. ¡Ahorra bytes!
CalculatorFeline

1
@CatsAreFluffy Los haría inaccesibles ...
Leaky Nun

3

CJam, 26

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

Pruébalo en línea

Explicación:

El programa construye una serie de dividendos involucrados en el cálculo de la expansión decimal, hasta que encuentre un dividendo que haya visto antes. Luego toma todos los dividendos que comienzan con ese, y los divide por n para obtener los dígitos de la repetición.

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 bytes

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

Ahorré 3 bytes al hacer un seguimiento de los dividendos, una idea que tomé de la respuesta CJam de @aditsu .

Probarlo en repl.it .


2

Jalea , 12 10 bytes

%³×⁵
1ÇÐḶ:

Ahorré 2 bytes al hacer un seguimiento de los dividendos, una idea que tomé de la respuesta CJam de @aditsu .

Pruébalo en línea!

Cómo funciona

%³×⁵     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

Lenguaje GameMaker, 152 bytes

Basado en la respuesta 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}

Acabo de encontrar un error en mi enfoque y lo solucioné, por lo que tal vez también necesite actualizar esto.
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;}

Similar a mi solución CJam.


1

Perl 6 , 37 bytes

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

Si no le importa, solo funcionará con denominadores que se ajusten a un entero de 64 bits, puede eliminar la llamada al método .FatRat.

Explicación:

# 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]

Prueba:

#! /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 bytes

$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));
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.