Sequências de Skolem
Uma sequência de Skolem é uma sequência de 2n
números em que todo número i
entre 1
e n
ocorre exatamente duas vezes, e a distância entre as duas ocorrências i
é exatamente de i
etapas. Aqui estão alguns exemplos de sequências de Skolem:
1 1
1 1 4 2 3 2 4 3
16 13 15 12 14 4 7 3 11 4 3 9 10 7 13 12 16 15 14 11 9 8 10 2 6 2 5 1 1 8 6 5
As seguintes sequências não são sequências de Skolem:
1 2 1 2 (The distance between the 1's is 2, not 1)
3 1 1 3 (The number 2 is missing)
1 1 2 1 1 2 (There are four 1's)
Objetivo
Escreva um programa, função ou expressão para contar o número de todas as seqüências de Skolem de um determinado comprimento. Mais explicitamente, sua entrada é um número inteiro n
e sua saída é o número de sequências de comprimento de Skolem 2n
. Esta sequência tem uma entrada OEIS . Para n = 0
, você pode retornar 0
ou 1
. Os primeiros valores, começando por 0
, são
0, 1, 0, 0, 6, 10, 0, 0, 504, 2656, 0, 0, 455936, 3040560, 0, 0, 1400156768
Regras e pontuação
Isso é código de golfe. O formato de saída é relaxado dentro do razoável.
0, 1, 0, 0, 6...
na sua pergunta? Esse é o trecho de código? Em caso afirmativo, qual idioma é esse?0
? Se você deseja admitir0
como uma entrada válida, a saída deve ser1
.Respostas:
GolfScript,
4846 caracteresA versão mais rápida ( experimente online ) - corre razoavelmente rápido, por exemplo,
n=8
leva cerca de dois segundos. E a abordagem escolhida tem realmente poucos caracteres.Esta versão também funciona com máscaras de bits. Ele constrói a matriz de resultados possíveis de 1 para cima, ou seja, para
n=3
:Enquanto alguns resultados (como 000011) têm duas continuações possíveis, outros (por exemplo, 001100) não têm nenhum e são removidos da matriz de resultados.
Explicação do código:
fonte
Expressão J, 47 caracteres
Exemplo:
Demora cerca de 30 segundos
y=:5
na minha máquina.o algoritmo é o mais lento possível:
~.(i.!+:y)A.,~>:i.y
gera toda permutação1 2 .. y 1 2 .. y
e remove entradas duplicadas((=&{:+.2-#@])#;.2)\"1
calcula:(...)\"1
para cada prefixo de cada linha:#;.2
conta os elementos antes de cada ocorrência do último elemento#@]
conta o número de contagens (ou seja, o número de ocorrências do último elemento)=&{:
determina a "igualdade" "de" "último elemento" s da lista de contagem e da lista original.+.
é um OR lógico.=&{:+.2-#@]
lê "os últimos elementos [da lista de contagens e da lista original] são iguais ou existe apenas um elemento [na lista de contagens] em vez de dois".*/"1
multiplica (AND lógico) nas linhas da tabela de condições, determinando quais permutações são sequências de Skolem.+/
soma esses e zeros juntos.fonte
GolfScript (46 caracteres)
Esta é uma expressão que recebe entrada na pilha. Para transformá-lo em um programa completo, com entrada no stdin, acrescente
~
É bastante ineficiente - a maior parte das economias que fiz ao reduzir para 56 caracteres sem golfe foi expandindo o leque de loops de maneiras que não introduzem resultados incorretos, mas fazem o cálculo de resíduos.
A abordagem é o mascaramento bit a bit de produtos cartesianos. Por exemplo, (usando binário para as máscaras) para
n=4
o código não armazenado, calcularia o xor de cada elemento no produto cartesiano[00000011 00000110 ... 11000000] x [00000101 00001010 ... 10100000] x ... x [00010001 ... 10001000]
. Qualquer resultado com 8 bits só poderia ser alcançado por máscaras sem sobreposição.Para otimizar o tamanho em vez da velocidade, o código acumula produtos parciais (
S1 u S1xS2 u S1xS2xS3 ...
) e faz com que cada produto seja constituído por2n
elementos, e não apenas pelo2n-1-i
que pode realmente contribuir para uma sequência válida.Rapidez
A versão para golfe dura
n=5
10 segundos no meu computador e mais de 5 minutos paran=6
. A versão original não gasta calculan=5
em menos de um segundo en=6
em cerca de 1 minuto. Com um filtro simples em resultados intermediários, ele pode calcularn=8
em 30 segundos. Joguei o jogo em 66 caracteres (como um programa - 65 caracteres em uma expressão), mantendo os loops o mais restrito possível e filtrando as colisões intermediárias:fonte
GolfScript, 49 caracteres
Espera o número
n
em STDIN. Isso é código-golfe - não tente o código comn
mais de 5.fonte
Sálvia, 70
Isso é um pouco menor que o meu original.
Como funciona:
Dada uma matriz 0/1, o problema exato de cobertura dessa matriz é encontrar um subconjunto das linhas que somam (como números inteiros) ao vetor all-ones. Por exemplo,
tem uma solução
Minha abordagem favorita para os problemas é convertê-los em um problema exato de capa. As sequências de Skolem facilitam isso com eficiência. Faço um problema exato de cobertura em que as soluções estão em desuso com as sequências de comprimento Skolem
2n
. Por exemplo, uma linha do problema paran=6
éonde um 1 na posição
a < n
significa que o símboloa
é usado. As posições restantes correspondem aos locais reais na sequência. Uma capa exata corresponde a cada símbolo sendo usado exatamente uma vez e a cada local sendo preenchido exatamente uma vez. Por construção, qualquer símbolok
em um local está ak
espaços de distância de seu parceiro.No Sage,
DLXCPP
é uma implementação de "links de dança" - resolve o problema exato da capa de uma maneira excepcionalmente elegante. É um dos meus algoritmos favoritos de todos os tempos, e estar na superfície do Sage torna uma enumeração combinatória uma alegria.fonte
len(list(...))
salvará 4 caracteres.len(list(...))
n = 16. E isso mataria totalmente o tempo de execução.