配列のソート


105

概念的には、この課題は本当に簡単です。負でない整数のリストが与えられます。可能であれば、で構成されるリストがソートされるように、負でない整数を見つけます。そのようなものが存在しない場合、出力は有効なものと間違えられないものである必要があります。たとえば、負の数、まったくない、エラーなどです。aiNbi = ai XOR NNN

以下に例を示します。

[4, 7, 6, 1, 0, 3]

このリストのすべての要素XOR 5を取得すると、

[1, 2, 3, 4, 5, 6]

ソートされます。(結果のリストが一意の要素を持ち、ギャップを含まないことは要件ではないことに注意してください。そのような操作の結果が[0, 1, 1, 3]それでも有効である場合)。

[4, 7, 1, 6, 0, 3]

そのようなものはN存在しません。

プログラムまたは関数を作成し、STDIN(または最も近い代替)、コマンドライン引数または関数引数を介して入力を取得し、STDOUT(または最も近い代替)、関数の戻り値または関数(out)パラメーターを介して結果を出力できます。

入力は、任意の便利なリスト形式または文字列形式です。がそれぞれより小さく、リストに少なくとも1つの要素が含まれていると仮定することができます。ai231

コードは、数秒でテストケース(特に4つの大きなテストケース)を処理する必要があります。

標準の規則が適用されます。

テストケース

返されないすべてのテストケースには-1、無限の数の正解があります。ここにリストされているものは最小のものです。入力のすべての整数で同じビット(特に、リストの最大数の最上位ビットより大きいビット)を追加設定することにより、追加のソリューションが存在します。

[4 7 6 1 0 3] => 5
[4 7 1 6 0 3] => -1
[0 1 3 4 6 7] => 0
[4 2 3 1] => 6
[2 3 0 0 7 7 4 5 11 11] => 2
[2 3 0 0 7 7 5 4 11 11] => -1
[1086101479 748947367 1767817317 656404978 1818793883 1143500039] => -1
[180522983 1885393660 751646477 367706848 331742205 724919510 850844696 2121330641 869882699 1831158987 542636180 1117249765 823387844 731663826 1762069894 240170102 1020696223 1212052937 2041219958 712044033 195249879 1871889904 1787674355 1849980586 1308879787 1743053674 1496763661 607071669 1987302942 178202560 1666170841 1035995406 75303032 1755269469 200581873 500680130 561748675 1749521426 1828237297 835004548 934883150 38711700 1978960635 209243689 1355970350 546308601 590319412 959613996 1956169400 140411967 112601925 88760619 1977727497 672943813 909069787 318174568 385280382 370710480 809689639 557034312 865578556 217468424 346250334 388513751 717158057 941441272 437016122 196344643 379529969 821549457 97008503 872313181 2105942402 603939495 143590999 1580192283 177939344 853074291 1288703007 1605552664 162070930 1325694479 850975127 681702163 1432762307 1994488829 780869518 4379756 602743458 1963508385 2115219284 1219523498 559301490 4191682 1918142271 169309431 346461371 1619467789 1521741606 1881525154] => -1
[37580156 64423492 87193676 91914964 93632157 96332899 154427982 176139560 184435039 228963836 230164674 279802291 301492375 309127664 345705721 370150824 380319820 403997410 410504675 416543032 418193132 424733526 428149607 435596038 477224208 515649925 519407995 525469350 614538124 624884850 642649261 653488151 679260270 685637235 690613185 739141066 825795124 832026691 832633584 833213619 852655299 913744258 917674993 921902522 925691996 931307936 954676047 972992595 997654606 1020009811 1027484648 1052748108 1071580605 1108881241 1113730139 1122392118 1154042251 1170901568 1180031842 1180186856 1206428383 1214066097 1242934611 1243983997 1244736049 1262979035 1312007069 1312030297 1356274316 1368442960 1377432523 1415342434 1471294243 1529353536 1537868913 1566069818 1610578189 1612277199 1613646498 1639183592 1668015280 1764022840 1784234921 1786654280 1835593744 1849372222 1875931624 1877593764 1899940939 2007896363 2023046907 2030492562 2032619034 2085680072 2085750388 2110824853 2123924948 2131327206 2134927760 2136423634] => 0
[1922985547 1934203179 1883318806 1910889055 1983590560 1965316186 2059139291 2075108931 2067514794 2117429526 2140519185 1659645051 1676816799 1611982084 1736461223 1810643297 1753583499 1767991311 1819386745 1355466982 1349603237 1360540003 1453750157 1461849199 1439893078 1432297529 1431882086 1427078318 1487887679 1484011617 1476718655 1509845392 1496496626 1583530675 1579588643 1609495371 1559139172 1554135669 1549766410 1566844751 1562161307 1561938937 1123551908 1086169529 1093103602 1202377124 1193780708 1148229310 1144649241 1257633250 1247607861 1241535002 1262624219 1288523504 1299222235 840314050 909401445 926048886 886867060 873099939 979662326 963003815 1012918112 1034467235 1026553732 568519178 650996158 647728822 616596108 617472393 614787483 604041145 633043809 678181561 698401105 776651230 325294125 271242551 291800692 389634988 346041163 344959554 345547011 342290228 354762650 442183586 467158857 412090528 532898841 534371187 32464799 21286066 109721665 127458375 192166356 146495963 142507512 167676030 236532616 262832772] => 1927544832
[1922985547 1934203179 1883318806 1910889055 1983590560 1965316186 2059139291 2075108931 2067514794 2117429526 2140519185 1659645051 1676816799 1611982084 1736461223 1810643297 1753583499 1767991311 1819386745 1355466982 1349603237 1360540003 1453750157 1461849199 1439893078 1432297529 1431882086 1427078318 1487887679 1484011617 1476718655 1509845392 1496496626 1583530675 1579588643 1609495371 1559139172 1554135669 1549766410 1566844751 1562161307 1561938937 1123551908 1086169529 1093103602 1202377124 1193780708 1148229310 1144649241 1257633250 1241535002 1247607861 1262624219 1288523504 1299222235 840314050 909401445 926048886 886867060 873099939 979662326 963003815 1012918112 1034467235 1026553732 568519178 650996158 647728822 616596108 617472393 614787483 604041145 633043809 678181561 698401105 776651230 325294125 271242551 291800692 389634988 346041163 344959554 345547011 342290228 354762650 442183586 467158857 412090528 532898841 534371187 32464799 21286066 109721665 127458375 192166356 146495963 142507512 167676030 236532616 262832772] => -1

最後に、提出が十分に効率的であることを確認するための4つの非常に大きなテストケースを以下に示します。

なぜこれを行うのでしょうか?

先日、XOR演算で配列を「ソート」できるため、最初にソートすることなくO(log n)の配列でバイナリ検索を実行できるようになりました。N擬似線形時間で決定することが可能であると思われるため、これはほとんどのソートアルゴリズムのより高速な代替手段となり、基数ソートのメモリ要件はありません。もちろん、並べ替えられていない配列全体の直線線形検索の方が高速ですが、同じ配列を何度も検索する場合は、単一の線形事前計算によって各検索に必要な時間が大幅に短縮されます。

残念ながら、これが機能するリストのクラスはかなり制限されています(一様にランダムな分布は認められそうにありませんN)。

興味深い質問は、チェックしやすい、および/またはより広いリストのクラスに適用できる他の全単射関数があるかどうかです。


42
Xorting」はそのための本当にクールな名前です。
insertusernamehere

7
@insertusernamehereそのクレジットはrandomraに送られます。
マーティンエンダー

3
非常に興味深い挑戦です!
DavidC

4
Paebbels:Xortingキーを持っていると仮定すると、元の値を計算することが可能です。ここでの目的(バイナリ検索)では、入力とキーをXORし、「ソート済み」配列に存在することを確認します。確かに並べ替えですが、並べ替える関係/関数は、各要素の位置が同じままで選択されます。
2015

8
@Paebbelsこれが並べ替えだと主張したことはありません。私は作り上げられた言葉でそれを呼びました、そしてあなたが引用する段落には理由のために引用符で「ソート」があります。私のポイントは、これが配列を実際に並べ替えなくても特定の操作(バイナリ検索など)で並べ替えられたかのように処理できる全単射変換であるということでした。
マーティンエンダー

回答:


7

ゼリー、25バイト

ṡ2Zµ^/Bo1Ḅ‘×>/|/H
Ç-¹^Ç¥?

最新のコミットはこの課題の後期ですが、上記のコードはこのリビジョンで機能します。オンラインでお試しください!

大規模なテストケースを実行するには、シェルに応じて、STDINから入力を読み取るプログラムで上記のコードをラップする必要があります。オンラインでお試しください!

テストケース

$ xxd -c 13 -g 1 xort-prog.jelly 
0000000: ae 32 5a 8c 5e 2f 42 6f 31 a4 b6 94 3e  .2Z.^/Bo1...>
000000d: 2f 7c 2f 48 0a 92 2d 8e 5e 92 84 3f     /|/H..-.^..?
$ ./jelly f xort-prog.jelly '[4, 7, 6, 1, 0, 3]'; echo
5
$ ./jelly f xort-prog.jelly '[4, 7, 1, 6, 0, 3]'; echo
-1
$ ./jelly f xort-prog.jelly '[0, 1, 3, 4, 6, 7]'; echo
0
$ ./jelly f xort-prog.jelly '[4, 2, 3, 1]'; echo
6
$ ./jelly f xort-prog.jelly '[2, 3, 0, 0, 7, 7, 4, 5, 11, 11]'; echo
2
$ ./jelly f xort-prog.jelly '[2, 3, 0, 0, 7, 7, 5, 4, 11, 11]'; echo
-1
$
$ wget -q http://pastebin.com/raw/{P96PNi79,zCNLMsx9,GFLBXn5b,6F1Yn3gG}
$ xxd -c 14 -g 1 xort-func.jelly 
0000000: ae 32 5a 8c 5e 2f 42 6f 31 a4 b6 94 3e 2f  .2Z.^/Bo1...>/
000000e: 7c 2f 48 0a 92 2d 8e 5e 92 84 3f 0a a0 92  |/H..-.^..?...
$ tr \  , < P96PNi79 | time -f '\n%es' ./jelly f xort-func.jelly
-1
3.69s
$ tr \  , < zCNLMsx9 | time -f '\n%es' ./jelly f xort-func.jelly
0
2.78s
$ tr \  , < GFLBXn5b | time -f '\n%es' ./jelly f xort-func.jelly
1096442624
2.73s
$ tr \  , < 6F1Yn3gG | time -f '\n%es' ./jelly f xort-func.jelly
-1
2.70s

アイデア

これは@Jakubeのanswerと同じアプローチを使用しますが、私の実装は少し異なります。

Jellyにはまだ並べ替えがないため、xorting候補を計算し、入力リストとXORし、XORされたリストのxorting候補を計算し、新しい候補がゼロかどうかを確認します。そうであれば、最初の候補を印刷します。それ以外の場合は、-1を出力します。

また、ゼリーはまだ(山車を返すことができ偶数の整数除算)を整数にキャストする全くまともな方法がありませんように見えるので、私は、次の電源までの番号のリストを丸めるのではなく創造的な方法を考え出す必要があった2。log-floor-powではなく、すべての整数を2進数に変換し、すべての2進数を1に置き換え、整数に戻し、1を加算し、2で除算します。

コード

ṡ2Zµ^/Bo1Ḅ‘×>/|/H  Helper link. Argument: M (list of integers)

ṡ2                 Yield all overlapping slices of length 2 (pairs) of M.
  Z                Zip to group first and second coordinates.
   µ               Begin a new, monadic chain.
    ^/             XOR the corresponding coordinates.
      B            Convert all results to binary.
       o1          OR (logical) all binary digits with 1.
         Ḅ         Convert back to integer.
          ‘        Increment all integers.
           ×>/     Multiply each rounded (a ^ b) by (a > b).
                   This replaces (a ^ b) with 0 unless a > b.
              |/   OR all results.
                H  Halve the result.

Ç-¹^Ç¥?            Main link. Input: L (list of integers)

Ç                  Call the helper link on L. Result: C (integer)
     ¥             Create a dyadic chain:
   ^                 XOR the elements of L with C.
    Ç                Call the helper link on the result.
      ?            If the result in non-zero:
 -                   Yield -1.
  ¹                Else, yield C.

36

Pyth、40 36 31 30バイト

Ju.|G^2slHxMf>FT.:Q2Z|tSIxRJQJ

オンラインで試す:デモンストレーションまたはテストスイート

大きなテストケースはそれぞれ数秒で終了します。

説明:

最初に、この方法とその理由を説明します。サンプルリストを使用してこれを行います[7, 2, 13, 9]

最初の2つの数字はすでに間違っています(7 > 2)。その不等式記号(7 xor X < 2 xor X)を変更するには、いくつかの数値でxorを実行します。xorはバイナリ表現を操作するため、それらを見てみましょう。

7 = 1 1 1
2 =   1 0

xorにいくつかの数値を各数値に適用すると、いくつかの位置の値が変化します。最初の位置(2^0)の値を変更しても、不等式記号は変わりません。2番目の位置(2^1)で値を変更すると、同じことが起こります。我々は第4、第5、...位置(で値を変更した場合も記号は変更されません2^32^4、...)。3番目の位置(2^2)を変更すると、不等式記号の方向のみが変更されます。

7 xor 2^0 = 1 1 0   7 xor 2^1 = 1 0 1   7 xor 2^2 =   1 1   7 xor 2^3 = 1 1 1 1
2 xor 2^0 =   1 1   2 xor 2^1 =     0   2 xor 2^2 = 1 1 0   2 xor 2^3 = 1 0 1 0
     6 > 3               5 > 0               3 < 6               15 > 10

一度に複数の位置を変更すると、もちろん同じことが起こります。変更する位置のいずれかが3番目の場合、不等式記号は変更され、そうでない場合は変更されません。

次のペアは既にソートされています:2 < 13。バイナリ表現を見ると、それに何でもxorすることができ、4番目の位置(2^3)を変更する場合を除いて、不等式記号はまだ正しいことがわかります。

 2 =     1 0    2 xor 2^3 = 1 0 1 0
13 = 1 1 0 1   13 xor 2^3 =   1 0 1
   2 < 13            10 > 5

したがって、4番目の位置を変更する必要はありません。次のペアでは、を変更します13 > 9。ここでも、3番目の位置を変更する必要があります。

13 = 1 1 0 1   13 xor 2^2 = 1 0 0 1
 9 = 1 0 0 1    9 xor 2^2 = 1 1 0 1
   13 > 9            9 < 13

まとめ:並べ替えられたリストを作成するには、再び3番目の位置を変更する必要があり、4番目の位置を変更しないでください。他のすべてのポジションは重要ではありません。最小数は単純4 = 0100です。他の選択肢は次のようになり5 = 01016 = 01107 = 011120 = 1010021 = 10101、...

Xoring with 4はリストになり[3, 6, 9, 13]、with 6will get [1, 4, 11, 15]およびwith 21will getになります[18, 23, 24, 28]

そのため、リストの場合、位置を見つける必要があります。これは、間違った方向を指している場合に不等式記号を変更します。ペアのxorの最上位ビットを取得するだけで位置を見つけます。これらすべての位置(または)を組み合わせて、候補番号を作成します。すでにソートされたペアを誤って破棄していないかどうかを確認します。

Ju.|G^2slHxMf>FT.:Q2Z   implicit: Q = input list
                .:Q2    all substrings of length 2
            f>FT        filter for pairs that are in descending order
          xM            apply xor to each such pair
 u                  Z   reduce this list, start value G = 0
                           iteration value is H
     ^2slH                 2 to the power of floor(logarithm base 2 of H)
                           this gives a mask representing the most significant bit
  .|G                      update G with the bitwise or of G and ^
J                       store the result in J


|tSIxRJQJ   
    xRJQ      xor each element of the input list with J
  SI          check if the list is sorted
 t            subtract 1
|       J     this number or (if equal to zero) J
              implicit print

3
私はそのようなクリーンでシンプルなソリューションの存在を強く勧めています。
キントピア

より数学的に鈍感な私たちにとって、これがなぜ機能するのかを説明できたら素晴らしいでしょう。私はすべてのステップを理解していますが、すべてのxor'ed降順ペアのビット単位またはMSBが正しい値になる理由がわかりません。
ルーク

1
@Luke長い説明を追加しました。うまくいけばそれが役立つ。
ジャクベ

素晴らしい説明!
edc65

1
あなたは2進値を保持する場合、変更する必要がありますビット、および変更されないために持っているビットは、その後、あなたはこれ以上の反復を使用して、最終的な結果持っている
edc65

15

ルビー2、119

->a,*o{a.each_cons(2){|x,y|x==y||o[i=(x^y).bit_length-1]==1-(o[i]=x[i])&&(return-1)};(o.map(&:to_i).reverse*'').to_i 2}

大規模なテストケースでは42ミリ秒で実行されます。

ゴルフをしていない:

def first_differing_bit(a,b)
  (a^b).bit_length - 1
end

def xort(ary)
  required_bits = []
  ary.each_cons(2) do |a,b|
    i = first_differing_bit(a,b)
    if i > -1
      bit = a[i]
      if required_bits[i] && required_bits[i] != bit
        return -1
      else
        required_bits[i] = bit
      end
    end
  end
  required_bits.map(&:to_i).reverse.join.to_i(2)
end

適切なアルゴリズムを見つけること自体が難題だったので、一度は最初にゴルフのないバージョンを書き、それからゴルフをしました。

実際、数年前にこのようなものを書いて、各ノードがその比較関数を動的に再定義できるようにすることで、ローカルに自己バランスをとるバイナリツリー構造を作成しようとしました。最初はxorだけを使用できると思っていましたが、ランダムデータの場合、実行可能な値になる可能性は低いと言えます。


良い解決策は、配列の初期化とrubyのビット[]関数が好きです。しかし、例えばリストを試してみてください。[4,4,4]これはevalを試みるときにSyntaxErrorを出し0bます。幸運なことに、私にはよくあることですが、同じバイト数で同じことを行う別の方法があります。:これは私が願って、動作するはずです->a,*o{a.each_cons(2){|x,y|x==y||o[i=(x^y).bit_length-1]==1-(o[i]=x[i])&&(return-1)};(o.map(&:to_i).reverse*'').to_i 2}
blutorange

確かにそうです、いいキャッチ!
histocrat

11

ジュリア、174 144 77 75 71

[編集]匿名化と様々な略記についてAlex A.に感謝します。
[編集2]独自の実装をbuiltinに置き換えましたissorted()

線形時間で実行され、顕著な遅延なしに大きなファイルを処理します。負の数でも同様に機能します。

l->(r=0;s=issorted;for d=63:-1:0 s((l$r).>>d)||(r$=2^d)end;s(l$r)?r:[])

特定のキーに最も近い結果を計算する別のバリ​​アント(上記は最小値を返します)。

(l,r)->(s=issorted;for d=63:-1:0 s((l$r).>>d)||(r$=2^d)end;s(l$r)?r:[])

使用法:

julia> xort = l->(r=0;s=issorted;for d=63:-1:0 s((l$r).>>d)||(r$=2^d)end;s(l$r)?r:[])
(anonymous function)

julia> xort([4 7 6 1 0 3])
5

例、ステップバイステップ: [4 7 6 1 0 3] => 5

Start with:
     4  0b0100
     7  0b0111
     6  0b0110
     1  0b0001
     0  0b0000
     3  0b0011
result  0b0000

If the first n bits are sorted, do nothing.
        0b0
        0b0
        0b0
        0b0
        0b0
        0b0
result  0b0000
          ^
If the first n bits are not sorted, flip the nth bit.
        0b01            0b00
        0b01            0b00
        0b01            0b00
        0b00      =>    0b01
        0b00            0b01
        0b00            0b01
result  0b0000          0b0100
           ^               ^
        0b000
        0b001
        0b001
        0b010
        0b010
        0b011
result  0b0100
            ^
        0b0000          0b0001  1
        0b0011          0b0010  2
        0b0010          0b0011  3
        0b0101    =>    0b0100  4
        0b0100          0b0101  5
        0b0111          0b0110  6
result  0b0100          0b0101  5
             ^               ^
If the bit flip does not sort the truncated integers, xorting is
impossible. We continue anyway and check for success in the end.

2
71バイト:l->(r=0;s=issorted;for d=63:-1:0 s((l$r).>>d)||(r$=2^d)end;s(l$r)?r:[])
アレックスA.

8

JavaScript(ES6)85 97 114 117

編集削除された愚かな、役に立たない最後AND
Edit2上位ビット検索短縮
Edit3うわー!ES6(ほとんど)にトップビットを見つけるための組み込み機能があることを発見しました(Math.clz32はトップ0ビットをカウントします)

これは@Jakubeのソリューションに基づいています(plsは賛成です)。自分では見つけられなかったでしょう。

ここでは、リストを1回繰り返し、反転する必要があるビットでビットマスクを保持し、保持する必要があるビットで別のマスクを保持して、一歩先へ進みます。

ビットマスクのオーバーラップがある場合、解決策はありません。そうでない場合、解決策は「反転するビット」です。

javascriptのバイナリ演算は符号付き32ビット整数でのみ機能するため、戻り値は負または0の符号付き32ビット整数です。

解決策がない場合、戻り値は「X」です

l=>l.map(v=>(t=v^p&&1<<(31-Math.clz32(v^p)),v>p?k|=t:c|=t,p=v),p=l[c=k=0])&&c&k?"X":c

テスト

jsfiddleでの長いテスト

X=l=>l.map(v=>(t=v^p&&1<<(31-Math.clz32(v^p)),v>p?k|=t:c|=t,p=v),p=l[c=k=0])&&c&k?"X":c

console.log=x=>O.textContent+=x+'\n'
;[
[[4,7,6,1,0,3], 5],
[[4,7,1,6,0,3], 'X'],
[[0,1,3,4,6,7], 0],
[[4,2,3,1], 6], 
[[2,3,0,0,7,7,4,5,11,11], 2],
[[2,3,0,0,7,7,5,4,11,11], 'X'],
[[1086101479,748947367,1767817317,656404978,1818793883,1143500039],'X'],
[[180522983,1885393660,751646477,367706848,331742205,724919510,850844696,2121330641,869882699,1831158987,542636180,1117249765,823387844,731663826,1762069894,240170102,1020696223,1212052937,2041219958,712044033,195249879,1871889904,1787674355,1849980586,1308879787,1743053674,1496763661,607071669,1987302942,178202560,1666170841,1035995406,75303032,1755269469,200581873,500680130,561748675,1749521426,1828237297,835004548,934883150,38711700,1978960635,209243689,1355970350,546308601,590319412,959613996,1956169400,140411967,112601925,88760619,1977727497,672943813,909069787,318174568,385280382,370710480,809689639,557034312,865578556,217468424,346250334,388513751,717158057,941441272,437016122,196344643,379529969,821549457,97008503,872313181,2105942402,603939495,143590999,1580192283,177939344,853074291,1288703007,1605552664,162070930,1325694479,850975127,681702163,1432762307,1994488829,780869518,4379756,602743458,1963508385,2115219284,1219523498,559301490,4191682,1918142271,169309431,346461371,1619467789,1521741606,1881525154],'X'],
[[37580156,64423492,87193676,91914964,93632157,96332899,154427982,176139560,184435039,228963836,230164674,279802291,301492375,309127664,345705721,370150824,380319820,403997410,410504675,416543032,418193132,424733526,428149607,435596038,477224208,515649925,519407995,525469350,614538124,624884850,642649261,653488151,679260270,685637235,690613185,739141066,825795124,832026691,832633584,833213619,852655299,913744258,917674993,921902522,925691996,931307936,954676047,972992595,997654606,1020009811,1027484648,1052748108,1071580605,1108881241,1113730139,1122392118,1154042251,1170901568,1180031842,1180186856,1206428383,1214066097,1242934611,1243983997,1244736049,1262979035,1312007069,1312030297,1356274316,1368442960,1377432523,1415342434,1471294243,1529353536,1537868913,1566069818,1610578189,1612277199,1613646498,1639183592,1668015280,1764022840,1784234921,1786654280,1835593744,1849372222,1875931624,1877593764,1899940939,2007896363,2023046907,2030492562,2032619034,2085680072,2085750388,2110824853,2123924948,2131327206,2134927760,2136423634],0],
[[1922985547,1934203179,1883318806,1910889055,1983590560,1965316186,2059139291,2075108931,2067514794,2117429526,2140519185,1659645051,1676816799,1611982084,1736461223,1810643297,1753583499,1767991311,1819386745,1355466982,1349603237,1360540003,1453750157,1461849199,1439893078,1432297529,1431882086,1427078318,1487887679,1484011617,1476718655,1509845392,1496496626,1583530675,1579588643,1609495371,1559139172,1554135669,1549766410,1566844751,1562161307,1561938937,1123551908,1086169529,1093103602,1202377124,1193780708,1148229310,1144649241,1257633250,1247607861,1241535002,1262624219,1288523504,1299222235,840314050,909401445,926048886,886867060,873099939,979662326,963003815,1012918112,1034467235,1026553732,568519178,650996158,647728822,616596108,617472393,614787483,604041145,633043809,678181561,698401105,776651230,325294125,271242551,291800692,389634988,346041163,344959554,345547011,342290228,354762650,442183586,467158857,412090528,532898841,534371187,32464799,21286066,109721665,127458375,192166356,146495963,142507512,167676030,236532616,262832772],1927544832],
[[1922985547,1934203179,1883318806,1910889055,1983590560,1965316186,2059139291,2075108931,2067514794,2117429526,2140519185,1659645051,1676816799,1611982084,1736461223,1810643297,1753583499,1767991311,1819386745,1355466982,1349603237,1360540003,1453750157,1461849199,1439893078,1432297529,1431882086,1427078318,1487887679,1484011617,1476718655,1509845392,1496496626,1583530675,1579588643,1609495371,1559139172,1554135669,1549766410,1566844751,1562161307,1561938937,1123551908,1086169529,1093103602,1202377124,1193780708,1148229310,1144649241,1257633250,1241535002,1247607861,1262624219,1288523504,1299222235,840314050,909401445,926048886,886867060,873099939,979662326,963003815,1012918112,1034467235,1026553732,568519178,650996158,647728822,616596108,617472393,614787483,604041145,633043809,678181561,698401105,776651230,325294125,271242551,291800692,389634988,346041163,344959554,345547011,342290228,354762650,442183586,467158857,412090528,532898841,534371187,32464799,21286066,109721665,127458375,192166356,146495963,142507512,167676030,236532616,262832772],'X']
].forEach(t=>{
  var i=t[0],k=t[1],r=X(i)
  console.log((k==r?'OK ':'Error (expected '+k+') ')+r+' for input '+i)
})
<pre id=O></pre>


8

ES6、84バイト

a=>(i=e=0,a.reduce((x,y)=>(z=1<<31-Math.clz32(x^y),x>y?i|=z:y>x?e|=z:z,y)),i&e?-1:i)

編集:答えを書くのに私がかかった頃には、アルゴリズムはすでに@Jakubeによって独立して投稿されていました。私のアルゴリズムは同じですが、これは正直な盗作ではありませんでした!また、別のJavaScriptの回答も投稿されています。誰かのつま先を踏んでいるとすみません。

編集:edc65のおかげで8バイト保存されました。


あなたは誰かのつま先をまったく踏んでいません。これは良い答えであり、素晴らしい仕事です。:)
アレックスA.

いいね、あなたは@ edc65を破った!それはほとんど起こりません。
ママファンロール

あなたは私の票を持っています。あなたも私を打ち負かすためにclz32関数を使うべきだと思います。
edc65

1<<31>>>32ゼロだけだったら、さらに4バイト節約できました。
ニール

5

C、144バイト

#include <strings.h>
#include <stdio.h>
m[2],l,i;main(v){while(scanf("%d",&v)==1)m[l<v]|=(i++&&v^l)<<~-fls(v^l),l=v;printf("%d",*m&m[1]?-1:*m);}

これはほぼ標準のC99です(いくつかのint指定子が欠落しており、1つの引数がありますmain)。また0<<-1、0であることにも依存します(少なくともClangでコンパイルした場合は正しいようです—他の人はテストしていません)

私はJakubeの方法を採用し、Cに移植しました。Cのサイズが驚くほどうまくいくと思います。また、超高速(大規模な4を含むすべてのテストファイルを実行するのに0.061秒)です。STDINから入力を受け取り、一致する値または-1をSTDOUTに出力するため、次のいずれかで実行します。

echo "4 7 6 1 0 0 3" | ./xort
./xort < file.txt

壊す:

// Globals initialise to 0
m[2],                                    // Stores our bit masks
                                         // (m[0]=CHANGE, m[1]=MUST NOT CHANGE)
l,                                       // Last value
i;                                       // Current iteration
main(v){
    while(scanf("%d",&v)==1)             // Read each value in turn
        m[l<v]|=                         // If they are sorted, we mark a bit as
                                         // MUST NOT CHANGE (m[1]), otherwise we
                                         // mark as CHANGE (m[0])
                (i++&&v^l)               // If this is the first iteration,
                                         // or the value is unchanged, mark nothing
                          <<~-fls(v^l),  // Mark the highest bit which has changed
                                         // = (1<<(fls(v^l)-1)
        l=v;                             // Update last value
    printf("%d",
                *m&m[1]                  // Check if result is valid (if any bits
                                         // are both MUST NOT CHANGE and CHANGE,
                                         // it is not valid)
                       ?-1               // Print -1 on failure
                          :*m);          // Print value on success
}

4

ジュリア、124バイト

f(x,g=0)=issorted(([g|=2^Int(log2(h1)for h=map(k->k[1]$k[2],filter(j->j[1]>=j[2],[x[i-1:i]for i=2:endof(x)]))];g)$x)?g:-1

これは、整数配列を受け入れて整数を返す関数です。ジャクベのアプローチを使用します。

ゴルフをしていない:

function f{T<:Integer}(x::Array{T,1}, g::T=0)
    # Get all pairs of elements in the input array
    pairs = [x[i-1:i] for i = 2:endof(x)]

    # Filter to pairs in descending order
    desc = filter(j -> j[1]  j[2], pairs)

    # Map XOR over these pairs
    xord = map(k -> k[1] $ k[2], desc)

    # For each element of this array, update the
    # parameter g (which defaults to 0) as the
    # bitwise OR of itself and 2^floor(log2(element))
    for h in xord
        g |= 2^Int(log2(h) ÷ 1)
    end

    # If the array constructed as g XOR the input is
    # sorted, we've found our answer! Otherwise -1.
    return issorted(g $ x) ? g : -1
end

好奇心から、なぜXOR $ですか?
コメアリンガーアーイング

3

Python 2、204バイト

def f(a):
 m=n=0
 for i in range(32):
  b=2**(31-i);m|=b
  for n in[n,n|b]:
   if not q(a,m,n):break
  else:return-1
 return n
def q(a,m,n):
 if a:p=a[0]&m^n
 for t in a:
  t=t&m^n
  if t<p:return 1
  p=t

入力はリストとして関数fに渡されます。

このコードは、最上位ビットから始めて、Nの値(プログラムではnという名前)を一度に1ビットずつ計算します。(「for i」ループ)

各ビット位置について、「for n」ループは最初にnのそのビットに0を使用しようとします。それが機能しない場合、1を使用しようとします。これらのどちらも機能しない場合、解決策はありません。else節は、ifステートメントではなく「for n」ループ上にあることに注意してください。Pythonでは、forステートメントにelse節を含めることができます。else節は、ループが完了するまで実行された後に実行されますが、ループから抜け出すと実行されません

q関数は、リスト(a)、ビットマスク(m)、およびリスト内の各値とxorされる値(n)を指定して、リストの順序に関する問題をチェックします。順序付けに問題がある場合は1を返し、順序に問題がない場合はNoneを返します。デフォルトの戻り値はなしですので、数文字節約できました。

このコードは、空のリストまたは1要素のリストを正しく処理し、0を返します。関数qの「if a:」は、リストが空の場合のIndexError例外を回避するためだけにあります。したがって、空のリストを処理する必要がない場合は、さらに5バイトを削除できます。

私のコンピューターでは、大規模なテストケース#3に0.262秒かかりました。#2もほぼ同じです。すべてのテストケースは一緒に0.765秒かかりました。


1
空のリストを処理する必要はありません。それを明確にします。
マーティンエンダー

3

CJam、37バイト

q~_2ew{:>},{:^2mLi2\#}%0+:|_@f^_$=\W?

ここでテストしてください。

これは、他のいくつかの回答と同じアルゴリズムを使用します。基本的には、テストケースの作成に使用したリファレンス実装です。ただし、問題のあるペアのみをチェックし、結果を並べ替えて単純に試すというJakubeのトリックを盗みました。これは擬似線形性を壊しますが、O(n log n)はテストケースに対して十分に高速です。私の元のコードは、すでに順番に並んでいるペアもチェックし、相対的な順序を維持するために切り替えてはならないビットのリストを作成し、最後に2つのビットマスクの間に重複がないことを確認しました。このアルゴリズムは、元々Ben Jacksonによって提案されました。


2

Python 2、226 214バイト

昨日作成したシンプルなアルゴリズムで、今日もゴルフをしました。

o=input()
s=sorted
p=s(set(o),key=o.index)
n=q=0
while 1:
 a=1
 while 1-q and p[0]<p[1]:p=p[1:];q=len(p)==1
 if q:break
 while not p[0]^a<p[1]^a:a*=2
 n+=a;p=[i^a for i in p]
t=[a^n for a in o]
print[-1,n][s(t)==t]

ゴルフをしていない:

def xor(a,b): return a^b

def rm_dupes(seq):
    seen = set()
    seen_add = seen.add
    return [x for x in seq if not (x in seen or seen_add(x))]

def rm_sorted(seq):
    while seq[0] < seq[1]:
        seq = seq[1:]
        if len(seq) == 1: return seq
    return seq

inp = input()
oi = inp

inp = rm_dupes(inp)
n=0
old_inp=0
while old_inp != inp:
    old_inp = inp
    inp = rm_sorted(inp)
    if len(inp)==1:break
    highest_set0 = len(bin(inp[0]))-3 # bin returns in form 0bxxx
    highest_set1 = len(bin(inp[1]))-3 # bin returns in form 0bxxx
    if highest_set1 == 0:
        try:
            t0 = max(int(bin(inp[0])[3:], 2), 1)
        except ValueError: toggle_amount = 1
        else: toggle_amount = t0^inp[0]
    else:
        fallen = False
        for i in xrange(max(highest_set0,highest_set1)+1):
            toggle_amount = 2**i
            if inp[0]^toggle_amount < inp[1]^toggle_amount:
                fallen = True
                break
        assert(fallen)
    n+=toggle_amount
    inp = [i^toggle_amount for i in inp]

out=map(xor, oi, [n]*len(oi))
if sorted(out)==out :print n
else:print -1

2

C、312バイト

#define R return
t,i,*b;f(int*a,int l,int k){int s=a[0]>>k&1,j=-1,i=1;if(k<0)R 0;for(;i<l;++i){t=a[i]>>k&1;if(s!=t)if(j<0)j=i,s=t;else R 1;}if(j<0)R f(a,l,k-1);else{if(s+b[k]==2)R 1;b[k]=s+1;R f(a,j,--k)||f(a+j,l-j,k);}}h(int*a,int l){int c[32]={0};b=c;if(f(a,l,30))R -1;t=0;for(i=0;i<32;++i)t|=(b[i]&1)<<i;R t;}

h(int*a,int l)配列へのポインターとその長さをとる関数を定義します。これがテストプログラムの巨人です。

わずかに未使用:

int t, i, *b;

int f(int * a, int l, int k) {
    int s = a[0] >> k & 1;
    int j = -1;
    int i = 1;
    if (k < 0) return 0;
    for (; i < l; ++i) {
        t = a[i] >> k & 1;
        if (s != t) {
            if (j < 0) {
                j = i;
                s = t;
            } else return 1;
        }
    }
    if (j < 0) {
        return f(a, l, k - 1);
    } else {
        if (s + b[k] == 2) return 1;
        b[k] = s + 1;
        return f(a, j, --k) || f(a + j, l - j, k);
    }
}

int h(int * a, int l) {
    int c[32] = {0};
    b = c;
    if (f(a, l, 30)) return -1;
    t = 0;
    for (i = 0; i < 32; ++i) {
        t |= (b[i] & 1) << i;
    }
    return t;
}

2

Mathematica、99 97文字

アドバイスをくれたMartinBüttnerに感謝します。

x@l_:=If[OrderedQ[l~BitXor~#],#,-1]&@Fold[#+#2Boole@!OrderedQ@⌊l~BitXor~#/#2⌋&,0,2^32/2^Range@32]

説明:

Nゼロから開始して複数回変更を試み、候補を検証するテストを行いNます。

ステップ1.これらの数値(32ビット整数)を「xor」でN= 0現在)で除算し、2^31次で除算します⌊l~BitXor~#/#2⌋。3つのケースがあります。

  • 注文された、例えば{0, 0, 1, 1, 1, 1, 1, 1};
  • 修正できます{1, 1, 1, 1, 0, 0, 0, 0}
  • その他、例えば{0, 0, 1, 0, 0, 1, 1, 1}

我々はに何もしないN最初のケースのために、あるいは我々は、追加2^31するN第二ケースの注文を修正するために:#+#2Boole@!OrderedQ@...。3番目のケースについては、リストを修正することはできません。したがって、単純化するために(または何でも)追加2^31Nます。

ステップ2.これらの数値をで「xor」Nで除算し2^30ます。再び3つのケースがあります。

  • 注文された、例えば{0, 1, 2, 2, 2, 2, 3, 3};
  • 修正できます{1, 1 , 0, 0, 3, 2, 2, 2}
  • その他、例えば{3, 3, 1, 3, 2, 0, 1, 0}

我々はに何もしないN最初のケースのために、あるいは我々は、追加2^30するN第二ケースの注文を訂正します。それ以外の場合、Xortingは不可能であることがわかります。したがって、単純化のために再度追加2^30Nます。

ステップ3〜32我々再帰的にこれらの数字は「XOR」によるED取得Nとで割りました2^292^28、...、 2^0。同様のことを行います:Fold[...,0,2^32/2^Range[32]]

ステップ33.これでようやく候補者が得られNます。リストが実際にソートIf[OrderedQ[l~BitXor~#],#,-1]&されているかどうかを確認するために使用されNます。リストが一部によってxortingできる場合、N常に最初または2番目のケースに遭遇することを証明することは難しくありません。


2

Perl 6、79バイト

時間制限がなければ、おそらく最短のPerl 6コードは

{first {[<=] $_ X+^@_},^2*.max} # 31 bytes

代わりに、もう少し賢いことをしなければなりません。
これに戻るのにしばらく時間がかかったので、すでに良いアルゴリズムとその背後にある理由を説明する答えがありました。

{$/=0;for @_.rotor(2=>-1) ->(\a,\b){b>=a or$/+|=2**msb a+^b};$/if [<=] $/X+^@_} # 79
{
  # cheat by using a special variable
  # so there is no need to declare it
  $/=0;

  # takes the elements two at a time, backing up one
  for @_.rotor(2=>-1)
    # since that is a non-flat list, desugar each element into 2
    # terms
    ->(\a,\b){
      # if they are not sorted
      b>=a or
      # take the most significant bit of xoring the two values
      # and numeric or 「+|」 it into 「$/」
      $/+|=2**msb a+^b
    };


  # returns 「$/」 if the list is Xorted
  # otherwise returns Empty
  $/if [<=] $/X+^@_

  # 「 $/ X[+^] @_ 」
  # does numeric xor 「+^」 between 「$/」
  # and each element of the original list 「@_」
}

使用法:

# give it a lexical name for ease of use
my &code = {...}

say code [8,4,3,2,1];     # 15

say code [4,7,6,1,0,3]; # 5
say code [4,7,1,6,0,3]; # ()
say code [0,1,3,4,6,7]; # 0
say code [4,2,3,1];     # 6
say code [2,3,0,0,7,7,4,5,11,11]; # 2
say code [2,3,0,0,7,7,5,4,11,11]; # ()
say code [1086101479,748947367,1767817317,656404978,1818793883,1143500039]; # ()

# the example files
for 'testfiles'.IO.dir.sort».comb(/«\d+»/) {
  printf "%10s in %5.2f secs\n", code( @$_ ).gist, now - ENTER now;
}
#         () in  9.99 secs
#          0 in 11.70 secs
# 1096442624 in 13.54 secs
#         () in 11.44 secs

1

Mathematica 650415 194バイト

この挑戦はXor、私が考えもしなかったことについてかなり理解するのに役立ちました。コードを削るのに長い時間がかかりましたが、努力する価値がありました。

BitXor基数10の数値に直接作用します。これにより、以前のバージョンからコードが大幅に削減されました。

ロジックは簡単です。1つは、いくつかの提出のように数字のペアではなくBitXor、現在の「キー」で編集された後の数字の完全なセットで機能します。

暫定的な解決策、つまりゼロの「キー」から始めます。つまり、すべてのビットがゼロです。元のn数値がBitXor0で編集されると、変更されずに返されます。番号の順序をrange 1, 2, ...nと関連付けます。これは、完全に順序付けられたリストを表します。-1から1の間の値を持つ相関関係は、数字の順序を反映しています。

次に、hiビットを設定し、新しいキー、およびBitXor現在の数字のセットを持つキーを取得します。数値の新しいシーケンスと完全に順序付けられたリストとの相関関係が改善される場合は、ビットを設定したままにしてください。そうでない場合は、ビットを未設定のままにします。

この方法で、高ビットから低ビットに進みます。最良の相関が1である場合、キーはソリューションです。そうでない場合、-1です。

たとえば、解決策が見つかったらすぐにプロセスを中断するなど、コードをもう少し効率的にする方法がありますが、これにはより多くのコーディングが必要であり、現在のアプローチはそのまま非常に高速です。(最後の最長のテストケースには20ミリ秒かかります。)

c@i_:=Correlation[Ordering@i,Range[Length[i]]]//N;
t@{i_,k_,b_,w_}:=(v= c@BitXor[i,m=k+2^(b-1)];{i,If[v>w,m,k],b-1,v~Max~w})
g@i_:= (If[#4==1,#2,-1] &@@Nest[t,{i,0,b=1+Floor@Log[2,Max@i],x=c@i},b])

g[{4, 7, 6, 1, 0, 3}]

5


g[{4, 7, 1, 6, 0, 3}]

-1


g2@{0, 1, 3, 4, 6, 7}

0


g@{1922985547, 1934203179, 1883318806, 1910889055, 1983590560, 1965316186,2059139291, 2075108931, 2067514794, 2117429526, 2140519185, 1659645051, 1676816799, 1611982084, 1736461223, 1810643297, 1753583499, 1767991311, 1819386745, 1355466982, 1349603237, 1360540003, 1453750157, 1461849199, 1439893078, 1432297529, 1431882086, 1427078318, 1487887679, 1484011617, 1476718655, 1509845392, 1496496626, 1583530675, 1579588643, 1609495371, 1559139172, 1554135669, 1549766410, 1566844751, 1562161307,1561938937, 1123551908, 1086169529, 1093103602, 1202377124, 1193780708, 1148229310, 1144649241, 1257633250, 1247607861, 1241535002, 1262624219, 1288523504, 1299222235,840314050, 909401445, 926048886, 886867060, 873099939, 979662326,963003815, 1012918112, 1034467235, 1026553732, 568519178, 650996158,647728822, 616596108, 617472393, 614787483, 604041145, 633043809, 678181561, 698401105, 776651230, 325294125, 271242551, 291800692, 389634988, 346041163, 344959554, 345547011, 342290228, 354762650, 442183586, 467158857, 412090528, 532898841, 534371187, 32464799, 21286066, 109721665, 127458375, 192166356, 146495963, 142507512, 167676030, 236532616, 262832772}

1927544832


1

Add ++125 119バイト

D,g,@@,BxBBBDbU1€oB]BJ2$Bb1+
D,j,@,bUBSVcGbU£{g}B]BkAbUBSVcGbU£>B]BKBcB*¦Bo2/i
L!,B#a=
D,f,?!,{j}Vad{j}BF€Bx1]G$0=-1$Qp

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

私は実際にAdd ++がこれを行うことができることを本当に誇りに思っており、ここでは最長の解決策ではありません

f各要素を個別の引数としてとる関数を宣言します(例$f>4>2>3>1

使い方

人々を締めつける、それは長い乗り物になるだろう

D,g,@@,		; Declare a function 'g'
		; Example arguments: 		[4 7]
	Bx	; Xor;			STACK = [3]
	BB	; To binary;		STACK = [11]
	BD	; Digits;		STACK = [[1 1]]
	bU	; Unpack;		STACK = [1 1]
	1€o	; Replace 0s with 1s;	STACK = [1 1]
	B]	; Wrap;			STACK = [[1 1]]
	BJ	; Concatenate;		STACK = ['11']
	2$Bb	; From binary;		STACK = [3]
	1+	; Increment;		STACK = [4]
		;			Return   4

D,j,@,		; Declare a function 'j'
		; Example argument:		[[4 7 6 1 0 3]]
	bU	; Unpack;		STACK = [4 7 6 1 0 3]
	BS	; Overlapping pairs;	STACK = [4 7 6 1 0 3 [[4 7] [4 6] [6 1] [1 0] [0 3]]]
	VcG	; Keep first element;	STACK = [[[4 7] [4 6] [6 1] [1 0] [0 3]]]
	bU	; Unpack;		STACK = [[4 7] [4 6] [6 1] [1 0] [0 3]]
	£{g}	; Apply 'g' over each;	STACK = [4 2 8 2 4]
	B]	; Wrap;			STACK = [[4 2 8 2 4]]
	Bk	; Global save;		STACK = []		; GLOBAL = [4 2 8 2 4]
	A	; Push arguments;	STACK = [[4 7 6 1 0 3]]
	bU	; Unpack;		STACK = [4 7 6 1 0 3]
	BSVcGbU	; Overlapping pairs;	STACK = [[4 7] [4 6] [6 1] [1 0] [0 3]]
	£>	; Greater than each;	STACK = [0 1 1 1 0]
	B]	; Wrap;			STACK = [[0 1 1 1 0]]
	BK	; Global get;		STACK = [[0 1 1 1 0] [4 2 8 2 4]]
	BcB*	; Products;		STACK = [[0 2 8 2 0]]
	¦Bo	; Reduce by logical OR;	STACK = [10]
	2/i	; Halve;		STACK = [5]
		;			Return   5

L!,		; Declare 'lambda 1'
		; Example argument:		[[1 2 3 4 5]]
	B#	; Sort;			STACK = [[1 2 3 4 5]]
	a=	; Equal to argument;	STACK = [1]
		; 			Return   1

D,f,?!,		; Declare a function 'f'
		; Example arguments:		[[4 7 6 1 0 3]]
	{j}	; Call 'j';		STACK = [5]
	V	; Save;			STACK = []		; REGISTER = 5
	ad	; Push arguments twice;	STACK = [[4 7 6 1 0 3] [4 7 6 1 0 3]]
	{j}	; Call 'j';		STACK = [[4 7 6 1 0 3] 5]
	BF	; Flatten;		STACK = [4 7 6 1 0 3 5]
	€Bx	; Xor each with 5;	STACK = [1 2 3 4 5 6]
	1]	; Call 'lambda 1';	STACK = [1]
	G$	; Retrieve REGISTER;	STACK = [5 1]
	0=	; If equal to 0:
	-1$Q	;   Return -1
	p	; Else, pop condition;	STACK = [5]
		;			Return   5

1

スタックス、29 バイト

¬√▬ⁿ{j╔■α√ï(íP♫_z(.▀ng▒JU↨@b┬

オンラインで実行してデバッグします!

@RainerPのソリューションを使用します(ビットパーツを個別に反転しますが、その32rrパーツを使用します)。

線形時間の複雑さ。

解凍されたバージョンを使用して説明します。

32rr{|2Y;{y/m:^!c{,{y|^m~}Mm,:^ud:b
32rr                                   Range [32,31..0]
    {                      m           Map each number `k` in the range with
     |2Y                                   `2^k`
        ;{y/m                              Map each number `l` in the input to `floor(l/2^k)`
             :^!                           The mapped array is not non-decreasing
                                           This is the binary digit `l` is mapped to
                c{       }M                If that's true, do
                  ,{y|^m~                  Flip the corresponding bit of every element in the input
                            ,:^        The final array is sorted
                               ud      Take inverse and discard, if the final array is not sorted this results in zero-division error
                                 :b    Convert mapped binary to integer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.