Código de golfe para meus verdadeiros amigos

35

... e golfe de verdade para meus amigos de código.

Este é um desafio baseado em uma história em quadrinhos XKCD de um ano que consiste principalmente de brindes (paródias da primeira história em quadrinhos) seguindo um padrão distinto, mas com uma ligeira variação.

Sua tarefa é escrever um programa (ou função) que receba a primeira metade de qualquer brinde do quadrinho (tudo, inclusive o friends) como entrada (via stdin ou argumento de função) e produza (ou retorne) o texto preciso de A segunda parte. Você não precisa manipular entrada inválida, aplicam-se brechas padrão, o código mais curto em bytes ganha.

Exemplos

Para ajudar aqueles que não querem copiar os brindes de qualquer outro lugar, aqui estão todos eles, separados em entrada e saída.

Input: Champagne for my real friends
Output: and real pain for my sham friends!

Input: Pseudopods for my real friends
Output: and real pods for my pseudo-friends!

Input: Petticoats for my real friends
Output: and real coats for my petty friends.

Input: Loosestrife for my real friends
Output: and real strife for my loose friends!

Input: Ladybugs for my real friends
Output: and real bugs for my lady friends!

Input: Single-payer for my real friends
Output: and RealPlayer for my single friends.

Input: Tumbleweeds for my real friends
Output: and real weed for my Tumblr friends!

Input: Fauxhawks for my real friends
Output: and real hawks for my faux friends!

Input: Platonic solids for my real friends
Output: and real solids for my platonic friends!
ivzem
fonte
Eu acho que você tem um erro de digitação em Single-payer(em vez de Single-player).
Kevin Cruijssen 13/03/19
4
Kevin: Não. Realmente é Single-payer.
ivzem
@KevinCruijssen - Pode ser um erro de digitação, mas, se for, é o Randall @ XKCD's, não o ivzem. Há uma discussão sobre isso no Explain xkcd . Além disso, ivzem - assim que vi o título na lista HNQ, eu tinha certeza de que você estava fazendo referência a esse quadrinho. Bem feito!
Bobson

Respostas:

18

Retina , 119 bytes

A versão anterior não gerenciava corretamente o espaço em "sólidos platônicos", esta funciona e é mais curta :)

ew
rw
eds
ed
(\w+) ?([^oatr ]\w{3}.+)real
and real $2$1
C
S
gne
in
o 
o-
ti
ty
T`TL`Tl
p\w+y.+
$&.
s$
s!
real -p
RealPl

Experimente online!

Isso transforma a entrada na saída através de uma série de substituições.

A parte mais interessante é essa substituição (tipo um regex golf):

(\w+) ?([^oatr ]\w{3}.+)real
and real $2$1

O que faz quase todo o trabalho, dividindo a primeira palavra, colocando suas peças nos lugares certos, removendo espaços extras e construindo a estrutura da saída. Para funcionar corretamente no caso de teste "Tumbleweeds", isso depende da substituição anterior "eds" -> "ed".

O restante é composto principalmente por substituições que tratam de casos especiais. Outras partes interessantes são:

T`TL`Tl

Isso transforma tudo, exceto "T" (no Tumblr), em minúsculas.

p\w+y.+
$&.
s$
s!

Isso coloca um "." no final de cada frase, contendo uma palavra com "y" algumas letras após "p" ("mesquinho" e "pagador" na prática). Então coloca um "!" no final de todas as frases terminadas com um "s" (todas as outras).

Leo
fonte
Isso imprime um espaço extra depois platonic. Correção sugerida: TIO (+5 bytes)
math junkie
11
@math_junkie Obrigado, I fez upload de uma nova versão que corrige o problema com espaços e é ainda mais curto :)
Leo
10

Python 2, 291 269 293 255 247 bytes

Obrigado Erik the Outgolferpor salvar 22 bytes!

+24 bytes para contabilizar algumas saídas que terminam em .vez de!

lambda x:'and '+['real '+'pain%ssham ,pods%spseudo-,coats%spetty ,strife%sloose ,bugs%slady ,weed%sTumblr ,hawks%sfaux ,solids%splatonic '.split(',')['noarsekc'.find(x[7])],'RealPlayer%ssingle ']['-'in x]%' for my '+x[-7:]+'!.'['-'in x or'tt'in x]

Solução simples para começar. Verifica a oitava letra da entrada, conforme sugerido nos comentários, e procura a saída correspondente em um dicionário uma matriz.

Experimente Online!

viciado em matemática
fonte
Você pode ter esquecido Single-payer for my real friends...
Mathieu Rodic
@MathieuRodic Não, isso é bastante intencional. RealPlayeré um caso especial
junkie de matemática 14/03
Opa, desculpe, leia muito rapidamente.
Mathieu Rodic
6

SOGL , 143 bytes

_╔x⅜²‘,8WWAa"⅞+1Tλ²⅞ƨ◄…χŗbdŗu8ņ∑Ι⅓I‼hzΔμō┘═q‼xΘ▼²ηpG⅔─┌¡↕+wd÷[≈┐α┌ļ○(‚δΦEΤα{‚φ▒k׀:╚s&⅛↑»‘ |Θwθ1w"ρ└⁸‘S∆∫⁴‘a1>*+oo"¤Ε○Φr‘o2w _@ŗo"æn‘o"χ}49⁶‘aWT

Isso usa essa string como parte principal. "|" são os divisores e "_" são espaços reservados para espaço, portanto, a divisão funcionaria corretamente.

RealPlayer single_|weed Tumblr_|strife loose_|bugs lady_|pods pseudo-|pain sham_|solids platonic_|coats petty_|hawks faux_

Exemplo de entrada: "Sólidos platônicos para meus verdadeiros amigos" Explicação:

..‘,8WWAa"..‘ |Θwθ1w"..‘S∆∫⁴‘a1>*+oo"..‘o2w _@ŗo"..‘o"..‘aWT  strings shortened
..‘                                                           push "personcake" (the indexing string) ["personcake"]
    8W                                                        get the 8-th char                       
   ,                                                           from the input                         ["personcake", "c"]
      W                                                       get its in "personcake" (1-indexed)     [7]
       Aa                                                     save on variable A                      [7]
         "..‘                                                 push the long string                    [7, "RealPlayer...faux_"]
              |Θ                                              split on "|"                            [7, ["RealPlayer single_", ..., "hawks faux_"]]
                w                                             get the Ath item of the array           [["..."], "solids platonic_"]
                 θ                                            split on spaces                         [["..."], ["solids", "platonic_"]]
                  1w                                          get the 1st item                        [["..."], ["solids", "platonic_"], "solids"]
                    "..‘                                      push "and "                             [["..."], ["solids", "platonic_"], "solids", "and "]
                        S∆∫⁴‘                                 push "real "                            [["..."], ["solids", "platonic_"], "solids", "and ", "real "]
                             a1>*                             multiply by A(index) > 1                [["..."], ["solids", "platonic_"], "solids", "and ", "real "]
                                 +                            join together                           [["..."], ["solids", "platonic_"], "solids", "and real "]
                                  o                           output                                  [["..."], ["solids", "platonic_"], "solids"]
                                   o                          output (the 1st item of the array)      [["..."], ["solids", "platonic_"]]
                                    "..‘o                     output " for my "                       [["..."], ["solids", "platonic_"]]
                                         2w                   get the 2nd item of the array           [["..."], ["solids", "platonic_"], "platonic_"]
                                            _@ŗ               replace "_" with " "                    [["..."], ["solids", "platonic_"], "platonic "]
                                               o              output that                             [["..."], ["solids", "platonic_"]]
                                                "..‘o         output "friends"                        [["..."], ["solids", "platonic_"]]
                                                     "..‘     push ".!!!!!!.!"                        [["..."], ["solids", "platonic_"], ".!!!!!!.!"]
                                                         aW   get the Ath item                        [["..."], ["solids", "platonic_"], "!"]
                                                           T  output, disabling implicit output       [["..."], ["solids", "platonic_"]]
dzaima
fonte
6

Python 3 , 788 , 403 , 359 396 bytes

Última versão

Esta é agora a minha quinta tentativa. Consegui metade do tamanho do meu programa original. Agora inclui o "-" ausente e acredito que seja uma solução completa. Ainda suspeito do lado volumoso; mas muito mais perto do objetivo. Eu tive muita ajuda . Obrigado por todas as orientações úteis.

s=input()
x=0
l= "Ch,pain,Sham,Ps,pods,psuedo-,Pe,coats,petty,Lo,strife,loose,La,bugs,lady,Si,RealPlayer,single,Tu,weed,Tumblr,Fa,hawks,faux,Pl,solids,platonic".split(",")
a,b,c,d,e,f,g,h = " and real","for my","friends",".!","print(a,l[p+1],b,l[p+2]",",c+d[0])","+c+d[1])",",c+d[1])"
for p in range(0,27,3):
 x+=1
 if s[:2] == l[p]:
  if x == 2: eval(e+g)
  else: eval(e+f if x in(3,6) else e+h)

Experimente online!


Postagem original

Este é o meu primeiro post sobre código de golfe, então peço desculpas antecipadamente pelo meu programa desajeitado. Não é possível ver como um programa poderia ser feito para converter "Champagne" em "pain", "sham" analisando as palavras. No entanto, eu gostaria de ver alguém resolver isso. Portanto, como meu nível de habilidade determina que meu programa precise saber com antecedência que "Champagne" é "dor", "farsa", parecia haver pouco sentido em realmente codificar uma solicitação de entrada. Como resultado, deixei de fora e fui um pouco literal com minha saída de impressão. Espero que esteja tudo bem :)

phraseList= [   ("Champagne","pain","Sham"), 
                ("Psudeopods","pods","psuedo-"), 
                ("Petticoats","coats","petty"),
                ("Loosestrife","strife","loose"),
                ("Ladybugs","bugs","lady"),
                ("Single-payer","coats","petty"),
                ("Petticoats","RealPlayer","single"),
                ("Tumbleweeds","weed","Tumblr"),
                ("Fauxhawks","hawks","faux"),
                ("Platonic solids","real solids","platonic")
                ]

for phrase in phraseList:
    print("Input: ",phrase[0], "for my real friends.")
    if "-" in phrase[2]:
        print("Output: and real", phrase[1], "for my", phrase[2]+ "friends!")
    else:
        print("Output: and real", phrase[1], "for my", phrase[2], "friends!")
Brian
fonte
3
Da Central de Ajuda : Todas as soluções para os desafios devem: [...] Ser um candidato sério aos critérios vencedores em uso. Por exemplo, uma entrada em um concurso de código de golfe precisa ser jogada, e uma entrada em um concurso de velocidade deve fazer alguma tentativa de ser rápida.
Erik the Outgolfer
11
Olá e bem-vindo ao site. Essa é uma questão de código-golfe que exige que você faça um esforço para minimizar o tamanho do seu código. Você deve remover espaços em branco desnecessários e renomear variáveis ​​com 1 caractere.
Assistente de trigo
Você pode colocar a frase inteira List em uma linha, reduzir a indentação em um espaço, juntar as impressões em uma linha com if e else, e o espaço em branco nas impressões não é necessário. Enfim, eu não sei se você está autorizado a apenas imprimir todas as saídas;)
Mega Man
11
Olá! Parece que esta é sua primeira resposta de código de golfe. Infelizmente, você parece ter entendido mal a pergunta, especialmente a tabela "Exemplos" na parte inferior, que mostra apenas como cada entrada deve mapear para uma saída correspondente. Atualmente, o seu programa apenas imprime essa tabela. mais como uma competição de Assistente de trigo um Q & a site._ já fez isso, de modo que é melhor
ivzem
Olá e bem-vindo ao PPCG. Você pode perder muitos bytes removendo espaços e usando variáveis ​​de letra única. Lembro que, quando comecei aqui, demorou algum tempo para me acostumar. Eu acho que você é como eu. Você gasta muito tempo escrevendo código legível. Como eu disse, bem-vindo ao PPCG e um novo mundo;)
ElPedro
6

Röda , 299 292 288 259 bytes

4 bytes salvos graças a @fergusq por usar em ,vez de ..nas pushinstruções

Bytes salvos graças a @fergusq me mostrando o caminho indexOf

h a{r=indexOf(a[7:8],"noarspekc")A="pain>pods>coats>strife>Player>bugs>weed>hawks>solids>sham >pseudo->petty >loose >lady >single >Tumblr >faux >platonic >!>!>.>!>!>.>!>!>!"/">";["and "];["Real"]if[r=4]else["real "];[A[r]," for my ",A[r+9],"friends",A[r+18]]}

Experimente online!

Tão perto de Python ... tão perto .... Sua jogada, Python.

Explicação

h a{
  r=indexOf(a[7:8],"noarspekc")  /*Gets the index of the character in this string*/
  /*Variable A contains all the unique words for each test case*/
  A="pain>pods>coats>strife>Player>bugs>weed>hawks>solids>sham >pseudo->petty >loose >lady >single >Tumblr >faux >platonic >!>!>.>!>!>.>!>!>!"/">"
  ["and "]
  ["Real"]if[r=4]else["real "]   /*RealPlayer*/
  [A[r]," for my ",A[r+9],"friends",A[r+18]]   /*Print everything using var A*/
}
Kritixi Lithos
fonte
Você pode salvar um byte usando interpolação de string na última instrução? Edit: na verdade, a maneira mais curta é provavelmente empurrar muitas strings para o stream em vez de uma, ie. substitua ..por ,.
fergusq
@fergusq Obrigado pela dica!
Kritixi Lithos 12/03
Além disso, você pode simplesmente usar r=indexOf(a[7:8],"noarspekc").
fergusq
@fergusq Ah, eu não sabia que esse tipo de coisa existia. Obrigado!
Kritixi Lithos 13/03/19
5

JavaScript (ES6), 230 228 221 216 bytes

s=>'and '+((n='paonrsekc'.search(s[7]))?'real ':'')+'RealPl740s5 /450p3y /540p5-/pain0s3 /460l4 /340l3 /540T4r /350f3 /860p7 '.split`/`[n].replace(/\d\d?/g,n=>s.substr(n/10+1,n%10)||' for my ')+'friends'+'.!'[+(n>1)]

Teste

Arnauld
fonte
3

PHP, 202 220 204 203 bytes

and real <?=[pods,solids,hawks,strife,RealPlayer,pain,bugs,weed,coats][$q=md5($argv[1].LnI)%9].' for my '.[pseudo,platonic,faux,loose,single,sham,lady,Tumblr,petty][$q].' -'[!$q].friends.'.!'[!$q||$q&3];
user63956
fonte
3

Perl, 173 168 bytes

Removendo novas linhas e recuos, isso se torna 173 bytes de código Perl5. Roubou descaradamente a primeira regexp da resposta de Retina de Leo. (O meu demorou alguns caracteres a mais)

sub f{
  my($_)=@_;
  s,(\S+[oieyxm ])(\S{4}.+)real,and real $2\l$1,;
  s,gne,in,;
  s,ch,sh,;
  s,ti,ty,;
  s,eds,ed,;
  s,tumble,Tumblr,;
  s,real -p,RealPl,;
  s,o ,o-,;
  s,c ,c,;
  /ng|tt/?"$_.":"$_!"
}

Para a versão perl5> = 5.14, outros 5 bytes podem ser removidos com eval e o novo / r modificador de substituição de regexp. Terminando com 168 bytes:

sub f{my($_)=@_;eval's,(\S+[oieyxm ])(\S{4}.+)real,and real $2\l$1Xgne,inXch,shXti,tyXeds,edXtumble,TumblrXreal -p,RealPlXo ,o-Xc ,c,;/ng|tt/?"$_.":"$_!"'=~s/X/,;s,/gr}

Experimente online!

Kjetil S.
fonte
2

C, 367 bytes

Não acabou tão curto quanto parecia.

i,j,c;f(char*s){c=s[7]-97;char t[9],u[200];char*r=s;s+=j=c&&c-17?c-10&&c-18?c-2?5:8:3:4;for(i=0;*++s-32;t[i++]=*s);t[c-4?i:i-1]=0;for(i=0;*r++-t[0];)u[i++]=*(r-1);u[i]=32;u[i+1]=0;u[0]+=32;u[c?i:i-1]=c?c-2?c-14?32:45:0:121;printf("and %s%s for my %sfriends%c",c-15?"real ":"RealPlayer",c-15?c-13?t:"pain":"",c-13?c-4?c-17?u:"loose ":"Tumblr ":"sham ",c&&c-15?33:46);}
Steadybox
fonte
2

Java 7, 585 553 bytes

import java.util.*;String c(String s){Map m=new HashMap(){{put("Ch","pain");put("Ps","pods");put("Pe","coats");put("Lo","strife");put("La","bugs");put("Si","Player");put("Tu","weed");put("Fa","hawks");put("Pl","solids");put("Ch1","sham ");put("Ps1","pseudo-");put("Pe1","petty ");put("Lo1","loose ");put("La1","lady ");put("Si1","single ");put("Tu1","Tumblr ");put("Fa1","faux ");put("Pl1","platonic ");}};String r=s.substring(0,2);int c=r.charAt(1);return"and "+(c=='i'?"Real":"real ")+m.get(r)+" for my "+m.get(r+1)+"friends"+(c=='i'|c=='e'?'.':'!');}

-32 bytes graças a @Zircon .

Definitivamente, você pode jogar golfe usando algo diferente de um mapa.

Explicação:

import java.util.*;            // Import required for the Map & HashMap
String c(String s){            // Method with String parameter and String return-type
  Map m=new HashMap(){{        //  The Map
    put("Ch","pain");put("Ps","pods");put("Pe","coats");put("Lo","strife");put("La","bugs");put("Si","Player");put("Tu","weed");put("Fa","hawks");
                               //  Add mapping from first two characters with first word
    put("Ch1","sham ");put("Ps1","pseudo-");put("Pe1","petty ");put("Lo1","loose ");put("La1","lady ");put("Si1","single ");put("Tu1","Tumblr ");put("Fa1","faux ");put("Pl1","platonic ");
                               //  Add mapping from first two characters + "1" with second word (+ space or '-' for edge-case `pseudo-friends`)
  }};                          // End of Map initialization
  String r=s.substring(0,2);   //  Get the first two characters of the input String
  int c=r.charAt(1);           //  Get the second character
  return "and "                //  return "and "
    + (c=='i'?"Real":"real ")  //   + "Real" or "real " for edge-case `RealPlayers`
    + m.get(r)                 //   + first word from Map
    + " for my "               //   + " for my "
    + m.get(r+1)               //   + second word from Map
    + "friends"                //   + "friends"
    + (c=='i'|c=='e' ? '.'     //   + '.' for edge-cases 'Petticoats' and 'Single-player
      : '!');                  //     or '!' for all other cases
}                              // End of method

Código do teste:

Experimente aqui. (ideone.com está com problemas ultimamente, então estou usando o TIO agora ..)

import java.util.*;
class M{
  static String c(String s){Map m=new HashMap();m.put("Ch","pain");m.put("Ps","pods");m.put("Pe","coats");m.put("Lo","strife");m.put("La","bugs");m.put("Si","Player");m.put("Tu","weed");m.put("Fa","hawks");m.put("Pl","solids");m.put("Ch1","sham ");m.put("Ps1","pseudo-");m.put("Pe1","petty ");m.put("Lo1","loose ");m.put("La1","lady ");m.put("Si1","single ");m.put("Tu1","Tumblr ");m.put("Fa1","faux ");m.put("Pl1","platonic ");String r=s.substring(0,2);int c=r.charAt(1);return"and "+(c=='i'?"Real":"real ")+m.get(r)+" for my "+m.get(r+1)+"friends"+(c=='i'|c=='e'?'.':'!');}

  public static void main(String[] a){
    System.out.println(c("Champagne for my real friends"));
    System.out.println(c("Pseudopods for my real friends"));
    System.out.println(c("Petticoats for my real friends"));
    System.out.println(c("Loosestrife for my real friends"));
    System.out.println(c("Ladybugs for my real friends"));
    System.out.println(c("Single-player for my real friends"));
    System.out.println(c("Tumbleweeds for my real friends"));
    System.out.println(c("Fauxhawks for my real friends"));
    System.out.println(c("Platonic solids for my real friends"));
  }
}
Kevin Cruijssen
fonte
11
Eu acho que você pode salvar bytes usando a inicialização entre chaves e em putvez de m.put.
Zircon
2

C (gcc) , 311 bytes

Padrões claros, mas muitas exceções. Ainda assim, deve haver uma maneira melhor do que isso!

f(char*s){char*t="\"5$#(=931",*r[]={"pain", "sham","pods","pseudo","coats","petty","strife","loose","bugs","lady","Player","single","weed","Tumblr","hawks","faux","solids","platonic"};int i=strchr(t,*s^s[2])-t;printf("and %s%s for my %s%cfriends%c",i^5?"real ":"Real",r[i*2],r[i*2+1],i^1?32:45,i^5&&i^2?33:46);}

Experimente online!

gastropner
fonte