Изучение космического пространства

14

Пространство x набора целых чисел - это множество всех целых чисел, которые можно получить, комбинируя начальные целые числа с обычным побитовым оператором xor ( ^). Например, xorspace из (8, 4)IS (0, 4, 8, 12): 0 4 ^ 4, 12 4 ^ 8, и никакие другие числа не может быть достигнуто. Обратите внимание, что начальные числа всегда включены, согласно этому определению (например, 4 равно 4 ^ 4 ^ 4).

Ваша цель - написать самую короткую программу, которая принимает список неотрицательных целых чисел в качестве входных данных и выводит количество элементов в их пространстве.

  • Стандартные лазейки запрещены.
  • Ввод и вывод могут быть в любом из обычных форматов . Вклад гарантированно будет действительным, непустым и без дубликатов.
  • Ваш код должен быть в состоянии обработать все тестовые случаи менее чем за день .

Контрольные примеры

Input: 0
Output: 1

Input: 6
Output: 2

Input: 8 4
Ouput: 4

Input: 0 256
Output: 2

Input: 256 259 3
Output: 4

Input: 60 62 94 101 115
Output: 32

Input: 60 62 94 101 115 40 91
Output: 32

Input: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
Output: 64

Input: 1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384
Output: 32768
Grimmy
источник

Ответы:

2

Pyth, 8 байт

lu{+xM*Q

Тестирование

Объяснение:

Чтобы сгенерировать xorspace, мы находим фиксированную точку взятия xor каждой пары чисел, добавления каждого числа и дедупликации. Затем мы берем длину результата. Это выполняется за 20 секунд (только в автономном режиме) в последнем тесте.

lu{+xM*Q
lu{+xM*QGGQ    Implicit variable introduction
 u        Q    Find the fixed point of the following, starting with the input,
               where the current value is G.
      *QG      Form the Cartesian product of Q (input) and G (current)
    xM         Take the xor of every pair
   +           Add the current values
  {            Deduplicate
l              Output the length of the result.

Упакованный Pyth , 7 байтов

HexDump:

0000000: d9d7 dabf 1355 51                        .....UQ

То же, что и выше, с 7-битной кодировкой ASCII.

Поместите вышесказанное в файл с помощью xxd -rи запустите его следующим образом:

py packed-pyth.py xorspace.ppyth '[256, 259, 3]'
isaacg
источник
Я думаю, что вы можете сделать l{mxFdy.
xnor
@xnor, yприменяемый к тестам с 1 по 63, слишком медленный. У меня нет 2 ^ 63 памяти.
Исаак
10

MATL , 11 байт

t"G!Z~Ghu]n

Попробуйте онлайн!

Последний тестовый пример не запускается в онлайн-интерпретаторе из-за ограничений памяти, но работает на компьютере менее чем за 2 секунды на современном компьютере.

объяснение

Для ввода размера nэто делает следующее:

  1. Инициализируйте результат для ввода.
  2. Повторите nраз:
    1. Применить побитовое XOR ко всем парам записей из текущего результата и ввода.
    2. Прикрепите входные значения к результату.
    3. Дедуплицировать.
  3. На выходе получается количество элементов конечного результата.

Код комментирования.

t      % Implicit input: row vector. Duplicate
"      % For each (i.e. do as many times as the input size)
  G!   %   Push input as a column vector
  Z~   %   Bitwise XOR with broadcast, i.e. for all pairs of entries of the
       %   two arguments. The first argument is the accumulated result
       %   from the previous iteration, the second is the input vector
  G    %   Push input again
  h    %   Postpend
  u    %   Unique values. Gives a row vector
]      % End
n      % Number of entries. Implicitly display

пример

Промежуточные результаты (шаги 2.1 и 2.3) для ввода [256 259 3]:

Первая итерация: [256 259 3]с [256 259 3]: вычисление всех пар побитового XOR дает матрицу

  0   3 259
  3   0 256
259 256   0

Прикрепление [256 259 3]и дедупликация

0 3 259 256

Вторая итерация: текущий результат [0 3 259 256]с [256 259 3]. После дедупликации это снова дает

0 3 259 256

Третья итерация: снова

0 3 259 256

Таким образом, вывод 4(количество записей результата).

Луис Мендо
источник
Пояснения пожалуйста? Вы не можете использовать O (2 ^ n).
Эрик Outgolfer
Я понятия не имею, как это работает, но это определенно не O (2 ^ n). Он на самом деле решает (1 2 3… 63) тестовый пример довольно быстро, хотя это наихудший случай для метода грубой силы.
Grimmy
2
Как это так быстро? Я пытался сделать почти то же самое в Желе, но первая попытка была убита через 19 минут ... (Теперь пытаюсь с большей оперативной памятью.)
Деннис
2
Я считаю , что это является O (2ⁿ) в худшем случае; просто в тесте, который это выполняет, n всего 15, поэтому программа все еще работает довольно быстро.
2
@ ais523 Промежуточные числа, полученные из побитового XOR, никогда не могут быть больше, чем максимальное число на входе M. Таким образом, размер вектора промежуточных результатов никогда не превышает M, а сложность равна O ( M*M). ОП сказал, что точное определение nне имеет значения, поэтому, если я определю, nкак Mя могу утверждать, что это O ( n*n).
Луис Мендо
8

Haskell , 64 байта

f принимает список целых чисел и возвращает целое число

import Data.Bits
f l|m<-maximum l,m>0=2*f(min<*>xor m<$>l)|0<1=1

Попробуйте онлайн!

Это не обрабатывает пустой список, для этого вы можете, но $0:вместо пробела после maximum.

Как это устроено

  • Если максимум mсписка равен нулю, возвращает 1.
  • Иначе, xors каждый элемент с максимумом.
    • Если результат меньше, чем элемент, элемент заменяется им.
    • Это обязательно обнуляет самый значимый бит, установленный в любом месте списка.
    • Затем рекурсы в результирующем списке удваивают результат рекурсии.
  • Этот процесс по существу выполняет исключение Гаусса (хотя отбрасывает последние строки, устанавливая их в 0) по модулю 2, в матрице, строки которой являются битовыми представлениями списка чисел. Множество битовых представлений "xorspace" представляет собой векторное пространство по модулю 2, натянутое на строки этой матрицы, и число элементов которого равно 2 в степени ранга строки матрицы.
  • Этот алгоритм имеет полиномиальное время, поэтому определенно должен быть лучше, чем O (2 ^ n).
Орджан Йохансен
источник
Это в основном алгоритм, о котором я думал (для преодоления границ сложности), хотя это особенно элегантный способ его представления. Приятно видеть это в правильном ответе.
4

Mathematica, 52 байта

2^MatrixRank[PadLeft@IntegerDigits[#,2],Modulus->2]&
alephalpha
источник
Почему вы удалили свой ответ Pari / GP? Казалось, работает нормально. РЕДАКТИРОВАТЬ: не имеет значения, он провалил некоторые тесты на самом деле.
Grimmy
@ Грими, почему ты принял мой ответ? Это код-гольф, выигрывает самый короткий код.
алефальфа
Извините, я изменил принятый ответ на 7-байтовый упакованный Pyth.
Grimmy
3

05AB1E , 8 байтов

vDy^ìÙ}g

Попробуйте онлайн!

Все тесты заканчиваются менее чем за 1 минуту на TIO.

Emigna
источник
Это не соответствует последнему критерию: «Ваш код должен быть в состоянии обработать все тестовые случаи менее чем за день (без O (2 ** n)»). »
Grimmy
@Grimy: Не читал 2^nчасть: /
Emigna
@Grimy: теперь обновлено, чтобы завершить все тестовые задания менее чем за 1 минуту (и с меньшим количеством использованных байтов)
Emigna
Думал, âü^Ùgпока я не увидел, что вы можете xor более одного раза, отличное решение.
Волшебная Осьминог Урна
@carusocomputing: Это сохраняет байт, но я не уверен насчет сложности.
Эминья
3

Python 2 , 55 байт

r={0}
for n in input():r|={x^n for x in r}
print len(r)

Попробуйте онлайн!

Выбивает функции:

f=lambda l,r={0}:l and f(l[1:],r|{x^l[0]for x in r})or len(r)
f=lambda l:len(reduce(lambda r,n:r|{x^n for x in r},l,{0}))

Красивый метод исключения строк Эрджана Йохансена на один байт короче.

Python 2 , 54 байта

f=lambda l:1-any(l)or 2*f([min(x,x^max(l))for x in l])

Попробуйте онлайн!

XNOR
источник
2

Желе , 9 8 байт

0œ|⁺^¥/L

Завершает все тестовые случаи менее чем за 8 секунд на TIO с незначительными требованиями к памяти.

Попробуйте онлайн!

Как это устроено

0œ|⁺^¥/L  Main link. Argument: A (array)

0œ|       Perform multiset union with 0, prepending 0 if A doesn't contain it.
      /   Reduce A by the link to the left.
     ¥      Combine the previous two links into a dyadic chain.
            Left argument: V (array). Right argument: n (integer)
    ^           Bitwise XOR each element in V with n.
   ⁺            This quick refers to the previous link, making it a shorthand for
                the link 'œ|'. Thus, it performs multiset union on V and the array
                of bitwise XORs.
       L  Compute the length of the result.
Деннис
источник
1

Python, 113 байт

def f(x):
 u,s=[0],{0}
 while u:
	a=u.pop()
	for b in x:
	 c=a^b
	 if c not in s:u+=[c]
	 s.add(c)
 return len(s)
user1502040
источник
Это работает, но я считаю 113 байтов; я что-то пропустил?
Grimmy
@totallyhuman это, вероятно, потому что вы считаете табуляции как 8 байт, а не как один байт.
Grimmy
Если первый отступ - пробел, следующий - табуляция, а последний - табуляция + пробел (или 2 табуляции), то это 113 байтов
daniero
@Grimy На самом деле каждая вкладка - это 4 пробела, а не 8.
Эрик Игрок в гольф
Полная программа будет короче, поскольку она экономит горстку отступов. Кроме того, цикл for может быть сжат в одну строку, что u+=[c][c in s:]эквивалентно вашему ifутверждению.
Деннис