Suponha que você esteja amarrando um fio de Froot Loops para colar, pulseira, cadarço ou o que quer. Existem 6 cores ansa: r ed, o gama, y ellow, g reen, b lue, e p urple. Você quer que seu fio comece com vermelho à esquerda e circule na ordem do arco-íris, indo para a direita, terminando em roxo. Ou seja, você deseja fazer com que seu fio possa ser representado pela cadeia roygbp
repetida várias vezes (possivelmente 0).
O problema é que você já amarrou seus loops, e não em uma ordem específica. Quais loops você deve comer e não comer para maximizar o número de ciclos arco-íris corretos da esquerda para a direita, com o primeiro laço vermelho e o último laço roxo?
Escreva um programa ou função que capte uma sequência arbitrária de caracteres roygbp
e imprima ou retorne uma sequência do mesmo comprimento e
no lugar de loops para comer e n
no lugar de loops para não comer.
Por exemplo, se o seu fio Froot Loop parecia
a entrada seria
gorboypbgbopyroybbbogppbporyoygbpr
e indo da esquerda para a direita, podemos encontrar três roygbp
seqüências completas de arco-íris, mas alguns dos loops precisam ser devorados. Assim, a saída seria
eenenneennenennneeeeneennenennnnne
resultando em um fio perfeito de 3 ciclos:
Se não houver ciclos de arco-íris completos na entrada, a saída será toda e
e o fio terminará sem loop. por exemplo, a entrada proygb
tem saída eeeeee
. Por outro lado, proygbp
tem saída ennnnnn
.
Você pode assumir que todos os fios de entrada têm pelo menos um loop.
O código mais curto em bytes vence.
r
ouoygbproygbpr
também pode se qualificar?Respostas:
Pitão, 31 bytes
Incrivelmente ineficiente, explicação em breve.
yUlz
gera todos os subconjuntos possíveis de todos os índices possíveis dez
(a entrada) em ordem. Por exemplo, se a entrada forabc
:Em seguida,
hf!
encontra o primeiroT
na lista acima, tal que:jk.DzT"roygbp"k
é falso..D
pega uma string e uma lista de índices e exclui os elementos nesses índices. Assim.D"abcd",1 3
é"ac"
. Como.D
retorna uma lista (que não deve ser o caso, será corrigida em versões futuras do Pyth), eu usojk
(k
is""
) para juntá-la novamente em uma string. A:_"roygbp"k
peça substitui todas as instâncias de um ciclo pela sequência vazia.Como a string vazia é falsa, os parágrafos acima explicam como encontro o menor conjunto de índices necessários para comer para obter uma string composta apenas por ciclos.
:*lz\n_\e
depois transforma essa lista de índices em umannnneeennene
string.fonte
Hexagony ,
920722271 bytesSeis tipos diferentes de loops de frutas, você diz? Foi para isso que a Hexagony foi criada .
Ok, não foi. Oh Deus, o que eu fiz comigo mesma ...
Este código é agora um hexágono de comprimento lateral 10 (começou em 19). Provavelmente poderia ser jogado mais, talvez até no tamanho 9, mas acho que meu trabalho foi feito aqui ... Para referência, existem 175 comandos reais na fonte, muitos dos quais são espelhos potencialmente desnecessários (ou foram adicionados para cancelar um comando a partir de um caminho de cruzamento).
Apesar da aparente linearidade, o código é realmente bidimensional: o Hexagony o reorganiza em um hexágono regular (que também é um código válido, mas todo o espaço em branco é opcional no Hexagony). Aqui está o código desdobrado em todas as suas ... bem, eu não quero dizer "beleza":
Explicação
Eu nem tentarei explicar todos os caminhos complicados de execução nesta versão golfada, mas o algoritmo e o fluxo de controle geral são idênticos a essa versão não-golfada, que pode ser mais fácil de estudar para os realmente curiosos depois de explicar o algoritmo:
Honestamente, no primeiro parágrafo eu estava apenas brincando. O fato de estarmos lidando com um ciclo de seis elementos foi realmente uma grande ajuda. O modelo de memória do Hexagony é uma grade hexagonal infinita, em que cada extremidade da grade contém um número inteiro de precisão arbitrária assinado, inicializado como zero.
Aqui está um diagrama do layout da memória que usei neste programa:
O bit longo e reto à esquerda é usado como uma sequência terminada em 0,
a
de tamanho arbitrário, associada à letra r . As linhas tracejadas nas outras letras representam o mesmo tipo de estrutura, cada uma girada em 60 graus. Inicialmente, o ponteiro da memória aponta para a extremidade rotulada como 1 , voltada para o norte.O primeiro bit linear do código define a "estrela" interna das arestas com as letras
roygbp
, além de definir a aresta inicial como1
, de modo que saibamos onde o ciclo termina / começa (entrep
er
):Depois disso, voltamos ao limite identificado como 1 .
Agora, a ideia geral do algoritmo é esta:
e
na borda rotulada ? , porque enquanto o ciclo não estiver completo, devemos assumir que teremos que comer esse personagem também. Depois, passaremos ao redor do ringue para o próximo personagem do ciclo.e
s no ? arestas comn
s, porque agora queremos que esse ciclo permaneça no colar. Em seguida, passamos à impressão de código.e
en
). Em seguida, procuramos a aresta 1 (para pular o restante de um ciclo potencialmente incompleto) antes de passar para a impressão de código também.e
para cada caractere. Então ele se move para o ? borda associada ao personagem. Se for negativo, simplesmente encerramos o programa. Se for positivo, basta imprimi-lo e passar para o próximo caractere. Depois de concluir o ciclo, voltamos à etapa 2.Outra coisa que pode ser interessante é como eu implementei as seqüências de tamanho arbitrário (porque é a primeira vez que usei memória ilimitada no Hexagony).
Imagine que estamos em algum momento em que ainda estamos lendo caracteres para r (para que possamos usar o diagrama como está) e um [0] e um 1 já foram preenchidos com caracteres (tudo a noroeste deles ainda é zero) ) Por exemplo, talvez tenhamos acabado de ler os dois primeiros caracteres
og
da entrada nessas bordas e agora estamos lendo ay
.O novo personagem é lido na borda de entrada. Nós usamos o ? borda para verificar se esse caractere é igual a
r
. (Há um truque bacana aqui: a hexagonia só pode distinguir entre positivo e não positivo facilmente, portanto, verificar a igualdade por subtração é irritante e requer pelo menos dois ramos. podemos comparar os valores usando o módulo, que só dará zero se forem iguais.)Uma vez que
y
é diferente der
, passamos a borda (não marcado) para a esquerda do em e copiar oy
ali. Agora, avançamos mais pelo hexágono, copiando o caractere uma aresta cada vez mais, até que tenhamosy
a aresta oposta a pol . Mas agora já existe um caractere em um [0] que não queremos sobrescrever. Em vez disso, "arrastar" oy
em torno da próxima hexágono e verificar a 1 . Mas há um personagem lá também, então vamos mais um hexágono. Agora um [2] ainda é zero, então copiamos oy
afim disso. O ponteiro da memória agora se move de volta ao longo da corda em direção ao anel interno. Sabemos quando chegamos ao início da string, porque as bordas (não identificadas) entre a a [i] são zero enquanto ? é positivoEssa provavelmente será uma técnica útil para escrever código não trivial no Hexagony em geral.
fonte
Hexagonia , 169 bytes
Fui inspirado pela resposta de Martin Büttner (é o esolang dele também) e decidi que posso fazê-lo no tamanho 8. (Estou convencido de que também é possível no tamanho 7, mas é muito difícil. Já passei quatro dias sem -para isso.)
Dispostas hexagonalmente:
Na verdade, o programa não usa a
#
instrução, então usei esse caractere para mostrar quais células são realmente não utilizadas. Além disso, toda célula no-op que é atravessada em apenas uma direção é um espelho (por exemplo,_
se atravessada na horizontal), para que você saiba que todos os.
caracteres são atravessados em mais de uma direção.Explicação
No início, executamos a sequência de instruções
r''o{{y''g{{b''p"")"
. Estes estão espalhados um pouco ao acaso pelo código, porque eu os apertei depois que escrevi todo o resto. Eu uso]
para mudar para o próximo ponteiro de instrução algumas vezes; Dessa forma, eu posso me teleportar para outro canto do hexágono. O restante do programa é executado pelo ponteiro de instrução # 3.A memória agora tem a seguinte aparência, com as bordas importantes rotuladas com nomes que usarei nesta explicação:
As arestas rotuladas significam o seguinte:
in
: Usamos essa borda para armazenar um caractere que lemos de STDIN.%
: Usamos essa vantagem para realizar uma operação de módulo sobre o caráter ler de STDIN (in
) e o caractere atual “válido” (r
,o
, etc.), o que será0
se eles são iguais. Eu roubei esse truque da resposta de Martin Büttner, mas o resto do programa é diferente.#
: Enquanto lemos caracteres "inválidos" (ou seja, cores que precisamos comer), aumentamos essa margem. Portanto, essa margem lembra quantose
s precisamos produzir posteriormente.r?
: Sempre0
exceto onde está a parter
(vermelha). Isso nos diz quando completamos um ciclo.O programa continua assim:
#
. Caso contrário, vá para o próximo segmento da memória no sentido horário.r?
for positivo, fizemos uma revolução inteira. Faça uma rodada completa e produza se#
e
1n
por segmento. Isso define cada um de#
volta para0
. (Elee
é colocado em uma aresta sem rótulo, mas, para an
desapropriação da#
aresta, definimos o0
uso de uma*
(multiplicação) depois, o que funciona porque sabemos que todas as%
arestas são zero no momento.#
+1e
s até voltar ao pontor?
positivo, e saia.Após uma execução completa, a memória parece aproximadamente a seguinte no final. Você notará as bordas que contêm
101
(o código ASCII dee
); uma dasin
arestas é-1
(EOF); todas as#
arestas estão em 0; e o ponteiro da memória termina nar?
margem positiva .fonte
Retina ,
1488579 bytesVocê pode executar isso a partir de um único arquivo de origem com o
-s
sinalizador de intérprete.Explicação
Vamos resolver as coisas simples primeiro:
Anexa
#roygbp
ao final da string, que usaremos para calcular dinamicamente o ciclo de letras.O próximo (longo) passo descobre quais loops devem ser mantidos e os substitui
n
. Vamos ver como isso funciona daqui a pouco.Isso se livra do nosso auxiliar de pesquisa no final da string.
Isso substitui todos os caracteres que não foram substituídos na segunda etapa por
e
, concluindo a transformação.Agora vamos voltar para o segundo passo.
A estrutura básica usa um truque, que eu descobri há alguns meses atrás para substituir caracteres selecionados em uma correspondência global:
onde
...
corresponde a um padrão arbitrariamente complexo. Isso corresponde ao caractere a ser substituído.
e, em seguida, inicia um olhar para trás (que você deve ler da direita para a esquerda). O lookbehind captura tudo até o personagem correspondente em um grupoprefix
. Em seguida, ele muda para um olhar à frente , que agora começa no início da string e pode conter um padrão complexo. Após o caractere que queremos substituir nesse padrão, colocamos um olhar opcional por trás , que verifica se oprefix
grupo corresponde aqui. Caso isso aconteça, ele captura uma string vazia no diretórioflag
grupo. Caso contrário, por ser opcional, não afeta o estado do mecanismo de expressão regular e é ignorado. Finalmente, uma vez que o lookahead é correspondido com sucesso, resta apenas o\k<flag>
final que coincide apenas se o sinalizador foi definido em algum momento durante o cálculo.Agora vamos desmontar um pouco a regex longa usando grupos nomeados e modo de espaçamento livre:
Espero que você reconheça o esboço geral de cima, então precisamos apenas olhar para o que eu preenchi
...
.Queremos capturar o próximo personagem do ciclo no grupo
char
. Fazemos isso também lembrando a string de#
para o caractere atual emcycle
. Para obter o próximo caractere, usamos um lookahead para procurar o#
. Agora tentamos combinarcycle
e, em seguida, o próximo caracterechar
. Isso geralmente será possível, a menos quechar
seja o último caracterep
. Nesse caso,\k<cycle>
corresponderá a todo o restante da sequência e não haverá um caractere a ser capturadochar
. Portanto, o mecanismo recua, omite a referência traseiracycle
e apenas corresponde ao primeiro caracterer
.Agora, temos o próximo caractere do ciclo
char
, procuramos a próxima ocorrência possível desse caractere.*?\k<char>
. Esses são os caracteres que queremos substituir, então colocamos oprefix
cheque depois dele. Esses passos (encontre o próximochar
no ciclo, procure a próxima ocorrência dele, defina o sinalizador, se apropriado) agora são simplesmente repetidos com a+
.Na verdade, é tudo o que há para encontrar a subsequência cíclica, mas também precisamos garantir que terminemos em a
p
. Isso é bastante fácil: basta verificar se o valor atualmente armazenadochar
correspondep
ao final da string com.*\k<char>$
. Isso também garante que nossa string de pesquisa não seja usada para concluir um ciclo incompleto, porque precisamos do rastreamentop
para esta verificação.fonte
Python 2,
133 130 126121 bytesO primeiro loop obtém ciclos e o segundo remove um ciclo incompleto
Economizou 3 bytes graças ao JF e 5 do DLosc
fonte
r
en
assimr=n=''
:?R=r.count
não funciona, pois as seqüências são imutáveis, assimR
como''.count
quandor
é alterado.Perl 5,
7665 bytesUma pitada de expressões regulares puras e não diluídas.
Primeiro encontra o que não deve ser comido. O que resta é comestível.
Teste
fonte
[^o]*
etc., você pode usar.*?
(quantificador não ganancioso)?\s
vez de\n
na classe de caracteres negativos da primeira versão.r(.*?)o(.*?)y(.*?)g(.*?)b(.*?)p
n$1n$2n$3n$4n$5n
[^n\s]
e
(4 arquivos, 57 bytes).Lua, 101 bytes
Usa padrões de Lua de forma criativa; Eu acho que é uma abordagem interessante.
Ele substitui todos os caracteres não consumidos por "*" s, substitui todos os caracteres alfanuméricos por "e" s e, em seguida, substitui todos os "*" s por "n" s.
fonte
Javascript (ES6), 118
Fiddle testado no Firefox. Ouvi dizer que o Chrome suporta funções de seta agora, mas ainda não testei isso no Chrome.
Ungolfed:
fonte
...
notação.gawk, 96
Constrói o padrão de pesquisa
"([^r]*)r([^o]*)o([^y]*)y([^g]*)g([^b]*)b([^p]*)p"
e a substituição"\\1n\\2n\\3n\\4n\\5n\\6n"
. Após essa substituição, ele declara tudo o que é comida ("e"), que não faz parte de um arco-íris completo.Essa combinação garante automaticamente que nenhum arco-íris será prejudicado durante esta operação e nenhum arco-íris cortado será exibido no final.
fonte
Pitão, 42 bytes
Experimente online: Demonstração
fonte
CJam, 41 bytes
Abordagem de força bruta que tenta todas as variações de comer / não comer e seleciona a que resulta no colar mais longo e válido.
Experimente online no intérprete CJam .
fonte
CJam, 50 bytes
Experimente online
Isso é um pouco mais longo do que alguns dos outros envios, mas é muito eficiente com complexidade linear. Ele varre a string de entrada e combina os caracteres um por um.
A parte principal do algoritmo é realmente bastante compacta. Cerca da metade do código é para remover o ciclo incompleto no final.
fonte
C90, 142-146 bytes (até 119, dependendo)
Opera em tempo linear para comer eficientemente os loops de frutas que não podem fazer parte de um lindo arco-íris. Em seguida, um pós-processo mata qualquer loop parcial no final.
Aqui estão quatro versões:
Versão 1 (146 bytes), ligue com
[name] [string]
:main(int a,char**b){char*v=b[1],*s="roygbp",i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';while(k-->0)v[--i]='e';puts(v);}
Versão 2 (142 bytes), chame com
[name] [string] [rainbow order]
:main(int a,char**b){char*v=b[1],*s=b[2],i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';while(k-->0)v[--i]='e';puts(v);}
Isso permite que você defina seu próprio pedido de arco-íris com as cores que desejar, desde que não sejam
n
oue
. Isso realmente torna o código mais curto!Versão 3 (123 bytes), chame como a versão 1:
main(int a,char**b){char*v=b[1],*s="roygbp",i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';puts(v);}
Este fornece o máximo de seu arco-íris possível! Os arco-íris à direita incompletos mostram promessa! Não devemos comê-los!
Versão 4 (119 bytes), chame como a versão 2:
main(int a,char**b){char*v=b[1],*s=b[2],i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';puts(v);}
Igual à versão 3, mas MOAR RAINBOW TYPES!
Limitação menor: a máquina deve ter caracteres assinados (o caso geral) e a string deve ser bastante curta. Produz um final
\n
para maior clareza.A versão 1 é a única que passa claramente os requisitos, embora a versão 2 seja discutível. As versões 3 e 4 são uma interpretação menos correta (mas ainda divertida) da pergunta.
fonte
Pitão, 38 bytes
Eu sei que isso é significativamente mais longo que a resposta do orlp, mas este é executado em tempo linear: o)
Experimente aqui .
Em resumo, este programa substitui todos os caracteres após o 'p' final por espaços e itera sobre cada caractere na sequência resultante. Se o caractere for o próximo na sequência 'roygbp', imprima 'n', caso contrário, imprima 'e'.
Eu lutei para encontrar uma maneira mais curta de processar a string de entrada.
_>_zJ
em particular, parece estranho, mas<Jz
não fornece a sequência necessária quandoJ == 0
, ou seja, quando a entrada termina com um 'p'.fonte
Haskell, 138 bytes
g
faz isso.fonte
f
ez
como infixo:'n'%'n'='n'
etc. Além disso, alguns parênteses na definição deg
podem ser removidos com$
.Javascript (ES6),
8582 bytesA regra "colar deve terminar em púrpura" era originalmente um grande obstáculo, aumentando minha pontuação de 66 para 125, mas eu achei um caminho mais curto sobre ela (felizmente!).
Explicação:
Este código percorre cada caractere na entrada e substitui cada um por
r
oue
com esta lógica:p
E o personagem for o próximo no arco-íris, mantenha-o (substitua-o porn
).e
).Ungolfed:
Sugestões são bem-vindas!
fonte
Python 2, 254 bytes
Rotações!
Desculpe o trocadilho. : P
fonte