Explorando o xorspace

14

O espaço x de um conjunto de números inteiros é o conjunto de todos os números inteiros que podem ser obtidos combinando os números inteiros iniciais com o operador xor bit a bit usual ( ^). Por exemplo, o xorspace de (8, 4)é (0, 4, 8, 12): 0 é 4 ^ 4, 12 é 4 ^ 8 e nenhum outro número pode ser alcançado. Observe que os números iniciais são sempre incluídos, por esta definição (por exemplo, 4 é 4 ^ 4 ^ 4).

Seu objetivo é escrever o programa mais curto que recebe uma lista de números inteiros não negativos como entrada e gera o número de elementos em seu espaço x.

  • As brechas padrão são proibidas.
  • A entrada e a saída podem estar em qualquer um dos formatos usuais . A entrada é garantida como válida, não vazia e sem duplicatas.
  • Seu código deve poder processar todos os casos de teste em menos de um dia .

Casos de teste

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
fonte

Respostas:

2

Pitão, 8 bytes

lu{+xM*Q

Suíte de teste

Explicação:

Para gerar o xorspace, encontramos o ponto de correção de pegar o xor de cada par de números, adicionar cada número e deduplicar. Então, tomamos a duração do resultado. Isso é executado em 20 segundos (apenas offline) no caso de teste final.

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.

Pacote Pyth , 7 bytes

Hexdump:

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

O mesmo que o acima, com uma codificação ASCII de 7 bits.

Coloque o acima em um arquivo com xxd -re execute-o da seguinte maneira:

py packed-pyth.py xorspace.ppyth '[256, 259, 3]'
isaacg
fonte
Eu acho que você pode fazer l{mxFdy.
Xnor
O @xnor yaplicado ao caso de teste de 1 a 63 é muito lento. Não tenho 2 ^ 63 de memória.
Isaacg
10

MATL , 11 bytes

t"G!Z~Ghu]n

Experimente online!

O último caso de teste não é executado no interpretador online devido a limitações de memória, mas é executado offline em menos de 2 segundos em um computador moderno.

Explicação

Para entrada de tamanho n, faça o seguinte:

  1. Inicialize o resultado para entrada.
  2. nTempos de repetição :
    1. Aplique o XOR bit a bit a todos os pares de entradas do resultado e da entrada atuais.
    2. Anexe valores de entrada ao resultado.
    3. Desduplicar.
  3. A saída é o número de elementos do resultado final.

Código comentado.

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

Exemplo

Os resultados intermediários (etapas 2.1 e 2.3) para entrada [256 259 3]são:

Primeira iteração: [256 259 3]com [256 259 3]: computar todos os pares de bit a bit-XOR fornece à matriz

  0   3 259
  3   0 256
259 256   0

Anexando [256 259 3]e desduplicando

0 3 259 256

Segunda iteração: resultado atual [0 3 259 256]com [256 259 3]. Depois de deduplicar isso novamente,

0 3 259 256

Terceira iteração: novamente

0 3 259 256

Portanto, a saída é 4(número de entradas do resultado).

Luis Mendo
fonte
Explicação, por favor? Você não pode usar O (2 ^ n).
Erik the Outgolfer
Não tenho ideia de como isso funciona, mas definitivamente não é O (2 ^ n). Na verdade, ele resolve o caso de teste (1 2 3… 63) muito rapidamente, mesmo que seja o pior caso para o método de força bruta.
Grimmy
2
Como isso é tão rápido? Eu tenho tentado fazer praticamente o mesmo em Jelly, mas a primeira tentativa foi morto aos 19 minutos ... (Agora a tentar com mais memória RAM.)
Dennis
2
Eu acredito que este é O (2ⁿ) pior caso; é apenas que, no teste que o exercita, n é de apenas 15, portanto o programa ainda é executado rapidamente.
2
@ ais523 Os números intermediários obtidos do bit-XOR nunca podem ser maiores que o número máximo na entrada, chame-o M. Portanto, o tamanho do vetor de resultados intermediários nunca excede Me a complexidade é O ( M*M). O OP disse que a definição exata de nnão importa, portanto, se eu definir ncomo Mposso afirmar que é O ( n*n).
Luis Mendo
8

Haskell , 64 bytes

f pega uma lista de números inteiros e retorna um número inteiro.

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

Experimente online!

Isso não lida com uma lista vazia, pois você pode, mas em $0:vez do espaço apósmaximum .

Como funciona

  • Se o valor máximo m da lista for zero, retornará 1.
  • Caso contrário, xors todos os elementos com o máximo.
    • Se o resultado for menor que o elemento, o elemento será substituído por ele.
    • Isso necessariamente zera o bit mais significativo definido em qualquer lugar da lista.
    • Em seguida, recursa na lista resultante, dobrando o resultado da recursão.
  • Esse processo executa essencialmente a eliminação gaussiana (embora jogue fora as linhas finais definindo-as como 0) módulo 2, na matriz cujas linhas são as representações de bits da lista de números. O conjunto de representações de bits do "xorspace" é o módulo de espaço vetorial 2 estendido pelas linhas desta matriz e cujo número de elementos é 2 à potência da classificação de linha da matriz.
  • Esse algoritmo é tempo polinomial, portanto deve ser definitivamente melhor que O (2 ^ n).
Ørjan Johansen
fonte
Este é basicamente o algoritmo em que eu estava pensando (para superar os limites da complexidade), embora seja uma maneira particularmente elegante de representá-lo. É bom vê-lo em uma resposta adequada.
4

Mathematica, 52 bytes

2^MatrixRank[PadLeft@IntegerDigits[#,2],Modulus->2]&
alefalpha
fonte
Por que você excluiu sua resposta Pari / GP? Parecia estar funcionando bem. EDIT: deixa pra lá, ele falhou em alguns casos de teste.
Grimmy
@ Grimy Por que você aceitou minha resposta? Este é um código-golfe, o código mais curto vence.
alephalpha
Desculpe, mudei a resposta aceita para o Pyth one de 7 bytes.
Grimmy
3

05AB1E , 8 bytes

vDy^ìÙ}g

Experimente online!

Todos os casos de teste terminam em menos de 1 minuto no TIO.

Emigna
fonte
Isso falha no último critério: «Seu código deve ser capaz de processar todos os casos de teste em menos de um dia (nada de O (2 ** n)). »
Grimmy
@Grimy: Não leu a 2^nparte: /
Emigna
@Grimy: Agora atualizado para terminar allt estudos de casos em menos de 1 minuto (e com menos bytes usado)
Emigna
Estava pensando âü^Ùgaté que vi que você pode xor mais de uma vez, boa solução.
Magic Octopus Urn
@carusocomputing: Isso economiza um byte, mas não tenho certeza sobre a complexidade.
Emigna
2

Geléia , 9 8 bytes

0œ|⁺^¥/L

Conclui todos os casos de teste em menos de 8 segundos no TIO, com requisitos de memória insignificantes.

Experimente online!

Como funciona

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.
Dennis
fonte
1

Python, 113 bytes

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
fonte
Funciona, mas estou contando 113 bytes; perdi algo?
Grimmy
@totallyhuman é provavelmente porque você está contando tabulações como 8 bytes, em vez de um único byte.
Grimmy
Se o primeiro dente é um espaço, próximo é um separador, e o último um separador + um espaço (ou 2 abas), então é 113 bytes
daniero
@Grimy Na verdade, cada separador é 4 espaços não 8.
Erik as Outgolfer
Um programa completo seria mais curto, pois economiza um punhado de recuo. Além disso, o loop for pode ser condensado em uma única linha, como u+=[c][c in s:]é equivalente à sua ifdeclaração.
Dennis