Xorting Array


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 (หรือทางเลือกที่ใกล้เคียงที่สุด), ค่าส่งคืนของฟังก์ชันหรือพารามิเตอร์

อินพุตอาจอยู่ในรายการที่สะดวกหรือรูปแบบสตริง คุณอาจสันนิษฐานว่ารายการนั้นน้อยกว่าแต่ละรายการและรายการนั้นมีองค์ประกอบอย่างน้อยหนึ่งรายการ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ในเวลา pseudolinear ซึ่งจะทำให้เป็นทางเลือกที่เร็วกว่าอัลกอริทึมการเรียงลำดับส่วนใหญ่และมันไม่ได้มีความต้องการหน่วยความจำของการเรียงลำดับแบบ Radix แน่นอนว่าการค้นหาแบบเส้นตรงผ่านอาเรย์ที่ไม่ได้เรียงลำดับจะเร็วขึ้น แต่ถ้าคุณต้องการค้นหาอาเรย์เดียวกันหลายครั้งการคำนวณเชิงเส้นก่อนเดี่ยวสามารถลดเวลาที่ต้องใช้ในการค้นหาแต่ละครั้งลงอย่างมาก

น่าเสียดายที่คลาสของรายการนี้ใช้งานได้ค่อนข้าง จำกัด (การแจกแจงแบบสุ่มสม่ำเสมอไม่น่าจะยอมรับN)

คำถามที่น่าสนใจคือมีฟังก์ชัน bijective อื่น ๆ ที่ง่ายต่อการตรวจสอบและ / หรือใช้กับรายการที่กว้างขึ้น


42
" Xorting " เป็นชื่อที่ยอดเยี่ยมมากสำหรับสิ่งนั้น
insertusernamehere

7
@insertusernamehere เครดิตสำหรับการไปที่ randomra
Martin Ender

3
ความท้าทายที่น่าสนใจอย่างมาก!
DavidC

4
Paebbels: สมมติว่าคุณมี Xorting key มันเป็นไปได้ที่จะคำนวณค่าดั้งเดิม สำหรับจุดประสงค์ที่นี่ (การค้นหาแบบไบนารี่) คุณต้อง XOR อินพุตด้วยคีย์จากนั้นตรวจสอบว่ามีอยู่ในอาร์เรย์ 'เรียงลำดับ' แน่นอนว่ามันเป็นการเรียงลำดับ แต่ความสัมพันธ์ / ฟังก์ชั่นที่คุณเรียงลำดับจะถูกเลือกตำแหน่งของแต่ละองค์ประกอบจะยังคงเหมือนเดิม
meiamsome

8
@ Paebbels ฉันไม่เคยอ้างว่านี่เป็นการเรียงลำดับ ฉันเรียกมันด้วยคำที่สร้างขึ้นแล้วและย่อหน้าที่คุณอ้างถึงมี "เรียงลำดับ" ในเครื่องหมายคำพูดด้วยเหตุผล ประเด็นของฉันคือว่านี่เป็นการแปลง bijective ที่ช่วยให้อาร์เรย์ได้รับการปฏิบัติราวกับว่ามันถูกจัดเรียงสำหรับการดำเนินการบางอย่าง (เช่นการค้นหาแบบไบนารี) โดยไม่ต้องจัดเรียงจริง
Martin Ender

คำตอบ:


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แต่การนำไปใช้ของฉันนั้นแตกต่างออกไปเล็กน้อย

เยลลี่ยังไม่มีการเรียงลำดับดังนั้นเราจึงคำนวณผู้สมัคร xorting, XOR ในรายการอินพุต, คำนวณ xorting ผู้สมัครของรายการ XORed และตรวจสอบว่าผู้สมัครใหม่เป็นศูนย์หรือไม่ ถ้าเป็นเช่นนั้นเราจะพิมพ์ผู้สมัครคนแรก; มิฉะนั้นเราพิมพ์-1

นอกจากนี้เจลลี่ดูเหมือนว่าจะไม่มีทางมีสติที่จะส่งข้อมูลไปยังจำนวนเต็มเลย (แม้จะแบ่งจำนวนเต็มสามารถกลับลอย) เพื่อให้ฉันได้มาด้วยวิธีที่สร้างสรรค์มากกว่าการปัดเศษรายการตัวเลขลงไปที่อำนาจต่อไปของ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]ฉันจะทำเช่นนี้กับรายการตัวอย่างเช่น:

ตัวเลขสองตัวแรกนั้นผิด ( 7 > 2) เราต้องการ xor ที่มีตัวเลขบางส่วนเพื่อเปลี่ยนสัญลักษณ์ความไม่เท่าเทียม ( 7 xor X < 2 xor X) ตั้งแต่ xor ทำงานกับการเป็นตัวแทนไบนารีให้ดูที่พวกเขา

7 = 1 1 1
2 =   1 0

เมื่อเราใช้ xor ด้วยตัวเลขจำนวนหนึ่งกับแต่ละหมายเลขค่าที่ตำแหน่งบางตำแหน่งจะเปลี่ยนไป หากคุณเปลี่ยนค่าที่ตำแหน่งแรก ( 2^0) สัญลักษณ์ความไม่เท่าเทียมจะไม่เปลี่ยนแปลง สิ่งเดียวกันเกิดขึ้นเมื่อเราเปลี่ยนค่าที่ตำแหน่งที่สอง ( 2^1) ยังเป็นสัญลักษณ์จะไม่เปลี่ยนแปลงถ้าเราเปลี่ยนค่าที่สี่ห้า ... ตำแหน่ง ( 2^3, 2^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. ถ้าเราดูการแทนแบบไบนารีเราสังเกตว่าเราสามารถ xor อะไรก็ได้และสัญลักษณ์ความไม่เท่าเทียมยังคงถูกต้องยกเว้นเมื่อเราเปลี่ยนตำแหน่งที่สี่ ( 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 = 0101, 6 = 0110, 7 = 0111, 20 = 10100, 21 = 10101...

XORing กับ4จะส่งผลให้ในรายการ[3, 6, 9, 13]ด้วย6จะได้รับ[1, 4, 11, 15]และจะได้รับ21[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
ฉันขอเตือนสติถึงการมีอยู่ของวิธีแก้ปัญหาที่เรียบง่ายและสะอาด
quintopia

มันจะยอดเยี่ยมถ้าคุณสามารถอธิบายได้ว่าทำไมมันถึงใช้ได้กับพวกเราที่มีความป้านทางคณิตศาสตร์มากกว่า ฉันเข้าใจทุกขั้นตอน แต่ไม่เห็นเลยว่าทำไมค่าบิตหรือ MSB ของทุกคู่ลดลงของ xor'ed จะเป็นค่าที่ถูกต้อง
ลุค

1
@Luke เพิ่มคำอธิบายที่ยาว หวังว่ามันจะช่วย
Jakube

คำอธิบายที่ยอดเยี่ยม!
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 มิลลิวินาทีในกรณีทดสอบขนาดใหญ่

Ungolfed:

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 ได้ แต่อย่างที่คุณบอกว่าสำหรับข้อมูลแบบสุ่มมีค่าไม่น่าจะเป็นไปได้


ทางออกที่ดีฉันชอบการเริ่มต้นอาร์เรย์และฟังก์ชั่นบิต [] ของรูบี้ แต่ลองยกตัวอย่างเช่นรายการ[4,4,4]นี้จะให้ SyntaxError ขณะที่มันพยายามที่จะ 0beval โชคดีที่มันเกิดขึ้นกับฉันบ่อยครั้งมีวิธีอื่นในการทำสิ่งเดียวกันในจำนวนไบต์เท่ากัน สิ่งนี้ควรใช้งานได้ฉันหวังว่า:->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

จับแน่นอนดี!
ฮิสโทแกต

11

Julia, 174 144 77 75 71

[แก้ไข] ขอบคุณ Alex A. สำหรับการไม่ระบุชื่อและการจดชวเลขต่าง ๆ
[แก้ไข 2] 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 bytes:l->(r=0;s=issorted;for d=63:-1:0 s((l$r).>>d)||(r$=2^d)end;s(l$r)?r:[])
Alex A.

8

JavaScript (ES6) 85 97 114 117

แก้ไขลบโง่, ไร้ประโยชน์ล่าสุดและ
Edit2ค้นหาบิตบนสุดสั้นลง
Edit3ว้าว! ผมค้นพบว่า ES6 (เกือบ) มีในตัวเพื่อหาสิ่งที่บิตบน (Math.clz32 นับด้านบน 0 บิต)

สิ่งนี้จะขึ้นอยู่กับวิธีการแก้ปัญหาของ @Jakube (pls upvote นั้น) ฉันไม่เคยพบมันด้วยตัวเอง

ที่นี่ฉันไปหนึ่งก้าวไปข้างหน้าย้ำรายการครั้งเดียวและรักษาบิตหน้ากากที่มีบิตที่จะต้องพลิกและอีกคนหนึ่งที่มีบิตที่จะต้องเก็บไว้

หากมีการซ้อนทับกันของมาสก์บิตแล้วไม่สามารถแก้ปัญหาได้อีกวิธีหนึ่งคือ "บิตเพื่อพลิก"

เนื่องจากการดำเนินงานแบบไบนารีใน 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; อัลกอริทึมของฉันเหมือนกัน แต่นี่ไม่ได้เป็นการลอกเลียนแบบความซื่อสัตย์! นอกจากนี้ฉันสังเกตเห็นว่ามีการโพสต์คำตอบ JavaScript อื่นด้วยเช่นกัน ขออภัยถ้าฉันเหยียบนิ้วเท้าของทุกคน

แก้ไข: บันทึก 8 ไบต์ขอบคุณ edc65


คุณไม่ได้เหยียบนิ้วเท้าของใครเลย นี่เป็นคำตอบที่ดีงานที่ดี :)
Alex A.

เยี่ยมมากคุณชนะ @ edc65! ที่เกือบจะไม่เคยเกิดขึ้น
Mama Fun Roll

คุณมีคะแนนของฉัน ฉันคิดว่าคุณควรใช้ฟังก์ชั่น clz32 เพื่อเอาชนะฉันอีกครั้ง
edc65

ถ้าเพียงแค่1<<31>>>32เป็นศูนย์แล้วฉันสามารถบันทึกอีก 4 ไบต์
Neil

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 (ซึ่งดูเหมือนจะเป็นจริงเมื่อรวบรวมกับเสียงดังกราวอย่างน้อย - ฉันไม่ได้ทดสอบคนอื่น)

ฉันใช้วิธีของ Jakube แล้วส่งไปที่ C. ฉันคิดว่ามันน่าประหลาดใจที่ขนาดดีสำหรับ C. มันก็เร็วมากด้วย (0.061s สำหรับเรียกใช้ไฟล์ทดสอบทั้งหมดรวมถึง 4 ตัวใหญ่) ใช้อินพุตจาก 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

Julia, 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 ของ

Ungolfed:

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" จะพยายามใช้ 0 สำหรับบิตนั้นของ n ก่อน หากไม่ได้ผลก็ลองใช้ 1 หากไม่ได้ผลงานเหล่านี้แสดงว่าไม่มีวิธีแก้ไข โปรดทราบว่าประโยคอื่นอยู่ในลูป "for n" ไม่ใช่คำสั่ง if ใน Python คำสั่ง for สามารถมีส่วนคำสั่งอื่นซึ่งจะถูกดำเนินการหลังจากวนรอบจะเสร็จสมบูรณ์ แต่จะไม่ดำเนินการถ้าเราแยกออกจากวง

ฟังก์ชัน q ตรวจสอบปัญหาเกี่ยวกับลำดับรายการที่กำหนด list (a), bit mask (m) และค่าที่จะ xored ด้วยแต่ละค่าใน list (n) มันจะส่งกลับ 1 ถ้ามีปัญหากับการสั่งซื้อหรือไม่มีถ้าการสั่งซื้อเป็น ok ไม่มีคือค่าส่งคืนเริ่มต้นดังนั้นฉันจึงบันทึกอักขระหลายตัว

รหัสนี้จัดการรายการที่ว่างเปล่าหรือรายการที่มี 1 องค์ประกอบอย่างถูกต้องกลับ 0 "ถ้า:" ในฟังก์ชั่น q มีเพียงเพื่อหลีกเลี่ยงข้อยกเว้น IndexError เมื่อรายการว่างเปล่า ดังนั้นจึงสามารถลบได้อีก 5 ไบต์หากไม่จำเป็นต้องจัดการกับรายการที่ว่างเปล่า

บนคอมพิวเตอร์ของฉันกรณีทดสอบขนาดใหญ่ # 3 ใช้เวลา 0.262 วินาที # 2 ใช้เวลาประมาณเดียวกัน กรณีทดสอบทั้งหมดเข้าด้วยกันใช้เวลา 0.765 วินาที


1
ไม่จำเป็นต้องจัดการกับรายการว่างฉันจะอธิบายให้ชัดเจน
Martin Ender

3

CJam, 37 ไบต์

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

ทดสอบที่นี่

นี่ใช้อัลกอริทึมเดียวกันกับคำตอบอื่น ๆ เป็นหลักในการใช้งานอ้างอิงของฉันซึ่งฉันใช้ในการสร้างกรณีทดสอบ อย่างไรก็ตามฉันได้ขโมยเคล็ดลับของจากุบในการตรวจสอบคู่ที่กระทำผิดและลองใช้ผลลัพธ์ด้วยการเรียงลำดับ สิ่งนี้จะทำลาย pseudolinearity แต่O (n log n)ยังคงเร็วพอสำหรับกรณีทดสอบ รหัสเดิมของฉันยังตรวจสอบคู่ที่มีอยู่แล้วตามลำดับและสร้างรายการบิตที่ต้องไม่สลับเพื่อรักษาลำดับญาติและตรวจสอบในตอนท้ายว่าไม่มีการซ้อนทับกันระหว่างมาสก์สองบิต ขั้นตอนวิธีการนี้ได้รับการแนะนำมาโดยเบนแจ็คสัน


2

Python 2, 226 214 ไบต์

อัลกอริทึมแบบ Simpleish สร้างขึ้นเมื่อวานนี้ golfed วันนี้

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]

Ungolfed:

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)การใช้ตัวชี้ไปยังอาร์เรย์และความยาวของมัน นี่คือโปรแกรมทดสอบโปรแกรม

ungolfed เล็กน้อย:

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 ตัวละคร

ขอบคุณ Martin Büttnerสำหรับคำแนะนำ

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

คำอธิบาย:

เราจะทำหลาย ๆ พยายามที่จะปรับเปลี่ยนการเริ่มต้นจากศูนย์และทำแบบทดสอบเพื่อตรวจสอบผู้สมัครNN

ขั้นตอนที่ 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^31เพื่อที่จะแก้ไขเพื่อให้กรณีที่สอง:N #+#2Boole@!OrderedQ@...ในขณะที่กรณีที่สามเป็นไปไม่ได้ที่จะ xorting รายการสิ่งที่เราเคยทำดังนั้นเราจึงเพิ่ม2^31เพื่อNความเรียบง่าย (หรืออะไรก็ตาม!)

ขั้นตอนที่ 2.เราได้รับตัวเลขเหล่านี้ "แฮคเกอร์" เอ็ดและหารด้วย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^30เพื่อNที่จะแก้ไขเพื่อให้กรณีที่สอง มิฉะนั้นเราตระหนักดีว่า xorting เป็นไปไม่ได้ทำให้เราเพียงแค่เพิ่ม2^30การNสำหรับความเรียบง่ายอีกครั้ง

ขั้นตอนที่ 3 ~ 32.เราซ้ำได้รับหมายเลขเหล่านี้ "แฮคเกอร์" เอ็ดNและหารด้วย2^29, 2^28, ... 2^0, และทำสิ่งที่คล้ายกัน:Fold[...,0,2^32/2^Range[32]]

ขั้นตอนที่ 33Nตอนนี้เราจนได้รับผู้สมัคร If[OrderedQ[l~BitXor~#],#,-1]&จะใช้ในการตรวจสอบว่าNxorting รายการจริงหรือไม่ หากรายการสามารถ xorting โดยบาง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

Mathematica 650 415 194 ไบต์

ความท้าทายนี้ช่วยให้ฉันเข้าใจค่อนข้างเกี่ยวกับXorที่ฉันไม่เคยคิด ใช้เวลานานในการลดขนาดโค้ด แต่ก็คุ้มค่ากับความพยายาม

BitXorทำงานโดยตรงบนฐาน 10 หมายเลข นี่เป็นการลดรหัสจากเวอร์ชันก่อนหน้าอย่างมาก

ตรรกะนั้นง่าย ผลงานชิ้นหนึ่งไม่ได้มีคู่ของตัวเลข (เหมือนที่ส่งมาบางส่วน) แต่ใช้แทนชุดตัวเลขที่สมบูรณ์หลังจากBitXorแก้ไขด้วย "คีย์" ปัจจุบัน

เริ่มต้นด้วยวิธีแก้ปัญหาเบื้องต้นหรือ "สำคัญ" ของศูนย์นั่นคือกับบิตทั้งหมดเป็นศูนย์ เมื่อnตัวเลขดั้งเดิมถูกBitXored ด้วยศูนย์พวกเขาจะถูกส่งกลับไม่เปลี่ยนแปลง เชื่อมโยงการเรียงลำดับของตัวเลขด้วยช่วง1, 2, ...nซึ่งแสดงถึงรายการที่เรียงลำดับอย่างสมบูรณ์แบบ ความสัมพันธ์ที่มีค่าระหว่าง -1 ถึง 1 จะแสดงถึงการเรียงลำดับหมายเลขที่ดีเพียงใด

จากนั้นตั้งค่า hi bit รับคีย์ใหม่และBitXorคีย์พร้อมชุดตัวเลขปัจจุบัน หากความสัมพันธ์ระหว่างลำดับของตัวเลขใหม่กับรายการที่เรียงลำดับอย่างสมบูรณ์เป็นการปรับปรุงให้ตั้งค่าบิตไว้ ถ้าไม่ปล่อยให้บิต unset

ดำเนินการในลักษณะนี้ตั้งแต่ 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┬

เรียกใช้และแก้ไขข้อบกพร่องออนไลน์!

การแก้ปัญหาของ Uses @ 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.