シャルコフスキーの奇妙な順序


33

前書き

この課題では、正の整数の特定の順序付けを扱います。順序は次のようになります。

   3,    5,    7,    9,    11, ...
 2*3,  2*5,  2*7,  2*9,  2*11, ...
 4*3,  4*5,  4*7,  4*9,  4*11, ...
 8*3,  8*5,  8*7,  8*9,  8*11, ...
16*3, 16*5, 16*7, 16*9, 16*11, ...
 ...
... 64, 32, 16, 8, 4, 2, 1

最初に、1より大きいすべての奇数整数を昇順でリストします。次に、1より大きい2倍の奇数の整数をリストし、4倍、8倍、というように、すべてのkについて、1より大きい奇数の整数の2 k倍を昇順でリストします。最後に、1で終わる降順で2のべき乗をリストします。すべての正の整数は、この「リスト」に1回だけ出現します。

より明確に、2つの異なる正の整数A = n・2 pおよびB = m・2 qを検討します。ここで、n、m≥1は奇数で、p、q≥0です。次に、次の条件のいずれかが当てはまる場合、順序付けでABの前に来ます。

  • n> 1m> 1およびp <q
  • 1 <n <mおよびp = q
  • n> m = 1
  • n = m = 1およびp> q

この順序付けは、シャルコフスキーの定理として知られる驚くべき数学的結果に現れます。これは、力学系の周期的な点に関するものです。ここでは詳細を説明しません。

タスク

この課題におけるあなたの仕事は、上記の順序を計算することです。入力は2つの正の整数ABであり、等しい場合があります。順序でABの前にある場合、出力は真実の値であり、そうでない場合、偽の値です。場合はA = B、あなたの出力はtruthyでなければなりません。一貫している限り、ABはどちらの順序でも取ることができます。

整数のオーバーフローを心配する必要はありませんが、アルゴリズムは任意の大きな入力に対して理論的に機能するはずです。

テストケース

真実のインスタンス

3 11
9 6
48 112
49 112
158 158
36 24
14 28
144 32
32 32
32 8
3 1
1 1

偽のインスタンス

1 2
1 5
11 5
20 25
2 8
256 255
256 257
72 52
2176 1216
2176 2496

回答:


6

JavaScript(ES6)、53 49バイト

f=(a,b)=>b<2||a>1&&(a&b&1?a<=b:a&1|~b&f(a/2,b/2))

説明:

  • bが1の場合、aはbの前(または等しい)
  • それ以外の場合、aが1の場合、aはbの前にありません
  • それ以外の場合、aとbの両方が奇数であれば、通常の不等式チェックを使用します
  • それ以外の場合、aが奇数の場合、bの前に配置されます
  • それ以外で、bが奇数の場合、aはbの前にありません
  • それ以外の場合は、aとbの両方を2で除算して再試行してください。

編集:@Arnauldのおかげで2バイト保存されました。


いいね ここでは再帰を使用することを考えていませんでした。だろうa&1|~b&1&f(a/2,b/2)動作しますか?
アーナルド

@Arnauldよくわかりませんが、無限にループするのではないかと心配でした。
ニール

b<2最終的には真実だからできません。さて、もう1つの問題は、必要以上の反復を処理し、浮動小数点値を取得することです。しかし、期待どおりに機能しない反例を見つけることはできません。
アーナルド

@Arnauldああ、そう、私はb<2もともと使っていませんでしたが、今はうまくいくと思います。
ニール

@Arnauldより良いまだ、以降f(a/2,b/2)だけを返す01falseまたはtrue、私も必要ありません&1
ニール

5

Python 2、87 71バイト

k=lambda n:[n&~-n<1,(n&-n)*cmp(n&~-n,1),n/(n&-n)]
lambda a,b:k(a)<=k(b)

これはおそらくどのサイズの賞も受賞しませんが、この答えは、辞書式に順序付けされたときに正しい順序になる整数からの3つの式を使用して3タプルを構築することによって機能します。

読み取り可能な用語では、タプルはA = n・2 pの場合です。

[n == 0, p * (1 - 2*(n == 0)), n]

5

Python 2、50バイト

lambda*l:cmp(*[([-n][n&n-1:],n&-n,n)for n in l])<1

各番号は、ソート順序が目的の順序であるトリプルにマップされます。

  • 主な値は [-n][n&n-1:]で、最後に2のべき乗を処理します。がのべき乗であるn&n-1場合、ビット単位の「and」はゼロになります。もしそうなら、listを取得し、そうでなければ空のlist を取得します。これにより、すべての2のべき乗が順序の最後に、降順になります。n2[-n][]
  • セカンダリ値n&-nは、の2のべき乗係数を抽出しnます。
  • 最終値のnタイブレークは、2の累乗に等しく、より大きな数を支持します。

それぞれのタプルを渡してcmp、その比較がであるかどうかを確認します<=0。Python 3は(n&n-1<1)/n、トリプルの最初の値にfloat除算を使用して1 バイトを保存しますが、がありませんcmp


cmp(...)<=0同等ではありませんcmp(...)<1か?
mathmandan

@mathmandanはい:)
xnor

私は、逆の順序で整数を取り、~代わりに使用することは許されると思う<1
ミッチシュワルツ

4

JavaScript(ES6)、70 64バイト

おそらくもう少しゴルフすることができますが、最初の試みとして:

x=>y=>(a=x&-x,x/=a,b=y&-y,y/=b,y<2?x>1|b<=a:x>1&(b>a|b==a&y>=x))

カリー化構文で入力を受け取ります(x)(y)0/を返します1

テストケース


周りと内側の角かっこを削除できますが、実行に影響はありb>a||(b==a&&y>=x)ません。
XavCo7

@ XavCo7内部のブラケットを外しても大丈夫です。すべての既存のテストケースは引き続きパスしますが、このような入力[1, 5]は誤って真実と識別されます。
アーナルド

1
@Arnauld将来の新しいテストケースとして追加します。
Zgarb

3

Perl 6の89の 84バイト

->\a,\b{my \u=*>max a,b;a==first a|b,flat [1,2,4...u].&{(3*$_,5*$_...u for $_),.reverse}}

{my \u=*>@_.max;@_[0]==first @_.any,flat [1,2,4...u].&{.map(*X*(3,5...u)),.reverse}}

オンラインで試してください。

厳密には短くはありませんが、実際に順序付けシーケンス(各サブシーケンスの安全な上限まで)を生成し、最初にどの入力が表示されるかをチェックするソリューションを作成することは興味深いと思いました。

例えば:

  • 入力の2, 3場合:

    3 5
    6
    12
    4 2 1
    ...そして、その3前に現れることを観察します2

  • 入力の9, 6場合:

    3 5 7 9 11
    6 10
    12
    24
    48
    16 8 4 2 1
    ...そして、その9前に現れることを観察します6

よりスマートで、生成するシーケンスの数はさらに少なくなりますが、コードのバイト数が増えます。


2

Python 2、54バイト

f=lambda a,b:b<2or[f(a/2,b/2),a>1,0,1<a<=b][a%2+b%2*2]

Neilに似た再帰的ソリューション。


これはいくつかのテストケースを台無しにしているようです。それf(158,158)は偽でf(2,8)あり、真であると言います。
XNOR

@xnorおっと、今修正する必要があります。
orlp

これf(1,5)は偽だと言います。
xnor 16

悪いのは、f(1,5)Falseであるべきだということですが、コードはTrueを返します。
xnor 16

@xnorああ、私はバグを発見しました、今修正しました(私は願っています)。私はニールの説明に少しゆるすぎました。
orlp 16

1

Mathematica、65バイト

OrderedQ[{1,#}&/@#//.{a_,b_/;EvenQ@b}->{2a,b/2}/.{a_,1}->{∞,-a}]&

正の整数のリストを取得し、リストがTrueシャルコフスキー順の昇順のシーケンスを形成する場合はFalseそうでない場合に返す、名前のない関数。(特に、入力リストに要素が2つだけある必要はありません。追加された機能は無料です。)

アルゴリズムの中心となる関数は、{1,#}&/@#//.{a_,b_/;EvenQ@b}->{2a,b/2}2の係数を繰り返し移動してm*2^km奇数のフォームの整数を順序付きペア{2^k,m}に変換します(入力リストのすべての要素に変換します)。OrderedQ次に、結果の順序付きペアのリストが既にソートされているかどうかを判断します。デフォルトでは、最初の要素で昇順、次に2番目の要素で昇順になります。

2のべき乗の数が異なる規則に従うことを除いて、まさにそれが私たちが望むものです。そうでチェックインする前にOrderingQ、我々は最後のルール適用/.{a_,1}->{∞,-a}、変換(例えば){64,1}にします{∞,-64}。これにより、順序の正しい位置に2のべき乗が配置されます。


0

ハスケル、 143 138バイト

基本的に、基準の比較的簡単な実装:

e n=head[k-1|k<-[0..],n`mod`(2^k)>0]   -- exponent of 2
f n=n`div`2^e n                        -- odd part
a#b|n<-f a,p<-e a,m<-f b,q<-e b=n>1&&(m>1&&p<q||n<m&&p==q||m<2)||n<2&&m<2&&p>q||a==b  

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


0

Python、159 158 153 144 142 141バイト

Kritixi Lithosのおかげで2バイト節約できまし

これは主に私のPythonでゴルフを練習するだけです!
すべての巧妙な答えの方法ではなく、OPによって与えられた式を使用しました

f=lambda a,p=0:(a&1)*(a,p)or f(a>>1,p+1)
t=lambda(n,p),(m,q):(n==1)*(m==1)&(p>=q)or (m>1)&(p<=q)|(n<=m)&(p==q)or m==1
lambda a,b:t(f(a),f(b))

不要なスペースを削除することでゴルフを楽しむことができます。たとえば(a, b)、2行目では、カンマとの間のスペースを削除できますb
Kritixi Lithos

0

APL(Dyalog Extended)、27バイト

1⊃∘⍋⍮⍥{p⍵⍮⍨-⍵⍴⍨⍵=2*p←⊥⍨~⊤⍵}

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

左引数がaで右が暗黙の暗黙の二項関数b

アプローチは、xnorのPython 2ソリューションとほぼ同じです。、各数値をネストされた配列に変換し、辞書編集で比較するという点で、。

パート1:数値をネストされた配列に変換する

{p⍵⍮⍨-⍵⍴⍨⍵=2*p←⊥⍨~⊤⍵}   Input: positive integer N
                  ⊤⍵    Convert N to binary digits
                 ~      Flip all the bits (1 to 0, 0 to 1)
             p←⊥⍨       Count trailing ones and assign it to p
                        (maximum power of 2 that divides N)
         ⍵=2*           Test if N itself is equal to 2^p
     -⍵⍴⍨               If true, create 1-element array containing -N;
                        otherwise, an empty array
 p⍵⍮⍨                   Form a 2-element nested array;
                        1st element is the above, 2nd is [p, N]

パート2:2つのネストされた配列を比較する

1⊃∘⍋⍮⍥f   Input: A (left) and B (right)
     f   Evaluate f A and f B
         Create a 2-element nested array [f A, f B]
         Grade up; indexes of array elements to make it sorted
          Here, the result is [0 1] if A  B, [1 0] otherwise
1⊃∘       Take the element at index 1 (0-based)

dfn構文は、例えば、{a:x ⋄ b:y ⋄ z}意味if a then x else if b then y else zなどの条件ステートメントをサポートしますが、この場合は冗長すぎるため使用できません。


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