Um quadrado latino é uma praça que tem símbolos nas linhas ou colunas não repetiu: .
13420
21304
32041
04213
40132
E como muitos jogadores de Sudoku sabem, você não precisa de todos os números para deduzir os números restantes.
Seu desafio é compactar um quadrado latino no menor número possível de bytes. Você precisa fornecer um ou dois programas que comprima / descompacta.
Várias informações:
- Os números usados sempre serão
0..N-1
, ondeN
é o comprimento da borda do quadrado eN<=25
- Na descompressão, o quadrado latino deve ser idêntico à entrada.
- Seu (s) programa (s) deve (ão) descomprimir qualquer quadrado latino (dentro do tamanho máximo quadrado), não apenas os que eu forneci. As taxas de compressão também devem ser semelhantes.
- Você deve realmente executar a compactação e o descompactador para obter sua pontuação (sem tempos de execução no final do universo)
Os casos de teste podem ser encontrados no github . Sua pontuação é o tamanho total de casos de teste compactados.
EDIT: A partir das 20:07 de 7 de julho, atualizei os casos de teste (para corrigir um problema de geração). Execute novamente o seu programa nos novos casos de teste. Obrigado Anders Kaseorg .
code-challenge
compression
Nathan Merrill
fonte
fonte
0
emboran-1
:)n
símbolos diferentes. : PRespostas:
Python,
1281.3751268.625 bytesCodificamos o quadrado latino uma “decisão” de cada vez, em que cada decisão é de uma destas três formas:
Em cada etapa, fazemos todas as inferências lógicas que podemos com base em decisões anteriores e, em seguida, escolhemos a decisão com o menor número de opções possíveis, o que leva o menor número de bits a representar.
As opções são fornecidas por um decodificador aritmético simples (div / mod pelo número de opções). Mas isso deixa alguma redundância na codificação: se k decodifica a uma praça onde o produto de todos os números de escolhas era m , então k + m , k + 2⋅ m , k + 3⋅ m , ... decodificação para a mesma casa com algum estado restante no final.
Aproveitamos essa redundância para evitar codificar explicitamente o tamanho do quadrado. O descompressor começa tentando decodificar um quadrado de tamanho 1. Sempre que o decodificador termina com o estado restante, ele joga fora esse resultado, subtrai m do número original, aumenta o tamanho em 1 e tenta novamente.
Saída:
fonte
np.stack()
. Nesse caso, ele pode ser substituído pornp.array([…])
, e eu o fiz na versão atual.MATLAB,
3'062.52'888.125 bytesEssa abordagem apenas abandona a última linha e a última coluna do quadrado e converte cada entrada em palavras com uma certa profundidade de bits. A profundidade do bit é escolhida mínima para o quadrado de tamanho especificado. (Sugestão de @KarlNapf) Essas palavras são apenas anexadas uma à outra. Descompressão é justamente o contrário.
A soma de todos os casos de teste é 23'105 bits ou 2'888.125 bytes. (Ainda é válido para os casos de teste atualizados, pois o tamanho das minhas saídas depende apenas do tamanho da entrada.)
fonte
n=9..16
4 bits é suficiente.Python 3, 10772 bits (1346,5 bytes)
Leva 0,1 segundos para compactar e descomprimir os casos de teste combinados.
Verifique a pontuação no Ideone .
fonte
len(possible)
é 1 epossible.index(rows[i][j])
é 0 , para que o símbolo seja codificado sem nenhum custo.J , 2444 bytes
Confia no builtin
A.
para converter de e para uma permutação de números inteiros [0, n) e um índice de permutação.Compactar, 36 bytes
A entrada é uma matriz 2D que representa o quadrado latino. Cada linha é convertida em um índice de permutação e esse índice é convertido em uma lista de dígitos base 255 e substituído por um valor ASCII. Cada sequência é unida usando o caractere ASCII em 255.
Descomprimir, 45 bytes
Divide a sequência de entrada em cada valor ASCII de 255 e analisa cada grupo como 255 dígitos base. Em seguida, usando o número de grupos, crie uma lista de números inteiros [0, comprimento) e permute-a de acordo com cada índice e retorne-a como uma matriz 2D.
fonte
Python,
605245213556 bytescompress
pega o quadrado como uma cadeia de linhas múltiplas, assim como nos exemplos e retorna uma cadeia de caracteres binária, enquantodecompress
faz o oposto.Remova a última linha + coluna e feche o restante.
base64
, não parece necessáriofonte
Python 3, 1955 bytes
Ainda outro que usa índices de permutação ...
saída
fonte
Python3 -
3.5723.581 bytesdataCompress
pega uma lista de tuplas inteiras e retorna uma string.dateDeCompress
pega uma string e retorna uma lista de tuplas inteiras.Em resumo, para cada linha, esse programa pega o índice de permutação de linhas e o salva na base 36. A descompressão leva muito tempo com entradas grandes, mas a compactação é realmente rápida mesmo em entradas grandes.
Uso:
dataCompress([(2,0,1),(1,2,0),(0,1,2)])
resultado:
c|4|3|0
dataDeCompress("c|4|3|0")
resultado:
[(2, 0, 1), (1, 2, 0), (0, 1, 2)]
fonte
permutations
chamadaslist
-permutations
retorna um gerador, que gera preguiçosamente todas as permutações, mas se você tentar transformá-lo em umlist
, ele gera ansiosamente todas as permutações, o que leva muito tempo.O(n)
tempo, em vez daO(n!)
abordagem de força bruta da verificação de todas as permutações .Java, 2310 bytes
Convertemos cada linha do quadrado em um número que representa qual permutação lexicográfica está usando números fatorádicos, também conhecido como sistema de números fatoriais. , que é útil para numerar permutações.
Escrevemos o quadrado em um arquivo binário em que o primeiro byte é o tamanho do quadrado e, em seguida, cada linha possui um byte para o número de bytes na representação binária de um Java BigInteger, seguido pelos bytes desse BigInteger.
Para reverter o processo e descomprimir o quadrado, lemos o tamanho de volta e, em seguida, cada BigInteger, e usamos esse número para gerar cada linha do quadrado.
O permutor é adaptado de uma classe que escrevi há alguns anos para trabalhar com permutações:
Uso:
Com um quadrado latino
latin.txt
, comprima-o:E descompacte-o:
fonte