Fixando um colar de laço Froot


47

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 roygbprepetida 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 roygbpe imprima ou retorne uma sequência do mesmo comprimento eno lugar de loops para comer e nno lugar de loops para não comer.

Por exemplo, se o seu fio Froot Loop parecia

Froot Loop aleatória

a entrada seria

gorboypbgbopyroybbbogppbporyoygbpr

e indo da esquerda para a direita, podemos encontrar três roygbpseqüê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:

Costa de Froot Loop do ciclo de 3 arco-íris

Se não houver ciclos de arco-íris completos na entrada, a saída será toda ee o fio terminará sem loop. por exemplo, a entrada proygbtem saída eeeeee. Por outro lado, proygbptem 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.


1
@Fatalize Sim. Observe a parte sobre como maximizar o número de ciclos do arco-íris. Senão você poderia comer todos eles.
Calvin Hobbies

15
Você realmente classificou e enfiou as frutas para tirar as fotos, não é?
Martin Ender

13
@ MartinBüttner Naturalmente
Calvin's Hobbies

1
Todo ciclo do arco-íris precisa começar rou oygbproygbprtambém pode se qualificar?
orlp

4
Sim, mas se estiverem amarrados a um colar ou pulseira, certamente podem ser girados?
Peter Peter

Respostas:


11

Pitão, 31 bytes

:*lz\nhf!:jk.DzT"roygbp"kyUlz\e

Incrivelmente ineficiente, explicação em breve.

yUlzgera todos os subconjuntos possíveis de todos os índices possíveis de z(a entrada) em ordem. Por exemplo, se a entrada for abc:

[[], [0], [1], [2], [0, 1], [0, 2], [1, 2], [0, 1, 2]]

Em seguida, hf!encontra o primeiro Tna lista acima, tal que :jk.DzT"roygbp"ké falso. .Dpega uma string e uma lista de índices e exclui os elementos nesses índices. Assim .D"abcd",1 3é "ac". Como .Dretorna uma lista (que não deve ser o caso, será corrigida em versões futuras do Pyth), eu uso jk( kis "") para juntá-la novamente em uma string. A :_"roygbp"kpeç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_\edepois transforma essa lista de índices em uma nnnneeennenestring.


55

Hexagony , 920 722 271 bytes

Seis tipos diferentes de loops de frutas, você diz? Foi para isso que a Hexagony foi criada .

){r''o{{y\p''b{{g''<.{</"&~"&~"&<_.>/{.\.....~..&.>}<.._...=.>\<=..}.|>'%<}|\.._\..>....\.}.><.|\{{*<.>,<.>/.\}/.>...\'/../==.|....|./".<_>){{<\....._>\'=.|.....>{>)<._\....<..\..=.._/}\~><.|.....>e''\.<.}\{{\|./<../e;*\.@=_.~><.>{}<><;.(~.__..>\._..>'"n{{<>{<...="<.>../

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":

          ) { r ' ' o { { y \
         p ' ' b { { g ' ' < .
        { < / " & ~ " & ~ " & <
       _ . > / { . \ . . . . . ~
      . . & . > } < . . _ . . . =
     . > \ < = . . } . | > ' % < }
    | \ . . _ \ . . > . . . . \ . }
   . > < . | \ { { * < . > , < . > /
  . \ } / . > . . . \ ' / . . / = = .
 | . . . . | . / " . < _ > ) { { < \ .
  . . . . _ > \ ' = . | . . . . . > {
   > ) < . _ \ . . . . < . . \ . . =
    . . _ / } \ ~ > < . | . . . . .
     > e ' ' \ . < . } \ { { \ | .
      / < . . / e ; * \ . @ = _ .
       ~ > < . > { } < > < ; . (
        ~ . _ _ . . > \ . _ . .
         > ' " n { { < > { < .
          . . = " < . > . . /

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:

                 ) { r ' ' o { { \ / ' ' p { . . .
                . . . . . . . . y . b . . . . . . .
               . . . . . . . . ' . . { . . . . . . .
              . . . . . . . . \ ' g { / . . . . . . .
             . . . . . . . . . . . . . . . . . . . . .
            . . . . . . . . . . . . . . . . . . . . . .
           . . . . . . . . > . . . . < . . . . . . . . .
          . . . . . . . . . . . . . . > . . ) < . . . . .
         . . . . . . . . . . / = { { < . . . . ( . . . . .
        . . . . . . . . . . . ; . . . > . . . . . . . . . <
       . . . . . . . . . . . . > < . / e ; * \ . . . . . . .
      . . . . . . . . . . . . @ . } . > { } < . . | . . . . .
     . . . . . / } \ . . . . . . . > < . . . > { < . . . . . .
    . . . . . . > < . . . . . . . . . . . . . . . | . . . . . .
   . . . . . . . . _ . . > . . \ \ " ' / . . . . . . . . . . . .
  . . . . . . \ { { \ . . . > < . . > . . . . \ . . . . . . . . .
 . < . . . . . . . * . . . { . > { } n = { { < . . . / { . \ . . |
  . > { { ) < . . ' . . . { . \ ' < . . . . . _ . . . > } < . . .
   | . . . . > , < . . . e . . . . . . . . . . . . . = . . } . .
    . . . . . . . > ' % < . . . . . . . . . . . . . & . . . | .
     . . . . _ . . } . . > } } = ~ & " ~ & " ~ & " < . . . . .
      . . . \ . . < . . . . . . . . . . . . . . . . } . . . .
       . \ . . . . . . . . . . . . . . . . . . . . . . . < .
        . . . . | . . . . . . . . . . . . . . . . . . = . .
         . . . . . . \ . . . . . . . . . . . . . . . . / .
          . . . . . . > . . . . . . . . . . . . . . . . <
           . . . . . . . . . . . . . . . . . . . . . . .
            _ . . . . . . . . . . . . . . . . . . . . .
             . . . . . . . . . . . . . . . . . . . . .
              . . . . . . . . . . . . . . . . . . . .
               . . . . . . . . . . . . . . . . . . .
                . . . . . . . . . . . . . . . . . .
                 . . . . . . . . . . . . . . . . .

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:

insira a descrição da imagem aqui

O bit longo e reto à esquerda é usado como uma sequência terminada em 0, ade 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 como 1, de modo que saibamos onde o ciclo termina / começa (entre pe r):

){r''o{{y''g{{b''p{

Depois disso, voltamos ao limite identificado como 1 .

Agora, a ideia geral do algoritmo é esta:

  1. Para cada letra do ciclo, continue lendo as letras de STDIN e, se forem diferentes da letra atual, acrescente-as à string associada a essa letra.
  2. Quando lemos a carta que estamos procurando, armazenamos uma ena 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.
  3. Há duas maneiras de interromper esse processo:
    • Ou nós completamos o ciclo. Nesse caso, fazemos outra rápida ronda no ciclo, substituindo todos os es no ? arestas com ns, porque agora queremos que esse ciclo permaneça no colar. Em seguida, passamos à impressão de código.
    • Ou atingimos EOF (que reconhecemos como um código de caractere negativo). Nesse caso, escrevemos um valor negativo em ? borda do caractere atual (para que possamos distingui-lo facilmente de ambos ee n). 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.
  4. O código de impressão passa pelo ciclo novamente: para cada caractere no ciclo, ele limpa a sequência armazenada enquanto imprime um epara 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 ogda entrada nessas bordas e agora estamos lendo a y.

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 de r, passamos a borda (não marcado) para a esquerda do em e copiar o yali. Agora, avançamos mais pelo hexágono, copiando o caractere uma aresta cada vez mais, até que tenhamos ya aresta oposta a pol . Mas agora já existe um caractere em um [0] que não queremos sobrescrever. Em vez disso, "arrastar" o yem 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 oyafim 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 ? é positivo

Essa provavelmente será uma técnica útil para escrever código não trivial no Hexagony em geral.


12
...Uau. Apenas Uau.
Elias Benevedes

1
Não pode vencer o desafio de golfe, mas ... cara, isso é uma solução elegante ...
thanby

Como grupos de pontos seguidos parecem ocorrer com frequência na fonte, talvez você possa adicionar um recurso ao idioma para codificação de pontos no comprimento de execução ou algo para reduzir o comprimento do código.
mbomb007

@ mbomb007 O golfe não é realmente uma prioridade no Hexagony. ;) Além disso, não tenho mais caracteres para distinguir a codificação de comprimento de execução do código real ... (E acho que um código realmente bom não teria essas execuções de no-ops.)
Martin Ender

30

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.)

r'.'o\|{##|_#{#>\_{b{"]_\..<>"<>\/><#y/''"_<.}]''/'\>)}}.\}}'{<"\\#_#/<|##|#@#"p><n'>"{,<##g#_/#'.\<\##'#{(.<#e;#"\##%\\(};/*#>.)\>##_/"{__\}#>}=\#>=<|>##)|###_'#\"{__\\

Dispostas hexagonalmente:

       r ' . ' o \ | {
      # # | _ # { # > \
     _ { b { " ] _ \ . .
    < > " < > \ / > < # y
   / ' ' " _ < . } ] ' ' /
  ' \ > ) } } . \ } } ' { <
 " \ \ # _ # / < | # # | # @
# " p > < n ' > " { , < # # g
 # _ / # ' . \ < \ # # ' # {
  ( . < # e ; # " \ # # % \
   \ ( } ; / * # > . ) \ >
    # # _ / " { _ _ \ } #
     > } = \ # > = < | >
      # # ) | # # # _ '
       # \ " { _ _ \ \

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:

layout de memória próximo ao início do programa

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á 0se 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 quantos es precisamos produzir posteriormente.
  • r?: Sempre 0exceto onde está a parte r(vermelha). Isso nos diz quando completamos um ciclo.

O programa continua assim:

  • Continue lendo os personagens. Se não é o personagem que estamos procurando, aumente #. Caso contrário, vá para o próximo segmento da memória no sentido horário.
  • Ao passar para o próximo segmento, se r?for positivo, fizemos uma revolução inteira. Faça uma rodada completa e produza se # e1 npor segmento. Isso define cada um de #volta para 0. (Ele eé colocado em uma aresta sem rótulo, mas, para a ndesapropriação da #aresta, definimos o 0uso de uma *(multiplicação) depois, o que funciona porque sabemos que todas as %arestas são zero no momento.
  • Ao ler um personagem, se ele não for positivo (ou seja, EOF), volte ao redor do círculo e dê #+1 es até voltar ao ponto r?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 de e); uma das inarestas é -1(EOF); todas as #arestas estão em 0; e o ponteiro da memória termina na r?margem positiva .

layout de memória no final do programa


15

Retina , 148 85 79 bytes

$
#roygbp
.(?<=(?=((?=.*#(\2?(.))).*?\3(?<=^\5())?)+.*\3$)(.*))\4
n
#.*

[^n]
e

Você pode executar isso a partir de um único arquivo de origem com o -ssinalizador de intérprete.

Explicação

Vamos resolver as coisas simples primeiro:

$
#roygbp

Anexa #roygbpao 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.

#.*
<empty>

Isso se livra do nosso auxiliar de pesquisa no final da string.

[^n]
e

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:

.(?<=(?=...(?<=^\k<prefix>(?<flag>))?...)^(?<prefix>.*))\k<flag>

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 grupo prefix. 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 o prefixgrupo corresponde aqui. Caso isso aconteça, ele captura uma string vazia no diretórioflaggrupo. 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:

.
(?<=
  (?=
    (?:
      (?=
        .*#
        (?<cycle>
          \k<cycle>?
          (?<char>)
        )
      )
      .*?
      \k<char>
      (?<=^\k<prefix>(?<flag>))?
    )+
    .*
    \k<char>$
  )
  (?<prefix>.*)
)
\k<flag>

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 em cycle. Para obter o próximo caractere, usamos um lookahead para procurar o #. Agora tentamos combinar cyclee, em seguida, o próximo caractere char. Isso geralmente será possível, a menos que charseja o último caractere p. Nesse caso, \k<cycle>corresponderá a todo o restante da sequência e não haverá um caractere a ser capturado char. Portanto, o mecanismo recua, omite a referência traseira cyclee apenas corresponde ao primeiro caractere r.

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 o prefixcheque depois dele. Esses passos (encontre o próximo charno 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 armazenado charcorresponde pao 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 rastreamento ppara esta verificação.


7

Python 2, 133 130 126 121 bytes

r=n=''
for c in input():r+='en'[c=='roygbp'[r.count('n')%6]]
for c in r:n+=['e',c][n.count('n')<r.count('n')/6*6]
print n

O primeiro loop obtém ciclos e o segundo remove um ciclo incompleto

Economizou 3 bytes graças ao JF e 5 do DLosc


Você não conseguiu combinar a inicialização re nassim r=n='':?
JF

A atribuição R=r.countnão funciona, pois as seqüências são imutáveis, assim Rcomo ''.countquando ré alterado.
Ruth Franklin

3

Perl 5, 76 65 bytes

Uma 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.

s/r(.*?)o(.*?)y(.*?)g(.*?)b(.*?)p/n$1n$2n$3n$4n$5n/g;s/[^n\s]/e/g

Teste

$ perl -p fruitloops.pl <<<gorboypbgbopyroybbbogppbporyoygbpr
eenenneennenennneeeeneennenennnnne

1
Eu gosto dessa abordagem. Em vez de [^o]*etc., você pode usar .*?(quantificador não ganancioso)?
DLosc

Ótima dica, obrigado! Eu não sabia que o qualificador não ganancioso seria útil.
LukStorms 15/09/2015

Se você deseja evitar a substituição de espaços à direita, pode usar em \svez de \nna classe de caracteres negativos da primeira versão.
DLosc

1
Mesma abordagem na Retina: r(.*?)o(.*?)y(.*?)g(.*?)b(.*?)p n$1n$2n$3n$4n$5n [^n\s] e(4 arquivos, 57 bytes).
DLosc

Oh, certo. \ s inclui também os feeds de linha. Boa pegada. E bom saber que Retina pode pelo menos vencer Perl em seu próprio jogo.
LukStorms 15/09/2015

3

Lua, 101 bytes

s=arg[1]:gsub("r(.-)o(.-)y(.-)g(.-)b(.-)p.-","*%1*%2*%3*%4*%5*"):gsub("%w","e"):gsub("*","n")print(s)

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.


2

Javascript (ES6), 118

a=>eval("b=[...a],d=0,e=b.map(f=>f=='roygbp'[d%6]?'n'[++d&0]:'e');for(i=e.length-1;i&&b[i]!='p';e[i--]='e');e.join``")

Fiddle testado no Firefox. Ouvi dizer que o Chrome suporta funções de seta agora, mas ainda não testei isso no Chrome.

Ungolfed:

input=>eval("
    array = [...input],
    rainbow_index = 0,
    mapped = array.map( item=>
        item == 'roygbp'[rainbow_index%6] ? 'n'[++rainbow_index&0] : 'e'
        // when we encounter an item of the rainbow, do not eat and start using
        // the next rainbow item, otherwise eat
    );
    // go through backwards and eat until we find a 'p' indicating the last
    // complete loop
    for(i = mapped.length - 1; i && array[i]!='p'; mapped[i--] = 'e');

    mapped.join``
")

O Chrome suporta funções de seta, mas aparentemente ainda não é a ...notação.
DLosc

2

gawk, 96

{for(;c=substr("roygbp",++i,1);r=r"\\"i"n")p=p"([^"c"]*)"c;$0=gensub(p,r,"g");gsub(/[^n]/,"e")}1

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.



1

CJam, 41 bytes

2r:R,m*{R.*s__,6/"roygbp"*=\,~*}$0="en"f=

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 .


1

CJam, 50 bytes

l{"roygbp"T=={'nT):T;}{'e}?}%W%_'ne=6%{_'n#'et}*W%

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.


1

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 nou e. 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.


1

Pitão, 38 bytes

Eu sei que isso é significativamente mais longo que a resposta do orlp, mas este é executado em tempo linear: o)

u+G?qH@"roygbp"/G\n\n\e+_>_zJx_z\p*Jdk

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'.

                                          Implicit: z=input(), d=' ', k=''
                            Jx_z\p        Find number of chars after last p, store in J
                        _>_zJ             Take all but J chars of the input
                       +          *Jd     Append J spaces
u                                    k    Reduce on the above, starting with ''
               /G\n                       Count 'n' in output so far
      @"roygbp"                           Take relevant char from sequence string (modulus indexing)
   ?qH                                    Does the current char equal the above?
 +G                \n\e                   Select 'n' or 'e' as appropriate and append

Eu lutei para encontrar uma maneira mais curta de processar a string de entrada. _>_zJem particular, parece estranho, mas <Jznão fornece a sequência necessária quando J == 0, ou seja, quando a entrada termina com um 'p'.


1

Haskell, 138 bytes

g faz isso.

f(c:r)(h:t)|c==h='n':(f(r++[c])t)|0<1='e':(f(c:r)t)
f _""=""
z 'n' 'n'='n'
z a b='e'
r=reverse
g s=zipWith z(f"roygbp"s)(r$f"pbgyor"(r s))

Eu acho que você pode salvar alguns bytes, definindo fe zcomo infixo: 'n'%'n'='n'etc. Além disso, alguns parênteses na definição de gpodem ser removidos com $.
Zgarb 16/09/2015

1

Javascript (ES6), 85 82 bytes

A 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!).

s=>(i=j=0,s.replace(/./g,x=>s.lastIndexOf`p`>=j++&x=='roygbp'[i%6]?(i++,'n'):'e'))

Explicação:

Este código percorre cada caractere na entrada e substitui cada um por rou ecom esta lógica:

  • Se a posição do personagem for <= a última posição de pE o personagem for o próximo no arco-íris, mantenha-o (substitua-o porn ).
  • Caso contrário, coma (substitua-o por e).

Ungolfed:

function a(s) {
  var i=0, j=0, r='';
  t = t.replace(/./g, function (x) {
    if (s.lastIndexOf('p') >= j++ && x == 'roygbp'.charAt(i)) {
      i++;
      i %= 6;
      return 'n';
    } else {
      return 'e';
    }
  });
  return r;
}

Sugestões são bem-vindas!


0

Python 2, 254 bytes

Rotações!

i=raw_input();r='roygbp';l='r';d=''
for n in i:
 if n==l:d+='n';l=r[(r.index(l)+1)%6]
 else:d+='e'
d=list(d)[::-1];p=(r.index(l)+1)%6;
for s in range(len(d)):
 if d[s]=='n'and p-1:d[s]='e';p-=1
if d.count('n')<6:print'e'*len(d)
else:print''.join(d[::-1])

Desculpe o trocadilho. : P

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.