プライムカエル🐸


44

「prime frog」は、3または19に到達するまで整数間をジャンプする奇妙な動物です...


プログラムは、整数nを入力として受け入れ、以下のアルゴリズムの結果(3または19)を出力する必要があります。

与えられた整数に対してn >= 2

  1. fカエルの位置にしましょう。最初に設定されますn
  2. if f = 3またはf = 19:カエルがジャンプを停止した場合-プログラムと出力を停止しますf
  3. if fが素数の場合:カエルはその位置にジャンプし2×f-1ます。手順2に戻ります。
  4. 場合f複合体である:聞かせdすることfの最大のプライム除数。カエルはその位置にジャンプしf-dます。手順2に戻ります。

例:

以下の例n = 5

5 > 9 > 6 > 3 stop

プログラムは出力するはず3です。

別の例n = 23

23 > 45 > 40 > 35 > 28 > 21 > 14 > 7 > 13 > 25 > 20 > 15 > 10 > 5 > 9 > 6 > 3 stop

繰り返しますが、プログラムはを出力するはず3です。

テストケース:

10 => 3
74 => 19
94 => 3
417 => 3
991 => 19
9983 => 19

あなたは仮定することができ1 < n < 1000000ます(これらの値についてプログラムの終了を確認しました)。


3
3ループは[3 5 9 6 3]、19ループは[19 37 73 145 116 87 58 29 57 38 19]
アルノー

8
クールなCollat​​zバリエーション。
アーサー

3
カエルが常に3または19に来ることを証明できない場合、アルゴリズムの項目2を変更して、カエルがループに入った場合(前に見た位置に遭遇した場合)、ジャンプを停止し、最小値を返すと言うことができますそのループのメンバー。
ジェッペスティグニールセン

4
@PyRulezそれに達したら、おそらくOPに伝える必要があります。
mbomb007

3
@KeyuGanこれは、Math.SEに投稿するのがいいかもしれません。
mbomb007

回答:



12

C(gcc)、 87  65バイト

i,k;f(n){for(i=n;i>1;)for(k=i;k%--i;);n=~16&n-3?f(n-k?:n+n-1):n;}

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

説明:

i,k;
f(n)
{
    for (i=n; i>1;)              // Loop until `k` is prime (the largest positive
                                 // `i` inequal to `k` that divides `k` is 1).
        for (k=i; k%--i;);       // Find the largest factor `k`

    n =                          // Returning like this is undefined behaviour,
                                 // but happens to work with gcc. This can be
                                 // replaced with `return` at the cost of 4 bytes.

        ~16&n-3                  // If `n` is 3 or 19, this expression equals 0 and
                                 // the algorithm halts. Otherwise the function
                                 // calls itself to perform the next iteration.

        ? f(n-k ?: n+n-1)        // If `n-k` is non-zero, n is not prime.
                                 // In this case call `f` with the value of `n-k`.
                                 // (Omitting the second `n-k` between `?` and `:`
                                 // is a gcc extension)
                                 // Otherwise call `f` with `2*n-1`.

        : n;                     // All done, `n` is returned.
}

ポータブル版(72バイト):

i,k;f(n){for(i=n;i>1;)for(k=i;k%--i;);return~16&n-3?f(n-k?n-k:n+n-1):n;}

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

より適切な変数名の場合:

f,r;o(g){for(f=g;f>1;)for(r=f;r%--f;);g=~16&g-3?o(g-r?:g+g-1):g;}

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


5
単語カエルとあなたの変数との遊びを完全に愛しています。+1。
rayryeng-モニカを復元

10

網膜63 62バイト

1バイトを節約してくれたNeilに感謝します。

{`^(11+)(?<!^\2+(11+))(?=\1+$)

^(?!(11+)\1+$|111$|1{19}$)1
$_

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

単項の入出力(テストスイートは便宜上10進数を使用します)。このソリューションは、大きな入力に対しては非常に遅くなります。9983TIO上のテストケースがタイムアウト。

説明

のため{、プログラムの両方の段階は、文字列に影響を与えなくなるまでループで実行されます。コンポジットのステージ処理とプライム処理のステージを交互に行います。これにより、実際の条件(Retinaには実際には存在しません)を回避できます。現在の値がステージにとって不適切な種類である場合、ステージは単に何もしません。

^(11+)(?<!^\2+(11+))(?=\1+$)

これにより、コンポジットが処理されます。可能性のある除数をに一致させます(11+)が、それがに合成されないことを確認する(?<!^\2+(11+))ため、素因数のみを考慮します。の欲張りのため+、これは最大の要因を優先します。次に、残りの文字列を繰り返して一致させることにより、この潜在的な除数が実際の除数であることを確認し(?=\1+$)ます。この除数は文字列から単純に削除されます。これは、単項式で何かを減算する方法です。

^(?!(11+)\1+$|111$|1{19}$)1
$_

319を除く素数を処理します。負の先読みは、入力が3ではなく19ではなく、複合であることを確認します。次に、単一の1文字列を照合し、それを文字列全体に置き換えます。これは、n-1 + nを計算する単項形式であり、もちろん2n-1です。

我々がヒットしたら3または19を、どちらのステージは、文字列を一致させることができますし、それはもはや変更されません。


1
1$'と同じではありません$_か?
ニール

4
......はい@Neil
マーティン・エンダー

8

、15バイト

Ω€p57§|o←DṠ-o→p

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

説明

Ω€p57§|o←DṠ-o→p  Implicit input n.
Ω                Do this to n until
 €p57            you get a prime factor of 57 (which are 3 and 19):
            o→p   Take last element of the prime factors of n
          Ṡ-      and subtract it from n,
     §|           or if this gives 0 (so n is prime),
       o←D        double and decrement n.

8

ゼリー、12バイト

_ÆfṂoḤ’$µÐḶṂ

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

使い方

_ÆfṂoḤ’$µÐḶṂ  Maink link. Argument: n

        µ     Combine the links to the left into a chain.
         ÐḶ   Repeatedly call the chain monadically until the results are no longer
              unique. Yield the loop, i.e., the first occurrence of the first
              repeated integer, up to and excluding the repetition.
              Let's call the argument of the chain k.
_Æf             Subtract all prime factors of k from k.
   Ṃ            Take the minimum of the differences. This yields 0 iff k is prime.
     Ḥ’$        Compute 2k-1.
    o           Take the logical OR of the results.
              The result is now a rotation of either [3, 5, 9, 6] or
              [19, 37, 73, 145, 116, 87, 58, 29, 57, 38].
          Ṃ   Take the minimum, yielding either 3 or 19.

7

Wolfram言語(Mathematica)、6566 68 バイト

#//.i:Except[3|19]:>If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i]&
  • -1バイト、Misha Lavrovのおかげ!
  • -2バイト、Martinに感謝!

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

先端に触発され。基本的に、アルゴリズムを再作成するだけです。

//.でありRepeatedReplace/;ですCondition。そのため、コードは、が評価されるまでi_(単一の数量)をIf[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i]に置き換えます。i!=3&&!=19True

基準:

基準


3
楽しい事実:このコードは次のように大きい数字では動作しません10000000010ので、maximum number of iterations is 2^16 (= 65536)
J42161217

1
3と19をチェックする少し短い方法は#//.i:Except[3|19]:>If[PrimeQ@i,2i-1,i-#&@@Last@FactorInteger@i]&
ミシャラヴロフ

@MishaLavrovしかし結果は間違っていますか?
Keyuガン

私にとっては@KeyuGan、二つの機能が正確に整数1000 1〜のために同じ結果を与える
ミーシャラブロフ

1
おそらくあなたが抱えている問題は、コメントからコピーして貼り付けるときに印刷できない文字が挿入されることです。
ミシャラヴロフ

6

05AB1E19 18 17バイト

[ÐƵηfså#pi·<ëDfθ-

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

説明

[      #            # loop until
 Ð   så             # a copy of the current value is contained in
  Ƶηf               # the unique prime factors of 171
        pi          # if the current value is prime
          ·<        # double and decrement
            ë   -   # else subtract
             Dfθ    # the largest prime factor of a copy of the current value

4
ソースコードに実際のカエルがいるために+1
Arnaud

57991が1分以上
RosLuP

@RosLuP:非常に長いテストケースをオフラインで実行したほうがよい;)
Emigna

5

JavaScript(ES6)、73 71 69バイト

f=n=>57%n?f(n-(g=(k,d=1)=>++d<k?k%d?g(k,d):g(k/d):d<n?d:1-n)(n)):n%38

テストケース

書式設定およびコメント化

f = n =>                 // given n
  57 % n ?               // if n is neither 3, 19 or 57 (and assuming that n is > 1):
    f(                   //   do a recursive call to f() with:
      n -                //     n minus
      (g = (k, d = 1) => //     the result of the recursive function g():
        ++d < k ?        //       increment d; if d is less than k:
          k % d ?        //         if d is not a divisor of k:
            g(k, d)      //           recursive call to g() with k and d unchanged
          :              //         else:
            g(k / d)     //           recursive call to g() with k = k / d, d = 1
        :                //       else, d is now the highest prime divisor of n:
          d < n ?        //         if d is less than n:
            d            //           n is composite: return d, which results in f(n - d)
          :              //         else:
            1 - n        //           n is prime: return 1 - n, which results in f(2n - 1)
      )(n)               //     initial call to g()
    )                    //   end of recursive call to f()
  :                      // else:
    n % 38               //   return n % 38 (gives 19 as expected if n = 57)

1
スマート、代わりに57%nとを使用しn%38ますn==3|n==19私のJavaの回答にも1バイトを保存しましたので、ありがとう!
ケビンCruijssen

2:26 InternalError:あまりにも多くの再帰ideoneでは57991の入力はprog.js生成
RosLuP

in tio f = n => 57%n?f(n-(g =(k、d = 1)=> ++ d <k?k%d?g(k、d):g(k / d) ?:D <N D:1-N)(N)):N%38プリント(F(57991))停止プログラムではない出力を生成し、それは私には思える
RosLuP

1
@RosLuPこれは、特定の制約のないコードゴルフチャレンジです。現在のコンセンサスでは、速度またはメモリの制限(コールスタックサイズなど)は、質問で特に明記されていない限り無視できるということです。シーケンスはそれを超えてテストされていないため、1000000の制限は単なる参考情報であると当たり前のことと思います。ちなみに、70バイトのソリューションはまったく問題なく、おそらくコードゴルフチャレンジの93バイトバージョンよりも適切です。
アーナウルド


4

パイソン2110 105 103 101バイト

@Lynnのおかげで-2バイト

f=lambda n,i=2,k=0:i/n and(n*(n&~16==3)or f((2*i-1,k-i)[k>0]))or n%i and f(n,i+1,k)or f(n/i,2,k or n)

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


パイソン2116の 112 105バイト

f=lambda n,i=2:i/n*i or n%i and f(n,i+1)or f(n/i)
n=input()
while~16&n-3:n=[2*n-1,n-f(n)][f(n)<n]
print n

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


1
…n*(n&~16==3)or…2バイト節約します。
リン

入力は、sys.setrecursionlimit 57991(20000)のために
RosLuP

4

MATL22 21バイト

1バイトを削除してくれた@Giuseppeに感謝します!

`tZp?Eq}tYfX>-]tI19h-

オンラインでお試しください!または、すべてのテストケースを確認します

説明

`           % Do...while
  t         %   Duplicate. Takes (implicit) input the first time
  Zp        %   Is it prime? 
  ?         %   If so
    Eq      %     Times 2, minus 1
  }         %   Else
    t       %     Duplicate
    YfX>-   %     Prime divisors, maximum, subtract
  ]         %   End
  t         %   Duplicate
  I19h      %   Push array [3 19]
  -         %   Subtract, element-wise. The result is truthy if and only if
            %   it doesn't contain any zero
            % End (implicit). Next iteraton if top of the stack is truthy
            % Display (implicit)

4

Haskell-154バイト

f 3=3
f 19=19
f n
 |(c==[1])=f$2*n-1
 |True=f$n-head c
 where c=z n;v b=reverse[x|x<-[1..(b-1)],b`rem`x==0];z j=case v j of[1]->[1];s->filter((==[1]).v)$s

おそらくここでいくつかのゴルフのトリックを欠いている、これはハスケルゴルフでの私の最初の試みです。


こんにちは、サイトへようこそ。パターンガードに改行やスペースは必要ありません。また、使用することができる1>0ためTrue、ほとんどの時間が、多くの場合、例えば、割り当てを使用する方がよいかもしれませんc<-z n
小麦ウィザード

1
[x|x<-[b-1,b-2..1],rem b x==0]reverse[x|x<-[1..(b-1)],brem よりも短いx==0]
小麦ウィザード

2
最後に、ハスケルゴルフについて議論したい場合は、Of Monads and Menに参加できます。
小麦ウィザード

3

ニーム17 16バイト

ͻY𝐏𝕚÷D𝐌Ξᚫ<#D𝐏𝐠𝕊

説明:

ͻ                   Start infinite loop
 D                  Duplicate
  Y                 Push 57
   𝐏                Prime factors: [3 19]
     𝕚              If the second-to-top of stack is in the list
      ÷             Break the loop
       D            Duplicate
        𝐌Ξᚫ<       If prime, double and decrement
            #D𝐏𝐠𝕊   Otherwise, subtract the largest prime factor

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



3

Java 8、140 135 134 94バイト

n->{for(int f,t,m=0;57%n>0;n=f>n?2*n-1:n-m)for(t=n,f=1;f++<t;)for(;t%f<1;t/=m=f);return n%38;}

-5バイトは、ループを使用してJava 7の再帰メソッドをJava 8ラムダに変換します。
-1への暗黙のおかげバイト@ArnauldのJavaScriptの答え変更することにより、n!=3&n!=19およびreturn n;57%n>0return n%38;
どういうわけか2つのループを組み合わせてn素数であるかどうかを確認し、同時に最大の素因数を取得することは可能だと思いますが、(まだ)わかりません。したがって、これは今のところ初期バージョンになります。
@Nevayのおかげで、私ができなかったことを行うことで、すさまじいバイト数になりました。ループを組み合わせて素数と最大素数を一度にチェックします。

説明:

ここで試してみてください9999991秒未満でも実行されます)。

n->{                  // Method with integer as both parameter and return-type
  for(int f,          //  Flag-integer
          t,          //  Temp-integer
          m=1;        //  Max prime factor integer, starting at 0
      57%n>0;         //  Loop (1) as long as `n` is not 3, not 19 and not 57:
      n=f>n?          //    After every iteration: if `f` is larger than `n`:
         2*n-1        //     Change `n` to `2*n-1`
        :             //    Else:
         n-m)         //     Change `n` to `n-m`
    for(t=n,          //   Reset `t` to `n`
        f=1;          //   Reset `f` to 1
        f++<t;)       //   Inner loop (2) from 2 to `t` (inclusive)
      for(;t%f<1;     //    Inner loop (3) as long as `t` is divisible by `f`
        t/=m=f;       //     Set `m` to `f`, and set `t` to `t/f`
      );              //    End of inner loop (3)
                      //   End of inner loop (2) (implicit / single-line body)
                      //  End of loop (1) (implicit / single-line body)
  return n%38;        //  Return `n%38`, which is now either 3 or 19
}                     // End of method

1
C#の多言語であることを示す1文字の短い:(
Ian H.

@IanH。Hehe、はい、通常はそうです:のn=>代わりにn->。そして、時には小文字/大文字の呼び出し。;)
ケビンクルーイッセン

1
94バイト:n->{for(int f,t,m=0;57%n>0;n=f>n?2*n-1:n-m)for(t=n,f=1;f++<t;)for(;t%f<1;)t/=m=f;return n%38;}
Nevay

@Nevayありがとう!ループを組み合わせることができるはずだと思っていましたが、理解できませんでした。おかげでなんと40バイトも節約できました!
ケビンCruijssen

3

Bash、73バイト

((57%$1))&&$0 $[(x=$1-`factor $1|sed 's/.* //'`)?x:2*$1-1]||echo $[$1%38]

オンラインでお試しください!TIOで動作するようにわずかに変更されました。

を使用して独自のスクリプトファイルを再帰的に呼び出します$0これは./filename.shとして実行する必要があるため、TIOでは機能しません。コマンドライン引数として入力を受け入れます。

@ArnauldのJS answerと同じモジュラストリックを使用します

テストケース

$ for t in 5 23 10 74 94 417 991 9983;{ echo -n "$t -> "; ./prime-frog.sh $t; }
5 -> 3
23 -> 3
10 -> 3
74 -> 19
94 -> 3
417 -> 3
991 -> 19
9983 -> 19


1

Pyth、19バイト

.W!/P57H?P_ZtyZ-ZeP

すべてのテストケースを確認してください!

殻の答えは(2バイト節約するために私を触発,3 19するがP57)。

仕組み

.W!/ P57H?P_ZtyZ-ZeP-完全なプログラム。

.W-機能的なwhile。A(値)は真実ですが、値= B(値)です。最後の値を返します。
    P57-57の素因数([3、19])。
   / H-現在の値の出現回数をカウントします。
  !-論理否定。0->真実、その他->偽。
        ?P_Z-現在の値が素数の場合:
            tyZ-現在の値を2倍にし、デクリメントします。
               -ZeP-それ以外の場合、それ自体から現在の値の最大素因数を引きます。
                     -暗黙的に印刷します。

1

PowerShell150 126バイト

for($n="$args";57%$n){$a=$n;$d=for($i=2;$a-gt1){if(!($a%$i)){$i;$a/=$i}else{$i++}};if($n-in$d){$n+=$n-1}else{$n-=$d[-1]}}$n%38

オンラインでお試しください!(警告:数字が大きいほど遅い)

反復法。PowerShellには素因数分解が組み込まれていないため、これはPrime Factors Buddiesに関する私の答えからコードを借用しています。

最初はforループです。セットアップ$nは入力値に設定され、条件57%$n式はゼロでない限りループを継続します(このトリックのArnauldに感謝します)。ループ内では、最初に$a(に設定$n)の素因数のリストを取得します。これは、Prime Factors Buddiesから借用したコードです。入力$aがすでに素数である場合、これは$a(重要な)だけを返します。これは(潜在的には$a)に格納され$dます。

次はif/ else条件です。if部分、我々はかどうかを確認し$nています-in $d。もしそうなら、それは$n素数であることを意味するので、$n=2*$n-1またはを取り$n+=$n-1ます。それ以外の場合は複合であるため、最大の素因数を見つける必要があります。意味することに我々は最後の1取る必要がある[-1]のを$dしてからそれを差し引く$n$n-=。これが機能するのは、ループアップし2ているため、の最後の要素$dがすでに最大になるからです。

ループ処理が完了したら$n%38、パイプラインに配置するだけで(再びArnauldに感謝します)、出力は暗黙的になります。


1

APL(Dyalog Unicode)113 90 59 バイト

CY 'dfns'
g←{1pco ⍵:f(2×⍵)-1f⍵-⊃⌽3pco ⍵}
f←{⍵∊3 19:⍵⋄g ⍵}

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

TIOは最大3200までの値で動作します。最後のテストケースのPCでテストしました。TIOでテストするにf valueは、コードの最後に追加するだけです。 もう適用されません。私の主性チェックアルゴリズムが本当に悪かったと指摘してくれた@Adámに感謝します。23バイトの保存にも。

バイトカウントを修正するために編集されました。

使い方

CY 'dfns'                      # Imports every Defined Function, which is shorter than importing just the function I used (pco).

g←{1pco ⍵:f(2×⍵)-1f⍵-⊃⌽3pco ⍵} 
g                              # define g as
   1pco ⍵:                      # if the argument ⍵ is prime
          f(2×⍵)-1              # Call f over 2×⍵-1
                  f            # else, call f over
                               # the first element of the
                      3pco     # list of prime factors of ⍵
                               # reversed

f←{⍵∊3 19:⍵⋄g ⍵}
f                              # Define f as
        :                      # if the argument ⍵
                               # is in
     3 19                       # the list [3, 19]
                               # return the argument ⍵
                               # else
            g                  # call g over the argument ⍵

1

公理、93バイト

h(n)==(repeat(n=3 or n=19 or n<2=>break;prime? n=>(n:=2*n-1);n:=n-last(factors(n)).factor);n)

テスト:

(4) -> [[i,h(i)] for i in [10,74,94,417,991,9983]]
   (4)  [[10,3],[74,19],[94,3],[417,3],[991,19],[9983,19]]
                                                  Type: List List Integer

68バイトの関数があります

q x==(n<4=>3;n=19=>n;prime? n=>q(2*n-1);q(n-last(factors n).factor))

しかし、n = 57991の場合(よく覚えていれば)、予約されているスタックスペースがなくなります。


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