終了、純粋に周期的、または最終的に周期的?


21

前書き

有限の小数桁がある場合、小数は終了します。たとえば、0.4(2/5)は10進数が1つあるため終了します。

小数は、無限の数の小数桁を持ち、繰り返しのある小数の部分の前に小数桁がない場合、純粋に周期的です。たとえば、0.142857142857142…(1/7)は、繰り返しがあるため純粋に周期的です。 142857、小数点の直後から繰り返し始めます。

小数は、無限の小数桁数を持ち、繰り返しのある小数部の前に有限数の小数桁がある場合、最終的には周期的です。たとえば、0.166666666666666…(1/6)は最終的に周期的です。繰り返し6は1の後に繰り返されます。

あなたのタスク

数値pq(整数、0 <= p < q <= 100)が与えられたときに、p / qの 10進表現がが終了するか、純粋に周期的か、最終的に周期的かます。

あなたは出力しなければならないaことの終端であれば(すなわち0.1)を、bそれは純粋に定期だ場合(すなわち0.333 ...)、またはcそれは結局定期だ場合(すなわち0.166 ...)、どこabと、cお好みのいずれかの明確な、定数文字列です。

テストケース

0/1 => Terminating
0/2 => Terminating
1/2 => Terminating
0/3 => Terminating
1/3 => Purely Periodic
2/3 => Purely Periodic
0/4 => Terminating
1/4 => Terminating
2/4 => Terminating
3/4 => Terminating
0/5 => Terminating
1/5 => Terminating
2/5 => Terminating
3/5 => Terminating
4/5 => Terminating
0/6 => Terminating
1/6 => Eventually Periodic
2/6 => Purely Periodic
3/6 => Terminating
4/6 => Purely Periodic
5/6 => Eventually Periodic
0/7 => Terminating
1/7 => Purely Periodic
2/7 => Purely Periodic
3/7 => Purely Periodic
4/7 => Purely Periodic
5/7 => Purely Periodic
6/7 => Purely Periodic
0/8 => Terminating
1/8 => Terminating
2/8 => Terminating
3/8 => Terminating
4/8 => Terminating
5/8 => Terminating
6/8 => Terminating
7/8 => Terminating
0/9 => Terminating
1/9 => Purely Periodic
2/9 => Purely Periodic
3/9 => Purely Periodic
4/9 => Purely Periodic
5/9 => Purely Periodic
6/9 => Purely Periodic
7/9 => Purely Periodic
8/9 => Purely Periodic
0/10 => Terminating
1/10 => Terminating
2/10 => Terminating
3/10 => Terminating
4/10 => Terminating
5/10 => Terminating
6/10 => Terminating
7/10 => Terminating
8/10 => Terminating
9/10 => Terminating
0/11 => Terminating
1/11 => Purely Periodic
2/11 => Purely Periodic
3/11 => Purely Periodic
4/11 => Purely Periodic
5/11 => Purely Periodic
6/11 => Purely Periodic
7/11 => Purely Periodic
8/11 => Purely Periodic
9/11 => Purely Periodic
10/11 => Purely Periodic
0/12 => Terminating
1/12 => Eventually Periodic
2/12 => Eventually Periodic
3/12 => Terminating
4/12 => Purely Periodic
5/12 => Eventually Periodic
6/12 => Terminating
7/12 => Eventually Periodic
8/12 => Purely Periodic
9/12 => Terminating
10/12 => Eventually Periodic
11/12 => Eventually Periodic
0/13 => Terminating
1/13 => Purely Periodic
2/13 => Purely Periodic
3/13 => Purely Periodic
4/13 => Purely Periodic
5/13 => Purely Periodic
6/13 => Purely Periodic
7/13 => Purely Periodic
8/13 => Purely Periodic
9/13 => Purely Periodic
10/13 => Purely Periodic
11/13 => Purely Periodic
12/13 => Purely Periodic
0/14 => Terminating
1/14 => Eventually Periodic
2/14 => Purely Periodic
3/14 => Eventually Periodic
4/14 => Purely Periodic
5/14 => Eventually Periodic
6/14 => Purely Periodic
7/14 => Terminating
8/14 => Purely Periodic
9/14 => Eventually Periodic
10/14 => Purely Periodic
11/14 => Eventually Periodic
12/14 => Purely Periodic
13/14 => Eventually Periodic
0/15 => Terminating
1/15 => Eventually Periodic
2/15 => Eventually Periodic
3/15 => Terminating
4/15 => Eventually Periodic
5/15 => Purely Periodic
6/15 => Terminating
7/15 => Eventually Periodic
8/15 => Eventually Periodic
9/15 => Terminating
10/15 => Purely Periodic
11/15 => Eventually Periodic
12/15 => Terminating
13/15 => Eventually Periodic
14/15 => Eventually Periodic

すべてのテストケースはこちらで見つけることができます。

出力には独自の3つの値を選択できますが、どの値であるかを明確にする必要があります。

覚えておいて、これはであるため、バイト数が最小のコードが優先されます。

ヒント

終了:

最も単純な形式の終端小数の分母の素因数分解は、2と5のみで構成されます。

純粋に周期的:

最も単純な形式の純粋に周期的な10進数の分母の素因数分解には、2または5は含まれません。

最終的に定期的:

最終的に周期的な10進数の分母の最も単純な形式の素因数分解には、少なくとも1つの2または5が含まれますが、他の数値も含まれます。

リーダーボード

これは、通常のリーダーボードと言語ごとの勝者の概要の両方を生成するスタックスニペットです。

回答が表示されるようにするには、次のマークダウンテンプレートを使用して、見出しから回答を開始してください。

# Language Name, N bytes

N提出物のサイズはどこですか。スコアを改善する場合、古いスコアを打つことで見出しに残すことができます。例えば:

# Ruby, <s>104</s> <s>101</s> 96 bytes

ヘッダーに複数の数字を含める場合(たとえば、スコアが2つのファイルの合計であるか、インタープリターフラグペナルティーを個別にリストする場合)、実際のスコアがヘッダーの最後の数字であることを確認します。

# Perl, 43 + 2 (-p flag) = 45 bytes

言語名をリンクにして、リーダーボードスニペットに表示することもできます。

# [><>](http://esolangs.org/wiki/Fish), 121 bytes



2
それが実際に重複していると思ったら、私は近い票を投じたでしょう。「ほとんど」という言葉を使用したのには理由があります。
ピーターテイラー

1
フォームのP / Qで分数を与える方法を考えますか?分子と分母を別々の関数引数として使用できますか?
デニス

2
特定の条件を満たす非一定の値を出力できますか。たとえば、終了する場合は偽、純粋に定期的な場合は1、最終的には定期的な場合は1より大きい値などです。
ETHproductions

1
いいえ、1/13は、繰り返しが '076923'であるため、純粋に周期的です。0が繰り返して繰り返されます。
オリバーNi

回答:


8

ゼリー、10 バイト

:gÆfḍ⁵ṢQ¬Ḅ

分母と分子を(この順序で)引数として受け入れます。終了する場合は0、完全に周期的な場合は1、最終的に周期的な場合は2を返します。オンラインでお試しください!または、すべてのテストケースを確認します

使い方

:gÆfḍ⁵ṢQ¬Ḅ  Main link. Arguments: d (denominator), n (numerator)

 g          Compute the GCD of d and n.
:           Divide d by the GCD, yielding the denominator of the simplified form.
  Æf        Yield all prime factors of the previous result.
    ḍ⁵      Test 10 for divisibility by each prime factor.
            This yields 1 for 2 and 5, 0 for all other primes.
      Ṣ     Sort the resulting Booleans.
       Q    Unique; deduplicate the sorted Booleans.
        ¬   Logical NOT; replace 0 with 1 and vice versa to yield one of the
            following arrays.
              [    ]  <- no prime factors (denominator 1)
              [   0]  <- only 2 and 5
              [1   ]  <- neither 2 nor 5
              [1, 0]  <- mixed
         Ḅ  Unbinary; convert from base 2 to integer.
            This maps [] and [0] to 0, [1] to 1, and [1, 0] to 2.

11

JavaScript(ES6)、70 .. 68 53バイト

f=(a,b,s=[],x)=>a?(s[a]^=a)?f(a*10%b,b,s,x||a):x==a:0

終了の場合0、純粋に周期的な場合はtrue、最終的に周期的な場合falseを返します。

使い方

ここで行っているのは、実際に手作業で部門をシミュレートすることです。

  1. a?...:0-分子がゼロの場合、ここで停止してを返し0ます。シーケンスは終了しています
  2. (s[a]^=a)?...:x==a-既にこの分子に遭遇したことがある場合、シーケンスは周期的であり、永遠に繰り返されることを意味します。ここで停止し、シーケンスの最初の値と等しいtrue場合(純粋に周期的)またはa等しくない場合(最終的には周期的)を返します。xfalse
  3. f(a*10%b,b,s,x||a)-それ以外の場合、分子aに10 を掛けます。分母の除算の剰余を計算しbます。そして、この残りを新しい分子として使用してプロセスを繰り返します。(aシーケンスにまだ格納されていない場合は、シーケンスの最初の値としても渡しxます。)

  • :分子= 1
  • :分母= 7
  • :10の乗算
  • :残り
  • 灰色:商の数字(ここでは実際に数字を気にしません。上記のコードでは計算していません)

division


9

Python、62 61 59バイト

f=lambda n,d,r=[0,0]:(r[:3]+r).count(n)or f(10*n%d,d,r+[n])

プリント1結局周期のために、2純粋な周期のために、そして4終端します。

repl.itですべてのテストケースを確認します


魅力的!何を*rするの?
ETHproductions

タプルrを解凍します。f(1, *(2, 3), 4)はと同等f(1, 2, 3, 4)です。
デニス

したがって、これはJSでは56バイトになりますf=(n,d,...r)=>n in r?~(n>0?n==r[0]:2):f(10*n%d,d,...r,n)
。– ETHproductions

私の悪い63バイト(inPythonとJSではまったく異なる目的に役立つことを忘れていました):f=(n,d,...r)=>~r.indexOf(r)?~(n>0?n==r[0]:2):f(10*n%d,d,...r,n)
ETHproductions

@ETHproductionsニート。f=(n,d,...r)=>~(i=r.indexOf(n))?n&&!i:f(10*n%d,d,...r,n)うまくいくと思います。
デニス

6

Perl、49 46 45バイト

+3を含む -p

デニスのエレガントなアイデアに基づいていますが、完璧な方法で実装されています

STDINに入力番号を与える

terminating.pl <<< "2 26"

termninating.pl

#!/usr/bin/perl -p
/ /;1until$a{$_=$_*10%$' or$`}++;$_=$a{$`}

終了する場合は2を出力します。定期的な場合は1、最終的には定期的な場合はなし


特定のグループのすべての数値は、同じ値を与える必要があります。
オリバーNi

@OliverNi今やる
Ton Hospel

3

バッチ、247バイト

@set/af=%1,g=%2
:g
@if not %f%==0 set/ah=g,g=f,f=h%%g&goto g
@set/ae=d=%2/g
:l
@set/ag=-~!(d%%2)*(!(d%%5)*4+1)
@if not %g%==1 set/ad/=g&goto l
@if %d%==1 (echo Terminating)else if %d%==%e% (echo Purely Periodic)else echo Eventually Periodic

分数から正確な小数までの高速gcd10トリックを使用します。明らかに、カスタム出力形式を使用することで、大量のバイトを節約できました。


@if %d%==1 (echo T)else if %d%==%e% (echo P)else echo E42バイト節約するだけではどうですか?
ETHproductions

明らかに、カスタム出力形式を使用することで、大量のバイトを節約できました。
オリバーNi

@ETHproductionsオリバーが引用で指摘したように、彼は望んでいないと思います。
エリックアウトゴルファー

3

JavaScriptの(ES6)、91 88 85 79 75 74 78バイト

f=(n,d,g=(a,b)=>b?g(b,a%b):a,t=g(d/=c=g(n,d),10))=>n*~-d?t-1?f(n/c,d/t)/0:1:+f

出力NaN、終了するための1純粋に定期的にするために、そしてInfinity最終的には定期的なため。

テストスニペット

説明

最初に、ndの両方をgcd(d、n)で除算して、小数部を最も単純な形式に減らします。これにより、結果が純粋に周期的なものとして計算される2/6のような状況を回避できます。また、変数tgcd(d、10)として定義します。これは後で使用されます。

最初のチェックは、n0であるか、d1であるかです。場合(D-1)* nは 0であり、我々が戻り+f、またはNaNで:分率である終了します

次のチェックは、t1かどうかです。その場合、1を返します。小数部は純粋に周期的です。

場合tがありません 1、我々は分裂DによってTを、再び全機能を実行し、0による除算の場合、N /(D / T)が終了し、この戻りのNaN / 0 = NaNに:分率である終了します。それ以外の場合、1/0 = Infinityを返します。端数は最終的に周期的です。


最も単純な形式への還元はどこにありますか?
トンホスペル

@TonHospel修正済み。
ETHproductions

@Arnauldどういう意味かわかりません。Infinityこれらすべての値に対して返されます。
ETHproductions

@Arnauld Aw、男、私は調整することなく逃げることができると思ったn...それを指摘してくれてありがとう。
ETHproductions

3

Mathematica、41バイト

Ordering@{d=Denominator@#,GCD[d,10^d],1}&

出力{3,1,2}入力は、終端小数拡張を持っている場合{2,3,1}、入力は、純粋に周期的な小数拡張を持っている場合、及び{3,2,1}入力は、最終的に周期的な小数拡張を持っている場合。

卑劣なトリックに基づいて、次の場合d分数の分母がの最大公約数、その後、最低の条件であるd10^d等しいd場合はdその素因数分解の唯一の2秒と5秒を持っています。素因数分解に2も5も1なければifに等しいd; d2s / 5sと他の素数がある場合、中間の整数に等しくなります。

このOrdering関数は、トリプルの最小、次に最小、最大の要素がどこにあるかを報告するだけで、関係は左から右に壊れています。

欠陥:入力が0の場合では{1,2,3}なく、バリアントの出力を返します{3,1,2}

Mathematica、46バイト、ひねくれた

b[a][[Log[d=Denominator@#,GCD[d,10^d]]]][[1]]&

a[[1]]入力に終端の小数展開があるb[[1]]か、入力に純粋に周期的な小数展開b[a]があるか、入力に最終的に周期的な小数展開があるかを返します。すべての場合にエラーをスローします!

上記のように、その最大公約数が1、d、またはその中間のどこにあるかを知りたいです。そのgcdの底dの対数は、0、1、またはその間にあるものに等しくなります。

次に、Mathematicaの拷問を開始します。b[a][[n]]意味n表現の目の部分がb[a]。したがって、b[a][[1]]戻りますab[a][[0]]戻りますb。そしてb[a][[x]]、ここでx0〜1の数値は、Mathematicaにエラー「Part :: pkspec1:式xを部品仕様として使用できません」をスローさせます。b[a][[x]]未評価で返されます。

これは、既に最終的に定期的なケースのための出力であることを除いて、適切に3例を区別するb[a][[x]]ため、非一定である、x何かの実際の対数です。したがって、[[1]]すでに説明した出力に適用します。Mathematicaが内部的にどのように表現するかb[a][[x]]により、結果b[a][[x]][[1]]は単純b[a]です。一方、適用[[1]]aと、異なるエラー「Part :: partd:Part specification a [[1]] is long than object of depth」が発生します。そしてa[[1]]未評価で返します(同様にb)。

欠陥:入力0に関するもので、b[a]代わりにを返しますa[[1]]


2

C 173バイト

stdinから2つの整数を取得し、純粋に周期的な場合は1、最終的に周期的な場合は-1、終了する場合は0を出力します。

int r;main(_,n,d){_-1?_-2?d-1?d%2&&d%5?r=1:d%2?main(3,n,d/5):main(3,n,d/2),r=r?-1:0:r=0:d?main(2,d,n%d):r=n:scanf("%d %d",&n,&d),main(2,n,d),main(3,n/r,d/r),printf("%d",r);}

ゴルフをしていない:

// returns 1 for periodic, 0 for terminating, <0 for eventually periodic
int periodic(int num, int den) { // 3
    if (den == 1) return 0;
    if (den % 2 && den % 5) // pure periodic
        return 1;
    if (den % 2) return periodic(num,den/5) ? -1 : 0;
    return periodic(num,den/2) ? -1 : 0;
}

int gcd(int num, int den) { // 2
    if (den) 
        return gcd(den,num%den);
    return num;
}

int main(n,d) // 1
{
    scanf("%d %d",&n,&d);
    printf("%d",periodic(n/gcd(n,d),d/gcd(n,d)));
    return 0;
}   

ハーフゴルフ:

int r;main(_,n,d){
    _-1? 
    _-2?
    // periodic
    d-1?
        d%2&&d%5?
            r=1:
                d%2?
                    main(3,n,d/5): //periodic
                    main(3,n,d/2), //periodic
                        r=r?-1:0:
                r=0
    // gcd
    :d?main(2,d,n%d):r=n // gcd
    // main
    :scanf("%d %d",&n,&d),
     main(2,n,d), // gcd
     main(3,n/r,d/r), // periodic
     printf("%d",r);
}

2

実際には、15バイト

これは、デニスのゼリーの回答に基づいています0は終了、1は完全に周期的、2は最終的に周期的です。ゴルフの提案を歓迎します。オンラインでお試しください!

▼Ny9u♀%SR♂b╔2@¿

アンゴルフ

      Implicit input [a, b].
▼     Divide a and b by gcd(a,b).
Ny    Get the unique prime divisors of the reduced denominator.
9u    Push 10.
♀%    10 mod every member of uniq_p_d.
SR    Sort the mods and reverse.
♂b    Logical buffer. Converts every (10 % p != 0) to 1, and everything else to 0.
        Meaning if 2 or 5 divided b, they are now 0, and every other prime is now 1.
╔     Uniquify the list.
        If terminating, return [0].
        If purely periodic, return [1].
        If eventually periodic, return [1, 0].
        Else, (if b was 1), return [].
2@¿   Convert from binary to decimal. Return 0, 1, or 2.
      Implicit return.

1

Mathematica、44バイト

If[ListQ@Last@#,Length@#==1]&@@RealDigits@#&

戻り値Null終了するため、True純粋に定期的なため、とFalse最終的。

説明

RealDigits

Nの10進数展開を見つけます(繰り返し数字は余分な頭で囲まれていList {}ます)。

ListQ@Last@#

10進数展開の最後の要素がであるかどうかを確認しListます。

Length@#==1

上記の条件がの場合、True10進展開全体が1つのもので構成されているかどうかを確認します。(A Listは1つのエンティティとしてカウントされます)。(リターンTrueまたはFalse

(条件がの場合、3番目の引数がないためFalsea Nullが返されますIf


1

Pyth31 27バイト

AQ={P/HiGH?l@H=j25T?l-HT1Z2

入力

4,12

ここで試してみることができます。プリント1最終的には定期的なため、2純粋に定期的なため、および0終端します。codegolfで回答するのはこれが初めてです。どんな提案でも大歓迎です。

説明

AQ                                              // 1st element to G and 2nd element to H
    ={P                                         // Assign unique prime factors to H
        /H                                      // Simplify denominator
            iGH                                 // Find GCD
                ?l                              // Check length of filtered H
                    @H                          // Filter H by Y
                        =j25T                   // Assign a set [2,5] to T
                                ?l-HT           // Check length of H - T
                                        1Z2     // Print result

[2,3]は[2,5] = [2]でフィルタリングされますが、[2,3,5]-[2,5] = [3]でフィルタリングされます。


1

PARI / GP、64バイト

f(x,y)=if(setminus(factor(y=y/gcd(x,y))[,1]~,[2,5]),gcd(y,10)>1)

終了する場合は何も出力せず、純粋な場合は0、最終的に定期的な場合は1を出力します。

あまり空想ではありませんが、始めたときにはもっと良いものを望んでいました。


1

05AB1E16 11バイト

@Adnanのおかげで5バイト節約されました!

¿²r/fTrÖbÙJ

純粋に定期的な場合は0、終了の場合は1、最終的に定期的な場合は10を印刷します。

説明:

                 # Implicit input
                 # Implicit input
  ¿              # Take GCD of numbers
   ²             # Push top value from input register
    r            # Reverse stack order
     /           # Divide (denominator by GCD)
      f          # Find unique prime factors
       TrÖ       # Test 10 for divisibility
          b      # Convert (True -> 1, False -> 0)
           Ù     # Deduplicate array
            J    # Join chars in array
                 # Implicit print

入力は、p newline qとして取得されます。

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


05AB1Eをご利用いただきありがとうございます:)。Osabieは暗黙的な入力も使用するため、最初の2つを削除できますI。さらに、に事前定義された定数10Tです。と同じ2Bですb:)。
アドナン

入力レジスタを使用することもできます。これは¿²r/fTrÖbÙJ最終コードとして提供されます:)。
アドナン

1

PHP、126バイト

$d=$argv[2];$a[]=$n=$argv[1];while($n%$d&&!$t){$n*=10;$t=in_array($n%=$d,$a);$a[]=$n;}if($a[1]&&$t)$t+=$a[0]!=end($a);echo+$t;

終了した場合は0、最終的には純粋に周期的な2の場合は1を出力します。ここで、分子が配列内に2回ある場合、周期セッションが終了した場合に開始します。echo end($a);値である0 あなたが入れた私を信頼していない場合は$t=count($a)>$d?2:0;ループで

それをより明確にするために追加してください print_r($a);またはvar_dump($a);またはjson_encode($a);ループの後

分子が2つのアイテム間のアイテムを2回カウントし、周期の長さを取得でき、周期が始まる最初の分子による位置を確認できる場合、1つの分子を2回、または配列の末尾にゼロを表示できます

そのため、周期シーケンスの位置と長さを見つけることができます if($t){echo $p=array_search(end($a),$a);echo $l=count($a)-$p-1;}

定期的な視覚化

$d=$argv[2];
$a[]=$n=$argv[1]; #array numerator
$r[]=$n/$d^0; #array result of the division
$r[]=".";
while($n%$d&&!$t){
    $n*=10; 
    $n-=$d*$r[]=$n/$d^0;
    $t=in_array($n%=$d,$a); #stop if numerator is twice 
    $a[]=$n;
}
if($a[1]&&$t)$t+=$a[0]!=end($a); #periodic term starts directly?
if($t){
    echo $p=array_search(end($a),$a)."\n"; #output the beginning position of the periodic term
    echo $l=count($a)-$p-1; #output the length of the periodic term
    echo "\n";
    echo str_repeat(" ",2+$p).str_repeat("_",$l-1)."\n"; #visualize the periodic term
    #echo join(array_slice($r,0,1+$p)).join(array_slice($r,1+$p))."\n";# if you want only the periodic term 
    echo join($r); #result if the division
}
echo+$t; # 0 terminated 1+2 periodic 2 periodic start not directly

定期的な期間を視覚化する出力

1/18
   _
0.05

1/12
    _
0.083

1/13
  ______
0.076923

1/14
   ______
0.0714285

130バイトの別の方法

$r=bcdiv(($z=$argv)[1],$z[2],400);for($p=2;$i++<200;)if(substr($r,2,$i)==substr($r,2+$i,$i))$p=1;echo strlen(rtrim($r,0))<50?0:$p;

拡張版

$r=bcdiv(($z=$argv)[1],$z[2],400); # 100 is the maximal denominator 
# we need a string length with the double value of the sum the length from 1 until the denominator
for($p=2;$i++<200;)if(substr($r,2,$i)==substr($r,2+$i,$i))$p=1;
# all results begin with 0. 
#take two substrings with the same length after that and comparize both. 
#if we found 2 same substrings we have a periodic which starts at the first decimal place
echo strlen(rtrim($r,0))<50?0:$p; 
# if we can trim the length of the result we have a terminated result

正確な小数への小数も参照してください。
ニール

@Neil、コードを修正して他の質問に答える必要があるということですか?
ヨルクヒュルサーマン

さて、私は他の質問にはPHPの答えがないと考えていました。おそらくあなたはそれを提供したいと思うでしょう。
ニール

@RosLuP例3/53の場合、この配列は作成されます[3,30,35,32,2,20,41,39,19,31,45,26,48,3]
ヨルグヒュルサーマン

3/103 = 0.0291262135922330097087378640776699029126213592233009708などのように、同じ期間に同じ数字が表示される場合があります(たとえば、上記の00 ... 00の間の数字7)。 = 10 *(d%b)}ここで、数字はd / cで、各期間に値d_iは1つしかありません
。...-RosLuP
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.