11
\$\begingroup\$

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!

\$\endgroup\$
14
  • 1
    \$\begingroup\$ I always thought Scopa's primiera was more bizarre ;) \$\endgroup\$ Jul 12, 2018 at 22:08
  • \$\begingroup\$ @FryAmTheEggman you're right, I've changed it. Also, you may have a point about the primiera… ;) \$\endgroup\$ Jul 12, 2018 at 22:51
  • \$\begingroup\$ Can we take an array with the two values as input ? \$\endgroup\$
    – digEmAll
    Jul 13, 2018 at 18:05
  • 1
    \$\begingroup\$ @digEmAll sure thing. \$\endgroup\$ Jul 13, 2018 at 19:23
  • \$\begingroup\$ Not that bizarre. Very similar scoring exists on Portuguese Sueca and Bisca card games! \$\endgroup\$
    – sergiol
    Jul 13, 2018 at 23:15

13 Answers 13

5
\$\begingroup\$

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
\$\endgroup\$
5
\$\begingroup\$

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
\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$
    – Sparr
    Jul 13, 2018 at 1:24
  • 4
    \$\begingroup\$ @Sparr codegolf.meta.stackexchange.com/a/8427/31625 \$\endgroup\$ Jul 13, 2018 at 2:25
3
\$\begingroup\$

Japt, 25 21 16 bytes

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

£"78920"bXÉÃr- g

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ You can use the -g flag to save 2 bytes. \$\endgroup\$
    – Shaggy
    Jul 13, 2018 at 8:21
  • \$\begingroup\$ I have a 13 byte solution (also using the -g flag, if you want to try for it). \$\endgroup\$
    – Shaggy
    Jul 13, 2018 at 9:14
  • \$\begingroup\$ @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. \$\endgroup\$
    – Etheryte
    Jul 13, 2018 at 10:07
  • \$\begingroup\$ 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) \$\endgroup\$
    – Shaggy
    Jul 13, 2018 at 11:28
3
\$\begingroup\$

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
\$\endgroup\$
2
\$\begingroup\$

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.
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Not annoyed, but could whoever downvoted explain why? \$\endgroup\$
    – dylnan
    Jul 13, 2018 at 21:40
  • \$\begingroup\$ 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. \$\endgroup\$
    – Arnauld
    Jul 14, 2018 at 10:58
2
\$\begingroup\$

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
\$\endgroup\$
2
  • 1
    \$\begingroup\$ rank(c(6,0,5,1:4*0,1:3)[scan()])[1] (full program) will save you 6 bytes \$\endgroup\$
    – JayCe
    Jul 20, 2018 at 0:53
  • \$\begingroup\$ @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 ;) \$\endgroup\$
    – digEmAll
    Jul 20, 2018 at 6:53
2
\$\begingroup\$

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.

\$\endgroup\$
1
2
\$\begingroup\$

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.
\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
1
  • \$\begingroup\$ 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) \$\endgroup\$
    – ceilingcat
    Aug 4, 2018 at 16:48
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.