Trova il ripetuto della rappresentazione decimale!


12

In questa sfida 2 anni fa, abbiamo trovato il periodo di una frazione unitaria ( 1/n where n is a natural number).

Ora, il tuo compito è quello di scrivere un programma / funzione per trovare la ripetizione di una frazione di unità.

Il ripetizione è la parte dell'espansione decimale che si ripete all'infinito, come:

  • La rappresentazione decimale di 1/6è 0.16666..., quindi la ripetizione è 6.
  • La rappresentazione decimale di 1/11è 0.090909..., quindi la ripetizione è 09.
  • La rappresentazione decimale di 1/28è 0.0357142857142857142857..., quindi la ripetizione è 571428.

Specifiche

  • Inserisci in qualsiasi formato ragionevole.
  • Emette il repetend in decimale, stringa o elenco .
  • Per 1/7( 0.142857142857...), è necessario eseguire l'output 142857anziché 428571.
  • Per 1/13( 0.076923076923076923...), è necessario eseguire l'output 076923anziché 76923.
  • Nessuna forza bruta, per favore.

Casi test

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

punteggio

Questo è . La soluzione più breve in byte vince.

Nessuna risposta sarebbe accettata, perché l'obiettivo non è quello di trovare la lingua in grado di produrre la soluzione più breve, ma la soluzione più breve in ogni lingua.

Classifica



1
In che modo decidi che la ripetizione per 13 è 076923 e non 769230?
Aditsu ha smesso perché SE è MALE

@aditsu Perché non lo 1/13è0.076923076923...0.769230769230...
Leaky Nun

3
Dichiarare apertamente che non accetterai mai una risposta praticamente lo rende un catalogo. Basta non dire nulla e non accettare mai una risposta.
Dennis,

1
Puoi aggiungere uno snippet di stack per mostrare la soluzione più breve per ogni lingua.
Aditsu ha smesso perché SE è MALE

Risposte:


5

Java, 150 byte:

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

Spazio bianco aggiunto:

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, programma 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(;;)sarebbe meno byte che while(2<3)se pur essendo anche un ciclo infinito! (e meno byte rispetto while(1)anche a @Maltysen)
Marv

@Marv Come ho potuto dimenticarlo? Grazie!
Leaky Nun,

Inserisci le dichiarazioni per ae rnei cicli for. Salva byte!
CalculatorFeline

1
@CatsAreFluffy Li renderebbe inaccessibili ...
Leaky Nun

3

CJam, 26

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

Provalo online

Spiegazione:

Il programma crea una serie di dividendi coinvolti nel calcolo dell'espansione decimale, fino a quando non trova un dividendo che ha visto prima. Quindi prende tutti i dividendi a partire da quello e li divide per n per ottenere le cifre del ripetitore.

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 byte

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

Ho salvato 3 byte tenendo traccia dei dividendi, un'idea che ho preso dalla risposta CJam di @aditsu .

Testarlo su repl.it .


2

Gelatina , 12 10 byte

%³×⁵
1ÇÐḶ:

Risparmiato 2 byte tenendo traccia dei dividendi, un'idea che ho preso dalla risposta CJam di @aditsu .

Provalo online!

Come funziona

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

Lingua GameMaker, 152 byte

Basato sulla risposta di 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}

Ho appena trovato un bug nel mio approccio e l'ho risolto, quindi forse dovresti aggiornare anche questo.
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;}

Simile alla mia soluzione CJam.


1

Perl 6 , 37 byte

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

Se non ti interessa che funzioni solo con denominatori che rientrano in un numero intero a 64 bit, puoi rimuovere la chiamata del metodo a .FatRat.

Spiegazione:

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

Test:

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

$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));
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.