Piedra, Políglota, Tijeras


68

Escriba un programa que sea un políglota en tres idiomas que juegue piedra, papel y tijera .

La entrada para cualquier versión del programa es siempre una de las cadenas rocko papero scissors.

En el primer idioma, el programa debe generar la opción piedra-papel-tijera que supera la entrada:

Input     Output
rock      paper
paper     scissors
scissors  rock

En el segundo idioma, el programa debe generar la opción piedra-papel-tijera que vincula la entrada:

Input     Output
rock      rock
paper     paper
scissors  scissors

En el tercer idioma, el programa debe generar la opción piedra-papel-tijera que pierde en la entrada:

Input     Output
rock      scissors
paper     rock
scissors  paper

El código más corto en bytes gana. Tiebreaker es la respuesta más votada.

Las entradas y / o salidas pueden tener opcionalmente una nueva línea final, pero de lo contrario solo deberían ser las cadenas simples rock/ paper/ scissors. Es posible utilizar mayúsculas ROCK, PAPER, SCISSORSsi se desea.

Es posible que no usar diferentes versiones de un mismo idioma (por ejemplo, Python 2 y 3).


¿Puede salir un error de idioma?
Kritixi Lithos

2
@KritixiLithos Ir con el consenso meta . "Creo que terminar con un error o una excepción no detectada está bien aquí, siempre que no produzca una salida perdida a STDOUT".
Hobbies de Calvin

2
Nunca estoy muy seguro con los políglotas, ¿pueden los diferentes idiomas recibir información de diferentes maneras?
Jonathan Allan

3
@ JonathanAllan Eso está bien. Para algunos conjuntos de idiomas que solo tienen ciertas formas de entrada, sería necesario.
Aficiones de Calvin

Respuestas:


60

Python, brainfuck y JavaScript, 103 99 bytes ¡ Yay menos de 100 bytes!

0,[.5,];p=["rock","scissors","paper"]
1//1;lambda x:p[p.index(x)-1];"""
x=>p[-~p.indexOf(x)%3]//"""

En Python, esto define una función que supera la entrada, en brainfuck es solo un simple programa cat, y en JavaScript pierde. Aquí hay una versión que le da un nombre a las funciones f, y también solicita entradas en JavaScript y Python 3:

0,[.5,];p=["rock","scissors","paper"]
1//1;f=lambda x:p[p.index(x)-1];"""
f=x=>p[-~p.indexOf(x)%3]//"""

1//1;"""
console.log(f(prompt())) // JavaScript
1//1"""; print(f(input())) # Python

Pruébelo en línea (versión anterior): Python , brainfuck , JavaScript

Explicación:

En Python, """..."""es una cadena multilínea, que se puede usar como cualquier token. Cuando se coloca solo, no hace nada en absoluto. Lo uso para "ocultar" el código JavaScript de Python. Lo mismo ocurre con el (0,[.5,])bit, es solo una tupla que contiene ay 0una lista de 5, y también la 1//1parte, //en Python es la división de enteros, pero comienza un comentario en JavaScript. Aquí está el código despojado de estos tokens:

p=["rock","scissors","paper"]
lambda x:p[p.index(x)-1]

La primera línea se explica por sí misma, solo define la lista ppara contener las diferentes opciones en piedra, papel o tijera. La segunda línea define una función sin nombre que toma un argumento xy devuelve la opción que supera x(por ejemplo, el elemento anterior en p)


En JavaScript, //denota un comentario de una sola línea. De manera similar a Python, los tokens individuales se ignoran, por lo que el código despojado de estos tokens es:

p=["rock","scissors","paper"]
x=>p[-~p.indexOf(x)%3]

Esto funciona de manera similar a Python, primero configurando la lista ppara contener las opciones y luego definiendo una función anónima que da la opción perdedora. -~xes lo mismo x+1pero con mayor precedencia para que pueda omitir los parens.


En brainfuck, todos los personajes excepto +-,.[]<>se eliminan, dejando esto:

,[.,][,,]
[.-]
>[-.]

El comando ,lee un byte de entrada, lo .imprime y realiza un [...]bucle mientras el valor no es cero. Lo que este programa hace es leer la entrada e imprimirla un carácter a la vez hasta que \0se encuentre el carácter . Como no tenemos eso en el código, podemos ignorar el resto del programa. En efecto, esto solo hace eco de lo que escriba el usuario, vinculándolos efectivamente.


Estaba trabajando en una solución muy similar, pero me ganaste :). Tienes que actualizar el enlace Javascript TIO por cierto, es diferente de los otros dos.
DimP

2
x=>p[p.indexOf(x)+1]||"rock"//"""podría acortarse ax=>p[(p.indexOf(x)+1)%3]//"""
Lucas

13
+1 Nunca había visto a Brainfuck escondido tan bien. Por lo general, es obvio si un políglota también contiene BF. ¡No en este!
vsz

Creo que puede mover el programa BF un poco para guardar un byte o dos:1//1,[.5,];
ETHproductions

De hecho, creo que puede usar el existente []en la segunda línea para guardar más bytes:1//1,;lambda x:p[p.index(x,0)+-1];"""
ETHproductions

40

Python 2, Ruby, Retina, 90 83 bytes

-7 bytes gracias a Value Ink

s=['rock','paper','scissors']
print s[s.index((0and gets or input()))+(0and-2or-1)]

Pruébelo en línea: Python , Ruby , Retina

Gana en Ruby, pierde en Python y empata en Retina. Esta solución hace uso del hecho de que 0es verdad en Ruby pero falsey en Python. También utiliza indexación negativa tanto en Python como en Ruby.


andtiene prioridad sobre el operador or, por lo que s.index(0and STDIN.gets or input())funciona. Además, getses un alias para STDIN.getsen Ruby.
Value Ink el

10
¡+1 por no solo comentar el código de diferentes maneras!
leo

@ValueInk ¡Gracias! Pensé que tenía que haber una manera más concisa para obtener la entrada en Ruby, y resulta que no había
drogadicto de matemáticas

21

V, Brain-flak y Python 2, 97, 86, 81, 77 , 75 bytes

o='rock paper scissors'.split()
lambda s:o[o.index(s)-1]#ddt.C rHd*wywVp

¡Dos bytes guardados gracias a @ nmjcman101!

¡Esto fue súper divertido! Me gusta mucho esta respuesta porque es un resumen genial de los idiomas que me gustan: mi editor favorito, mi idioma no esotérico favorito y un idioma que escribí. (Técnicamente, Python 3 es mejor, pero Python 2 es más golfista ¯\_(ツ)_/¯).

Pruébalo en línea! en Python (ligeramente modificado para que pueda ver la salida), que imprime lo que pierde en la entrada.

Pruébalo en línea! en Brain-Flak, que imprime lo que se vincula con la entrada.

Pruébalo en línea! en V, que imprime lo que supera la entrada.

Como V se basa en caracteres ASCII no imprimibles, aquí hay un hexdump:

00000000: 6f3d 2772 6f63 6b20 7061 7065 7220 7363  o='rock paper sc
00000010: 6973 736f 7273 272e 7370 6c69 7428 290a  issors'.split().
00000020: 6c61 6d62 6461 2073 3a6f 5b6f 2e69 6e64  lambda s:o[o.ind
00000030: 6578 2873 292d 315d 231b 6464 742e 4320  ex(s)-1]#.ddt.C 
00000040: 720e 1b48 642a 7779 7756 70              r..Hd*wywVp

Explicación:

Pitón

En python, esto es muy sencillo. Definimos una lista de los tres elementos y devolvemos el elemento justo antes de la entrada. Dado que -1devuelve el elemento posterior, esto funciona de forma circular, y todo es muy sencillo y sencillo. Entonces, todo después #es un comentario.

Brain-Flak

Esto también es extremadamente sencillo en el ataque cerebral. Si tuviéramos que ganar o perder, esto probablemente sería varios cientos de bytes. Pero esto realmente funciona en 0 bytes. Al inicio del programa, toda la entrada se carga en la pila. Al final del programa, toda la pila se imprime implícitamente.

Una vez que eliminamos todos los caracteres irrelevantes, el código que Brain-Flak ve es

()[()]

Lo que simplemente se evalúa como 1 + -1, pero dado que este valor no se usa en absoluto, es un NOOP.

V

Aquí es donde se pone un poco raro. Nombrar la lista de Python opuede haber parecido arbitrario, pero definitivamente no lo es. En V, oabre una nueva línea y nos pone en modo de inserción. Entonces,

='rock paper scissors'.split()
lambda s:o[o.index(s)-1]#

se inserta en el búfer. Después de eso, el código relevante es:

<esc>ddxxf'C r<C-n><esc>Hd*wywVp

Explicación:

<esc>                          " Return to normal mode
     dd                        " Delete this line. Now the cursor is on '='
       t.                      " Move the cursor forward to the "'"
         C                     " Delete everything after the "'", and enter insert mode
           r                   " From insert mode, enter '<space>r'
            <C-n>              " Autocomplete the current word based on what is currently in the buffer
                               " Since only one word starts with 'r', this will insert 'rock'
                 <esc>         " Leave back to normal mode
                      H        " Go to the first line (where the input is)
                       d*      " Delete everything up until the next occurence of the input
                         w     " Move forward one word
                          yw   " Yank the word under the cursor
                            Vp " And paste that word over the current line, delete everything else

@WheatWizard En Python, no hay razón para no hacerlo también (excepto que tiene la misma longitud). Pero arruina todo en V.
DJMcMayhem

@WheatWizard Cause V es un lenguaje realmente extraño, y esta es una tarea realmente extraña para él. Todo depende en gran medida del diseño de los personajes, y .split()es más fácil deshacerse de los diversos paréntesis y citas que aparecen en su solución.
DJMcMayhem

Súper menor, pero puede sacarlo xxy reemplazarlo con a 2para hacer el comando 2f'ya ='que será eliminado por el d*posterior de todos modos. EDITAR: ¿podrías lograrlo t.?
nmjcman101

@ nmjcman101 Oooh, dulce, genial idea. ¡Gracias por el consejo!
DJMcMayhem

16

CJam , Retina , PHP, 92 86 85 bytes

ECHO["rock",0,"scissors","paper"][ORD(READLINE())%4];
#];"scissors  paper rock"S/rci=

Debe ejecutarse en PHP usando la -rbandera.

Pruébalo en CJam

Pruébalo en retina

Pruébalo en PHP

CJam

En CJam, todas las letras mayúsculas son variables predefinidas. En la primera línea, muchos de estos valores se insertan en la pila, junto con algunos literales de cadena y matriz. Se realizan algunos incrementos, decrementos y otras operaciones.

Después de todo eso, la pila está envuelta en una matriz (] ) y se descarta ( ;), por lo que nada de eso importa en absoluto. El programa principal de CJam es simplemente:

"scissors  paper rock"S/rci=

"scissors  paper rock"        e# Push this string
                      S/      e# Split it on spaces
                        r     e# Read the input
                         c    e# Cast to char (returns the first character in the string)
                          i   e# Cast to int (its codepoint)
                           =  e# Get the index of the split array (CJam has modular arrays)

Retina

Esto casi se siente como hacer trampa ...

Retina sustituirá cualquier coincidencia de la expresión regular ECHO["rock",0,"scissors","paper"][ORD(READLINE())%4];en la entrada con #];"scissors paper rock"S/rci=. Cualquiera que sea la coincidencia de esta expresión regular, ciertamente no coincide con nada enrock , papero scissors, por lo que no se hace ningún cambio. La entrada no modificada se emite implícitamente.

PHP

La segunda línea es un comentario, por lo que se ignora.

La primera línea usa el mismo algoritmo que la parte CJam, pero con un orden diferente de los resultados.


1
Las funciones TIL PHP no distinguen entre mayúsculas y minúsculas.
gcampbell

14

C, C ++, Python; 227 226 216 bytes

¡Ahorré un byte gracias a @Mat!

#include<stdio.h>/*
f=lambda a:"rock"if a[0]=="r"else"paper"if a[0]=="p"else"scissors"
"""*/
int f(char*b){puts(sizeof'b'-1?*b=='r'?"paper":*b=='s'?"rock":"scissors":*b=='r'?"scissors":*b=='s'?"paper":"rock");}
//"""

Define una función fen todos los idiomas. Gana en C, empata en Python, pierde en C ++. Como C ++ siempre hace / s

La parte entre el /*y el*/ es un bloque de comentarios en C y C ++, mientras que es la declaración de la función lambda en Python. Básicamente compara el primer carácter del argumento de la función y devuelve el movimiento que comienza con esa letra.

La parte entre """s es una cadena multilínea en Python, mientras que es la declaración de función en C y C ++. sizeof'b'-1descubre si el lenguaje actual es C de C ++. Tiene un valor verdadero si el tamaño es diferente a 1, un valor falso de lo contrario. En C los literales son de 4 bytes, mientras que en C ++ son de un solo byte. Luego, después de descubrir el idioma, solo mira la primera letra de la entrada y las salidas en consecuencia.

C

Pruébalo en línea!

C ++

Pruébalo en línea!

Pitón

Pruébalo en línea!


44
"La parte entre el ''" s es un bloque de comentario en Python" Es realmente una cadena de varias líneas.
ivzem

10

C ++, R, C; 252 240 226 220 209 bytes

#define b/*
M=function()cat(readline())
#*/
#import<stdio.h>
#define M()main(){int i=0;char t[9];char*u;char*s[]={"rock","paper","scissors"};scanf("%s",t);for(;*t-*s[i++];);puts(s[(i+=sizeof('a')==1)%3]);}
M()

Utiliza la diferencia entre C y C ++ de que el tamaño de un literal de caracteres es de 4 bytes en C y 1 byte en C ++.

C ++:

Pruébalo en línea!

R:

Resultado:

> #define b/*
> M=function()cat(readline())
> #*/
> #import<stdio.h>
> #define M()main(){int i=0;char t[9];char*u;char*s[]={"rock","paper","scissors"};scanf("%s",t);for(;*t-*s[i++];);puts(s[(i+=sizeof('a')==1)%3]);}
> M()
rock
rock

C:

Pruébalo en línea!


8

Gawk, Retina, Perl; 68 bytes

{eval"\$_=uc<>"}{$_=/[Sk]/?"paper":/[Pc]/?"rock":"scissors"}{print}

(con una nueva línea al final)

Gawk (ganador)

Un poco de basura por el bien de Perl, luego cambie el contenido de la línea ( $_que es lo mismo que $0porque la variable _no está definida) dependiendo de si contiene a ko a c, luego imprima el resultado. Ignora cualquier advertencia sobre las secuencias de escape, quise hacer eso.

{a_string_that_is_ignored}
{$_ = /[Sk]/ ? "paper" : /[Pc]/ ? "rock" : "scissors"}
{print}

Retina (corbata)

El mismo truco que Basic Sunset y otros: reemplaza las coincidencias de algunas expresiones regulares tontas en la primera línea por el contenido de la segunda línea, así que pasa la entrada.

Perl (perdedor)

Lea una línea y conviértala en mayúsculas, luego elija una palabra basada en una letra que contenga e imprima el resultado. El primer y último paso se envuelven evalpara ocultarlos de awk.

$_ = uc <>;
$_ = /[Sk]/ ? "paper" : /[Pc]/ ? "rock" : "scissors";
print $_

Gawk, Retina perl -p; 57 bytes

Estoy ingresando esto como una bonificación porque perl -pse supone que el cambio de línea de comando es parte del programa según las reglas habituales en este sitio, lo que lo haría no políglota.

{eval"\$_=uc"}$_=/[Sk]/?"paper":/[Pc]/?"rock":"scissors"

De nuevo con una nueva línea final para Retina . Esta vez, perl -ppara imprimir la salida automáticamente, la sobrecarga de perl se reduce significativamente. Puedo dejar que la tarea $_active una impresión implícita en awk .


¿Podría quizás agregar un enlace TIO (o un compilador en línea similar para probar) para cada uno de ellos?
Kevin Cruijssen

@KevinCruijssen Añadido. La salida en TIO para perl -pestá vacía, debe ser un error en TIO.
Gilles 'SO- deja de ser malvado'

7

> <>, Retina, Python 2: 144 127 123 bytes

1 byte guardado gracias a @Loovjo al eliminar un espacio

4 bytes guardados gracias a @ mbomb007 usando en inputlugar deraw_input

#v"PAPER"v?%4-2{"SCISSORS"v?%2:i
#>ooooo; >oooooooo<"ROCK"~<
a="KRS".index(input()[-1])
print["SCISSORS","ROCK","PAPER"][a]

Publicado en TNB como un desafío , decidí probar esta combinación de idiomas.

> <>

Pruébalo en línea!

La IP comienza a moverse hacia la derecha.

#                      Reflect the IP so that it now moves left and it wraps around the grid
i:                     Take one character as input and duplicate it

Los posibles caracteres que se tomarán en la entrada son PRS(ya que el programa solo toma el primer carácter). Sus valores ASCII son 80, 81y 82.

2%                     Take the modulo 2 of the character. Yields 0, 1, 0 for P, R, S respectively
?v                     If this value is non-zero (ie the input was ROCK), go down, otherwise skip this instruction

Si la entrada fue rock, entonces esto es lo que sucedería:

<                      Start moving to the left
~                      Pop the top most value on the stack (which is the original value of R and not the duplicate)
"KCOR"                 Push these characters onto the stack
<                      Move left
oooo                   Output "ROCK" as characters (in turn these characters are popped)
o                      Pop the top value on the stack and output it; but since the stack is empty, the program errors out and exits promptly.

De lo contrario, si la entrada fue SCISSORSo PAPER, esto es lo que la IP encontraría:

"SROSSICS"             Push these characters onto the stack
{                      Shift the stack, so the the original value of the first char of the input would come to the top
2-4%                   Subtract 2 and take modulo 4 of the ASCII-value (yields 2, 0 for P, S respectively)
?v                     If it is non-zero, go down, otherwise skip this instruction

Si la entrada fue PAPER, entonces:

>ooooooooo             Output all characters on the stack (ie "SCISSORS")
<                      Start moving left
o                      Pop a value on the stack and output it; since the stack is empty, this gives an error and the program exits.

De lo contrario (si la entrada fue SCISSORS):

"REPAP"                Push these characters onto the stack
v>ooooo;               Output them and exit the program (without any errors).

Retina

Pruébalo en línea!

En este caso, Retina considera cada par de dos líneas como un par de partido y sustitución. Por ejemplo, intenta reemplazar cualquier cosa que coincida con la primera línea con la segunda línea, pero como la primera línea nunca coincide, nunca la sustituye por nada, preservando así la entrada.

Python 2

Pruébalo en línea!

El programa Python requiere que se ingrese información entre "s.

Las dos primeras líneas son comentarios en Python.

a="KRS".index(input()[-1])             # Get the index of the last character of the input in "KRS"
print["SCISSORS","ROCK","PAPER"][a]    # Print the ath index of that array

No creo que el espacio después printde la última línea sea necesario.
Loovjo

Puedes usar en input()lugar de raw_input().
mbomb007

@Loovjo Gracias por el consejo :)
Kritixi Lithos

@ mbomb007 Eso no parece funcionar
Kritixi Lithos

@KritixiLithos funciona si la parte de Python recibe información entre comillas
undergroundmonorail

0

Ruby, Clojure, Common Lisp - 251 bytes

(print(eval '(if()({(quote SCISSORS)(quote PAPER)(quote PAPER)(quote ROCK)(quote ROCK)(quote SCISSORS)}(read))(eval(quote(nth(position(read)(quote("SCISSORS""PAPER""ROCK")):test(quote string-equal))(quote(ROCK SCISSORS PAPER))))))))
;'['"'+gets+'"']))

Versión más legible con espacios en blanco:

(print(eval '(if() ; distinguish between CLojure and Common Lisp
    ({(quote SCISSORS)(quote PAPER)(quote PAPER)
       (quote ROCK)(quote ROCK)(quote SCISSORS)}(read)) ; use hash-map as a function
    (eval(quote(nth ; find index of the input arg in the list
       (position(read)(quote("SCISSORS""PAPER""ROCK")):test(quote string-equal))  
    (quote(ROCK SCISSORS PAPER))))))))
 ;'['"'+gets+'"'])) ; ruby indexation

Clojure siempre gana, Ruby siempre dibuja, Common Lisp siempre pierde.

Para Ruby, todo lo que hay dentro de 's es una cadena. Se extiende a través de dos líneas. Luego usa el []operador con un argumento de cadena que devuelve la cadena en sí si está presente en la cadena. El resultado se imprime, Ruby simplemente refleja la entrada.

La segunda línea es un comentario para Clojure y Common Lisp. Se debe usar un montón de evaly quoteporque Clojure necesita asegurarse de que todos los símbolos sean válidos. Sería bueno reutilizar más código, pero incluso la nthfunción tiene firmas diferentes en estos idiomas. Básicamente, para Clojure se if()evalúa como verdadero y va a la primera rama cuando se llama a un mapa hash de posibles variantes con un argumento leído desde stdin. Common Lisp va a la segunda rama, encuentra la posición del argumento de stdin en la lista y devuelve el elemento correspondiente de la lista resultante.

Supongo que la parte Common Lisp se puede jugar más al golf.

Véalo en línea: Ruby , Common Lisp , Clojure


0

Scala, Javascript y Ook, 167 bytes

s=>{var a="paper,scissors,rock".split(",")/*/**/a[-1]="rock"
return a[a.indexOf(s)-1];`*/a((a.indexOf(s)+1)%3)//`//Ook. Ook. Ook! Ook? Ook. Ook! Ook! Ook. Ook? Ook!
}

Pruébalo en Scala Pruébalo en Javascript Prueba la versión brainfuck de Ook

Scala - gana

s=>{                                                      //define an anonymous function
  var a="paper,scissors,rock".split(",")                  //generate the array
  /* /* */ a[-1]="rock"                                   //scala supports nested comments,
  return a[a.indexOf(s)-1];`                              //so this comment...
  */                                                      //...ends here
  a((a.indexOf(s)+1)%3)                                   //return the winning string
  //`//Ook. Ook. Ook! Ook? Ook. Ook! Ook! Ook. Ook? Ook!  //another comment
}

Javascript - pierde

s=>{                                                   //define an anonymous function
  var a="paper,scissors,rock".split(",")               //generate the array
  /*/**/                                               //a comment
  a[-1]="rock"                                         //put "rock" at index -1
  return a[a.indexOf(s)-1];                            //return the string that loses
  `*/a((a.indexOf(s)+1)%3)//`                          //a string
  //Ook. Ook. Ook! Ook? Ook. Ook! Ook! Ook. Ook? Ook!  //a comment
}

Ook! - corbatas

La parte de Ook es el programa simple de brainfuck cat, ,[.,]trasladado a Ook.

s=>{var a="paper,scissors,rock".split(",")/*/**/a[-1]="rock"   //random stuff
return a[a.indexOf(s)-1];`*/a((a.indexOf(s)+1)%3)//`//         //more random stuff
Ook. Ook. Ook! Ook? Ook. Ook! Ook! Ook. Ook? Ook!              //the program
}                                                              //random stuff

Si lo usa, a[(a.indexOf(s)+2)%3]entonces no necesita configurarlo a[-1]="rock". Además, ¿no puedes poner el código Ook dentro de la cadena de JavaScript también?
Neil
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.