整数除算ループ


8

チャレンジ

あなたの言語でサポートされている正の整数を考える:

  1. 入力を受け取り、それを2つに分割します。このプログラムのすべての除算で、入力が奇数の場合、半分を切り上げ、半分を切り捨てます(例:7 -> 3,4でなく7 -> 3.5,3.5)。
  2. いずれかの数を半分に割り、次にこれら2つの新しい半分の大きい方を取り、分割されなかった数に戻します。例:3,4 -> (1,2),4 -> 1,6または3,4 -> 3,(2,2) -> 5,2
  3. 前に見たセットに到達するまで、手順2を繰り返します。例:5 -> 3,2 -> (1,2),2 -> 1,4 -> 1,(2,2) -> 3,23,2以前に見たので、繰り返すのをやめるかもしれません。これを実行する過程で、スタックを完全に使い果たす可能性があります。例:5 -> 3,2 -> (1,2),2 -> 1,4 -> (0,1),4 -> 0,5
  4. ループ内の各ペアを出力します(つまり、ペアの最初の出現から2番目までの、中間ステップなしの上記の2番目は含まれません)。例:3,2 -> 1,4。入力が含まれている場合は、それを出力しないでください0- 5 -> 3,2 -> 1,4ではなく0,5 -> 3,2 -> 1,4
  5. ペアを別々に分割して、手順1〜4を繰り返します。

I / O

入力は、1言語でサポートされている最大整数、またはコンピューターをクラッシュさせない最大整数のどちらか小さい方より大きいか小さい正の整数です。

出力は、任意の形式(文字列、リスト、配列など)の上記のループです。末尾の空白は許可されます。

同じループを2回出力したり、同じループの異なるバージョンを出力したりしないでください。例:2 -> 1,11,1 -> 2はどちらも有効なループですが、ループの異なるポイントから始まる同じループを記述しています。同様に、同一であるが逆の順序で実行される2つのループは出力されません。例:3 -> 1,2 -> 2,13 -> 2,1 -> 1,2は同じループですが、互いに逆方向に進みます。

区切り文字を使用して、ペア間、ペア内の各数値間、および各ループ間を区別できます。ただし、3つの異なる文字または文字列である必要があります。上記では、数値をコンマで、ペアを->'s'で、ループを退屈な命令で分けました。以下の例では、各ペアを括弧で囲み、ペア内の各数値の間にコンマを使用し、各ループの間に改行を使用します。

功績WheatWizardのコード@私の例のリストを固定します。以前のドラフトで述べたように、手作業で行っていたため、いくつかは欠けていたはずですが、男の子はいくつか欠けていました。

入力:2
出力:(2)(1,1)

入力:3
出力:

(3)(1,2)
(1,2)(2,1)
(3)(1,2)(2,1)

入力:4
出力:

(4)(2,2)(1,3)
(1,3)(3,1)
(4)(2,2)(1,3)(3,1)
(4)(2,2)(3,1)(1,3)
(3,1)(1,3)
(4)(2,2)(3,1)

入力: 5

出力:

(5)(2,3)(1,4)
(1,4)(3,2)
(2,3)(1,4)(3,2)(4,1)
(5)(2,3)(1,4)(3,2)(4,1)
(2,3)(4,1)
(5)(2,3)(4,1)

入力: 6

出力:

(6)(3,3)(1,5)
(1,5)(4,2)(2,4)
(4,2)(2,4)
(1,5)(4,2)(5,1)(2,4)
(4,2)(5,1)(2,4)
(6)(3,3)(1,5)(4,2)(5,1)
(6)(3,3)(5,1)(2,4)(1,5)
(2,4)(1,5)(4,2)
(5,1)(2,4)(1,5)(4,2)
(2,4)(4,2)
(5,1)(2,4)(4,2)
(6)(3,3)(5,1)

入力: 7

出力:

(7)(3,4)(1,6)
(1,6)(4,3)(2,5)
(2,5)(5,2)
(3,4)(1,6)(4,3)(2,5)(5,2)(6,1)
(7)(3,4)(1,6)(4,3)(2,5)(5,2)(6,1)
(3,4)(1,6)(4,3)(6,1)
(7)(3,4)(1,6)(4,3)(6,1)
(7)(3,4)(5,2)(2,5)(1,6)
(2,5)(1,6)(4,3)
(3,4)(5,2)(2,5)(1,6)(4,3)(6,1)
(7)(3,4)(5,2)(2,5)(1,6)(4,3)(6,1)
(5,2)(2,5)
(3,4)(5,2)(6,1)
(7)(3,4)(5,2)(6,1)

得点

これはなので、バイト数が最も少ないものが優先されます。


これが私の最初の課題ですので、どんなフィードバックでも大歓迎です。ここにサンドボックスへのリンク。

おもしろい事実:私はある日退屈して、この方法でランダムな小さな鉛筆の芯で遊んでいたのですが、結局、これらのタイプのループを続けることができることに気付きました。どういうわけか、私の最初の反応は「ねえ、これはコードゴルフにとって大きな挑戦になるでしょう」でした。


4
PPCGへようこそ。素敵な最初のチャレンジです。
FlipTack 2018年

(a,0)代わりに印刷しても(a)いいですか?これは強く型付けされた言語で意味をなす傾向があります。
アドホックガーフハンター2018

@WheatWizardいいえ。入力を印刷するときは、ゼロなしで入力を印刷するだけです。ここでは、1バイトまたは2バイトになるという課題は見たことがありません。
DonielF 2018年

OK、それで十分です。しかし、記録のために、私は確かにそれを1または2バイトとは呼びません。私にとっては、バイトカウントの約30%がゼロの削除によるものであるように見えます。
アドホックガーフハンター2018

同じループを逆にしても同じなので、ループを逆に出力できますか?
2018年

回答:


2

クリーン267 ... 167バイト

import StdEnv
f s l|any((==)s)l=[dropWhile((<>)s)l]#[h,t:_]=s
|1>h*t=f[max h t]l=f[h/2,(h+1)/2+t](l++[s])++(f[(t+1)/2+h,t/2](l++[s]))
@n=removeDup(f[n/2,(n+1)/2][[n]])

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

未ゴルフ:

loops num
    = removeDup (half (divide num) [[num]])
where
    divide num
        = [num/2, (num+1)/2]
    half [_, 0] list
        = list
    half [0, _] list
        = list
    half [a, b] list
        | isMember [a, b] list
            = [dropWhile ((<>) [a, b]) list]
        # [u, v: _]
            = divide a
        # [x, y: _]
            = divide b
        = (half [u, v+b] (list ++ [a, b])) ++ (half [a+y, x] (list ++ [a, b]))

2

Haskell227203バイト

Οurousのおかげで17バイト節約

(%)=div
u x|odd x=x%2+1|1>0=x%2
[0,b]!l=[b]!l
[b,0]!l=[b]!l
t!l|elem t l=[dropWhile(/=t)l]
t@[a,b]!l|q<-l++[t]=[a%2,u a+b]!q++[u b+a,b%2]!q
f x|q<-[x%2,u x]![[x]]=[a|(a,b)<-zip q[0..],notElem a$take b q]

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


同じように1要素と2要素の両方のケースを処理できるため、リストを使用するとタプルよりも短くなりますshowか?
2018年

@Οurous実はあなたは正しいです、それは短いだけです、それはちょうどいくつかの仕事をとります。
アドホックガーフハンター2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.