Esta questão é uma extensão do Verificar se as palavras são isomorfas e copia a primeira parte para fornecer a definição de isomorfia.
Duas palavras são isomorfos se tiverem o mesmo padrão de repetições de letras. Por exemplo, ambos ESTATE
e DUELED
têm padrãoabcdca
ESTATE
DUELED
abcdca
porque as letras 1 e 6 são iguais, as letras 3 e 5 são iguais e nada mais. Isso também significa que as palavras são relacionadas por uma cifra de substituição, aqui com a correspondência E <-> D, S <-> U, T <-> E, A <-> L
.
Dadas duas cadeias X e Y, com X não mais que Y, a tarefa é determinar se existe uma subcadeia de Y que é um isomorfo com X.
Entrada: Duas seqüências de letras não vazias de a..zA..Z, uma sequência por linha. Isso virá da entrada padrão.
Saída Uma substring da segunda string, que é um isomorfo com a primeira string, se existir. Caso contrário, imprima "Não!".
Regras Seu código deve ser executado em tempo linear no comprimento total da entrada.
Pontuação Sua pontuação é o número de bytes no seu código. Menos bytes ganha.
Exemplo de entrada e saída
adca
ddaddabdaabbcc
dabd
Gorjeta
Existe pelo menos uma solução de tempo não tão complicada, praticamente rápida e linear para esse problema.
Respostas:
Python 2,
338326323321310306297293290289280279266264259237230229226223222220219217 (260238231228225223221220218 com status de saída 0)O algoritmo é uma variação do KMP, usando um teste baseado em índice para correspondência de caracteres. A idéia básica é que, se tivermos uma incompatibilidade na posição
X[i]
, podemos voltar ao próximo local possível para uma partida, de acordo com o sufixo mais longoX[:i]
que é isomórfico para um prefixo deX
.Trabalhando da esquerda para a direita, atribuímos a cada caractere um índice igual à distância para a ocorrência anterior mais recente desse caractere, ou, se não houver ocorrência anterior, assumimos o comprimento do prefixo da string atual. Por exemplo:
Para testar se dois caracteres correspondem, comparamos os índices, ajustando-os adequadamente para índices maiores que o comprimento da (sub) sequência atual.
O algoritmo KMP se torna um pouco simplificado, pois não podemos obter uma incompatibilidade no primeiro caractere.
Este programa gera a primeira correspondência, se houver. Uso um erro de tempo de execução para sair no caso de uma correspondência, mas o código pode ser facilmente modificado para sair de forma limpa, ao custo de alguns bytes.
Nota: Para índices de computação, podemos usar
str.rfind
(em oposição à minha abordagem anterior usando um dicionário) e ainda ter complexidade linear, supondo questr.rfind
comece a pesquisar a partir do final (que parece a única opção de implementação sensata) - para cada caractere no alfabeto , nunca precisamos percorrer a mesma parte da string duas vezes, para que haja um limite superior das comparações (tamanho do alfabeto) * (tamanho da string).Como o código ficou ofuscado durante o golfe, eis uma solução anterior (293 bytes) que é um pouco mais fácil de ler:
A
e
função testa a equivalência de caracteres. Aexec
instrução atribui índices e faz algumas inicializações variáveis. O primeiro loop processa osX
valores de retorno e o segundo loop faz a pesquisa de cadeias.Atualização: Aqui está uma versão que sai corretamente, ao custo de um byte:
fonte
r=raw_input
vs. r =input
salva 4 bytes e os parênteses na impressão custam apenas 3.exec
.Python 3, 401 bytes
Isso ainda é praticamente não-destruído, mas acho que deve funcionar. O algoritmo principal é o KMP , mais um fator adicional que é fatorial no tamanho do alfabeto (o que é bom, pois o alfabeto é constante). Em outras palavras, esse é / deveria ser um algoritmo linear completamente impraticável.
Aqui estão algumas anotações para ajudar na análise:
Para testar, você pode substituir
s
por um alfabeto menor questring.ascii_letters
.fonte
APL (Dyalog) , 32 bytes
Esta é uma função infix, considerando X como argumento à esquerda e Y como argumento à direita.
Experimente online!
{
…}
Lambda anônima onde⍺
e⍵
representa os argumentos (X e Y)⍳⍨⍺
ɩ NDEX selfie de X ( Ɩ ndices da primeira ocorrência de elementos de X em X)⊂
coloque para que possamos procurar por todo esse padrão(
…)⍳
Índice da primeira ocorrência disso em…≢⍺
registro (comprimento) de X⍵,/⍨
todas as substrings desse tamanho de Y (redução de concatenação dessas, mas isso não é uma operação)s←
armazenar ems
(para s ubstrings)⍳⍨¨
ɩ NDEX selfie de cada um daquelesagora temos o índice do primeiro padrão, ou 1 + o número de padrões, se nenhuma correspondência foi encontrada
(
…)⊃⍨
Use esse índice para escolher…⊂'No!'
a cadeia incluída (para que funcione como um único elemento)s,
anexado coms
fonte