对数组进行异化


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)参数输出结果。

输入可以是任何方便的列表或字符串格式。您可以假设小于个,并且列表包含至少一个元素。ai231

您的代码必须在几秒钟内处理任何测试用例(尤其是四个大型用例)。

适用标准规则。

测试用例

对于每个不返回的测试用例,-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

最后,这里有四个非常大的测试用例,以确保提交足够有效:

为什么有人会这样做?

几天前,我想到XOR操作可以对数组进行“排序”,这使得可以在O(log n)中对数组执行二进制搜索而不必先对其进行排序。似乎可以N在伪线性时间内确定,这将使其成为大多数排序算法的较快替代方法,并且不具有基数排序的内存要求。当然,通过未排序数组进行直线线性搜索会更快,但如果要多次搜索同一数组,则一次线性预计算可以大大减少每次搜索所需的时间。

不幸的是,此列表适用的类别非常有限(一致的随机分布不太可能接受N)。

一个有趣的问题是是否还有其他易于检查和/或适用于更广泛列表类别的双射函数。


42
Xorting ”是一个很酷的名字。
2015年

7
@insertusernamehere功劳归于randomra。
马丁·恩德

3
一个非常有趣的挑战!
DavidC

4
Paebbels:假设您具有Xorting键,则可以计算原始值。出于此目的(二进制搜索),您可以将输入与键进行XOR运算,然后检查其是否存在于“ sorted”数组中。当然,这是一种排序,但是要选择的关系/功能是按每个元素的位置保持不变的方式选择的。
meiamsome

8
@Paebbels我从未宣称这是排序。我用一个虚构的词来称呼它,您引用的段落中的引号是“排序”的,这是有原因的。我的观点是,这是一个双射变换,可以将数组某些操作(例如二进制搜索)进行排序,而不必实际对其进行排序。
马丁·恩德

Answers:


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的答案相同的方法,但是我的实现有些不同。

Jelly还没有排序,因此我们计算一个xorting候选对象,将其与输入列表进行XOR,计算XORed列表的xorting候选对象,并检查新的候选对象是否为零。如果是这样,我们将打印第一个候选对象;否则,我们打印-1

而且,Jelly似乎还没有健全的方法来强制转换为整数(即​​使整数除法也可以返回浮点数),因此我不得不想出一种相当新颖的方法将数字列表四舍五入到下一个2的幂。我没有将log-floor-pow转换为二进制,而是将所有整数转换为二进制,将所有二进制数字替换为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]

前两个数字已经错误(7 > 2)。我们想对某个数字进行异或运算以更改不等式符号(7 xor X < 2 xor X)。由于xor在二进制表示形式上进行操作,因此请查看它们。

7 = 1 1 1
2 =   1 0

当我们对每个数字应用某个数字的xor时,某些位置的值将改变。如果更改第一个位置(2^0)的值,则不等式符号不会更改。当我们更改第二个位置(2^1)的值时,也会发生同样的事情。此外,如果我们在第四变化值,第五符号不会改变,...位置(2^32^4,...)。如果我们更改第三个位置(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

如果我们一次更改多个职位,当然会发生同样的事情。如果我们更改的任何位置都是第三个位置,则不平等符号更改,否则不更改。

下一对已经排序:2 < 13。如果我们查看二进制表示形式,我们会注意到,我们可以对其进行异或运算,并且不等式符号仍然正确,除非更改了第四个位置(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

因此,我们不想更改第四个位置。对于下一对,我们想更改一些东西,因为13 > 9。在这里,我们再次必须更改第三个位置。

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

现在回顾一下:要结束排序列表,我们再次必须更改第三个位置,并且不想更改第四个位置。其他所有职位都无关紧要。最小的数字就是4 = 0100。其他选择是5 = 01016 = 01107 = 011120 = 1010021 = 10101,...

与异或4会导致列表[3, 6, 9, 13],具有6会得到[1, 4, 11, 15]21会得到[18, 23, 24, 28]

因此,对于列表,我们需要找到位置,如果位置不正确,则将改变不等式符号。我们仅通过取对中异或的最高有效位来找到位置。我们将所有这些位置(与或)相结合得出一个候选号码。我们检查是否没有意外破坏已经排序的对。

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
我为这种干净,简单的解决方案的存在而感到遗憾
quintopia

如果您能解释一下为什么这对我们这些数学上比较钝的人有用,那就太好了。我理解所有步骤,但不太明白为什么每个异或降序对的按位或MSB都是正确的值。
路加福音

1
@Luke添加了详细的解释。希望它会有所帮助。
雅库布

精彩的解释!
edc65

1
如果保留2个二进制值,必须更改的位和不必更改的位,那么您的最终结果将没有更多迭代
edc65 2015年

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的bit []函数。但是以列表为例[4,4,4],尝试进行评估时会出现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]用buildin替换了我自己的实现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:[])
Alex A.15年

8

的JavaScript(ES6)85 97 114 117

编辑删除愚蠢,最后没用的AND
Edit2高位搜索缩短了
Edit3哇!我发现ES6(几乎)具有内置功能来查找最高位(Math.clz32计算最高的0位)

这基于@Jakube的解决方案(请支持)。我永远找不到自己。

在这里,我前进了一步,对列表进行了一次迭代,并对必须翻转的位保留了位掩码,对必须翻转的位保留了另一个掩码。

如果位掩码重叠,则不可能解决,否则解决方案是“翻转位”

由于javascript中的二进制运算仅对32位有符号整数有效,因此返回值是32位整数,可以为负或0。

如果没有解决方案,则返回值为“ 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独立发布;我的算法是一样的,但这不是honest窃。此外,我还注意到,自那时以来也发布了另一个JavaScript答案。抱歉,如果我踩到任何人的脚趾。

编辑:由于edc65,节省了8个字节。


您根本不会踩任何人的脚趾。这是一个很好的答案,很好的工作。:)
Alex A.

很好,您击败了@ edc65!那几乎永远不会发生。
Mama Fun Roll'1

你有我的票。我认为您也应该使用clz32函数再次击败我。
edc65 '16

如果只有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<<-10(至少使用Clang编译时似乎是正确的-我还没有测试其他代码)

我已经采用了Jakube的方法并将其移植到C。我认为它在C尺寸方面确实非常好。它也超快(运行所有测试文件(包括大量4个文件)的速度为0.061s)。它从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

这是一个接受整数数组并返回整数的函数。它使用Jakube的方法

取消高尔夫:

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 $
caird coinheringaahing

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)。(“ for i”循环)

对于每个位位置,“ for n”循环首先尝试对n的该位使用0。如果这不起作用,它将尝试使用1。如果这些都不起作用,则没有解决方案。请注意,else子句位于“ for n”循环中,而不是if语句中。在Python中,for语句可以包含else子句,该子句在循环运行完成后执行,但如果我们退出循环,则不会执行。

q函数检查给定列表(a),位掩码(m)以及要与列表中的每个值进行异或的值(n)的列表顺序是否存在问题。如果订购有问题,则返回1;如果订购正常,则返回None。默认返回值是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)对于测试用例仍然足够快。我的原始代码还检查了已经按顺序排列的对,并建立了一个不可切换的位列表以保持它们的相对顺序,最后检查了两个位掩码之间没有重叠。该算法最初由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位整数),这些数字N= 0现在)被“异或” 并除以2^31⌊l~BitXor~#/#2⌋。有以下三种情况:

  • 订购,例如{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^31N纠正第二种情况的顺序:#+#2Boole@!OrderedQ@...。对于第三种情况,我们不可能对列表做任何修改,因此为了简单起见,我们只是添加2^31N(或其他任何东西!)。

步骤2.我们得到这些数字“ xor”,N然后除以2^30。再有三种情况:

  • 订购,例如{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^30N纠正第二种情况的顺序。否则,我们意识到xorting是不可能的,因此为了简单起见,我们只添加2^30了xor N

步骤3到32。我们递归地得到这些数字“ ,” ,“ ... ” N和“ xor” 。并做类似的事情:2^292^282^0Fold[...,0,2^32/2^Range[32]]

步骤33。现在我们终于找到了候选人NIf[OrderedQ[l~BitXor~#],#,-1]&用于检查N列表是否确实如此。如果列表可以被某些人处理N,则不难证明我们将始终遇到第一种或第二种情况。


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

数学650 415 194字节

这个挑战使我对Xor自己从未想过的东西有了相当多的了解。花了很长时间缩减代码,但是值得付出努力。

BitXor直接以10为基数工作。这大大减少了早期版本中的代码。

逻辑很简单。一个作品,不是用成对的数字(就像一些提交的那样),而是用BitXor当前的“密钥”编辑后的完整的数字集。

从试探性解决方案开始,即“关键字”为零,即所有位均为零。如果原始n数字的BitXored为零,则将它们原封不动地返回。将数字的顺序与range关联起来,范围1, 2, ...n代表一个完美排序的列表。该相关性的值在-1和1之间,反映了数字排序的程度。

然后将hi位置1,获取新的密钥,以及BitXor具有当前数字集的密钥。如果新的数字序列和完美排序的列表之间的相关性有所改善,请保持该位置位。如果没有,请保持该位不变。

以这种方式从hi到低位。如果最佳相关性是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

添加++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

Stax,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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.