Injetar Rickrolls Textuais

13

Como o rickrolling é o melhor meme da Terra, você [conhece as regras e eu também] deve escrever o código mais curto que pode rickrollar textualmente o leitor desavisado. Deixe [você embaixo] um texto de entrada que contenha letras, pontuação e espaços. Sempre que uma frase [mentir e machucar você] das duas primeiras estrofes aparece no texto ...

We're no strangers to love
You know the rules and so do I
A full commitment's what I'm thinking of
You wouldn't get this from any other guy
I just wanna tell you how I'm feeling
Gotta make you understand

Never gonna give you up
Never gonna let you down
Never gonna run around and desert you
Never gonna make you cry
Never gonna say goodbye
Never gonna tell a lie and hurt you

... insira o restante da linha entre parênteses depois.

Entrada

Entrada é uma sequência de linhas única que contém apenas ASCII imprimível com nova linha à direita opcional.

Resultado

Saída é uma sequência de linha única. Sempre que um grupo de palavras (definido como a sequência de entrada dividida em espaços) corresponder a um grupo de palavras nas linhas das letras acima, insira as palavras restantes da linha na sequência, agrupadas entre colchetes.

Descrição adicional:

Isso é código-golfe , o menor número de bytes vence. Você pode escrever um programa ou função.

  • a correspondência não diferencia maiúsculas de minúsculas: we'reé convertida em we're [no strangers to love]mesmo que We'reesteja em maiúscula na letra.
  • a correspondência deve ser gananciosa. Does he know the answer?deve ser convertido para em Does he know the [rules and so do I] answer?vez deDoes he know [the rules and so do I] the [rules and so do I] answer?
  • Se uma palavra aparecer mais de uma vez na letra fornecida, escolha qualquer uma das ocorrências para completar a linha.
  • Se uma palavra for a última na linha da letra, não insira nada depois dela.
  • A pontuação é incluída como parte de uma "palavra". I'mé uma única palavra e não pode corresponder a I. Da mesma forma, you.não combina com nenhuma letra por causa do período.

Algumas palavras como Iaparecem várias vezes ao longo da letra, bem como no final de uma linha. Como a regra é que qualquer ocorrência nas letras acima pode ser usada e uma dessas ocorrências está no final de uma linha, nenhuma correspondência Ié necessária. A outra opção para Ié [just wanna tell you how I'm feeling].

Se duas correspondências se sobrepuserem, você pode escolher uma delas. Isso significa que how I'm thinkingpode se tornar how I'm [feeling] thinking [of]OR, how [I'm feeling] I'm thinking [of]pois I'mpode fazer parte de um how I'mou de outro I'm thinking. Se, no entanto, o texto de entrada era simples I'm thinking, a saída deveria ser I'm thinking [of].

Casos de teste adicionais:

I don't know what I'm doing with my life.
is converted to
I [just wanna tell you how I'm feeling] don't know [the rules and so do I] what I'm [thinking of] doing with my life.
Many additional solutions are possible, since words like `I` appear multiple times.


Will someone please save me from these memes?
is converted to
Will someone please save me from [any other guy] these memes?


Two strangers walked into a bar.  One said "hello."  The other said "goodbye."
is converted to
Two strangers [to love] walked into a [lie and hurt you] bar.  One said "hello."  The [rules and so do I] other [guy] said "goodbye."

Desafio inspirado por esse cara .

PhiNotPi
fonte
11
ಠ_ಠ
Alex A.
O segundo caso de teste parece estar errado ( fromdeve ficar from [any other guy]).
Maçaneta

Respostas:

6

gawk, 316 + 377 = 693

O primeiro parâmetro da linha de comando é o nome do arquivo da letra (375 bytes + 2 para invocação = 377). Rickrolls todos os outros arquivos. Imprime em stdout.

BEGIN{FPAT="[^ ]+ *";OFS=""}func d(a){b=tolower(a);sub(/ *$/,"",b);return b}FNR==NR{for(s=$0;NF;$0=s=$0){for(i=1;i<NF;i++){k=k $i;$i="";v[d(k)]="["$0"] "}$0=s;k=$1=""}next}{for(s=$0;NF;$0=s=$0){for(j=NF;(--j)>0&&!(d($0) in v);$(j+1)="");k=v[d($0)];if($0!~/ $/)k=" "k;printf($0 k);for($0=s;j-->=0;$(j+2)="");}print""}

Ungolfed

BEGIN{FPAT="[^ ]+ *";OFS=""}
func d(a){b=tolower(a);sub(/ *$/,"",b);return b}
FNR==NR{
  for(s=$0;NF;$0=s=$0){
    for(i=1;i<NF;i++)
    {
      k=k $i;
      $i="";
      v[d(k)]="["$0"] "
    }
    $0=s;
    k=$1=""
  }
  next
}
{
  for(s=$0;NF;$0=s=$0){
    for(j=NF;(--j)>0&&!(d($0) in v);$(j+1)="");
    k=v[d($0)];
    if($0!~/ $/)k=" "k;
    printf($0 k);
    for($0=s;j-->=0;$(j+2)="");
  }
  print""
}

Resultado dos testes

Entrada:

we're
We're
Does he know the answer?
I
how I'm thinking
I'm thinking
I don't know what I'm doing with my life.
Will someone please save me from these memes?
Two strangers walked into a bar.  One said "hello."  The other said "goodbye."
gonna run

Resultado:

we're [no strangers to love] 
We're [no strangers to love] 
Does he know the [rules and so do I] answer? 
I [just wanna tell you how I'm feeling] 
how I'm [feeling] thinking [of] 
I'm thinking [of] 
I [just wanna tell you how I'm feeling] don't know [the rules and so do I] what I'm [thinking of] doing with my life. 
Will someone please save me from [any other guy] these memes? 
Two strangers [to love] walked into a [lie and hurt you] bar.  One said "hello."  The [rules and so do I] other [guy] said "goodbye." 
gonna run [around and desert you] 
Rainer P.
fonte
1. Isso falha no primeiro caso de teste (coloca as coisas entre whate I'm, que é uma correspondência "não gananciosa"). 2. Isso falha no terceiro caso de teste (ele transforma os dois espaços em um). 3. Se você armazenar as letras em um arquivo separado, precisará contar esse arquivo (além de +2 para incluí-lo no awkcomando) na contagem de bytes.
Maçaneta
@Doorknob Thanks. A ganância é fixa. O arquivo da letra não é adicionado à minha contagem de caracteres, pois é inalterado e estava disponível ao público antes do início do desafio. Também não conto awko código fonte.
Rainer P.
Agora, isso falha na entrada gonna run(saída esperada gonna run [around and desert you], saída real gonna [tell a lie and hurt you] run [around and desert you]). Ele também mastiga vários espaços seguidos. Você precisa contar o arquivo de letras na contagem de bytes, pois é uma invocação não padrão do awkprograma.
Maçaneta
@Doorknob Ok. Reimplementei a maior parte do programa e exijo gawkagora a separação de campos com preservação de espaço. Passa em todos os casos de teste agora.
Rainer P.
Impressionante. Foi muito difícil cobrir todos os casos extremos neste desafio.
Maçaneta