Roccia, poliglotta, forbici


68

Scrivi un programma poliglotta in tre lingue che riproduce forbici rock-paper-scissors .

L'input per qualsiasi versione del programma è sempre una delle stringhe rocko papero scissors.

Nella prima lingua il programma deve produrre la scelta di rock-paper-scissors che batte l'input:

Input     Output
rock      paper
paper     scissors
scissors  rock

Nella seconda lingua, il programma deve produrre la scelta delle forbici rock-paper che lega l'input:

Input     Output
rock      rock
paper     paper
scissors  scissors

Nella terza lingua, il programma deve produrre la scelta delle forbici rock-paper-che perde in input:

Input     Output
rock      scissors
paper     rock
scissors  paper

Vince il codice più breve in byte. Tiebreaker è la risposta più votata.

Gli ingressi e / o le uscite possono facoltativamente avere una nuova riga finale, ma altrimenti dovrebbero essere solo le stringhe semplici rock/ paper/ scissors. È possibile utilizzare lettere maiuscole ROCK, PAPER, SCISSORSse desiderato.

Si può non utilizzare versioni diverse di una stessa lingua (ad esempio Python 2 e 3).


Può uscire un errore di lingua?
Kritixi Lithos,

2
@KritixiLithos Vai con il meta consenso . "Penso che terminare con un errore o un'eccezione non rilevata vada bene qui, a condizione che non produca output parassiti su STDOUT."
Calvin's Hobbies,

2
Mai abbastanza sicuro con i poliglotti, le diverse lingue possono ricevere input in modi diversi?
Jonathan Allan,

3
@JonathanAllan Va bene. Per alcuni insiemi di lingue che presentano solo determinate forme di input sarebbe necessario.
Hobby di Calvin il

Risposte:


60

Python, brainfuck e JavaScript, 103 99 byte Yay sotto 100 byte!

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

In Python, questo definisce una funzione che batte l'input, in brainfuck è solo un semplice programma cat e in JavaScript perde. Ecco una versione che dà un nome alle funzioni fe richiede anche input in JavaScript e 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

Provalo online (versione precedente): Python , brainfuck , JavaScript

Spiegazione:

In Python, """..."""è una stringa multilinea, che può essere utilizzata come qualsiasi token. Quando posizionato autonomo, non fa nulla. Lo uso per "nascondere" il codice JavaScript da Python. Lo stesso vale per il (0,[.5,])bit, è solo una tupla contenente un 0e un elenco di 5, e anche la 1//1parte, //in Python è una divisione intera, ma inizia un commento in JavaScript. Ecco il codice rimosso da questi token:

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

La prima riga è piuttosto autoesplicativa, definisce semplicemente la lista pper contenere le diverse scelte in forbici da carta. La seconda riga definisce una funzione senza nome che accetta un argomento xe restituisce la scelta che batte x(es. L'elemento precedente in p)


In JavaScript, //indica un commento a riga singola. Analogamente a Python, i singoli token vengono ignorati, quindi il codice rimosso da questi token è:

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

Funziona in modo simile a Python, impostando prima l'elenco pper contenere le scelte e quindi definendo una funzione anonima che dà la scelta perdente. -~xè lo stesso x+1ma con una precedenza più alta in modo che io possa saltare le parentesi.


In Brainfuck, tutti i personaggi tranne +-,.[]<>vengono rimossi, lasciando questo:

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

Il comando ,legge un byte di input, lo .stampa e [...]esegue il loop mentre il valore è diverso da zero. Ciò che fa questo programma è quindi leggere l'input e stamparlo un carattere alla volta fino a quando non \0viene trovato il carattere . Dal momento che non lo abbiamo nel codice, possiamo ignorare il resto del programma. In effetti, questo riecheggia qualunque cosa l'utente digiti, legandolo efficacemente.


Stavo lavorando a una soluzione molto simile ma mi hai battuto :). Devi aggiornare il collegamento Javascript TIO tra l'altro, è diverso dagli altri due.
DimP

2
x=>p[p.indexOf(x)+1]||"rock"//"""potrebbe essere abbreviato inx=>p[(p.indexOf(x)+1)%3]//"""
Luca

13
+1 Non ho mai visto Brainfuck nascosto così bene. Di solito è ovvio se un poliglotta contiene anche BF. Non in questo!
vsz

Penso che puoi spostare un po 'il programma BF per salvare un byte o due:1//1,[.5,];
ETHproductions

È un dato di fatto, penso che puoi usare quello esistente []sulla seconda riga per salvare più byte:1//1,;lambda x:p[p.index(x,0)+-1];"""
ETHproductions

40

Python 2, Ruby, Retina, 90 83 byte

-7 byte grazie a Value Ink

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

Provalo online: Python , Ruby , Retina

Vince in Ruby, perde in Python e lega in Retina. Questa soluzione sfrutta il fatto che 0è vero in Ruby ma falso in Python. Utilizza inoltre l'indicizzazione negativa sia in Python che in Ruby.


andha la precedenza sull'operatore or, quindi s.index(0and STDIN.gets or input())funziona. Inoltre, getsè un alias per STDIN.getsin Ruby.
Valore inchiostro

10
+1 per non solo commentare il codice in diversi modi!
leo,

@ValueInk Grazie! Ho pensato che ci doveva essere un modo più conciso per ottenere input in Ruby, e si scopre che c'era
drogato di matematica il

21

V, Brain-flak e Python 2, 97, 86, 81, 77 , 75 byte

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

Due byte salvati grazie a @ nmjcman101!

È stato molto divertente! Mi piace molto questa risposta perché è una bella panoramica delle lingue che mi piacciono: il mio editor preferito, la mia lingua preferita non esoterica e una lingua che ho scritto. (Tecnicamente Python 3 è migliore, ma Python 2 è più golfista ¯\_(ツ)_/¯).

Provalo online! in Python (leggermente modificato in modo da poter vedere l'output), che stampa ciò che perde nell'input.

Provalo online! in Brain-Flak, che stampa ciò che si lega con l'input.

Provalo online! in V, che stampa ciò che batte l'input.

Poiché V si basa su caratteri ASCII non stampabili, ecco 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

Spiegazione:

Pitone

In Python, questo è molto semplice. Definiamo un elenco dei tre elementi e restituiamo l'elemento subito prima dell'input. Poiché -1restituisce l'elemento posteriore, funziona in modo circolare ed è tutto molto semplice e intuitivo. Quindi, tutto ciò che segue #è un commento.

Brain-Flak

Questo è anche estremamente semplice in fatto di scoria cerebrale. Se dovessimo vincere o perdere, probabilmente sarebbero diverse centinaia di byte. Ma questo funziona in realtà in 0 byte. All'avvio del programma, tutti gli input vengono caricati nello stack. Alla fine del programma, l'intero stack viene stampato implicitamente.

Una volta rimossi tutti i caratteri irrilevanti, il codice brain-flak vede è

()[()]

Che semplicemente valuta 1 + -1, ma poiché questo valore non viene affatto utilizzato, è un NOOP.

V

Qui è dove diventa un po 'strano. Dare un nome all'elenco di Python opotrebbe sembrare arbitrario, ma sicuramente non lo è. In V, oapre una nuova riga e ci mette in modalità inserimento. Poi,

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

è inserito nel buffer. Successivamente, il codice pertinente è:

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

Spiegazione:

<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 In Python, non c'è motivo per non farlo (tranne che è della stessa lunghezza). Ma rovina tutto in V.
DJMcMayhem

@WheatWizard Cause V è un linguaggio davvero strano, e questo è un compito davvero strano per questo. Tutto dipende fortemente dalla disposizione dei personaggi ed .split()è più facile sbarazzarsi delle varie parentesi e citazioni che compaiono nella tua soluzione.
DJMcMayhem

Super minore, ma puoi eliminare xxe sostituirlo con a 2per eseguire il comando 2f'poiché ='comunque verrà eliminato dal d*successivo. EDIT: potresti riuscire a farcela t.?
nmjcman101,

@ nmjcman101 Oooh, dolce, fantastica idea. Grazie per il consiglio!
DJMcMayhem

16

CJam , Retina , PHP, 92 86 85 byte

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

Dovrebbe essere eseguito in PHP usando il -rflag.

Provalo in CJam

Provalo a Retina

Provalo in PHP

CJam

In CJam, tutte le lettere maiuscole sono variabili predefinite. Nella prima riga, molti di questi valori vengono inseriti nello stack, insieme ad alcuni letterali di stringhe e array. Vengono eseguiti alcuni incrementi, decrementi e altre operazioni.

Dopotutto, lo stack è racchiuso in un array ( ]) e scartato ( ;), quindi nessuna delle altre cose è importante. Il programma principale di CJam è semplicemente:

"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

Sembra quasi barare ...

Retina sostituirà qualsiasi corrispondenza della regex ECHO["rock",0,"scissors","paper"][ORD(READLINE())%4];nell'input con #];"scissors paper rock"S/rci=. Qualunque sia questo regex, di certo non corrisponde nulla in rock, papero scissors, in modo da nessuna sostituzione è fatta. L'input non modificato viene quindi implicitamente emesso.

PHP

La seconda riga è un commento, quindi viene ignorata.

La prima riga utilizza lo stesso algoritmo della parte CJam, ma con un diverso ordinamento dei risultati.


1
Le funzioni TIL PHP non fanno distinzione tra maiuscole e minuscole.
gcampbell,

14

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

Salvataggio di un byte grazie 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");}
//"""

Definisce una funzione fin tutte le lingue. Vince in C, lega in Python, perde in C ++. Come C ++ fa sempre / s

La parte tra il /*e il */è un blocco di commenti in C e C ++ mentre è la dichiarazione della funzione lambda in Python. Confronta sostanzialmente il primo carattere dell'argomento della funzione e restituisce la mossa che inizia con quella lettera.

La parte tra """s è una stringa multilinea in Python mentre è la dichiarazione di funzione in C e C ++. sizeof'b'-1scopre se la lingua corrente è C di C ++. Ha un valore di verità se la dimensione è diversa da 1, altrimenti un valore di falsa. Nel carattere C i letterali sono di tipo lungo a 4 byte mentre in C ++ sono un tipo di byte singolo. Quindi, dopo aver capito la lingua, guarda solo la prima lettera dell'input e l'output di conseguenza.

C

Provalo online!

C ++

Provalo online!

Pitone

Provalo online!


4
"La parte tra i" "" s è un blocco di commenti in Python "In realtà è una stringa multilinea.
Ivzem

10

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

#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()

Fa uso della differenza tra C e C ++ che la dimensione di un carattere letterale è di 4 byte in C e 1 byte in C ++.

C ++:

Provalo online!

R:

Risultato:

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

Provalo online!


8

Gawk, Retina, Perl; 68 byte

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

(con una nuova riga alla fine)

Gawk (vincitore)

Un po 'di spazzatura per il bene di Perl, quindi cambia il contenuto della linea ( $_che è lo stesso $0perché la variabile _non è definita) a seconda che contenga a ko a c, quindi stampa il risultato. Ignora qualsiasi avvertimento sulle sequenze di escape, intendevo farlo.

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

Retina (cravatta)

Stesso trucco di Basic Sunset e altri: sostituisci le corrispondenze di una stupida regexp sulla prima riga con il contenuto della seconda riga, quindi passa attraverso l'input.

Perl (perdente)

Leggi una riga e convertila in maiuscolo, quindi scegli una parola in base a una lettera che contiene e stampa il risultato. Il primo e l'ultimo passaggio vengono completati usando evalper nasconderli da awk.

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

Gawk, Retina perl -p,; 57 byte

Sto inserendo questo come bonus perché la commutazione della riga di comando perl -pdovrebbe far parte del programma secondo le normali regole su questo sito, il che non lo renderebbe un poliglotta.

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

Ancora una volta con una nuova riga finale per Retina . Questa volta, con la perl -pstampa automatica dell'output, l'overhead del perl è significativamente ridotto. Posso consentire al compito di $_attivare una stampa implicita in awk .


Potresti forse aggiungere un link TIO (o un compilatore online simile da testare) per ognuno di essi?
Kevin Cruijssen,

@KevinCruijssen Aggiunto. L'output su TIO per perl -pè vuoto, deve essere un bug su TIO.
Gilles 'SO- smetti di essere malvagio'

7

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

1 byte salvato grazie a @Loovjo rimuovendo uno spazio

4 byte salvati grazie a @ mbomb007 usando inputinvece diraw_input

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

Inserito in TNB come una sfida , ho deciso di provare questa combinazione di lingue.

> <>

Provalo online!

L'IP inizia a muoversi a destra.

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

I possibili caratteri che verranno inseriti nell'input sono PRS(poiché il programma accetta solo il primo carattere). I loro ASCII-valori sono 80, 81e 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

Se l'input fosse rock, questo è ciò che accadrebbe:

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

Altrimenti, se l'input fosse SCISSORSo PAPER, questo è ciò che l'IP incontrerebbe:

"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

Se l'input era PAPER, quindi:

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

Altrimenti (se l'input era SCISSORS):

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

Retina

Provalo online!

In questo caso, Retina considera ciascuna coppia di due righe come una coppia di una corrispondenza e sostituzione. Ad esempio, tenta di sostituire qualsiasi cosa che corrisponda alla prima riga con la seconda riga, ma poiché la prima riga non viene mai abbinata, non la sostituisce mai con nulla, preservando così l'input.

Python 2

Provalo online!

Il programma Python richiede che l'input sia inserito tra "s.

Le prime due righe sono commenti in 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

Non penso che lo spazio dopo printall'ultima riga sia necessario.
Loovjo,

Puoi usare input()invece di raw_input().
mbomb007,

@Loovjo Grazie per la punta :)
Kritixi Lithos

@ mbomb007 Non sembra funzionare
Kritixi Lithos,

@KritixiLithos funziona se la parte Python accetta input con virgolette
undergroundmonorail

0

Rubino, Clojure, Lisp comune - 251 byte

(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+'"']))

Versione più leggibile con spazi bianchi:

(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 vince sempre, Ruby disegna sempre, Common Lisp perde sempre.

Per Ruby tutto dentro 's è una stringa. Si estende su due linee. Quindi utilizza l' []operatore con un argomento stringa che restituisce la stringa stessa se è presente nella stringa. Il risultato viene stampato, Ruby rispecchia semplicemente l'input.

La seconda riga è un commento per Clojure e Common Lisp. Un sacco di evale quotedeve essere usato perché Clojure deve assicurarsi che tutti i simboli siano validi. Sarebbe bello riutilizzare di più il codice ma anche la nthfunzione ha firme diverse in queste lingue. Fondamentalmente per Clojure restituisce if()vero e va al primo ramo quando viene chiamata una mappa hash di possibili varianti con argomento letto dallo stdin. Il Lisp comune passa al secondo ramo, trova la posizione dell'argomento da stdin nell'elenco e restituisce l'elemento corrispondente dall'elenco risultante.

Immagino che la parte del Common Lisp possa essere giocata più a golf.

Guardalo online: Ruby , Common Lisp , Clojure


0

Scala, Javascript e Ook, 167 byte

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!
}

Provalo in Scala Provalo in Javascript Prova la versione Brainfuck di Ook

Scala: vince

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

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! - cravatte

La parte Ook è il semplice programma ,[.,]per gatti Brainfuck traslato su 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

Se lo usi a[(a.indexOf(s)+2)%3], non è necessario impostare a[-1]="rock". Inoltre, non puoi inserire anche il codice Ook nella stringa JavaScript?
Neil,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.