Scoring Briscola

11

1

Introduction

Briscola is one of Italy's most popular card games. It is a trick-taking card game, like Bridge. Briscola is well known for its bizarre point system. In this challenge, given two cards, you will output whether the first one scores more, less, or the same number of points as the second in Briscola's point system.

Challenge

Briscola is played with a deck of Italian playing cards. There are forty cards in a deck, 1-10 in each of the four suits: cups, swords, clubs, and coins. We will be ignoring the suits for this challenge. Cards 2 - 7 are the numeric cards, and cards 8, 9, and 10 are the face cards. The ranking of the cards, from highest to lowest, are:

 +------------------------+-------------+
 |     Cards, by Rank     | Point Value |
 +------------------------+-------------+
 | Ace (1)                |     11      |
 | Three (3)              |     10      |
 | King (10)              |      4      |
 | Knight (9)             |      3      |
 | Jack (8)               |      2      |
 | Numeric Cards (2, 4-7) |      0      |
 +------------------------+-------------+

Thanks to Orphevs for the nice table! :)

Your task is to create a full program or function which accepts two numbers 1-10 representing card ranks, and outputs (or returns) whether the point value of the first card is greater than, lesser than, or equal to the point value of the second card. Additional Notes:

  • Your program may output any three values to indicate less than, greater than, and equal to, however, it must output the same value for each condition each time.
  • Your program may use any IO defaults.
  • Standard loopholes are disallowed.
  • Either a full function or a program is permitted.
  • This question is , so lowest byte-count wins.

  • Here are some sample inputs and outputs:

     1, 4 => more than (ace scores 11 points, 4 scores 0 points, first is  more than second.
     8, 3 => less than (8 scores 2, 3 scores 10, first is less than second.
     5, 2 => equal (5 and 2 both score 0)

If you have any questions, don't hesitate to ask. Good luck!

Amphibological

Posted 2018-07-12T21:57:02.087

Reputation: 1 394

1

I always thought Scopa's primiera was more bizarre ;)

– FryAmTheEggman – 2018-07-12T22:08:11.320

@FryAmTheEggman you're right, I've changed it. Also, you may have a point about the primiera… ;) – Amphibological – 2018-07-12T22:51:04.700

Can we take an array with the two values as input ? – digEmAll – 2018-07-13T18:05:27.623

1@digEmAll sure thing. – Amphibological – 2018-07-13T19:23:08.630

Not that bizarre. Very similar scoring exists on Portuguese Sueca and Bisca card games! – sergiol – 2018-07-13T23:15:09.387

Why usual negative, zero, positive is disallowed? – Qwertiy – 2018-07-17T14:46:10.663

@Qwertiy what do you mean? I say above that you can output any three consistent values. – Amphibological – 2018-07-17T16:49:45.803

@Amphibological, i mean that a lot of languages use comparator returning a) nigative value - the first argument is smaller; b) zero - they are equal; c) positive value - the first is greater. But you are requiring constant values. – Qwertiy – 2018-07-17T19:52:53.780

@Qwertiy I think you are misunderstanding me. What you have mentioned is completely fine: you are returning consistent values for the different comparisons, which is all the challenge specifies. – Amphibological – 2018-07-17T21:19:57.803

@Amphibological, from the question: "output any three values ... however, it must output the same value for each condition each time" also note using Math.sign in many answers. – Qwertiy – 2018-07-17T22:23:06.387

@Qwertiy I apologize if my wording is confusing. The meaning was supposed to be that each condition ( less than, greater than, equal to) would yield the same value on each run. All the answers below, are as far as I can tell, valid. – Amphibological – 2018-07-17T22:40:01.027

@Amphibological, but without Math.sign, they wouldn't be valid, right? – Qwertiy – 2018-07-18T06:41:38.170

@Qwertiy yes, that's correct. – Amphibological – 2018-07-18T12:55:29.660

I did game it many years ago with my relatives (parenti) – RosLuP – 2019-10-19T09:04:10.340

Answers

2

Jelly, 12 11 bytes

“®µ½¤¢‘iⱮIṠ

Try it online!

  • -1 byte by using Luis Mendo's method.

Outputs 0 for equal, -1 for greater than and 1 for less than. Uses the code-page index “®µ½¤¢‘ which evaluates to [8, 9, 10, 3, 1].

Takes input as a pair of cards. Use 1,2 as an example.

“®µ½¤¢‘iⱮIṠ
“®µ½¤¢‘       [8,9,10,3,1]
       i      index of 
        Ɱ     each element in the input -> 5,0
         I    Finds the forward difference: 0-5 = -5.
          Ṡ   Sign -> -1.
                When ranks are equal, Ṡ returns 0 and when the rank of the second
                card is higher, Ṡ returns 1.

dylnan

Posted 2018-07-12T21:57:02.087

Reputation: 4 993

1Not annoyed, but could whoever downvoted explain why? – dylnan – 2018-07-13T21:40:55.720

In case it was an accidental downvote -- and assuming that it occurred after the last edit -- I'd suggest to do a dummy update to the post so that it can be undone when/if the downvoter realize that something went wrong. – Arnauld – 2018-07-14T10:58:32.163

5

JavaScript (ES6), 42 bytes

Takes the two ranks in currying syntax (a)(b). Returns 1 for more than, -1 for less than or 0 for equal.

a=>b=>Math.sign((s="05040000123")[a]-s[b])

Try it online!


Using a formula, 48 bytes

This is definitely longer than using a lookup table but also a bit more interesting.

Same I/O format.

a=>b=>Math.sign((g=n=>(1<<n&1802)*6%13)(a)-g(b))

Try it online!

How?

Because many cards have a value of \$0\$, we first want to mask them out. Given a card rank \$n\$, we compute:

$$p=2^n\text{ and }(2^1+2^3+2^8+2^9+2^{10})$$ $$p=2^n\text{ and }1802$$

  n (card)   | 2**n | AND 1802
-------------+------+----------
  1 (Ace)    |    2 |      2
  2          |    4 |      0
  3 (Three)  |    8 |      8
  4          |   16 |      0
  5          |   32 |      0
  6          |   64 |      0
  7          |  128 |      0
  8 (Jack)   |  256 |    256
  9 (Knight) |  512 |    512
 10 (King)   | 1024 |   1024

We now want to transform the remaining non-zero values in such a way that they can be sorted in the correct order. We use:

$$q=6p \bmod 13$$

    p (card)   |   6p | MOD 13
---------------+------+--------
    2 (Ace)    |   12 |   12
    8 (Three)  |   48 |    9
  256 (Jack)   | 1536 |    2     --> Ace > Three > King > Knight > Jack
  512 (Knight) | 3072 |    4
 1024 (King)   | 6144 |    8

Arnauld

Posted 2018-07-12T21:57:02.087

Reputation: 111 334

Has there been meta discussion about this approach using curried parameters? Technically this doesn't match this challenge, because the function you've written returns a function, not an answer. – Sparr – 2018-07-13T01:24:08.847

4

@Sparr https://codegolf.meta.stackexchange.com/a/8427/31625

– FryAmTheEggman – 2018-07-13T02:25:16.240

5

MATL, 12 bytes

[DEXIl]&mdZS

Input is an array of two numbers. Output is -1, 0 and 1 respectively for more than, equal to or less than.

Try it online!

Explanation

Consider input [1 4] as an example.

[DEXIl]    % Push [8 9 10 3 1]
           % STACK: [8 9 10 3 1] 
&m         % Implicit input. Index (1-based) of membership, 0 if not member
           % STACK: [5 0]
d          % Consecutive difference
           % STACK: -5
ZS         % Sign. Implicit display
           % STACK: -1

Luis Mendo

Posted 2018-07-12T21:57:02.087

Reputation: 87 464

3

Japt, 25 21 16 bytes

  • 1 => more than
  • -1 => less than
  • 0 => equal

£"78920"bXÉÃr- g

Try it online!

Luis felipe De jesus Munoz

Posted 2018-07-12T21:57:02.087

Reputation: 9 639

You can use the -g flag to save 2 bytes. – Shaggy – 2018-07-13T08:21:10.163

I have a 13 byte solution (also using the -g flag, if you want to try for it). – Shaggy – 2018-07-13T09:14:57.583

@Shaggy I wouldn't say that's saving two bytes, flagged submissions are just separate language solutions and don't count as pure Japt solutions. – Nit – 2018-07-13T10:07:18.403

If you don't want to use a flag then the solution I mentioned above becomes 15 bytes. (Hint: it uses the [8,9,10,3,1] array and base conversion) – Shaggy – 2018-07-13T11:28:02.727

3

Japt -g, 13 bytes

Outputs -1 for >, 1 for < and 0 for ===.

m!b#ù991ìD)rn

Try it or run multiple tests (The second line replicates the functionality of the -g flag to allow the flags to be used to process multiple inputs)


Explanation

                   :Implicit input of 2 integer array
m                  :Map
   #ù991           :  249991
        ìD         :  Convert to array of base-13 digits = [8,9,10,3,1]
 !b                :  Get the index of the current element in that
          )        :End map
           rn      :Reduce by subtraction
                   :Implicitly output the sign of the result

Shaggy

Posted 2018-07-12T21:57:02.087

Reputation: 24 623

2

R, 35 bytes

rank(c(6,0,5,1:4*0,1:3)[scan()])[1]

Try it online!

  • -6 Bytes thanks to @JayCe suggestion to switch to full program instead of function

The program returns 2 for 'greater than', 1 for 'less than', 1.5 for 'equal'

Explanation :

      c(6,0,5,1:4*0,1:3)[v]          # extract the score of each card in v (got from scan());
                                     # cards in v are used as indexes in the cards rank 
                                     # vector, which is based on briscola scores vector 
                                     # c(11,0,10,0,0,0,0,2,3,4) but divided by 2 and rounded 
                                     # to integer preserving the original order

rank(                      )[1]      # rank returns : c(1,  2)   if v[1] < v[2]
                                     #                c(2,  1)   if v[1] > v[2]
                                     #                c(1.5,1.5) if v[1] == v[2]
                                     # and we select the first value

digEmAll

Posted 2018-07-12T21:57:02.087

Reputation: 4 599

1rank(c(6,0,5,1:4*0,1:3)[scan()])[1] (full program) will save you 6 bytes – JayCe – 2018-07-20T00:53:13.683

@JayCe: yes I noticed that, but I'm still confused about the necessity to add cat() when it's a full program... anyway, updated my code ;) – digEmAll – 2018-07-20T06:53:21.587

2

Java 8, 69 66 bytes

a->b->Math.signum("05040000123".charAt(a)-"05040000123".charAt(b))

Lambda taking parameters in currying syntax, port of Arnauld's JavaScript answer.

Returns 0.0 equal, 1.0 for greater than, and -1.0 for less than. Try it online here.

Thanks to Kevin Cruijssen for golfing 3 bytes.

O.O.Balance

Posted 2018-07-12T21:57:02.087

Reputation: 1 499

1

You can save 3 bytes by doing a direct return with two times "05040000123".charAt(...) instead of the integer-array: a->b->Math.signum("05040000123".charAt(a)-"05040000123".charAt(b))

– Kevin Cruijssen – 2018-07-25T09:37:14.553

2

MarioLANG, 578 548 530 bytes

 )                    <
 ====================="
                   >-[!)
                   "==#)
                >-[!)) )
                "==#=) +
         >-----[!))) + +
         "======#==  + +
     >--[!)))   ++++              -(- <
     "===#===================    ====="
  >-[!)))+++++                    >) [!)+:
; "==#=======================     "===#===
>[!                      )))[!((>[!)[!):
"=#==========================#====#==#===
!;((                         <       >)-:
#============================"       "===

Try it online!

Explanation:

  • The first, big castle reads a card number as input and calculates its equivalent point value until it reads a 0 (no input). This supposes that there will be only two strictly positive values as input.
  • Note that I don't actually set the proper point values as they aren't needed, I just set as point value a number between [1-5] to help calculate which card has the most point values.
  • The second, small castle just compares the two calculated point values.
  • It returns 1 if the first point value is greater than the second one, -1 if the second point value is greater than the first one, and 0 if the point values are the same.

Charlie

Posted 2018-07-12T21:57:02.087

Reputation: 11 448

1

Python 2, 41 bytes

Outputs 1 for more than, -1 for less than, 0 for equal.

lambda a,b:cmp(s[a],s[b])
s="05040000123"

Try it online!

Poon Levi

Posted 2018-07-12T21:57:02.087

Reputation: 379

1

C (gcc), 57 bytes

Returns the usual [-1..1] for <, = and >, respectively.

char*s="-FAEAAAABCD";f(a,b){a=s[a];b=s[b];b=(a>b)-(a<b);}

Try it online!

ErikF

Posted 2018-07-12T21:57:02.087

Reputation: 2 149

Suggest *s=L"... instead of char*s="... and a=(s[a]>s[b])-(s[a]<s[b]) instead of a=s[a];b=s[b];b=(a>b)-(a<b) – ceilingcat – 2018-08-04T16:48:26.447

1

PHP, 51 45 bytes

<?=($m=_5040000123)[$argv[1]]<=>$m[$argv[2]];

Try it online!

To run it:

php -n <filename> <card1> <card2>

Example:

php -n briscola_score.php 3 1

Note: This code uses PHP 7's spaceship operator. So it won't work on any PHP version before 7.


Output:

  • 1 = more than (card1 > card2)
  • 0 = equal (card1 == card2)
  • -1 = less than (card1 < card2)

How?

Same as the approach used in many other answers, but in PHP. Creates a value map for cards and compares the card values from it. The position of the value in the map is same as card number.

Night2

Posted 2018-07-12T21:57:02.087

Reputation: 5 484

1

05AB1E, 14 bytes

ε78920S>sk}`.S

Returns 1, -1, or 0 for more than; less than; or equal respectively.

Try it online or verify all test cases.

Explanation:

ε              # Loop over the input-array
 78920S>       #  Convert 78920 to a list of digits, and increase each by 1,
               #  resulting in [8,9,10,3,1]
        sk     #  Index this list with the input-number (-1 if not found)
               #   i.e. [1,4] → [4,-1]
          }    # Stop the loop
`              # Put all items of the now mapped list separated onto the stack
 .S            # Take the signum (1 if a>b; -1 if a<b; 0 if a==b)
               #  i.e. 4 and -1 → 1

Kevin Cruijssen

Posted 2018-07-12T21:57:02.087

Reputation: 67 575

0

Javascript ES2016+, 73 chars

Not the shortest, but I hope interesting due to math and overflow :)

(x,y)=>Math.sign((x&8?x:(16-(x**40|0)%7)^16)-(y&8?y:(16-(y**40|0)%7)^16))

And the other version with 74 chars, unfortunately:

(x,y)=>eval('(x>y)-(x<y)'.replace(/\w/g,'($&&8?$&:(16-($&**40|0)%7)^16)'))

Test

Open browser console before running

f=(x,y)=>Math.sign((x&8?x:(16-(x**40|0)%7)^16)-(y&8?y:(16-(y**40|0)%7)^16))
console.table(Array(11).fill().map((x,i)=>Array(11).fill().map((x,j)=>f(i,j))))

screenshot

Qwertiy

Posted 2018-07-12T21:57:02.087

Reputation: 2 697