Скеля, Поліглот, Ножиці


68

Напишіть програму, яка є поліглотом на трьох мовах, який відтворює ножиці-папір-ножиці .

Вхід для будь-якої версії програми завжди є одним з рядків rockабо paperабо scissors.

Першою мовою програма повинна вивести ножиці "кам'яна папір", яка б'є вхід:

Input     Output
rock      paper
paper     scissors
scissors  rock

На другій мові програма повинна вивести ножиці "скеля-папір-ножиці", що зв'язує вхід:

Input     Output
rock      rock
paper     paper
scissors  scissors

Третьою мовою програма повинна виводити на стіни вибір, який втрачає вхід:

Input     Output
rock      scissors
paper     rock
scissors  paper

Виграє найкоротший код у байтах. Tierereaker - це відповідь з вищим голосом.

Входи та / або виходи необов'язково можуть мати зворотний новий рядок, але в іншому випадку повинні бути лише прості rock/ paper/ scissorsрядки. Ви можете використовувати великі букви ROCK, PAPER, SCISSORSякщо це необхідно.

Ви не можете використовувати різні версії однієї мови (наприклад, Python 2 і 3).


Чи може мовна помилка вийти, щоб вийти?
Kritixi Lithos

2
@KritixiLithos Перейти з мета консенсус . "Я думаю, що закінчення з помилкою або нездійсненним винятком є ​​нормальним, доки воно не виробляє бродячий вихід на STDOUT."
Захоплення Кальвіна

2
Ніколи не впевнений у поліглотах, чи можуть різні мови вводити різні способи?
Джонатан Аллан

3
@JonathanAllan Це нормально. Для деяких мовних наборів, які мають лише певні форми введення, було б необхідно.
Захоплення Кальвіна

Що сталося з Ящіркою, Споком? bigbangtheory.wikia.com/wiki/Rock_Paper_Scissors_Lizard_Spock
Ole Tange

Відповіді:


60

Python, brainfuck та JavaScript, 103 99 байт Так, під 100 байт!

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

У Python це визначає функцію, яка б'є вхід, у brainfuck це просто проста програма для котів, а в JavaScript вона втрачається. Ось версія, яка дає назви функціям f, а також запитує на введення в JavaScript та 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

Спробуйте в Інтернеті (старша версія): Python , brainfuck , JavaScript

Пояснення:

У Python """..."""є багаторядковий рядок, який можна використовувати як будь-який маркер. Якщо розмістити його окремо, він взагалі нічого не робить. Я використовую це, щоб "приховати" код JavaScript від Python. Те ж саме стосується і (0,[.5,])біта, це просто кортеж, що містить a 0і список 5, а також 1//1частину, //в Python є цілим поділом, але починає коментар у JavaScript. Ось код, позбавлений цих лексем:

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

Перший рядок досить зрозумілий, він просто визначає список, pщоб містити різні варіанти носіїв-папір. Другий рядок визначає неназвану функцію, яка бере один аргумент, xі повертає вибір, який перемагає x(наприклад, попередній елемент в p)


У JavaScript //позначає однорядковий коментар. Як і в Python, одиночні жетони ігноруються, тому код, позбавлений цих лексем, є:

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

Це працює аналогічно Python, спочатку встановивши список, pякий містить варіанти, а потім визначив анонімну функцію, яка дає програш. -~xте саме, x+1але з більш високим пріоритетом, щоб я міг пропустити парони.


У головному мовби кожен персонаж, крім цього +-,.[]<>, видаляється, залишаючи це:

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

Команда ,зчитує один байт введення, .друкує його та [...]циклічно, тоді як значення не дорівнює нулю. Тоді, що ця програма робить, це прочитати введення та друкувати його по одному символу за раз, поки символ не \0буде знайдений. Оскільки у нас цього немає в коді, ми можемо ігнорувати решту програми. По суті, це просто повторює те, що користувач вводить, ефективно пов'язуючи їх.


Працював над дуже подібним рішенням, але ти мене до цього побив :). Вам потрібно оновити посилання Javascript TIO btw, воно відрізняється від двох інших.
DimP

2
x=>p[p.indexOf(x)+1]||"rock"//"""може бути скорочений доx=>p[(p.indexOf(x)+1)%3]//"""
Лука

13
+1 Я ніколи не бачив, щоб Brainfuck так добре ховався. Зазвичай це очевидно, якщо поліглот також містить BF. Не в цьому!
vsz

Я думаю, ви можете трохи перемістити програму BF, щоб зберегти байт чи два:1//1,[.5,];
ETHproductions

Власне кажучи, я думаю, що ви можете використовувати наявні []у другому рядку, щоб зберегти більше байтів:1//1,;lambda x:p[p.index(x,0)+-1];"""
ETHproductions

40

Python 2, Ruby, Retina, 90 83 байт

-7 байт завдяки Ink Value Ink

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

Спробуйте в Інтернеті: Python , Ruby , Retina

Перемагає в Рубі, програє в Python, а зв'язки в Retina. Це рішення використовує той факт, що 0в Рубі є правдоподібним, але фальси в Python. Він також використовує негативну індексацію як в Python, так і в Ruby.


andмає перевагу оператора над or, тому s.index(0and STDIN.gets or input())працює. Також getsє псевдонімом STDIN.getsу Ruby.
Значення чорнила

10
+1 за те, що не просто коментувати код по-різному!
лео

@ValueInk Дякую! Я подумав, що повинен бути більш стислий спосіб отримати вклад в Ruby, і виявляється, що це було
математика наркоман

21

V, Brain-Flak і Python 2, 97, 86, 81, 77 , 75 байт

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

Два байти збережено завдяки @ nmjcman101!

Це було супер весело! Мені ця відповідь дуже подобається, тому що це крутий огляд мов, які мені подобаються: мій улюблений редактор, моя улюблена неезотерична мова та мова, яку я написав. (Технічно python 3 краще, але python 2 - це гольфіст ¯\_(ツ)_/¯).

Спробуйте в Інтернеті! в Python (трохи модифікований, щоб ви могли побачити вихід), який друкує те, що втрачає на вході.

Спробуйте в Інтернеті! в Brain-Flak, який друкує зв'язки із введенням.

Спробуйте в Інтернеті! у V, який друкує те, що б'є вхід.

Оскільки V покладається на недруковані символи ASCII, ось шестинадцять:

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

Пояснення:

Пітон

У python це дуже просто. Ми визначаємо список трьох елементів і повертаємо елемент безпосередньо перед введенням. Оскільки -1повертає задній елемент, це працює круговим чином, і все це дуже просто і легко. Потім, все після #- це коментар.

Мозок-Флак

Це також є надзвичайно простим у мозку. Якби нам довелося перемогти чи програти, це, мабуть, буде кілька сотень байт. Але це насправді працює в 0 байт. Після запуску програми весь вхід завантажується в стек. В кінці програми весь стек неявно друкується.

Після того, як ми видалимо всі неактуальні символи, код бачить головний промах

()[()]

Що просто оцінює 1 + -1, але оскільки це значення взагалі не використовується, це NOOP.

V

Ось де це стає трохи дивно. Названня списку python oможе здатися довільним, але це точно не так. У V oвідкриває новий рядок і вводить нас у режим вставки. Тоді,

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

вставляється в буфер. Після цього відповідним кодом є:

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

Пояснення:

<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 У Python немає жодної причини (крім того, що він однакової довжини). Але це все руйнує у V.
DJMcMayhem

@WheatWizard Причина V - це дійсно дивна мова, і це справді дивне завдання для неї. Все значною мірою покладається на компонування символів, і .split()їх легше позбутися від різних дужок і цитат, які відображаються у вашому рішенні.
DJMcMayhem

Супер другорядний, але ви можете вийняти xxта замінити його на a, 2щоб зробити команду, 2f'оскільки пізніше все-таки ='буде видалено d*пізніше. EDIT: ви могли б це зробити t.?
nmjcman101

@ nmjcman101 О, мила, приголомшлива ідея. Дякую за пораду!
DJMcMayhem

16

CJam , Retina , PHP, 92 86 85 байт

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

Потрібно запустити в PHP, використовуючи -rпрапор.

Спробуйте в CJam

Спробуйте це у Retina

Спробуйте це в PHP

CJam

У CJam всі великі літери є заздалегідь заданими змінними. У першому рядку багато з цих значень висуваються на стек разом з деякими літеральними рядками та масивами. Виконуються деякі прирости, декременти та інші операції.

Після всього цього стек загортається в масив ( ]) і відкидається ( ;), тому жоден з цих речей взагалі не має значення. Основна програма CJam - це просто:

"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)

Сітківка

Це майже схоже на обман ...

Сітківка замінить будь-яку відповідність регулярного виразу на вхіді ECHO["rock",0,"scissors","paper"][ORD(READLINE())%4];на #];"scissors paper rock"S/rci=. Те , що відповідає це регулярний вираз, це , звичайно , нічого не в матчі rock, paperабо scissors, так заміна не проводиться. Потім немодифікований вхід неявно виводиться.

PHP

Другий рядок - це коментар, тому його ігнорують.

Перший рядок використовує той же алгоритм, що і частина CJam, але з різним упорядкуванням результатів.


1
Функції TIL PHP нечутливі до регістру.
gcampbell

14

C, C ++, Python; 227 226 216 байт

Збережено байт завдяки @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");}
//"""

Визначає функцію fна всіх мовах. Виграє в C, зв'язки в Python, програє в C ++. Як і C ++ завжди робить / с

Частина між і /*та */є блоком коментарів у C та C ++, тоді як це оголошення лямбда-функції в Python. В основному він порівнює перший символ аргументу функції та повертає хід, що починається з цієї літери.

Частина між """s є багаторядковою рядком в Python, тоді як це декларація функції в C і C ++. sizeof'b'-1з'ясовує, чи є поточна мова C C ++. Він має триєднувальне значення, якщо розмір інший ніж 1, помилкове значення в іншому випадку. У літералі C символи - це 4-байтний довгий тип, тоді як у C ++ - це однобайтовий тип. Потім після з'ясування мови він просто переглядає першу букву вводу та виводить відповідно.

С

Спробуйте в Інтернеті!

C ++

Спробуйте в Інтернеті!

Пітон

Спробуйте в Інтернеті!


4
"Частина між" "" є блоком коментарів у Python "Це насправді багаторядковий рядок.
ivzem

10

C ++, R, C; 252 240 226 220 209 байт

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

Використовує різницю між C і C ++ у тому, що розмір буквеного символу становить 4 байти в C і 1 байт в C ++.

C ++:

Спробуйте в Інтернеті!

R:

Результат:

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

Спробуйте в Інтернеті!


8

Gawk, Retina, Perl; 68 байт

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

(з новим рядком в кінці)

Гаук (переможець)

Деякі сміття заради Перла, а потім змінити вміст рядка ( $_який такий же, як і $0тому, що змінна _не визначена) залежно від того, містить вона a kчи a c, після чого надрукуйте результат. Ігноруйте будь-яке попередження про послідовності втечі, я мав намір це зробити.

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

Сітківка (краватка)

Той самий трюк, що і Basic Sunset та інші: замініть збіги деякого нерозумного регулярного виразу на першому рядку вмістом другого рядка, тому передайте вхід.

Perl (програв)

Прочитайте рядок та перетворіть його у великі регістри, а потім виберіть слово, що базується на букві, та містить результат, і надрукуйте результат. Перший і останній крок обертаються, використовуючи, evalщоб сховати їх від awk.

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

Гаук, Ретіна perl -p,; 57 байт

Я ввожу це як бонус, оскільки вмикається командний рядок perl -p повинно бути частиною програми за звичайними правилами на цьому сайті, що зробить його не поліглотом.

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

Знову з заключним новим рядком для Retina . Цього разу, perl -pякщо надрукувати вихід автоматично, значно зменшуються накладні витрати. Я можу дозволити призначенню $_викликати неявний друк у розгорнутому стані .


Чи можете ви додати посилання TIO (або подібний онлайн-компілятор для тестування) для кожного з них?
Кевін Круїйсен

@KevinCruijssen Додано Вихід у TIO for perl -pпорожній, він повинен бути помилкою в TIO.
Жиль

7

> <>, Retina, Python 2: 144 127 123 байт

1 байт збережено завдяки @Loovjo, видаливши пробіл

4 байти збережено завдяки @ mbomb007, використовуючи inputзамістьraw_input

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

Опубліковано в ТНБ як виклик , я вирішив спробувати це поєднання мов.

> <>

Спробуйте в Інтернеті!

IP починає рухатися праворуч.

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

Можливі символи, які будуть взяті на вхід, є PRS(оскільки програма приймає лише перший символ). Їх ASCII-значення 80, 81і 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

Якщо вхід був рок, то це було б:

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

В іншому випадку, якщо вхід був SCISSORSабо PAPER, це IP-адреса зіткнеться:

"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

Якщо вхід був PAPER, то:

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

В іншому випадку (якщо вхід був SCISSORS):

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

Сітківка

Спробуйте в Інтернеті!

У цьому випадку Ретіна розглядає кожну пару двох ліній як пару відповідності та заміну. Наприклад, він намагається замінити що-небудь, що відповідає першому рядку, другим рядком, але оскільки перший рядок ніколи не збігається, він ніколи не замінює його нічим, тим самим зберігаючи вхід.

Пітон 2

Спробуйте в Інтернеті!

Програма Python потребує введення даних між "s.

Перші два рядки - це коментарі в 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

Я не думаю, що пробіл printв останньому рядку не потрібен.
Loovjo

Ви можете використовувати input()замість raw_input().
mbomb007

@Loovjo Дякую за підказку :)
Kritixi Lithos

@ mbomb007 Це, здається, не працює
Kritixi Lithos

@KritixiLithos працює, якщо частина пітона бере вказівки цитатами
undergroundmonorail

0

Ruby, Clojure, Common Lisp - 251 байт

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

Більш прочитана версія з пробілами:

(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 завжди перемагає, Ruby завжди малює, Common Lisp завжди програє.

Для Ruby все, 'що знаходиться в s - це рядок. Він пролягає через дві лінії. Тоді він використовує []оператор з аргументом рядка, який повертає сам рядок, якщо він присутній у рядку. Результат роздруковується, Ruby просто відображає вхід.

Другий рядок - це коментар для Clojure та Common Lisp. Купу evalі quoteпотрібно використовувати, тому що Clojure повинен переконатися, що всі символи є дійсними. Було б непогано використовувати код більше, але навіть nthфункції мають різні підписи на цих мовах. В основному Clojure if()оцінює істинно, і він переходить до першої гілки, коли викликається хеш-карта можливих варіантів з аргументом, прочитаним з stdin. Звичайний Lisp переходить до другої гілки, він знаходить позицію аргументу від stdin у списку і повертає відповідний елемент із списку, що виходить.

Я думаю, що загальну частину Lisp можна пограти більше.

Дивіться це в Інтернеті: Ruby , Common Lisp , Clojure


0

Scala, Javascript та Ook, 167 байт

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

Спробуйте в Scala Спробуйте в Javascript Спробуйте вигадливу версію Ook

Scala - виграє

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 - програє

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
}

Ой! - зв’язки

Частина Оок - це проста програма, яка ,[.,]нахабна кошка, переведена на Ок.

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

Якщо ви користуєтеся, a[(a.indexOf(s)+2)%3]то не потрібно встановлювати a[-1]="rock". Крім того, чи не можна також вставити код Ook і в рядок JavaScript?
Ніл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.