A idéia aqui é produzir um padrão quase repetitivo. Ou seja, a sequência que está sendo construída muda no último momento para evitar uma repetição de alguma subsequência. As subseqüências do tipo AA e ABA devem ser evitadas (onde B não é maior que A).
Exemplos:
Vou seguir em frente e começar listando todos os pequenos exemplos para tornar minha descrição mais clara. Vamos começar com 0.
Válido: 0 Inválido: 00 (padrão AA) Válido: 01 Inválido: 010 (padrão ABA) Inválido: 011 (padrão AA) Válido: 012 Válido: 0120 Inválido: 0121 (padrão ABA) Inválido: 0122 (padrão AA) Inválido: 01200 (padrão AA) Inválido: 01201 (padrão ABA; 01-2-01) Inválido: 01202 (padrão ABA) Válido: 01203
Agora, acredito firmemente que a 4
nunca é necessária, embora eu não tenha uma prova, porque encontrei facilmente sequências de centenas de caracteres que apenas usam 0123
. (Provavelmente, está intimamente relacionado à forma como são necessários apenas três caracteres para ter seqüências infinitas que não possuem nenhum padrão AA. Há uma página da Wikipedia sobre isso.)
Entrada / Saída
A entrada é um número inteiro único, positivo e diferente de zero n
. Você pode assumir isso n <= 1000
.
Saída é uma n
sequência de caracteres sem subseqüências que correspondem ao padrão proibido (AA ou ABA).
Amostras de entradas e saídas
>>> 1 0 0 >>> 2 01 >>> 3 012 >>> 4 0120 >>> 5 01203 >>> 50 01203102130123103201302103120132102301203102132012
Regras
- Somente os caracteres
0123
são permitidos. - B não é mais do que A. Isto é para evitar a situação em que
012345
tem de ser seguido por6
porque0123451
tem este:1-2345-1
. Em outras palavras, a sequência seria trivial e desinteressante. n
pode ser introduzido através de qualquer método desejado, exceto codificação.- A saída pode ser uma lista ou uma string, dependendo do que for mais fácil.
- Sem força bruta ; o tempo de execução deve ser da ordem de minutos, no máximo uma hora em uma máquina muito lenta, por
n=1000
. (Pretende-se desqualificar soluções que apenas circulam através den
permutações de todo o comprimento{0,1,2,3}
, para que truques e truques semelhantes sejam proibidos.) - As brechas padrão não são permitidas, como de costume.
- A pontuação está em bytes. Isso é código-golfe , então a entrada mais curta vence (provavelmente - veja o bônus).
- Bônus: escolha o dígito mais baixo permitido em cada etapa. Se
1
e3
são possíveis opções para o próximo dígito na sequência, escolha1
. Subtraia 5 bytes da sua pontuação. No entanto, tome nota da nota abaixo.
Nota!
Os becos sem saída são possíveis. Seu programa ou função deve evitá-los. Aqui está um exemplo:
Stump: 01203102130123103201302103120132102301203102132012302103120130231032012302132031023012032102312013021031230132031021301203210230132031021301203210230310320123102301320310330 Stump: 01203102130123103201302103120132102301203102132012302103120130231032012302132031023012032102312013021031230132031021301203210230132031021301203210230310320123102301320310330 Stump: 0120310213012310320130210312013210230120310213201230210312013023103201230213203102301203210231201302103123013203102130120321023013203102130120321023013203103303103103103102301320310330 Stump: 01203102130123103201302103120132102301203102132012302103120130231032012302132031023012032102312013021031230132031021301203210230132031021301203103103103102301320310330
Cada uma dessas seqüências não pode ser estendida mais (sem usar a 4
). Mas observe também que há uma diferença crucial entre os dois primeiros e os dois segundos. Substituirei a subsequência inicial compartilhada por uma X
para tornar isso mais claro.
Coto: X2130120 Coto: X2130123 Coto: X320 Coto: X321301203102130
Os últimos dois dígitos de X
são 10
, portanto, as únicas opções possíveis para o próximo dígito são 2
e 3
. A escolha 2
leva a uma situação em que a sequência deve terminar. O algoritmo ganancioso não funcionará aqui. (Não sem retroceder, pelo menos.)
fonte
n
? Se alguém der um algoritmo heurístico semi-ganancioso, como você verificará se ele não apresenta problemas por um período muito grande? O problema geral é interessante e não consegui encontrar nada sobre como evitar padrões, onde restringimos o comprimento de parte do padrão. Se alguém pode produzir uma receita geral, espero que seja a melhor abordagem.n
, mas, como os tocos encontrados pelo meu programa tendem a ficar mais longos em média 10 dígitos por vez, tenho certeza de que existe uma sequência infinita. Não sei como um algoritmo semi-ganancioso pode ser testado para seqüências arbitrariamente grandes. Eu poderia restringir o requisito paran
= 1000 e simplesmente não me preocupar com valores mais altosn
.AA
é realmente do tipoABA
ondeB
está vazio. Talvez isso ajude a simplificar algumas soluções.Respostas:
Retina , 86 bytes - 5 = 81
Onde
<empty>
representa uma linha de fuga vazia. Você pode executar o código acima a partir de um único arquivo com o-s
sinalizadorA entrada deve ser dada em unário , por exemplo
111111
. Ainda não testei a saída na ordem de milhares - duas das expressões regulares podem ficar um pouco lentas depois de um tempo - mas ela pode lidar facilmente com algumas centenas em poucos segundos.Explicação
Esta é uma solução simples de retorno.
0
.3
.Esse retorno é implementado por um loop de substituições de regex que é interrompido quando a sequência permanece inalterada por uma iteração.
Isso anexa
_
a à entrada, que é usada para separar a entrada unária da sequência que estamos construindo.Esta é a primeira substituição no loop (indicada pelo líder
(
). O regex corresponde se a) houver um caractere de palavra (ou seja, um dígito) no final da string (o que significa que a string é válida - veremos abaixo que sequências inválidas são marcadas com um final#
) eb) existem pelo menos tantos caracteres na sequência quanto na entrada (isso é verificado usando grupos de balanceamento ). Se for esse o caso, removemos a entrada e anexamos a!
. Isso!
serve para fazer com que todas as expressões regulares no loop falhem, de forma que elas terminem.Se houver um caractere de palavra no final (por exemplo, a sequência é válida e o loop não foi encerrado pela etapa anterior), acrescente a
0
.Se (em vez disso) a sequência tiver sido marcada como inválida e encerrada
3
, nós a removeremos3
(mas deixaremos a sequência como inválida, porque não há continuação possível para o prefixo atual ... para que o próximo caractere precise ser retornado também).Se a sequência estiver marcada como inválida e qualquer dígito que não
3
esteja no final, incrementamos o dígito e removemos o marcador.A última substituição no loop (como indicado pelo
)
). Ele verifica se a sequência terminaABA
(ondeB
não é maior que,A
mas potencialmente vazio). Os comprimentos relativos deA
eB
são novamente verificados usando grupos de balanceamento, e a repetição deA
é verificada com uma referência simples.Se esse regex corresponder, marcaremos a sequência inválida anexando
#
.Depois que o loop termina, tudo o que precisamos fazer é remover o
!
e, em seguida, ficar com a saída desejada.fonte
Python 2, 175 - 5 = 170 bytes
Este é o algoritmo ganancioso com retorno. Eu gostaria que fosse mais curto. Espero que esteja correto (veja abaixo).
Constrói a string um dígito de cada vez. Dada uma sequência de
d
dígitos que já encontrou, ele tenta anexar a0
como o(d+1)
dígito st. Se isso não funcionar, ele tenta a1
, então a2
, então a3
. Se nada disso funcionar, ele retornará aod
décimo dígito e o incrementará (se for menor que3
) ou o removerá (se for igual a3
, caso em que incrementa o anterior, etc.).A verificação de validade é a linha contida
.find
nela. Caso alguém decida ler meu código, devo dizer que este programa está realmente armazenando a string para trás, o que significa que está adicionando dígitos à frente . Portanto, a verificação envolve procurar lugares em que os primeirosc
dígitos apareçam novamente mais tarde na string (em qualquer lugar após os primeirosc
dígitos) e, se houver algum desses lugares, se o comprimento intermediário é no máximoc
.(É claro que ele reverte a sequência antes de imprimir.)
Também poderia ser facilmente mais rápido; Originalmente, tive que sair vários loops cedo para obter eficiência, mas isso custou bytes preciosos. Ele ainda funciona bem no intervalo de
n=1000
, no entanto.De qualquer forma, o programa parece exibir uma preferência pelos dígitos menores, mas não é uma preferência muito forte. Por exemplo, executá-lo com
n=2000
me deu uma string com523
zeros,502
uns,497
dois e478
três, terminando em30210312013021
. Portanto, se alguém mais estiver trabalhando em um algoritmo ganancioso, talvez possa confirmar esse resultado. Ou comn=1000
eu consegui[263, 251, 248, 238]
as contagens por dígito.Finalmente, eu mencionaria que essas contagens sugerem simetria, quase (embora não exatamente), como se tivéssemos começado com uma distribuição uniforme e depois convertido alguns dos
3
's para0
' s e alguns dos2
's para1
' s. Mas, obviamente, isso poderia ser apenas coincidência. Eu não faço ideia!fonte
Haskell, 115 (120 bytes - 5 bônus)
Corra online em Ideone
Exemplo de execução:
fonte