Xorting массив


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 " - это действительно классное название для этого.
insertusername здесь

7
@insertusernamehere Кредиты для этого идут на randomra.
Мартин Эндер,

3
Чрезвычайно интересный вызов!
DavidC

4
Паеббельс: при условии, что у вас есть ключ Xorting, можно рассчитать исходное значение. Для целей здесь (бинарный поиск) вы должны XOR ввести ключ и затем проверить, существует ли он в «отсортированном» массиве. Это, конечно, сортировка, но отношение / функция, по которой вы сортируете, выбрана, если позиция каждого элемента остается неизменной.
meiamsome

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 , но моя реализация немного отличается.

У Jelly пока нет сортировки, поэтому мы вычисляем кандидата на сортировку, XOR входного списка вместе с ним, вычисляем кандидата на сортировку списка XORed и проверяем, равен ли новый кандидат нулю. Если это так, мы печатаем первого кандидата; в противном случае мы печатаем -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). Мы хотим сделать 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. Если мы посмотрим на двоичное представление, мы заметим, что мы можем сделать что-то для него, и символ неравенства по-прежнему правильный, кроме случаев, когда мы меняем четвертую позицию ( 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 будет правильным значением.
Люк

1
@Luke Добавил длинное объяснение. Надеюсь, это поможет.
Якуб

Замечательное объяснение!
edc65

1
Если вы сохраняете 2 двоичных значения, биты, которые должны измениться, и биты, которые не должны изменяться, то у вас будет конечный результат без
повторов

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, но, как вы говорите, для случайных данных вряд ли найдется подходящее значение.


Хорошее решение, мне нравится инициализация массива и функция bit [] в ruby. Но попробуйте, например, список [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}
BluTrange

Действительно, хороший улов!
гистократ

11

Юлия, 174 144 77 75 71

[ПРАВКА] Спасибо Алексу А. за анонимность и различные сокращения.
[РЕДАКТИРОВАТЬ 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 байт:l->(r=0;s=issorted;for d=63:-1:0 s((l$r).>>d)||(r$=2^d)end;s(l$r)?r:[])
Алекс А.

8

JavaScript (ES6) 85 97 114 117

Редактировать Удален глупый, бесполезный последний И
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; мой алгоритм такой же, но это не был честный плагиат! Также я заметил, что с тех пор был опубликован еще один ответ JavaScript. Извините, если я наступаю на чьи-то пальцы.

Редактировать: 8 байтов сохранено благодаря edc65.


Вы не наступаете ни на чьи пальцы. Это хороший ответ, хорошая работа. :)
Алекс А.

Хорошо, ты победил @ edc65! Это почти никогда не происходит.
Mama Fun Roll

У тебя есть мой голос. Я думаю, что вы тоже должны использовать функцию 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<<-10 (что, по крайней мере, верно при компиляции с Clang - другие я не тестировал)

Я взял метод Якуба и портировал его на C. Я думаю, что он удивительно хорош по размеру для C. Он также очень быстр (0,061 с для запуска всех тестовых файлов, включая массивную 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

Юлия, 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

Это функция, которая принимает массив целых чисел и возвращает целое число. Он использует подход Якуба .

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 Coneheringaahing

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 n сначала пытается использовать 0 для этого бита n. Если это не работает, он пытается использовать 1. Если ни один из этих способов не работает, то решения не существует. Обратите внимание, что предложение else находится в цикле for n, а не в операторе if. В Python оператор for может содержать предложение else, которое выполняется после завершения цикла, но не выполняется, если мы вырвемся из цикла.

Функция q проверяет наличие проблем с порядком списка по списку (a), битовой маске (m) и значению, которое необходимо записать для каждого значения в списке (n). Возвращает 1, если есть проблема с заказом, или None, если заказ в порядке. Ничто не является возвращаемым значением по умолчанию, так что спасло меня несколько символов.

Этот код обрабатывает пустой список или список с 1 элементом правильно, возвращая 0. «if a:» в функции q существует только для того, чтобы избежать исключения IndexError, когда список пуст. Таким образом, можно удалить еще 5 байтов, если обработка пустых списков не требуется.

На моем компьютере большой тестовый пример № 3 занял 0,262 секунды. # 2 взял примерно то же самое. Все тестовые случаи вместе заняли 0,765 секунды.


1
Обработка пустых списков не требуется, я проясню это.
Мартин Эндер

3

CJam, 37 байт

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

Проверьте это здесь.

При этом используется тот же алгоритм, что и несколько других ответов. По сути, это моя эталонная реализация, которую я использовал для создания тестовых случаев. Однако я украл уловку Якуба, проверяя только пары-нарушители и просто пробуя результат с сортировкой. Это нарушает псевдолинейность, но O (n log n) все еще достаточно быстр для тестовых случаев. Мой оригинальный код также проверил пары, которые уже в порядке, и составил список битов, которые не должны переключаться, чтобы сохранить их относительный порядок, и в конце проверил, что между двумя битовыми масками нет перекрытий. Этот алгоритм был первоначально предложен Беном Джексоном .


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]

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)принимающую указатель на массив и его длину. Вот тестовая программа Бегемот.

Слегка разгульный

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 персонажей

Спасибо Мартину Бюттнеру за советы.

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^31к Nкорректировать порядок для второго случая: #+#2Boole@!OrderedQ@.... В то время как для третьего случая невозможно отсортировать список, что бы мы ни делали, поэтому мы просто добавляем 2^31к нему Nдля простоты (или чего-то еще!).

Шаг 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^30к Nкорректировать порядок для второго случая. В противном случае, мы понимаем , что xorting невозможно, поэтому мы просто добавить 2^30к Nдля простоты снова.

Шаг 3 ~ 32. Мы рекурсивно получить эти цифры «исключающее» под редакцией Nи разделены 2^29, 2^28, ..., 2^0. И делать похожие вещи:Fold[...,0,2^32/2^Range[32]]

Шаг 33. Теперь мы наконец получили кандидата N. If[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

Mathematica 650 415 194 байта

Этот вызов помог мне понять немного о Xorтом, о чем я никогда не думал. Сокращение кода заняло много времени, но оно того стоило.

BitXorработает непосредственно на базе 10 номеров. Это значительно сократило код из более ранних версий.

Логика проста. Один работает не с парами чисел (как это делали некоторые представления), а с полным набором чисел после BitXorредактирования с текущим «ключом».

Начнем с примерного решения или «ключа» с нуля, то есть со всеми битами равными нулю. Когда исходные nчисла BitXorобнуляются, они возвращаются без изменений. Соотнесите порядок чисел с диапазоном 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

Добавить ++ , 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.