Desafio
Você recebe duas cadeias de bits distintas do mesmo comprimento. (Por exemplo, 000
e 111
.) Seu objetivo é encontrar um caminho de um para o outro, de modo que:
- Em cada etapa, você altera apenas um bit (você pode ir
000
para qualquer um dos001
itens010
,100
). - Você não pode visitar a mesma sequência de bits duas vezes.
- O caminho é o maior possível, sob essas restrições.
Por exemplo, passando de 000
para 111
, podemos seguir o caminho
000, 001, 011, 010, 110, 100, 101, 111
que visita todas as cadeias de caracteres de 8 bits de comprimento 3, por isso deve ser o mais longo possível.
Regras
- Aplicam-se brechas padrão.
- Você pode considerar a entrada como duas seqüências de zeros e uns, ou como duas matrizes de zeros e uns, ou como duas matrizes de valores booleanos.
- Você não pode aceitar a entrada como dois números inteiros com a representação binária correta (escrever
000
e111
como0
e7
não é válido). - Se desejar, você pode usar o comprimento das cadeias de bits como entrada.
- É permitido ao seu programa produzir o caminho imprimindo as cadeias de bits visitadas uma de cada vez ou retornando uma matriz das cadeias de bits visitadas (cada uma no mesmo formato da entrada).
- Sua saída deve incluir o início e o fim do caminho (que são suas entradas).
- Isso é código-golfe , o código mais curto em bytes vence.
Exemplos
0 1 -> 0, 1
10 01 -> 10, 00, 01 or 10, 11, 01
000 111 -> any of the following:
000, 100, 110, 010, 011, 001, 101, 111
000, 100, 101, 001, 011, 010, 110, 111
000, 010, 110, 100, 101, 001, 011, 111
000, 010, 011, 001, 101, 100, 110, 111
000, 001, 101, 100, 110, 010, 011, 111
000, 001, 011, 010, 110, 100, 101, 111
1001 1100 -> 1001, 0001, 0000, 0010, 0011, 0111, 0101, 0100, 0110, 1110, 1010, 1011, 1111, 1101, 1100 (other paths exist)
code-golf
binary
graph-theory
Misha Lavrov
fonte
fonte
Respostas:
Casca ,
27 2624 bytesForça bruta, muito lenta. Experimente online!
Explicação
Husk lê naturalmente da direita para a esquerda.
fonte
Mathematica, 108 bytes
Entrada:
Resultado:
fonte
Mathematica, 175 bytes
Boa primeira pergunta!
Entrada
fonte
Haskell ,
212207 bytesProvavelmente é muito longo, mas finalmente funciona agora. (Obrigado a @Lynn pelo truque do produto cartesiano !) Thansk @nimi por -5 bytes!
Experimente online!
Explicação:
fonte
x<-mapM id$[1>0,1<0]<$b
[True,False]
? Se[False,True]
também funcionar, você pode usar[0>1..]
.Bool
éEnum
, e eu esqueci que<$
está disponível (primeiro tentou*>
que não está em Prelude)!Mathematica
116114 bytesCom vários bytes salvos, graças a Misha Lavrov.
Entrada (8 dimensões)
Saída (duração = 254, após 1,82 segundos)
Tuples[{0,1},{l=Length@#}],{2}]
& gera os números 0 ... 8 como listas binárias.O exterior
Tuples...{2}
produz todos os pares ordenados desses números binários.Plus@@x
soma cada um dos pares, gerando trigêmeos de 0, 1.Cases....Count[Plus@@x, 1]==1
retorna todas as somas que contêm um único 1. Elas surgem quando os dois números binários originais são conectados por uma aresta.Rules
conecta os vértices do gráfico, cada vértice sendo um número binário.Graph
cria um gráfico correspondente aos referidos vértices e arestas.FindPath
encontra até 2 ^ n caminhos que conectam o vértice a ao vértice b, os números fornecidos.Last
leva o mais longo desses caminhos.Para três dimensões, o gráfico pode ser representado em um plano, como mostrado aqui:
Para a entrada,
{0,0,0}, {1,1,1}
é produzido o seguinte:{{{0, 0, 0}, {0, 0, 1}, {0, 1, 1}, {0, 1, 0}, {1, 1, 0}, {1, 0, 0}, {1, 0, 1}, {1, 1, 1}}}
Este caminho pode ser encontrado no gráfico acima.
Também pode ser concebido como o caminho a seguir em 3 espaços, onde cada vértice corresponde a um ponto
{x,y,z}
. {0,0,0} representa a origem e {1,1,1} representa o ponto "oposto" em um cubo de unidade.Portanto, o caminho da solução corresponde a uma travessia de arestas ao longo do cubo da unidade. Nesse caso, o caminho é hamiltoniano: ele visita cada vértice uma vez (ou seja, sem cruzamentos e sem vértices omitidos).
fonte
2^(l+2)
no seu código?Haskell ,
141123 bytesUsa listas de números inteiros. Experimente online!
Explicação
A função principal é
!
e as funções auxiliares são#
ec
. Dada uma lista de bits,c
fornece todas as formas possíveis de virar um deles, por exemplo[0,1,1] -> [[1,1,1],[0,0,1],[0,1,0]]
.A função
#
pega uma lista de listas (a "memória") e uma lista (a "cadeia de bits inicial"). Ele constrói todos os caminhos de hipercubo que começam com o elemento inicial, contêm apenas cadeias de bits distintas e não pisam nas cadeias de caracteres da memória.A principal função
!
une tudo isso. Um truque que eu uso aqui ép*>x
(x
repetidaslength p
vezes) em vez delength p
. Como as repetições mais longasx
ocorrem posteriormente na ordem natural das listas,maximum
escolhe o caminho mais longo em ambos os casos, uma vez que as primeiras coordenadas dos pares são comparadas antes das segundas.fonte
Geléia ,
2527 bytes+2 bytes para corrigir um erro no meu golfe :( espero encontrar um caminho mais curto.
Um programa completo usando as cadeias de bits usando
1
e2
* como listas. Os argumentos sãofrom
eto
. O programa imprime uma lista de listas dos mesmos.*
0
e1
pode ser usado ao custo de um byte (adicione’
entreL2ṗ
eŒ!ç€...
para diminuir).Experimente online!
Quão?
atualizando ...
fonte
[1,1]
e[2,2]
saída[[1, 1], [2, 1], [1, 2], [2, 2]]
quando eu experimento on-line, o que não é um caminho válido.