Камень, полиглот, ножницы

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

Самый короткий код в байтах побеждает. Ответ Tiebreaker выше.

Входы и / или выходы могут опционально иметь завершающий символ новой строки, но в остальном должны быть только простые строки 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
Оле Танге

Ответы:

60

Python, brainfuck и JavaScript, 103 99 байт Yay до 100 байт!

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

В Python это определяет функцию, которая превосходит ввод, в brainfuck это просто простая программа cat, а в 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но с более высоким приоритетом, так что я могу пропустить парены.


В Brainfuck все персонажи, кроме +-,.[]<>, удаляются, оставляя это:

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

Команда ,читает один байт ввода, .печатает его и [...]зацикливает, пока значение не равно нулю. Затем эта программа читает входные данные и печатает их по одному символу за раз, пока символ не \0будет найден. Поскольку в коде этого нет, мы можем игнорировать остальную часть программы. По сути, это просто отражает все, что пользователь вводит, эффективно связывая их.

Loovjo
источник
Работал над очень похожим решением, но вы меня опередили :). Вы должны обновить ссылку на Javascript TIO, кстати, она отличается от двух других.
DimP
2
x=>p[p.indexOf(x)+1]||"rock"//"""может быть сокращено доx=>p[(p.indexOf(x)+1)%3]//"""
Луки
13
+1 Я никогда не видел, чтобы Brainfuck так хорошо скрывали. Обычно это очевидно, если полиглот также содержит BF. Не в этом!
вс
Я думаю, что вы можете немного переместить программу BF, чтобы сохранить один или два байта:1//1,[.5,];
ETHproductions
На самом деле, я думаю, что вы можете использовать существующую []во второй строке, чтобы сохранить больше байтов:1//1,;lambda x:p[p.index(x,0)+-1];"""
ETHproductions
40

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

-7 байт благодаря Value Ink

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

Попробуйте онлайн: Python , Ruby , Retina

Побеждает в Ruby, проигрывает в Python и связывает в Retina. Это решение использует тот факт, что 0верно в Ruby, но неверно в Python. Он также использует отрицательную индексацию как в Python, так и в Ruby.

математик наркоман
источник
andимеет приоритет над оператором or, поэтому s.index(0and STDIN.gets or input())работает. Кроме того, getsпсевдоним для STDIN.getsв Ruby.
Value Ink
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, вот 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

Объяснение:

питон

В питоне это очень просто. Мы определяем список из трех элементов и возвращаем элемент прямо перед входом. Так как -1возвращает элемент back, это работает циклически, и все это очень просто и легко. Тогда все после #- это комментарий.

Мозг-Flak

Это также чрезвычайно просто в мозговых штурмах. Если бы нам пришлось выиграть или проиграть, это было бы, вероятно, несколько сотен байтов. Но это на самом деле работает в 0 байтов. При запуске программы все входные данные загружаются в стек. В конце программы весь стек печатается неявно.

Как только мы удалим все нерелевантные символы, код мозговой зрелище увидит

()[()]

Который просто оценивает 1 + -1, но так как это значение вообще не используется, это NOOP.

В

Вот где это становится немного странным. Называть список питонов 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
DJMcMayhem
источник
@WheatWizard В Python тоже нет причин (кроме того, что это одинаковая длина). Но это разрушает все в V.
DJMcMayhem
@WheatWizard Cause V - действительно странный язык, и это действительно странная задача для него. Все в значительной степени зависит от расположения символов, и от .split()них легче избавиться, чем от различных скобок и кавычек, которые появляются в вашем решении.
DJMcMayhem
Супер минор, но вы можете взять xxи заменить его на a, 2чтобы сделать команду, 2f'так как ='она будет удалена d*позже. РЕДАКТИРОВАТЬ: вы могли бы сделать это 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 все заглавные буквы являются предопределенными переменными. В первой строке многие из этих значений помещаются в стек вместе с некоторыми строковыми и массивными литералами. Некоторые увеличения, уменьшения и другие операции выполняются.

После всего этого стек оборачивается в array ( ]) и discarded ( ;), поэтому ничего из этого не имеет значения вообще. Основная программа 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)

Сетчатка

Это почти похоже на обман ...

Retina заменит любое совпадение с регулярным выражением 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 ++ всегда делает / s

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

Часть между """s - это многострочная строка в Python, в то время как это объявление функции в C и C ++. sizeof'b'-1выясняет, является ли текущий язык C из C ++. Он имеет истинное значение, если размер не равен 1, в противном случае - ложное значение. В C символьные литералы имеют 4-байтовый тип, а в C ++ - однобайтовый. Затем, после определения языка, он просто смотрит на первую букву ввода и выводит соответственно.

С

Попробуйте онлайн!

C ++

Попробуйте онлайн!

питон

Попробуйте онлайн!

betseg
источник
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 ++:

Попробуйте онлайн!

Р:

Результат:

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

Попробуйте онлайн!

Steadybox
источник
8

Gawk, Retina, Perl; 68 байт

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

(с новой строкой в ​​конце)

Гоук (победитель)

Некоторый мусор ради Perl, затем измените содержимое строки ( $_что совпадает с $0тем, что переменная _не определена) в зависимости от того, содержит она kили a c, затем напечатайте результат. Проигнорируйте любое предупреждение о escape-последовательностях, я хотел сделать это.

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

Сетчатка (галстук)

Тот же трюк, что и у Basic Sunset и других: замените совпадения некоторых глупых регулярных выражений в первой строке содержимым второй строки, поэтому пропустите ввод.

Perl (неудачник)

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

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

Gawk, Сетчатка, perl -p; 57 байт

Я ввожу это в качестве бонуса, потому что переключение командной строки perl -pдолжно быть частью программы по обычным правилам на этом сайте, что сделает его не полиглотом.

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

Снова с заключительной новой строкой для Retina . На этот раз, при perl -pавтоматической печати вывода, накладные расходы perl значительно уменьшаются. Я могу позволить назначению $_вызвать неявную печать в awk .

Жиль "ТАК - перестань быть злым"
источник
Не могли бы вы добавить ссылку TIO (или аналогичный онлайн-компилятор для тестирования) для каждого из них?
Кевин Круйссен,
@KevinCruijssen Добавлено. Вывод на TIO для 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]

Размещенный в TNB как вызов , я решил опробовать эту комбинацию языков.

> <>

Попробуйте онлайн!

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

Сетчатка

Попробуйте онлайн!

В этом случае Retina рассматривает каждую пару из двух строк как пару совпадения и замены. Например, он пытается заменить что-либо, совпадающее с первой строкой, второй строкой, но, поскольку первая строка никогда не совпадает, он никогда не заменяет ее чем-либо, тем самым сохраняя входные данные.

Python 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
Kritixi Lithos
источник
Я не думаю, что пробел после printпоследней строки необходим.
Loovjo
Вы можете использовать input()вместо raw_input().
mbomb007
@Loovjo Спасибо за совет :)
Kritixi Lithos
@ mbomb007 Кажется, это не сработает
Kritixi Lithos,
@KritixiLithos это работает, если часть Python принимает ввод с кавычками
подземный
0

Рубин, 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()оценивается как true и переходит к первой ветви, когда вызывается хэш-карта возможных вариантов с аргументом, считанным из stdin. Common Lisp переходит ко второй ветви, он находит позицию аргумента из stdin в списке и возвращает соответствующий элемент из результирующего списка.

Я думаю, что часть Common Lisp может быть в гольфе больше.

Смотрите это онлайн: Ruby , Common Lisp , Clojure

cliffroot
источник
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 для ума

Скала - выигрывает

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
}

Ук! - галстуки

Часть Ook - это простая программа ,[.,]для кошек- мозговиков, переведенная на 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
corvus_192
источник
Если вы используете, a[(a.indexOf(s)+2)%3]то вам не нужно устанавливать a[-1]="rock". Кроме того, вы не можете поместить код Ook внутри строки JavaScript тоже?
Нил