10進数表現の繰り返しを見つけてください!


12

、この挑戦 2年前、我々が見つかりました。期間(単位分数のを1/n where n is a natural number)。

さて、あなたの仕事は単位分数の繰り返しを見つけるプログラム/関数を書くことです。

repetendは同様に、無限に繰り返される小数展開の一部です:

  • の10進表現は1/6です0.16666...、それからrepetend6です。
  • の10進表現は1/11です0.090909...、それからrepetendは09です。
  • の10進表現は1/28です0.0357142857142857142857...、それからrepetendは571428です。

スペック

  • 妥当な形式で入力してください。
  • 繰り返しを10進数、文字列、またはリストで出力します
  • 1/70.142857142857...)については、出力する必要があります142857代わりに428571
  • 1/130.076923076923076923...)、あなたは出力しなければならない076923代わりに、76923
  • 総当たりはしないでください。

テストケース

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

得点

これはです。バイト単位の最短ソリューションが勝ちます。

目標は最短のソリューションを作成できる言語を見つけることではなく、各言語で最短のソリューションを見つけることであるため、答えは受け入れられません。

リーダーボード



1
13の補充が769230ではなく076923であるとどのように決定しますか?
SEがEVILであるため、aditsuは終了します

@aditsuで1/130.076923076923...ないので0.769230769230...
リーキー修道女

3
あなたは答えを決して受け入れないだろうと公然と述べることは、これをカタログにします。ただ何も言わず、決して答えを受け入れないでください。
デニス

1
スタックスニペットを追加して、各言語の最短のソリューションを表示できます。
SEはEVILであるため、aditsuは終了しました

回答:


5

Java、150バイト:

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

追加された空白:

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、フルプログラム:

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(;;)while(2<3)無限ループである場合よりもバイト数が少なくなります!(およびwhile(1)@Maltysen よりも少ないバイト)
Marv

@Marvどうしてそれを忘れたのでしょうか?ありがとう!
漏れの修道女

for aおよびrforループに宣言を配置します。バイトを節約!
CalculatorFeline

1
@CatsAreFluffyそれはそれらにアクセスできないようになります...
リーキー修道女

3

CJam、26

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

オンラインで試す

説明:

このプログラムは、前に見た配当を見つけるまで、小数展開の計算に関連する一連の配当を作成します。次に、それから始まるすべての配当を受け取り、それらを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


2

ゼリー12 10 バイト

%³×⁵
1ÇÐḶ:

@aditsuのCJamの回答から取ったアイデアである配当を追跡することで2バイト節約しました

オンラインでお試しください!

使い方

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

GameMaker言語、152バイト

ケニーの答えに基づいて

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}

私のアプローチにバグを見つけて修正したので、これも更新する必要があるかもしれません。
漏れの修道女

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

私のCJamソリューションに似ています。


1

Perl 6、37バイト

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

64ビット整数に収まる分母のみで機能することを気にしない場合は、次のメソッド呼び出しを削除できます。 .FatRat

説明:

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

テスト:

#! /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バイト

$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));
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.