Código de golf para mis verdaderos amigos

35

... y golf real para mis amigos de código.

Este es un desafío basado en un cómic XKCD de un año que consiste principalmente en brindis (parodias del primero en el cómic) siguiendo un patrón distinto, pero con una ligera variación.

Su tarea es escribir un programa (o función) que tome la primera mitad de cualquier tostada del cómic (todo hasta e incluyendo el friends) como entrada (a través de stdin o un argumento de función) y genera (o devuelve) el texto preciso de la segunda mitad. No tiene que manejar entradas no válidas, se aplican lagunas estándar, el código más corto en bytes gana.

Ejemplos

Para ayudar a aquellos que no quieren copiar las tostadas de ningún otro lado, aquí están todos, separados en entrada y salida.

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
fuente
Creo que tienes un error tipográfico en Single-payer(en lugar de Single-player).
Kevin Cruijssen
44
Kevin: No. Realmente lo es Single-payer.
ivzem
@KevinCruijssen: puede ser un error tipográfico, pero si es así, es Randall @ XKCD, no ivzem. Hay una discusión al respecto en Explain xkcd . Además, ivzem: tan pronto como vi el título en la lista de HNQ, estaba seguro de que estabas haciendo referencia a ese cómic. ¡Bien hecho!
Bobson

Respuestas:

18

Retina , 119 bytes

La versión anterior no gestionaba correctamente el espacio en "sólidos platónicos", este funciona y es más corto :)

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

Pruébalo en línea!

Esto transforma la entrada en la salida a través de una serie de sustituciones.

La parte más interesante es esta sustitución (una especie de regex golf):

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

Lo que hace casi todo el trabajo, dividiendo la primera palabra, colocando sus piezas en los lugares correctos, eliminando espacios adicionales y construyendo la estructura de la salida. Para funcionar correctamente en el caso de prueba "Tumbleweeds", esto depende de la sustitución anterior "eds" -> "ed".

El resto está compuesto principalmente por sustituciones que se ocupan de casos especiales. Otras partes interesantes son:

T`TL`Tl

Esto convierte todo, excepto "T" (para Tumblr) en minúsculas.

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

Esto coloca un "." al final de cada oración que contiene una palabra con una "y" algunas letras después de una "p" ("insignificante" y "pagador" en la práctica). Luego coloca un "!" al final de todas las oraciones que terminan con una "s" (todas las demás).

León
fuente
Esto imprime un espacio extra después platonic. Solución sugerida: TIO (+5 bytes)
adicto a las matemáticas
1
@math_junkie Gracias, he subido una nueva versión que soluciona el problema con los espacios y es aún más corta :)
Leo
10

Python 2, 291 269 293 255 247 bytes

¡Gracias Erik the Outgolferpor guardar 22 bytes!

+24 bytes para tener en cuenta algunas salidas que terminan en .lugar 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]

Solución simple para comenzar las cosas. Comprueba la octava letra de la entrada, como se sugiere en los comentarios, y busca la salida correspondiente en un diccionario y una matriz.

Pruébalo en línea!

adicto a las matemáticas
fuente
Quizás te hayas olvidado Single-payer for my real friends...
Mathieu Rodic
@MathieuRodic No, eso es bastante intencional. RealPlayeres un caso especial
drogadicto de matemáticas
Vaya, lo siento, lee demasiado rápido.
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

Esto usa esta cadena como la parte principal. "|" son los divisores y "_" son marcadores de espacio, por lo que dividir funcionaría correctamente.

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

Ejemplo de entrada: "Sólidos platónicos para mis verdaderos amigos" Explicación:

..‘,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
fuente
6

Python 3 , 788 , 403 , 359 396 bytes

Ultima versión

Este es ahora mi quinto intento. He logrado la mitad del tamaño de mi programa original. Ahora incluye el "-" que falta y creo que es una solución completa. Todavía sospecho del lado voluminoso; pero mucho más cerca de la meta. He tenido mucha ayuda . Gracias por toda la útil ayuda.

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)

Pruébalo en línea!


Publicación original

Esta es mi primera publicación sobre golf de código, así que me disculpo de antemano por mi torpe programa. No puedo ver cómo se podría hacer un programa para convertir "Champagne" en "dolor", "farsa" al analizar las palabras. Sin embargo, me gustaría ver a alguien más resolver eso. Entonces, como mi nivel de habilidad dicta que mi programa necesita saber de antemano que "Champagne" es "dolor", "farsa", no parecía tener mucho sentido codificar una solicitud de entrada. Como resultado, lo he dejado fuera y he sido un poco literal con mi salida de impresión. Espero que esté bien :)

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
fuente
3
Desde el Centro de ayuda : Todas las soluciones a los desafíos deberían: [...] ser un serio candidato para los criterios ganadores en uso. Por ejemplo, una entrada a un concurso de golf de código debe ser golfizada, y una entrada a un concurso de velocidad debe hacer algún intento de ser rápido.
Erik the Outgolfer
1
Hola y bienvenidos al sitio. Esta es una pregunta de código de golf que requiere que haga un esfuerzo para minimizar la longitud de su código. Debe eliminar espacios en blanco innecesarios y cambiar el nombre de las variables para que tengan 1 carácter.
Wheat Wizard
Puede poner toda la fraseList en una línea, reducir la sangría a un espacio, juntar las impresiones en una línea con if y else, y el espacio en blanco en las impresiones no es necesario. De todos modos, no sé si solo puedes imprimir todas las salidas;)
Mega Man
1
¡Hola! Parece que esta es su primera respuesta de código de golf. Desafortunadamente, parece haber entendido mal la pregunta, especialmente la tabla "Ejemplos" en la parte inferior, que solo muestra cómo cada entrada debe correlacionarse con una salida respectiva. Actualmente, su programa solo imprime esa tabla. Además, es una práctica estándar colocar su código en un bloque de código (selecciónelo y haga clic en {}) para una mejor legibilidad y para mencionar su idioma de elección y recuento de bytes, ya que este sitio es más como una competencia que un sitio de preguntas y respuestas._ Wheat Wizard ya lo hizo, así que eso es mejor
ivzem
Hola y bienvenidos a PPCG. Podría perder muchos bytes eliminando espacios y utilizando variables de una sola letra. Recuerdo que cuando comencé aquí, me tomó un tiempo acostumbrarme. Supongo que eres como yo. Pasas mucho tiempo escribiendo código legible. Como dije, bienvenido a PPCG y un mundo nuevo;)
ElPedro
6

Röda , 299 292 288 259 bytes

4 bytes guardados gracias a @fergusq por usar en ,lugar de ..enpush declaraciones

Bytes guardados gracias a @fergusq que me muestra el camino de 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]]}

Pruébalo en línea!

Tan cerca de Python ... tan cerca ... Tu movimiento, Python.

Explicación

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
fuente
¿Se puede guardar un byte utilizando la interpolación de cadenas en la última instrucción? Editar: en realidad, la forma más corta es probablemente empujar muchas cadenas a la secuencia en lugar de una, es decir. reemplazar ..con ,.
fergusq
@fergusq Gracias por el consejo!
Kritixi Lithos
También puedes usarlo r=indexOf(a[7:8],"noarspekc").
fergusq
@fergusq Ah, no sabía que existiera tal construcción. ¡Gracias!
Kritixi Lithos
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)]

Prueba

Arnauld
fuente
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];
usuario63956
fuente
3

Perl, 173 bytes

Eliminando nuevas líneas y hendiduras, esto se convierte en 173 bytes de código Perl5. Desvergonzadamente robó la primera expresión regular de la respuesta de Retina de Leo. (El mío fue un par de caracteres más largo)

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 la versión perl5> = 5.14, se pueden eliminar otros 5 bytes con eval y el nuevo modificador de sustitución / r regexp. Terminando con 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}

Pruébalo en línea!

Kjetil S.
fuente
2

C, 367 bytes

No terminó tan corto como parecía.

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
fuente
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 gracias a @Zircon .

Definitivamente se puede jugar al golf usando algo diferente a un Mapa.

Explicación:

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 de prueba:

Pruébalo aquí (ideone.com tiene errores últimamente, así que estoy usando TIO ahora ..)

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
fuente
1
Creo que puede guardar bytes utilizando la inicialización de doble llave y en putlugar de m.put.
Zircon
2

C (gcc) , 311 bytes

Patrones claros, pero tantas excepciones. Aún así, debe haber una mejor manera que esto!

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);}

Pruébalo en línea!

gastropner
fuente