Score rock-paper-scissors

71

11

Given two string inputs of "Rock", "Paper", or "Scissors", determine the outcome of the RPS round. Output 1 if the first player wins, -1 if the second player wins, or 0 for a tie.

Rock Rock -> 0
Rock Paper -> -1
Rock Scissors -> 1
Paper Rock -> 1
Paper Paper -> 0
Paper Scissors -> -1
Scissors Rock -> -1
Scissors Paper -> 1
Scissors Scissors -> 0

You must use the exact strings "Rock", "Paper", and "Scissors" as inputs. You may choose whether the first players' choice is (consistently) given first or second. You may alternatively take them as a single input with a single-character or empty separator. The input is guaranteed one of the 9 possible pairings of the three choices in your input format.

The output should be a number 1, 0, or -1, or its string representation. Floats are fine. So are +1, +0, and -0.

Related: Coding an RPS game


Leaderboard:

var QUESTION_ID=106496,OVERRIDE_USER=20260;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/106496/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

xnor

Posted 2017-01-11T20:36:04.403

Reputation: 115 687

Does a single input with empty separator mean for example "rockpaper"? – Emigna – 2017-01-11T21:25:08.453

1@Emigna Yes, but capitalized as RockPaper. – xnor – 2017-01-11T21:26:13.693

15That was WAY more fun than I had anticipated, my lord there are some cool ways to do this. – Magic Octopus Urn – 2017-01-11T21:30:37.177

Can the input be an array of the two strings? – Luis Mendo – 2017-01-11T22:33:11.447

@LuisMendo Yes. – xnor – 2017-01-11T22:34:28.547

Wow, I completely agree with @carusocomputing There is currently more than one page of answers, and almost none of these use the same method twice. Usually you see a lot of: Port of Person's answer, or similar approaches done individually by different persons a lot more, but not with this challenge (so far). – Kevin Cruijssen – 2017-01-12T11:01:35.550

Bonus for including Lizard Spock ;) – Tobias Kienzler – 2017-01-12T20:34:26.480

So the input must be a single argument of a string containing both plays? It can't be 2 input strings? – Carcigenicate – 2017-01-12T20:49:20.777

@Carcigenicate No, that's an optional alternative. – xnor – 2017-01-12T21:40:39.560

@xnor OK, good. Should like halve the length of my solution lol. – Carcigenicate – 2017-01-12T21:42:46.040

The 'Winners by Language' thing doesn't work for me. – 0WJYxW9FMN – 2017-01-13T22:08:18.087

How did I get more points than the question itself? For shame to you question non-voters! – Magic Octopus Urn – 2017-01-24T21:29:11.027

Answers

73

Groovy, 67 56 50 Bytes

{a,b->Math.sin(1.3*((int)b[0]-(int)a[0])).round()}

Try it online!

Turns out that the rock, paper, scissors game has a pretty cool property.
Given strings a and b, take the first letter of each, this results in two of the following: R,P,S

The exhaustive list of possible values are (When 2 choices are combined):

XX=ASCII=Y=Wanted output
RR=82-82=0=0
PP=80-80=0=0
SS=83-83=0=0
RS=82-83=-1=1
RP=82-80=2=-1
PS=80-83=-3=-1
PR=80-82=-2=1
SR=83-82=1=-1
SP=83-80=3=1

Reorganizing the list to:

-3->-1
-2->1
-1->1
0->0
1->-1
2->-1
3->1

Gives us a sequence that looks inversely sinusoidal, and you can actually represent this formula as approximately (and by approximately I mean just barely enough to work, you could get an equation that is dead on but costs more bytes):

-sin((4*a[0]-b[0])/PI).roundNearest() = sin(1.3*(b[0]-a[0])).roundNearest()

The simplification of 4/pi to 1.3 was suggested first by @flawr and then tested by @titus for a total savings of 6 bytes.

Equation Explanation

Using groovy's double rounding properties, this results in the correct output for rock-paper-scissors.


05AB1E, 10 bytes (non-compete)

Ç¥13T/*.½ò

Try it online!

Same answer ported to 05AB1E using the new commands added 10/26/2017.

Magic Octopus Urn

Posted 2017-01-11T20:36:04.403

Reputation: 19 422

3Couldn't you make it shorter by using that -sin(x) = sin(-x),that means just reversing the order of a and b and dropping the leading -? Other than that, hardcoding an approximation of 4/Pi like 1.273 could be sufficient, or 1.3 or 9/7 or 5/4. – flawr – 2017-01-11T21:43:09.047

2

PS: I also suggest making a link to try it online so people like me can play around with your submission=)

– flawr – 2017-01-11T21:45:24.573

@flawr groovy on TIO? Since when! – Magic Octopus Urn – 2017-01-12T06:58:04.857

3You can save 1 byte with sin(b-a) instead of -sin(a-b). Great find! – Titus – 2017-01-12T08:27:39.900

2Save another 7 bytes by multiplying by 1.3 instead of 4/Math.PI; that´s sufficiently exact. – Titus – 2017-01-12T08:58:05.410

@carusocomputing On your ascii conversion chart, towards the top, it looks like you have the values for P and S swapped. btw, very cool answer! – CraigR8806 – 2017-01-12T13:06:01.657

@CraigR8806 P=80, R=82, S=83 is what I have up there, unless I'm blind (which is entirely possible). – Magic Octopus Urn – 2017-01-12T14:35:19.917

1@carusocomputing `XX=ASCII=Y=Wanted output

RR=82-82=0=0

PP=83-83=0=0 SS=80-80=0=0` – CraigR8806 – 2017-01-12T15:09:31.600

@CraigR8806 I AM blind! – Magic Octopus Urn – 2017-01-12T15:17:59.663

you could multiply by 2 and truncate instead of using round(), this might be shorter. /.8 instead of *1.3 seems to work, too. – 12Me21 – 2017-01-26T01:34:26.273

@12Me21 .trunc() is similar in length to .round() – Magic Octopus Urn – 2017-04-25T18:37:23.883

I meant truncate by doing |0 or something similar. – 12Me21 – 2017-04-26T19:18:43.073

44

C, 50 35 bytes

#define f(i)*(short*)(i+7)%51%4%3-1

Call f with a string containing both players, without separator, and it will return whether the first one wins.

Explanation:

By looking at the nine possible strings, it turns out that the letter pairs on columns 7 and 8 are unique:

       vv
RockPaper
PaperScissors
ScissorsRock
RockRock         // Sneakily taking advantage of the terminating zero
PaperPaper
ScissorsScissors
RockScissors
PaperRock
ScissorsPaper
       ^^

The offset and savage cast to short* retrieve these letter pairs, and interpret them as numbers:

29285
29545
21107
107
25968
21363
29555
27491
20595

Then it was a matter of brute-force to find the 51 and 4 remainders, which applied successively reduce these numbers to:

3 0 0 1 1 1 2 2 2

Which is just perfect to tack yet another remainder at the end, and offsetting the result.

See it live on Coliru

Quentin

Posted 2017-01-11T20:36:04.403

Reputation: 1 187

Just don't do anything like calculating -f(i) to calculate the other player's score - unexpected output will result! – nneonneo – 2017-01-12T01:56:28.630

4@nneonneo -(f(i)) should work fine. Macros are fun! – nwp – 2017-01-12T18:29:27.667

18

MATLAB/Octave, 63 54 52 bytes

It is very convenient that the ASCII-codes of the first letters of Rock,Paper,Scissors are R=82,P=80,S=83. If we subtract 79 we get conveniently 3,1,4, which we will use now as matrix indices: Here a 4x4-matrix is hardcoded, where the i,j-th entry corresponds to the outcome if you plug in the values from just before:

     1   2   3   4
  +---------------
1 |  0   0   1  -1
2 |  0   0   0   0
3 | -1   0   0   1
4 |  1   0  -1   0
A(5,5)=0;A(4:7:18)=1;A=A-A';@(x,y)A(x(1)-79,y(1)-79)

Try it online!

flawr

Posted 2017-01-11T20:36:04.403

Reputation: 40 560

16

Pure Bash, 31

Borrowing @Dennis's formula:

a=$1$1$2
echo $[(${#a}^67)%3-1]

Try it online.


Previous answer:

Pure Bash, 43 35

echo $[(7+(${#2}^3)-(${#1}^3))%3-1]
  • Get the string length of each arg (4, 5, 8 respectively for Rock, Paper, Scissors)
  • XOR each with 3 to give 7, 6, 11 (which when taken mod 3 give 1, 0, 2)

  • Then subtract and fiddle with mod 3 to get the desired result.

Try it online.

Digital Trauma

Posted 2017-01-11T20:36:04.403

Reputation: 64 644

15

Python, 40 30 bytes

lambda x,y:(len(2*x+y)^67)%3-1

Try it online!

Background

I've started with the function template

lambda x,y:(len(a*x+b*y)^c)%d-e

and ran a brute-force search for suitable parameters using the following program, then picked one with a minimal-length implementation.

RPS = 'Rock Paper Scissors'.split()
g = lambda x,y:2-(94>>len(6*x+y)%7)%4
r = range(1,10)
R = range(100)

def f(a, b, c, d, e):
    h = lambda x,y:(len(a*x+b*y)^c)%d-e
    return all(g(x, y) == h(x, y) for x in RPS for y in RPS)

[
    print('%2d ' * 5 % (a, b, c, d, e))
    for e in r
    for d in r
    for c in R
    for b in r
    for a in r
    if f(a, b, c, d, e)
]

Try it online!

Dennis

Posted 2017-01-11T20:36:04.403

Reputation: 196 637

14

Mathematica, 32 bytes

Mod[{1,-1}.(Length/@#-3)!,3,-1]&

Unnamed function taking an ordered pair of lists of characters, such as {{"R","o","c","k"},{"P","a","p","e","r"}}, and returning -1|0|1.

I wanted the code to avoid not only the three input words, but also the way-too-long function name ToCharacterCode; so I worked with the length 4,5,8 of the input words instead, and looked for a short function of those lengths that gave distinct answers modulo 3. (Integer division by 2 is mathematically promising, but those functions have too-long names in Mathematica.)

It turns out that taking the factorial of (the length – 3) gives the answers 1,2,120, which are 1,-1,0 modulo 3. Then we just compute, modulo 3, the difference of the two values (via the dot product {1,-1}.{x,y} = x-y, which is a good way when the two values are in a list).

Greg Martin

Posted 2017-01-11T20:36:04.403

Reputation: 13 940

1"It turns out..." You have an eye for these things – ngenisis – 2017-01-11T22:08:59.643

12

Ruby, 36 35 30 bytes

a=->a,b{(a+b)[12]?a<=>b:b<=>a}

Try it on ideone.com

Test output:

a=->a,b{(a+b)[12]?a<=>b:b<=>a}

puts a.call("Rock", "Rock")
puts a.call("Rock", "Paper")
puts a.call("Rock", "Scissors")
puts a.call("Paper", "Rock")
puts a.call("Paper", "Paper")
puts a.call("Paper", "Scissors")
puts a.call("Scissors", "Rock")
puts a.call("Scissors", "Paper")
puts a.call("Scissors", "Scissors")

0
-1
1
1
0
-1
-1
1
0

Takes advantage of the fact that 7 of the 9 correct results are generated just by doing a lexicographic comparison using the spaceship operator <=>. The (a+b)[12] just reverses the inputs to the comparison if the inputs are Paper and Scissors (and also Scissors Scissors - but that's 0 either way round).

With thanks to Horváth Dávid for saving me a character, and thanks to G B for saving me another 5.

Gareth

Posted 2017-01-11T20:36:04.403

Reputation: 11 678

You can use an anonymous lambda and save 2 characters. – G B – 2017-01-11T21:57:32.143

@GB If I don't give the function a name how am I supposed to call it? That smacks of cheating to me. But thanks for the other tip - I had looked at that but rejected it because ScissorsScissors is 16, but I see that doesn't actually matter. :-) – Gareth – 2017-01-11T22:03:52.040

That's not cheating. Anonymous functions are allowed by default.

– Dennis – 2017-01-15T19:41:41.940

@Dennis You can't call it without assigning it. It feels like cheating to me, and unfair on languages without anonymous functions that have to define a name. – Gareth – 2017-01-15T19:44:10.007

@Dennis Hmmm. I'm tempted to remove the 2 characters for the a= and add 5 for the .call since that's always required... – Gareth – 2017-01-15T19:54:12.643

The task is to create a function, not to call it. Stop thinking about ways to increase your byte count. :P – Dennis – 2017-01-15T20:00:56.953

10

Python, 39 36 34 33 bytes

lambda x,y:2-(94>>len(6*x+y)%7)%4

Try it online!

How it works

Let's take a look at a few values of the length of six copies of x and one copy of y modulo 7.

                                l(x,y) =:
x        y        len(x) len(y) len(6*x+y)%7
--------------------------------------------
Rock     Rock          4      4            0
Rock     Paper         4      5            1
Rock     Scissors      4      8            4
Paper    Rock          5      4            6
Paper    Paper         5      5            0
Paper    Scissors      5      8            3
Scissors Rock          8      4            3
Scissors Paper         8      5            4
Scissors Scissors      8      8            0

We can encode the outcomes ({-1, 0, 1}) by mapping them into the set {0, 1, 2, 3}. For example, the mapping t &mapsto; 2 - t achieves this and is its own inverse.

Let's denote the outcome of x and y by o(x, y). Then:

x        y        l(x,y) o(x,y) 2-o(x,y) (2-o(x,y))<<l(x,y)
-----------------------------------------------------------
Rock     Rock          0      0        2                10₂
Rock     Paper         1     -1        3               110₂
Rock     Scissors      4      1        1            010000₂
Paper    Rock          6      1        1          01000000₂
Paper    Paper         0      0        2                10₂
Paper    Scissors      3     -1        3             11000₂
Scissors Rock          3     -1        3             11000₂
Scissors Paper         4      1        1            010000₂
Scissors Scissors      0      0        2                10₂

Luckily, the bits in the last columns all agree with each other, so we can OR them to form a single integer n and retrieve o(x, y) as 2 - ((n ≫ o(x,y)) % 4). The value of n is 94.

Dennis

Posted 2017-01-11T20:36:04.403

Reputation: 196 637

9

Retina, 35 31 bytes

G`k P|r S|s R
*\)`.+
-
D`\w+
 .

Try it online!

Explanation

This works in two steps. First, we print the minus signs for the relevant inputs. Then we print a 0 for ties and a 1 otherwise.

G`k P|r S|s R
*\)`.+
-

This is two stages. The ) in the second stage groups them together, the * makes them a dry run (which means the input string will be restored after they were processed, but the result will be printed) and \ suppresses printing of a trailing linefeed. The two stages together will print a - if applicable.

The first stage is a Grep stage which only keeps the line if it contains either k P, r S, or s R. These correspond to the cases where we need to output -1. If it's not one of those cases, the input will be replaced with an empty string.

The second stage replaces .+ (the entire string, but only if it contains at least one character) with -. So this prints a - for those three cases and nothing otherwise.

D`\w+
 .

This is two more stages. The first stage is a Deduplication. It matches words and removes duplicates. So if and only if the input is a tie, this drops the second word.

The second stage counts the number of matches of ., which is a space followed by any character. If the input was a tie, and the second word was removed, this results in 0. Otherwise, the second word is still in place, and there's one match, so it prints 1 instead.

Martin Ender

Posted 2017-01-11T20:36:04.403

Reputation: 184 808

Here's a different approach based off the input string lengths. Its longer than yours, but I wonder if it could be golfed down any more? – Digital Trauma – 2017-01-11T22:38:11.833

@DigitalTrauma that's a really neat idea, but I'm not seeing anything to shorten it. I think you should post it anyway (and if you move the first line into the header then TIO won't include it in the byte count). – Martin Ender – 2017-01-12T07:14:57.747

8

05AB1E, 18 17 15 10 9 bytes

6 bytes saved with Digital Trauma's input length trick

€g3^Æ>3%<

Takes input as [SecondPlayersChoice,FirstPlayersChoice]

Try it online! or Validate all test-cases

Alternative 9 byte solution: íø¬ÇÆ>3%<

Explanation

€g          # length of each in input
  3^        # xor 3
    Æ       # reduce by subtraction
     >      # increment
      3%    # modulus 3
        <   # decrement

Previous 15 byte solution

A-D{„PSÊiR}Ç`.S

Try it online! or Validate all test-cases

Explanation

 A-               # remove the lowercase alphabet from the input (leaves a 2 char string)
   D{             # sort a copy of the leftover
     „PSÊ         # check if the copy isn't "PS" (our special case)
         iR}      # if true, reverse the string to get the correct sign
            Ç`    # convert the two letters to their character codes
              .S  # compare their values

Emigna

Posted 2017-01-11T20:36:04.403

Reputation: 50 798

You beat my fun one :( Ç¥13T/*.½ò WHY IT WORKS? NOBODY KNOWS. – Magic Octopus Urn – 2018-02-08T16:45:09.930

@MagicOctopusUrn: Uuuh, that sure is a weird one. What would the input format be for it to return an int as output? – Emigna – 2018-02-08T18:32:59.630

['R','P'] :P It's a port of this. – Magic Octopus Urn – 2018-02-09T16:18:14.937

@MagicOctopusUrn: Oh yeah, I forgot about that one. My favorite answer to this challenge :) – Emigna – 2018-02-09T19:33:19.760

6

Jelly, 8 bytes

L€Iµ-*×Ṡ

Try it online! (test suite, casts to integer for clarity)

How it works

L€Iµ-*×Ṡ  Main link. Argument: A (string array)

L€        Take the length of each string.
  I       Increments; compute the forward difference of the length.
   µ      Begin a new chain with the difference d as argument.
    -*    Compute (-1)**d.
      ×Ṡ  Multiply the result with the sign of d.

Dennis

Posted 2017-01-11T20:36:04.403

Reputation: 196 637

6

Python 2, 46 40 bytes

lambda x,y:+(x!=y,-1)[x[0]+y[0]in'RPSR']

Try it online!

With many thanks to @Dennis for letting me borrow his Try it online test code and for saving me 6 bytes.

Edit

@hashcode55 - Pretty much as you describe. (x!=y,-1) is a two element sequence and [x[0]+y[0]in'RPSR'] is computing which element to take. If the first letter of x + the first letter of y is in the character list then it will evaluate to True or 1 so (x!=y,-1)[1] will be returned. If it is not then (x!=y,-1)[0]. This is where it gets a bit tricky. The first element is in itself effectively another if. If x!=y then the first element will be True otherwise it will be False so if x[0]+y[0]in'RPSR' is false then either True or False will be returned depending on whether x==y. The + is a bit sneaky and thanks again to @Dennis for this one. The x!=y will return a literal True or False. We need a 1 or a 0. I still don't quite know how but the + does this conversion. I can only assume that by using a mathematical operator on True/False it is forcing it to be seen as the integer equivalent. Obviously the + in front of the -1 will still return -1.

Hope this helps!

ElPedro

Posted 2017-01-11T20:36:04.403

Reputation: 5 301

Hi! Can you please tell me how this syntax is working? Logically guessing, (x!=y,-1) this is working like if, if the list generates a true then -1 else x!=y. Whats the use of that + sign? A source documenting this kind of syntax would be really helpful! – hashcode55 – 2017-01-15T10:17:14.567

@hashcode55 - I have added an explanation to my answer. – ElPedro – 2017-01-15T11:32:54.273

To answer your uncertainty about the + - in this case, that's a unary plus, like +10, and is essentially a short way to convert to an integer. – FlipTack – 2017-01-15T13:22:40.270

Thanks @FlipTack. Kinda guessed that was what it is doing but thanks for the proper explanation. – ElPedro – 2017-01-15T13:26:19.437

@ElPedro Thanks a lot! That indeed helped me. – hashcode55 – 2017-01-15T19:10:20.350

5

JavaScript (ES6), 46 38 bytes

(a,b)=>(4+!b[4]+!b[5]-!a[4]-!a[5])%3-1

Makes use of the fact that Rock-Paper-Scissors is cyclic. JavaScript has neither spaceship nor balanced ternary operators, otherwise the answer would be (a,b)=>((b<=>'Rock')-(a<=>'Rock'))%%3.

Edit: Saved 8 bytes thanks to @WashingtonGuedes.

Neil

Posted 2017-01-11T20:36:04.403

Reputation: 95 035

1@WashingtonGuedes I can do even better than that! – Neil – 2017-01-11T22:07:24.837

You could curry to save 1 byte – MayorMonty – 2017-08-30T00:22:43.450

i tried running it and always return 0 – Vitim.us – 2018-01-19T23:03:08.987

5

Python 3, 54 bytes

lambda o,t:(o!=t)*[-1,1]['RPS'['PS'.find(t[0])]!=o[0]]

Try it online!

user63571

Posted 2017-01-11T20:36:04.403

Reputation:

5

MATL, 14 13 bytes

TTt_0vic1Z)d)

Try it online! Or verify all test cases.

Explanation

If the ASCII code of the initial letter of the first string is subtracted from that of the second string we get the value in the D column below. Taking modulo 5 gives the value M. The final value in parentheses is the desired result, R.

                        D        M     R
                       ---      ---   ---
Rock Rock          ->   0   ->   0   ( 0) 
Rock Paper         ->  −2   ->   3   (−1)
Rock Scissors      ->   1   ->   1   ( 1)
Paper Rock         ->   2   ->   2   ( 1)
Paper Paper        ->   0   ->   0   ( 0)
Paper Scissors     ->   3   ->   3   (−1)
Scissors Rock      ->  −1   ->   4   (−1)
Scissors Paper     ->  −3   ->   2   ( 1)
Scissors Scissors  ->   0   ->   0   ( 0)

Thus if we compute D and then M, to obtain R we only need to map 0 to 0; 1 and 2 to 1; 3 and 4 to −1. This can be done by indexing into an array of five entries equal to 0, 1 or −1. Since indexing in MATL is 1-based and modular, the array should be [1, 1, −1, −1, 0] (the first entry has index 1, the last has index 5 or equivalently 0). Finally, the modulo 5 operation can luckily be avoided, because it is implicitly carried out by the modular indexing.

TT     % Push [1 1]
t_     % Duplicate, negate: pushes [−1 −1]
0      % Push 0
v      % Concatenate vertically into the 5×1 array [1; 1; −1; −1; 0]
i      % Input cell array of strings
c      % Convert to 2D char array, right-padding with zeros if necessary
1Z)    % Take the first column. Gives a 2×1 array of the initial letters
d      % Difference
)      % Index into array. Implicit display

Luis Mendo

Posted 2017-01-11T20:36:04.403

Reputation: 87 464

5

CJam, 12 bytes

0XXWW]rcrc-=

The two inputs are space-separated. Their order is reversed with respect to that in the challenge text.

Try it online! Or verify all test cases.

Explanation

Translation of my MATL answer. This exploits the fact that in CJam c (convert to char) applied on a string takes its first character. Also, the array for the mapping is different because indexing in CJam is 0-based.

0XXWW    e# Push 0, 1, 1, -1, -1
]        e# Pack into an array
rc       e# Read whitespace-separated token as a string, and take its first char
rc       e# Again
-        e# Subtract code points of characters
=        e# Index into array. Implicitly display

Luis Mendo

Posted 2017-01-11T20:36:04.403

Reputation: 87 464

5

CJam, 15 14 12 bytes

rW=rW=-J+3%(

Take the ascii code of the last character of each string, then returns:

(a1 - a2 + 19) % 3 - 1

Test it here!

Arnaud

Posted 2017-01-11T20:36:04.403

Reputation: 8 231

4

dc, 18

1?Z9+2/rZ1+2/-3%-p

Try it online.

Note that the two args are passed (space-separated) on one line to STDIN. The args are contained in square brackets [ ] as this is how dc likes its strings.

dc has very limited string handling, but it turns out one of the things you can do is use the Z command to get a string length, which luckily is distinct for "Rock", "Paper" and "Scissors", and can be fairly simply arithmetically manipulated to give the desired result.

Digital Trauma

Posted 2017-01-11T20:36:04.403

Reputation: 64 644

4

Java 7, 82 bytes

int c(String...a){int x=(a[0].charAt(1)-a[1].charAt(1))%5/2;return x%2==x?x:x/-2;}

Ungolfed:

int c(String... a){
   int x = (a[0].charAt(1) - a[1].charAt(1)) % 5 / 2;
   return x%2 == x
           ? x
           : x / -2;
}

Explanation:

  • The second letters are o, a and c, with the ASCII decimals 111, 97 and 99.
  • If we subtract these from each other for the test cases we have the following results:
    • 0 (Rock, Rock)
    • 14 (Rock, Paper)
    • 12 (Paper, Scissors)
    • -14 (Paper, Rock)
    • 0 (Paper, Paper)
    • -2 (Paper, Scissors)
    • -2 (Scissors, Rock)
    • 2 (Scissors, Paper)
    • 0 (Scissors, Scissors)
  • If we take modulo 5 for each, we get 4, 2, -4, -2, -2, 2.
  • Divided by 2 x is now the following for the test cases:
    • x=0 (Rock, Rock)
    • x=2 (Rock, Paper)
    • x=1 (Paper, Scissors)
    • x=-2 (Paper, Rock)
    • x=0 (Paper, Paper)
    • x=-1 (Paper, Scissors)
    • x=-1 (Scissors, Rock)
    • x=1 (Scissors, Paper)
    • x=0 (Scissors, Scissors)
  • Only the 2 and -2are incorrect, and should have been -1 and 1instead. So if x%2 != x (everything above 1 or below -1) we divide by -2 to fix these two 'edge-cases'.

Test code:

Try it here.

class M{
  static int c(String...a){int x=(a[0].charAt(1)-a[1].charAt(1))%5/2;return x%2==x?x:x/-2;}

  public static void main(String[] a){
    String R = "Rock",
           P = "Paper",
           S = "Scissors";
    System.out.println(c(R, R)); // 0
    System.out.println(c(R, P)); // -1
    System.out.println(c(R, S)); // 1
    System.out.println(c(P, R)); // 1
    System.out.println(c(P, P)); // 0
    System.out.println(c(P, S)); // -1
    System.out.println(c(S, R)); // -1
    System.out.println(c(S, P)); // 1
    System.out.println(c(S, S)); // 0
  }
}

Output:

0
-1
1
1
0
-1
-1
1
0

Kevin Cruijssen

Posted 2017-01-11T20:36:04.403

Reputation: 67 575

Why the second letter out of curiosity? I had the same approach (kinda) but used the first letter. – Magic Octopus Urn – 2017-01-12T14:38:22.230

@carusocomputing Well, I noticed most of the other people were using either the first letter or length, and wanted to try something else. I first used the third letters (c, p, i) with the ASCII values 99, 112 and 105, as they seemed most useful, and noticed it would become 4, 2, 0 if I did modulo 5. Only then I figured I had to subtract both, so the 4, 2 and 0 weren't of much use. After some fuddling around/trial-and-error I tried the second letter and was getting more useful results with the same modulo 5 still present. Then I quickly came to the solution I presented above. :) – Kevin Cruijssen – 2017-01-12T14:48:24.577

@carusocomputing Wanted to try an unique approach, and considering I'm pretty bad at these kind of solutions, it isn't as short as some other solutions, but still unique (which was my initial goal). :) – Kevin Cruijssen – 2017-01-12T14:49:38.630

4

PHP, 34 bytes

<?=md5("BMn$argv[1]$argv[2]")%3-1;

user63956

Posted 2017-01-11T20:36:04.403

Reputation: 1 571

3

C#, 85 84 bytes

Saved 1 byte, thanks to TheLethalCoder

a=>b=>a==b?0:(a[0]=='R'&b[0]=='S')|(a[0]=='P'&b[0]=='R')|(a[0]=='S'&b[0]=='P')?1:-1;

It accepts two strings as an input, and outputs an integer. There is a tie, if the two strings are equal, otherwise it checks for the first charachter of the strings, in order to determine, which player wins.

Horváth Dávid

Posted 2017-01-11T20:36:04.403

Reputation: 679

Save one byte by using currying i.e. a=>b=>... – TheLethalCoder – 2017-01-13T15:36:19.607

3

Pyth, 16

t%+7h.+mx3ldQ3

Probably could be shorter.

        x3ld      # lambda to get string length then XOR with 3
       m    Q     # map over the input (array of 2 strings)
     .+           # difference of the two results
    h             # flatten one-element array
  +7              # add 7
 %           3    # mod 3
t                 # subtract 1 and implicit print

Online.

Digital Trauma

Posted 2017-01-11T20:36:04.403

Reputation: 64 644

3

JavaScript, 37, 32, 31 bytes

a=>b=>a==b?0:!(a+b)[12]^a>b||-1

If a equals b, output zero.

Otherwise, xor the result of checking if length not greater than 12 (comparison of Scissors and Paper) with the comparison of a greater than b.
If this returns 1, return it.

If it returns 0, use the OR operator to replace with -1.

Grax32

Posted 2017-01-11T20:36:04.403

Reputation: 1 282

Could you write this as a curried function a=>b=> to save a byte? – FlipTack – 2017-01-27T21:39:34.177

Yes. Thank you @FlipTack – Grax32 – 2017-01-30T00:53:22.237

2

Perl, 33 bytes

32 bytes of code + -p flag.

$_=/(.+) \1/?0:-/k P|r S|s R/||1

To run it:

perl -pe '$_=/(.+) \1/?0:-/k P|r S|s R/||1' <<< "Rock Paper"

Saved 3 bytes by using the regex of Martin Ender's Retina answer. (my previous regex was /R.*P|P.*S|S.*R/)

Explanation:

First, /(.+) \1/ checks if the input contains twice the same word, if so, the result is 0. Otherwise, /k P|r S|s R/ deals with the case where the answer is -1. If this last regex is false, then -/k P|r S|s R/is false, so we return 1.

Dada

Posted 2017-01-11T20:36:04.403

Reputation: 8 279

2

Batch, 116 bytes

@if %1==%2 echo 0&exit/b
@for %%a in (RockScissors PaperRock ScissorsPaper)do @if %%a==%1%2 echo 1&exit/b
@echo -1

Neil

Posted 2017-01-11T20:36:04.403

Reputation: 95 035

2

Japt, 19 bytes

-Ms(4*(Uc -Vc)/MP¹r

Try it here!

Inspired by carusocomputing's solution

Old 53-byte Solution

W=Ug c X=Vg c W¥X?0:W¥82©X¥83?1:W¥80©X¥82?1:W¥83©X¥80?1:J

Try it online!

Thanks again, ETHproductions!

Oliver

Posted 2017-01-11T20:36:04.403

Reputation: 7 160

1

You could start by using © instead of &&, changing the Ug0 c to Ug c (same with V) and replacing -1 with J. It's still quite a bit longer than the JS answer though, perhaps you can take some ideas from that

– ETHproductions – 2017-01-11T22:47:36.890

@ETHproductions Thanks! I don't know how I forget about © – Oliver – 2017-01-12T01:03:15.357

1Actually you can just do W=Uc. I don't know why I keep forgetting that c works on any string :P – ETHproductions – 2017-01-12T01:38:58.083

2

Jelly, 9 bytes

L€^3Iæ%1.

This uses the algorithm from @DigitalTrauma's Bash answer.

Try it online!

How it works

L€^3Iæ%1.  Main link. Argument: A (string array)

L€         Take the length of each string.
  ^3       XOR the lengths bitwise with 3.
    I      Increments; compute the forward difference of both results.
     æ%1.  Balanced modulo 1.5; map the results into the interval (-1.5, 1.5].

Dennis

Posted 2017-01-11T20:36:04.403

Reputation: 196 637

Dammit, I was about to start reading up on Jelly. Oh well, here it is in pyth. +1.

– Digital Trauma – 2017-01-12T00:17:58.580

2

PHP, 55 53 bytes

<?=(3-(ord($argv[2])%6%4-ord($argv[1])%6%4+3)%3*2)%3;
  • takes the ascii values of the first letters (from command line arguments): 82,80,83
  • %6: 4,2,5
  • %4: 0,2,1
  • difference (b-a):
    • PS:1-2,SR:2-0,RP:2-0 -> -1 or 2; +3,%3 -> 2
    • SP:2-1,RS:0-2,PR:0-2 -> -2 or 1; +3,%3 -> 1
    • RR,PP,SS:0; +3,%3: 0
  • (3-2*x): -1,1,3
  • %3: -1,1,0

sine version, 49 46 bytes

<?=2*sin(1.3*(ord($argv[2])-ord($argv[1])))|0;

a golfed port of carusocomputing´s answer:

3 bytes saved by @user59178

Titus

Posted 2017-01-11T20:36:04.403

Reputation: 13 814

1For the sine version for can save 3 bytes by replacing round(x) with 2*x^0 – user59178 – 2017-01-12T09:27:27.247

2

Perl, 25 bytes

$_=/kS|rR|sP/-/kP|rS|sR/

Code 24 bytes +1 byte for -p option.

The input should be on stdin without separators, e.g.:

echo PaperRock | perl -pe'$_=/kS|rR|sP/-/kP|rS|sR/'

The first regexp searches for first player win, the second for his loss. The difference is printed.

mik

Posted 2017-01-11T20:36:04.403

Reputation: 208

2

Python 2, 32 bytes

lambda*l:cmp(*l)*(1|-('R'in`l`))

Try it online

A fairly short "natural" solution, though not as short as Dennis's brute-forced solution.

The cmp(*l) compares the inputs lexicographically, giving -1, 0, or +1 for smaller, equal, and greater. This gives the right negated answer on each pair of "Paper", "Rock", "Scissors" except on Paper vs Scissors in either order. To fix that, we multiply by -1 on any input without an 'R' in the string rep. This also flips Scissors vs Scissors and Paper vs Paper, but those gave 0 anyway.

Thanks to xsot for saving a byte with the (1|-(_)) construct to turn a Bool into ±1. This is shorter than the alternatives.

lambda*l:cmp(*l)*cmp(.5,'R'in`l`)
lambda*l:cmp(*l)*(-1)**('R'in`l`)
lambda*l:cmp(*l)*(1-2*('R'in`l`))

xnor

Posted 2017-01-11T20:36:04.403

Reputation: 115 687

1There's a shorter alternative: (1|-('R'in\l`))` – xsot – 2017-01-16T01:59:22.160

@xsot Thanks! That's a nice trick for a common situation, you could add a tip for it. – xnor – 2017-01-18T00:17:02.203

Perhaps you could mention it in this tip. Also, for what it's worth, I first encountered this trick here.

– xsot – 2017-01-18T02:55:33.797

1

Scala, 148 bytes

object R extends App{val t=Seq('R','P','S')
val(a,b)=(args(0)(0),args(1)(0))
print(if(a==b)0 else if(t.indexOf(a)%3==(t.indexOf(b)-1)%3)-1 else 1)}

Thankfully, since semicolons are required to separate multiple commands on the same line, Scala benefits from having formattable golf code!

In this golfing attempt I learned that you can replace

"somestring".charAt(index) 

with

"somestring"(index) 

because Scala lets you treat strings as arrays for the purpose of getting characters.

Archmage stands with Monica

Posted 2017-01-11T20:36:04.403

Reputation: 171

This can be golfed immensely. For starters, you're allowed to do a function instead of a complete program in most challenges here, so instead of the whole object extends app thing and pulling from args, try something like: def g(a:Seq,b:Seq)=... – Ethan – 2017-01-13T19:54:52.867

Additionally, you need not print the value. Returning it is sufficient, which is great when golfing Scala, since the return is free. And you can improve it even further by using the trick posted in the Groovy answer, which works almost identically in Scala. – Ethan – 2017-01-13T20:10:11.840

1

C++, 98 bytes#

int main(int c,char*v[]){int a=v[2][0]-v[1][0];if(a%3==0)a=-a;if(a>1)a/=a;if(a<-1)a/=-a;return a;}

Could definitely be shortened, but I don't have that skill or knowledge. Enlightenment?

Fansay

Posted 2017-01-11T20:36:04.403

Reputation: 11

2Brought it down to 72, and there's probably more room to improve :) – Quentin – 2017-01-12T11:17:35.077

1

GNU Sed, 39, 38 bytes

36 bytes code + 2 bytes for the "nr" flags

Golfed

/^(.+)\1/{a0
b}
/kP|rS|sR/{a-1
b}
a1   

Test

>RPS() { echo "$1 => "`sed -rnf rps.sed<<<$1`; }

>RPS RockRock
RockRock => 0

>RPS RockPaper
RockPaper => -1

>RPS RockScissors
RockScissors => 1

>RPS PaperRock
PaperRock => 1

>RPS PaperPaper
PaperPaper => 0

>RPS PaperScissors
PaperScissors => -1

>RPS ScissorsRock
ScissorsRock => -1

>RPS ScissorsPaper
ScissorsPaper => 1

>RPS ScissorsScissors
ScissorsScissors => 0

zeppelin

Posted 2017-01-11T20:36:04.403

Reputation: 7 884

1

///, 87 bytes

/_/1\/\///Paper/p//Rock/r//Scissors/s// ///pr/_rs/_sp/_rp/-_sr/-_ps/-_pp/0//rr/0//ss/0/

Try it online!

Ungolfed

/Paper/p//Rock/r//Scissors/s// //
/pr/1//rs/1//sp/1/
/rp/-1//sr/-1//ps/-1/
/pp/0//rr/0//ss/0/

Cedric Reichenbach

Posted 2017-01-11T20:36:04.403

Reputation: 448

1

Clojure, 43 bytes

#(get[0 1 1](mod(-(count %)(count %2))6)-1)

Uses (length(arg_1) - length(arg_2)) % 6 as a lookup to [0 1 1] and returns -1 if it goes out of bounds.

NikoNyrh

Posted 2017-01-11T20:36:04.403

Reputation: 2 361

1

Clojure, 114 75 bytes

-39 bytes by accepting 2 parameters instead of parsing 1, and changing the "else" placeholder from :e to 0.

 (fn[[p][q]](let[d(-(int p)(int q))](cond(#{-1 -2 3}d)1(#{1 2 -3}d)-1 0 0)))

Ungolfed:

(defn rps-scorer [[p1] [p2]] ; Deconstruct out the first letters of each word
  (let [d (- (int p1) (int p2))] ; And find the difference of their numeric values
    (cond (#{-1 -2 3} d) 1 ; If it's a winning difference, return 1, else
          (#{1 2 -3} d) -1 ; If it's a losing difference, return -1, else
          :else 0))) ; return 0, because they're the same.

Totally naïve approach here. I found out if you subtract the ascii values of the first letter of each play, winning values will be -1, -2 and 3, and losing values will be 1, 2 and -3. I just check which set the plays fall into, then return based on membership.

Carcigenicate

Posted 2017-01-11T20:36:04.403

Reputation: 3 295

1

C#, 43 bytes

a=>b=>(a[0]-b[0])/3*2+Math.Sign(b[0]-a[0]);

C# treats characters like integers that you can add and subtract.

Grax32

Posted 2017-01-11T20:36:04.403

Reputation: 1 282

1

SmileBASIC, 39 bytes

INPUT A$,B$?(67XOR LEN(A$*2+B$))MOD 3-1

A port of Dennis's algorithm. XOR and MOD are really long, I'm sure this could be made shorter.

12Me21

Posted 2017-01-11T20:36:04.403

Reputation: 6 110

0

Perl 6,  63 54 40  39 bytes

{2>($_=[-] %(<Rock -1 Paper 0 Scissors 1>){@_})>-2??$_!!-.sign}

Try it

{3>($_=[R-] @_>>.substr(0,1)>>.ord)>-3??.sign!!-.sign}

Try it

{3>($_=[R-] @_>>.ord)>-3??.sign!!-.sign}

Try it

{($_=[-](82 X<=>@_».ord)%3)>1??-1!!$_}

Try it

Brad Gilbert b2gills

Posted 2017-01-11T20:36:04.403

Reputation: 12 713

0

C#, 28 bytes

(a,b)=>""[*a-*b+3]-2;

Contains unprintable characters, so here's a hex dump: enter image description here

Turns out my solution is pretty similar to Dennis's Python 3 answer, but calculates the index differently. not anymore

This uses unsafe so the string inputs need to be put in char* first.

How it works:

// Delegate signature
unsafe delegate int Signature(char* c, char* z);

/*unsafe Signature Lambda = */ (a, b) =>
    "\x1\x3\x3\x2\x1\x1\x3"               // The outcomes
    [*a - *b + 3]                         // Index by subtracting value of first char of p2
                                          // from p1, adding 3 so the result is >= 0
    -2                                    // Subtract 2 to put in range [-1, 1]

milk

Posted 2017-01-11T20:36:04.403

Reputation: 3 043

I think you ought to be including the unsafe term in your code, and so in the byte count. There is also a narrow consensus that 'untyped' lambdas are invalid, and you should include the types in the parameters, which C#ers should be aware of.

– VisualMelon – 2017-01-12T13:03:23.210

Based on that meta post, I don't think the types or unsafe are needed since both can be deduced. The problem clearly indicates the inputs are string types. The only string type in C# with the * prefix operator is char* which also implies unsafe. – milk – 2017-01-12T18:53:11.200

The types can't be deduced by the compiler (or at least are not), and the compiler will just complain about a lack of unsafe context (which also requires a compiler argument, which is usually counted as well). – VisualMelon – 2017-01-12T19:20:17.147

0

C 355 bytes

#define S strcmp f(char *a,char *b){*c[]={"Rock","Paper","Scissors"}; if((!S(a,c[0])&&!S(b,c[1]))||(!S(a,c[1])&&!S(b,c[2]))||(!S(a,c[2])&&!S(b,c[0]))==1 )puts("-1");if( (!S(a,c[0])&&!S(b,c[0]))||(!S(a,c[1])&&!S(b,c[1]))||(!S(a,c[2])&&!S(b,c[2]))==1 )puts("0");if( (!S(a,c[0])&&!S(b,c[2]))||(!S(a,c[1])&&!S(b,c[0]))||(!S(a,c[2])&&!S(b,c[1]))==1 )puts("1");}

Accept user inputs(argv[1],argv[2]) and pass it onto f(char *a, char *b); Here is the Ungolfed version:

 #define S strcmp
 void f(char *a,char *b)
 {
   char *c[]={"Rock","Paper","Scissors"};   
   if( (!S(a,c[0])&&!S(b,c[1]))||(!S(a,c[1])&&!S(b,c[2]))||(!S(a,c[2])&&!S(b,c[0]))==1 )
     puts("-1");   
   if( (!S(a,c[0])&&!S(b,c[0]))||(!S(a,c[1])&&!S(b,c[1]))||(!S(a,c[2])&&!S(b,c[2]))==1 )
     puts("0");
   if( (!S(a,c[0])&&!S(b,c[2]))||(!S(a,c[1])&&!S(b,c[0]))||(!S(a,c[2])&&!S(b,c[1]))==1 )
     puts("1");
 }

There must definitely be a way to shorten this! I don't know though.

@Timtech Hope i understood you right. This code works, but prints 0 even if the strings are not exact, not sure if that satisfies the specification.

`#define S strcmp f(){printf("%d",(!S(a,c[0])&&!S(b,c[1])||!S(a,c[1])&&!S(b,c[2])||!S(a,c[2])&&!S(b,c[0]))?-1:(!S(a,c[0])&&!S(b,c[2])||!S(a,c[1])&&!S(b,c[0])||(!S(a,c[2])&&!S(b,c[1]) )?1:0));}

Abel Tom

Posted 2017-01-11T20:36:04.403

Reputation: 1 150

Looks like there's lots of ways to golf this. Here's a tip, instead of having the if statements output -1, 0, or 1, have them store to var. Then initialize the var as 0 and drop the middle if statement, returning or outputting the value at the end. – Timtech – 2017-01-12T16:23:05.980

0

TI-Basic, 64 bytes

There is probably a shorter way but I'm not seeing it right now...

DelVar R1->P:2->S
Prompt Str1,Str2:1
If sum(not({~2,1}-sum(eval(sub(Str1,1,1)+"-"+sub(Str2,1,1
~1:Str1!=Str2

Timtech

Posted 2017-01-11T20:36:04.403

Reputation: 12 038

0

TI-84 BASIC, 55 bytes

Prompt Str1,Str2
sub(Str1,1,1→Str3
sub(Str2,1,1
(Str3≠Ans)*(1-2not(inString("SPPRRS",Str3+Ans

I saved a byte by using Prompt instead of Input thanks to Timtech.

Execution:

Input is given as two strings as prompted. The TI-84 does not have native lowercase letters.

prgmRPS
Str1=?"ROCK"
Str2=?"SCISSORS"

               1

Jakob

Posted 2017-01-11T20:36:04.403

Reputation: 2 428

0

C#, 48 bytes

(a,b)=>a==b?0:(a[0]>b[0])^(a[0]+b[0]==163)?-1:1;

Dmihawk

Posted 2017-01-11T20:36:04.403

Reputation: 321

0

Noodel, 21 bytes

1220200Ḷ2ėạȥḃ1€Ė⁻ạɲ⁻1

Try it:)

How It Works

The first input is the first player:) It works by using the first character of both the string inputs then subtract them. Then using that result to index into an string to get the correct value.

The result from each game after subtracting the values of the first characters:

"Rock"     -> "Rock"     =  0
"Rock"     -> "Paper"    = -2
"Rock"     -> "Scissors" =  1
"Paper"    -> "Rock"     =  2
"Paper"    -> "Paper"    =  0
"Paper"    -> "Scissors" =  3
"Scissors" -> "Rock"     = -1
"Scissors" -> "Paper"    = -3
"Scissors" -> "Scissors" =  0

How each position in the string is used to correspond to which game:

[0] or [-7] = 1 => "Rock" -> "Rock", "Paper" -> "Paper", "Scissors" -> "Scissors"
[1] or [-6] = 2 => "Rock" -> "Scissors"
[2] or [-5] = 2 => "Paper" -> "Rock"
[3] or [-4] = 0 => "Paper" -> "Scissors"
[4] or [-3] = 2 => "Scissors" -> "Paper"
[5] or [-2] = 0 => "Rock" -> "Paper"
[6] or [-1] = 0 => "Scissors" -> "Rock"

Break down of the actual script:

1220200               # Pushes the string "1220200" onto the stack.

       Ḷ2ėạȥḃ1€       # A loop that grabs the first character, turns it into a number, and then throws away the string.
       Ḷ2             # Loop the following block two times.
         ė            # Places what is on the top to the bottom (first loop is the string created before, second loop places the result of player two)
          ạ           # Grabs the first element of the string.
           ȥ          # Convert the string to a number as if it was a base 98 number.
            ḃ1        # Remove the second item off of the stack.
              €       # End of the loop.

               Ė⁻     # Grabs what is at the bottom of the stack then subtracts what was on the top from that.
               Ė      # Grabs what is at the bottom of the stack (which is the first number calculated (player two).
                ⁻     # Subtracts player one from player two producing the index into the string.

                 ạɲ⁻1 # Grabs an element from the string and decrements it by one to get the final result.
                 ạ    # Access the string based off of the number produced from the subtraction.
                  ɲ   # Turns that string into a number.
                   ⁻1 # Subtracts one from that number.

tkellehe

Posted 2017-01-11T20:36:04.403

Reputation: 605

0

Common Lisp, 83 bytes

(setq c(- #1=(char-code(elt(read)0))#1#))(cond((= c 0)0)((member c'(1 2 -3))-1)(1))

Try it online!

The algorithm is ported from Carcigenicate’s answer.

Renzo

Posted 2017-01-11T20:36:04.403

Reputation: 2 260

0

Zsh, 29 bytes

<<<${${:-{,,-,-}1}[#2-#1]:-0}

Try it online!

<<<${${:-{,,-,-}1}[#2-#1]:-0}
         {,,-,-}1                # expands to the list (1 1 -1 -1)
     ${:-        }               # empty-fallback (anon parameter)
   ${             [     ]   }    # index into list
                   #2-#1         # difference between each parameter's first character's codes
   ${                    :-0}    # if empty, substitute 0

This is similar to one of the CJam answers. However, since Zsh indexes from 0, we need the ${ :-0} empty fallback to handle the 'P' - 'P' => 0 case.

GammaFunction

Posted 2017-01-11T20:36:04.403

Reputation: 2 838

0

C#, 151 bytes

public class P{public static void Main(string[]a){int v=(a[0][0]-a[1][0]);v=v==2?-1:v==-1?1:v==-2?1:v==0?0:v==1?-1:v==3?1:-1;System.Console.Write(v);}}

Try Online

canttalkjustcode

Posted 2017-01-11T20:36:04.403

Reputation: 131

0

Rust, 110 107 bytes

fn r(a:&str,b:&str)->i8{let p=if a.as_bytes()[0]+b.as_bytes()[0]==163{(b,a)}else{(a,b)};p.1.cmp(&p.0)as i8}

Try it online!

Elcan

Posted 2017-01-11T20:36:04.403

Reputation: 913

0

Ruby -n, 20 bytes

p$_.to_i(30)/522%3-1

Try it online!

Take input in the form of "RockPaper", interpret it as a base 30 integer 18248834542947, divide by 522 rounding down to 34959453147, modulo 3 is 0, minus 1 is -1.

histocrat

Posted 2017-01-11T20:36:04.403

Reputation: 20 600