再帰的コラッツ予想


21

このCollat​​z推測あなたは任意の正の整数を取る場合は、以下のアルゴリズム十分な回数繰り返すこと公準:

if number is odd, then multiply by three and add one
if number is even, then divide by two

最終的には1になります。常に機能するように見えますが、常に機能することは証明されていません。

あなたはすでに1に達するのにかかる時間を計算しているので、私は少し物事を切り替えると思いました。

指定された正の整数から始めて、1(「停止時間」)に達するまでにかかる時間を計算します。次に、その番号の停止時間を見つけます。

1に達するまで、または100回の反復という完全に任意の制限に達するまで繰り返します。前者の場合、それが何回繰り返したかを出力します。後者の場合、整数でない限り、「Fail」または選択した他の一貫した出力を出力します1≤n≤100。このオプションに空の文字列を出力することはできません。ただし、範囲[1、100]以外の整数の出力は許可されています。

例:

Input: 2
2->1
Output: 1

Input: 5
5->5->5->5->5->...
Output: Fail

Input: 10
10->6->8->3->7->16->4->2->1
Output: 8

Input: 100
100->25->23->15->17->12->9->19->20->7->16->4->2->1
Output: 13

Input: 10^100
10^100->684->126->108->113->12->9->19->20->7->16->4->2->1
Output: 13

Input: 12345678901234567890
12345678901234567890->286->104->12->9->19->20->7->16->4->2->1
Output: 11

Input: 1
--Depending on your code, one of two things may happen. Both are valid for the purposes of this question.
1
Output: 0
--Or:
1->3->7->16->4->2->1
Output: 6

私は計算通り10^10012345678901234567890あなたの言語は、あなたがそれらのために異なる結果を得ることができ、より正確である場合にのみ、その大きさのために実数をサポートする言語を使用して。

得点

これはであるため、バイト数が最も少ない答えが優先されます。


回答:




6

アタッシュ、40バイト

`-&3@`#@PeriodicSteps[CollatzSize@Max&1]

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

これは私が作った新しい言語です。適切な中置言語の作成に取り掛かりたかったのですが、これが数学の模造品です。やった?

説明

これは、いくつかの機能の組み合わせです。これらの機能は次のとおりです。

  • PeriodicSteps[CollatzSize@Max&1]これにより、結果に重複する要素が含まれるまで引数を適用する関数が生成されます。Collat​​Sizeへの無効な入力を回避するために、この関数、は入力との大きい方にCollatzSize@Max&1適用CollatzSizeされます。10
  • `#引用符付き演算子です。この意味で単項的に適用されると、引数のサイズを取得します
  • `-&3は、「マイナス3」として読み取られる3関数`-に引数を結合する結合関数です。これは、PeriodicStepsアプリケーションがを生成する0ためです。(に5マップされるのような範囲外の数値もきちんと処理し-1ます。)

1
あなた自身の言語の使用は本当に許可されていますか?いくつかのバイトのみを使用して各codegolfの言語を作成することはできませんか?
ツィアキンプ

2
@Tweakimpもちろん、独自の言語の作成(および使用)は許可されています。ただし、タスクが単一のコマンドになるように(チャレンジがポストされた後)変更することは、標準的な抜け穴です。

2
@Tweakimpで気分が良くなったら、この課題を見る前にこの関数を設計しました。私は言語デザイナーなので、それが私がしていることです。
コナーオブライエン

それは、自作の言語が許されるかどうかというより一般的な質問であり、あなたが自分の言語を使ったという否定的な声明ではありません。
調整

4

J49 45バイト

ここで @randomraのコメントから取られた短いCollat​​z Sequenceコードのおかげで-4バイト。

(2-~[:#(>&1*-:+2&|*+:+>:@-:)^:a:)^:(<101)i.1:

101無効な結果の出力。

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

説明

当然、この説明はすぐに時代遅れになりました。私が持っていた古い49バイトの回答の観点からそれを残すつもりです、私は以下を含めます。更新が必要な場合は、お知らせください。再帰シーケンスの長さを見つける方法は同じままです。短いCollat​​zシーケンスメソッドを使用しました。

(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:)^:(<101)i.1:

Collat​​zシーケンスの長さを見つける

コードのこのセクションは次のとおりです

(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:)

説明は次のとおりです。

(1 -~ [: # %&2`(1+3&*)@.(2&|) ^: (1&<) ^: a:)  Given an input n
                                       ^: a:   Apply until convergence, collecting
                                                each result in an array.
                              ^: (1&<)         If n > 1 do the following, else
                                                return n.
                        (2&|)                  Take n mod 2.
           %&2                                 If n mod 2 == 0, divide by 2.
               (1+3&*)                         If n mod 2 == 1, multiply by 3 
                                                and add 1.
         #                                     Get the length of the resulting
                                                array.
 1 -~                                          Subtract 1.

残念ながら、^:結果を保存するように指示された場合のapply動詞()は初期値も保存するため、(いつものように)1つずれていることを意味します。したがって、1を引く理由。

再帰シーケンスの長さを見つける

(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:) ^: (< 101) i. 1:  Given an input n.
                                      ^: (< 101)        Apply 100 times,
                                                         collecting results
                                                         in an array.
(1-~[:#%&2`(1+3&*)@.(2&|)^:(1&<)^:a:)                   Collatz sequence length.
                                                 i. 1:  Index of first 1 (returns
                                                         101, the length of the
                                                         array if 1 not found).

1
あなたはヘッダ部を使用して気にしない場合は、これはおそらく、より正確にあなたの答えを紹介します
コナー・オブライエン

@ ConorO'Brien私はまったく知りません-どうやってそのようにフォーマットするのか本当に知りませんでした(しかし、私はこれからあなたのものを盗みます)。ありがとう
コール

1
なんてこった!
コナーオブライエン

1
38バイトは*i.~(<101)1&(#@}.a:2&(<*|{%~,*+1+])])]同等である必要があります
マイル


3

JavaScript(ES6)、57バイト

true失敗すると戻ります。戻り値0のため1

f=(n,k=i=0)=>n>1?f(n&1?n*3+1:n/2,k+1):k?i>99||f(k,!++i):i

テストケース


あなたのプログラムがオーバーフロー/不正確さを除いて正しい結果を計算する場合、またはOPが同様の数の実装を持つ言語を使用して結果を導き出した場合、私は懐疑的です(すべてのテストケースを手動で計算しなかったと仮定します)。
ジョナサンフレッチ

@JonathanFrech確かに。両方の結果が等しく無効であることがわかりました。
アーナウルド

3

APL(Dyalog Unicode)39 60 53 52 49バイト

@ngnのおかげで-3バイト

0∘{99<⍺:⋄1=⍵:01+(⍺+1)∇{1=⍵:01+∇⊃⍵⌽0 1+.5 3×⍵}⍵}

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

Collat​​zには@ngnコードを使用しますが、以前は@Urielのコードを使用していました。

仕様を満たしていない古いバージョンは次のとおりです。

{1=⍵:01+∇{1=⍵:02|⍵:1+∇1+3×⍵⋄1+∇⍵÷2}⍵}

2|⍵:1+∇1+3×⍵⋄1+∇⍵÷2->1+∇⊃⍵⌽0 1+.5 3×⍵
ngn


2

、21バイト

←€1↑101¡ȯ←€1¡?½o→*3¦2

オンラインでお試しください!-1失敗時に0、入力時に 戻ります1

説明

←€1↑101¡ȯ←€1¡?½o→*3¦2  Implicit input (a number).
             ?½o→*3¦2  Collatz function:
             ?     ¦2   if divisible by 2,
              ½         then halve,
               o→*3     else multiply by 3 and increment.
        ȯ←€1¡?½o→*3¦2  Count Collatz steps:
            ¡           iterate Collatz function and collect results in infinite list,
          €1            get 1-based index of 1,
        ȯ←              decrement.
       ¡               Iterate this function on input,
   ↑101                take first 101 values (initial value and 100 iterations),
←€1                    get index of 1 and decrement.

2

C(gcc)70 73バイト

g(x){x=x-1?g(x%2?3*x+1:x/2)+1:0;}f(x,m){for(m=0;(x=g(x))&&100>m++;);x=m;}

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

101反復回数が100を超えると戻ります。


1
PPCGへようこそ!この答えはないが、かなりので、有効なすべての機能の提出は再利用可能である必要が。に挿入することでこれを修正できると思いm=0ますf(おそらく、現在空のforintiailiserを使用してaを保存します;)。
マーティンエンダー

2

Clean146 ... 86バイト

ØrjanJohansenのおかげで-11バイト

import StdEnv
?f l n=hd[u\\1<-iterate f n&u<-l]

?(?(\b|isOdd b=3*b+1=b/2)[0..])[0..99]

部分関数リテラルとして。

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

アボートhd of []反復回数が100超えた場合
で終了をHeap Full〜上記の入力のための2^23あなたは、より大きなヒープサイズを指定しない限り。


1
私はあなたの答えからいくつかのClean構文(Haskellとは異なるため)を理解し始めています...ヘルパー関数でそれを短くすることができますj f l n=hd[u\\1<-iterate f n&u<-l]
Ørjanヨハンセン

@ØrjanJohansenありがとう!
Οurous

\a=...a部品は必要ありません、カレーです。(またはイータは減少します。)
ØrjanJohansen

@ØrjanJohansenああ、それを見逃した、ありがとう!
18年




1

APL NARS、115バイト、63文字

{d←0⋄{⍵=1:d⋄99<d+←1:¯1⋄∇{c←0⋄{1=⍵:c⋄c+←1⋄2∣⍵:∇1+3×⍵⋄∇⍵÷2}⍵}⍵}⍵}

おそらくループを使用すると、より明確になります... 4つの関数、2つのネストされたリコーシブ、および最初のグローバル変数カウンターとしての2番目の関数から見た、変数dの定義と= 0への初期化のみがあります。

q←{c←0⋄{1=⍵:c⋄c+←1⋄2∣⍵:∇1+3×⍵⋄∇⍵÷2}⍵}

この3番目の関数は、その引数のCollat​​z予想を解決するための呼び出し回数を返す関数です

{⍵=1:d⋄99<d+←1:¯1⋄∇q⍵}

これは2番目の関数です。arg= 1の場合、再帰を停止し、d自体が呼び出された回数を返します-1。それ以外の場合、それ自体が99回以上呼び出された場合、再帰を停止して-1(fail)を返します。そうでない場合は、引数のCollat​​z推測を計算し、Collat​​zシーケンスの長さの値を呼び出します。グローバル変数と同じ名前の関数内の1つの変数が定義されている場合、プログラマーがローカル変数と見なすと、これがすべて実行されているように見えても、大きな問題になる可能性があります。

  f←{d←0⋄{⍵=1:d⋄99<d+←1:¯1⋄∇{c←0⋄{1=⍵:c⋄c+←1⋄2∣⍵:∇1+3×⍵⋄∇⍵÷2}⍵}⍵}⍵}     
  f 2
1
  f 3
5
  f 5
¯1
  f 10
8
  f 100
13
  f 12313
7
  f 1
0

1

(Emacs、Common、...)Lisp、105バイト

100以上の反復に対してtを返します

(defun f(n k c)(or(> c 100)(if(= n 1)(if(= k 0)c(f k 0(1+ c)))(f(if(oddp
n)(+ n n n 1)(/ n 2))(1+ k)c))))

拡張:

(defun f (n k c)
  (or (> c 100)
      (if (= n 1)
          (if (= k 0) c
            (f k 0 (1+ c)))
        (f (if (oddp n) (+ n n n 1) (/ n 2))
           (1+ k) c))))
(f (read) 0 0)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.