Vi recentemente essa pergunta no stackoverflow. É uma ótima pergunta, mas há um problema fatal com a pergunta. Eles estão pedindo a melhor maneira de fazê-lo. Por exemplo, mais fácil de ler, mais idiomático, mais organizado etc. Eles não sabem que não é isso que importa? Você deveria perguntar como fazê-lo com o menor número de bytes de código!
Como duvido que essa pergunta seja apreciada no stackoverflow, decidi perguntar aqui.
O desafio
Você deve escrever o programa ou função mais curto possível que gere todas as formas possíveis de intercalar duas seqüências de caracteres arbitrárias. Por exemplo, se as duas cadeias são 'ab'
e 'cd'
, a saída é:
['abcd', 'acbd', 'acdb', 'cabd', 'cadb', 'cdab']
Como você pode ver, a
é sempre antes b
, e c
é sempre antes d
.
O IO pode estar em qualquer formato razoável. Use este código python para verificar e verificar sua saída. (crédito: JeD )
def shuffle(s,t):
if s=="":
return [t]
elif t=="":
return [s]
else:
leftShuffle=[s[0]+val for val in shuffle(s[1:],t)]
rightShuffle=[t[0]+val for val in shuffle(s,t[1:])]
leftShuffle.extend(rightShuffle)
return leftShuffle
IO de amostra:
shuffle("$", "1234"):
['$1234', '1$234', '12$34', '123$4', '1234$']
shuffle("az", "by"):
['azby', 'abzy', 'abyz', 'bazy', 'bayz', 'byaz']
shuffle("code", "golf"):
['codegolf', 'codgeolf', 'codgoelf', 'codgolef', 'codgolfe', 'cogdeolf', 'cogdoelf',
'cogdolef', 'cogdolfe', 'cogodelf', 'cogodlef', 'cogodlfe', 'cogoldef', 'cogoldfe',
'cogolfde', 'cgodeolf', 'cgodoelf', 'cgodolef', 'cgodolfe', 'cgoodelf', 'cgoodlef',
'cgoodlfe', 'cgooldef', 'cgooldfe', 'cgoolfde', 'cgoodelf', 'cgoodlef', 'cgoodlfe',
'cgooldef', 'cgooldfe', 'cgoolfde', 'cgolodef', 'cgolodfe', 'cgolofde', 'cgolfode',
'gcodeolf', 'gcodoelf', 'gcodolef', 'gcodolfe', 'gcoodelf', 'gcoodlef', 'gcoodlfe',
'gcooldef', 'gcooldfe', 'gcoolfde', 'gcoodelf', 'gcoodlef', 'gcoodlfe', 'gcooldef',
'gcooldfe', 'gcoolfde', 'gcolodef', 'gcolodfe', 'gcolofde', 'gcolfode', 'gocodelf',
'gocodlef', 'gocodlfe', 'gocoldef', 'gocoldfe', 'gocolfde', 'goclodef', 'goclodfe',
'goclofde', 'goclfode', 'golcodef', 'golcodfe', 'golcofde', 'golcfode', 'golfcode']
Como de costume, as brechas padrão se aplicam e a resposta mais curta em bytes vence. Como a pergunta era originalmente sobre python, eu adoraria ver a resposta mais curta em python. (E não, pyth não é python). No entanto, respostas em qualquer idioma são incentivadas.
fonte
Respostas:
Pyth, 26
Experimente aqui
Esta é uma implementação muito básica da fórmula recursiva fornecida. Ele define uma função
g
que executa a tarefa necessária. O link é um programa modificado que lê as seqüências de caracteres de nova linha STDIN separadas, para ser mais conveniente. Para chamar a função dog<string1><string2>
.Expansão:
As duas chamadas recursivas são muito parecidas, mas não consegui mais encontrar uma maneira de jogar golfe.
fonte
Haskell,
5348 bytesDefine uma função
%
para a qual,a%b
com strings,a,b
fornece uma lista de strings.Dadas duas seqüências, escolhemos uma das duas para pegar o primeiro caractere. Em seguida, repetimos o restante de duas cadeias, acrescentando esse caractere a cada resultado.
Quando uma das seqüências está vazia, o único resultado possível é a outra.
""%""=[""]
também seria suficiente, mas é mais longo.53 bytes:
Define uma função
%
para a qual,a%d
com strings,a,d
fornece uma lista de strings.A função é definida recursivamente. Se pegarmos um caractere da primeira string, ele deverá ser anexado a cada resultado da chamada recursiva no restante da primeira string com a segunda string. Simetricamente para a outra corda.
Para o caso base, se uma das seqüências estiver vazia, o resultado será uma lista de elementos únicos de sua concatenação. Isso é mais curto que dois casos para cada string estar vazia.
fonte
""%""=[""]
.Haskell, 47
%
é o operador que resolve esse desafio.#
é um operador que pega duas listas e encontra todas as maneiras de intercalá-las, de modo que o primeiro caractere seja da primeira string (com uma caixa de aresta - se a primeira lista estiver vazia, o resultado será uma lista vazia), recorrendo a%
.então,
%
funciona aplicando apenas#
duas vezes.Edit: A versão anterior teve um bug no qual
""%""
retornou["",""]
, então eu o consertei. Foi corrigido adicionando uma caixa base a%
, que permitiu remover uma caixa base do mesmo comprimento#
(o que realmente não fazia muito sentido).fonte
(#) :: [a]->[a]->[[a]]
, de modoa::[a]
eo resultado deve ser do tipo[[a]]
Python 2, 71 bytes
Exemplo de execução:
Dadas duas seqüências
x,y
, podemos pegar o primeiro caractere dex
e anexá-lo a cada resultado da chamada recursiva com ele ausentef(x[1:],y)
. Ou, podemos fazer o mesmo comx
ey
alternado. Tomandox,y
como entradap
ou como sua inversão `p [:: - 1], obtemos as duas possibilidades.Para evitar retirar de uma string vazia
x
, fazemos um curto-circuito lógico comx and
. Se ambas as strings estiverem vazias, nenhuma das strings pode serx
e nós obtemos uma lista vazia de possibilidades, comor
as quais corrigimos o caso base correto['']
.Uma estratégia generativa semelhante no Python 3 (73 bytes):
fonte
Python, 80
Conforme solicitado, aqui está uma resposta em python:
Obrigado Sp3000 por comer 4 bytes :)
fonte
CJam, 38
Experimente online
Programação dinâmica (usando recursão memorizada).
Explicação:
fonte
CJam, 32 bytes
Teste aqui.
Parece realmente fácil de jogar, mas até agora encontrei apenas 4 soluções alternativas com a mesma contagem de bytes:
A idéia básica é a de gerar todas as permutações de
0
s e1
s correspondente a que a corda para levar cada personagem no resultado de. Isso é tudo, inclusive oe!
. O resto simplesmente seleciona os caracteres nessa ordem das duas seqüências de caracteres.fonte
e*
e.*
que repita cada elemento em uma quantidade diferente. ;) (Ou seja, é um operador a fazer:a.*:~
. Suponho quee*
poderia ser usado para isso, já que atualmente erros se forem fornecidas duas listas).JavaScript (Firefox 30-57),
888481 bytesEdit: Salvo 4 bytes, melhorando minha condição de terminação. Economizou 3 bytes graças a @ edc65.
fonte
f=(a,b,z=(v,w)=>v[1]?f(v.slice(1),w).map(x=>v[0]+x):[v+w])=>z(a,b).concat(z(b,a))
v
como condição, mas nunca me ocorreu usarv[1]
.Braquilog , 8 bytes
Experimente online!
Toma a entrada como uma lista de duas cadeias através da variável de entrada e gera todas as intercalações possíveis através da variável de saída. Como os casos de teste parecem permitir intercalações duplicadas onde existem cartas compartilhadas, não tomei o cuidado de evitá-las, mas isso gera muito mais duplicatas e não apenas com cartas compartilhadas. (Se isso não for permitido, mas as duplicatas de letras compartilhadas não forem necessárias, basta adicionar três bytes para quebrar
{}ᵘ
a saída como uma lista sem duplicatas.)Essencialmente, isso gera todas as partições de ambas as seqüências e as intercala da maneira determinística normal em qualquer ordem. As intercalações duplicadas extras são devidas a pares de partições em que a diferença entre o comprimento do primeiro e o comprimento do segundo tem algum valor diferente de 0 ou 1, para que um deles tenha pedaços que sejam concatenados entre si no final. Portanto, para produzir saída com as mesmas multiplicidades da saída de amostra:
Braquilog , 17 bytes
Experimente online!
O código extra
{lᵐ-ℕ<2&}
falha em qualquer par de partições em que são feitas divisões estranhas. (Alterei o cabeçalho no TIO para imprimir com aspas para facilitar a verificação de saída no shell do Python.)fonte
MATL ,
3430 bytesIsso usa uma idéia desta resposta : se os comprimentos das strings forem
m
en
, enumere todos osm+n
padrões dem
bits com os bits definidos. Uma maneira de fazer essa enumeração é: gerar todas as permutações de um vetor comm
uns en
zeros e depois remover duplicatas.Experimente online!
Explicação
fonte
Ruby, 83 bytes
Uma função recursiva que retorna
[a+b]
se uma dessas cadeias estiver vazia. Caso contrário, ele retornará uma lista de stringsa[0] + every string in v[a[1..-1],b]
adicionadas a uma lista de stringsb[0] + every string in v[a,b[1..-1]]
fonte
Lote,
154152 bytesfonte