Golf a golf-scorer

25

1

As a kid, I used to play the card game "golf" a lot. Your challenge, should you choose to accept it, is to calculate the score of a golf hand. Since there are over 9000 variations on this card game1, we will go with the rules I remember playing.

Rules (of the game)

  • You end a round with 6 cards, and you want as few points as possible.

  • Jokers are not used.

  • Aces and 2s are worth -1, and -2 points respectively.

  • Jacks and Kings are both worth 0 points.

  • Cards from 3 to 10 are worth face value. However, these are cancelled when you pair them off. For example, a 5 is worth 5 points, but two 5s are worth zero. Three 5s are worth 5 points, (since the first 2 are paired off, but the 3rd is not.) and four 5s are worth 0 (since it makes 2 pairs).

  • Queens are worth 15 points. Queens cannot be cancelled, e.g. 2 queens are worth 30 points.

Rules (of the challenge)

Input will be an array of integers, or 6 individual integers. Whichever one you prefer. 1 represents an ace, 2-10 represents 2-10, and Jack, Queen, and King represents 11, 12, and 13. Output is the score of the hand according to the rules above. You can safely assume that all inputs are valid, e.g. no number appears more than 4 times, and all numbers are in the range [1, 13]. Input and output can be in any reasonable format.

Test IO:

[11, 10, 3, 1, 2, 2]    --> 8
[4, 5, 5, 3, 8, 7]      --> 22
[2, 2, 2, 2, 1, 1]      --> -10 (The lowest score possible)
[12, 12, 12, 12, 10, 9] --> 79 (The highest score possible)
[9, 9, 9, 9, 11, 1]     --> -1
[8, 8, 8, 8, 11, 13]    --> 0
[10, 9, 3, 7, 12, 2]    --> 42
[1, 2, 3, 4, 5, 6]      --> 15
[10, 9, 2, 3, 4, 1]     --> 23
[10, 3, 12, 3, 7, 12]   --> 47

Shortest answer in bytes wins!


1not really, but there are a lot of variations.

James

Posted 2016-05-24T02:51:43.670

Reputation: 54 537

Answers

3

Pyth, 28 27 25 bytes

s+*L%/Qd2}3Tm?<d3_d*15q12

Try it online. Test suite.

Explanation

  • Firstly, Pyth auto-appends some variables. The code is now s+*L%/Qd2}3Tm?<d3_d*15q12dQ.
  • }3T generates the list [3, 4, 5, 6, 7, 8, 9, 10].
  • Multiply each number in that list (*L) by the count of that number in the input (/Qd), modulo 2 (%2). The result is 0 for paired numbers and the number itself for non-paired ones.
  • Map over the input numbers (mQ):
    • If the number is less than 3 (?<d3), negate it (_d).
    • Otherwise check if it's 12 (q12d), and multiply the boolean by 15 (*15). The result is 15 for queens and 0 for anything else.
  • Concatenate the lists (+). The resulting list now contains the scores for the non-paired numbers (the first part) and the special cards A, 2, Q (the second part), with some extra zeroes.
  • Finally, take the sum of the result (s).

Alternative 25-byte solution

-+s*L%/Qd2}3T*15/Q12s<#3Q

This works similarly to the first one, but counts the queens separately and negates the aces and twos with a filter.

PurkkaKoodari

Posted 2016-05-24T02:51:43.670

Reputation: 16 699

11

Python 2, 72 70 bytes

f=lambda x,*T:[x*(-1)**T.count(x),~x%2*15,-x][(x-3)/8]+(T>()and f(*T))

At one point I wished Python treated 0**0 == 0 for once so that I could do (-condition)**num. Call like f(11, 10, 3, 1, 2, 2).

Previous 72-byte version:

f=lambda x,*T:[~x%2*15,x*(-1)**(x<3or T.count(x))][x<11]+(T>()and f(*T))

Sp3000

Posted 2016-05-24T02:51:43.670

Reputation: 58 729

5

><>, 63 57 56+2 = 65 59 58 bytes

The input numbers are expected to be on the stack at program start, so +2 bytes for the -v flag. Try it online!

</!?lp6$+1g6:
3\0
?\::6g2%*{+}1+:b=
;\~16g-26g2*-c6gf*+n

As all unused values in the code field are initialised to 0, it can be used to work out how many of each value is present on the stack by getting the value at [value,6], incrementing it, and putting it back in the code field. The total is then calculated as:

T = 0 + {for x in 3 to 10, x*([x,6]%2)} - [1,6] - 2*[2,6] + 15*[12,6]

Edit: golfed 6 bytes off by restructuring the input and switching the calculation steps around. Previous version:

:6g1+$6pl0=?\
/-*2g62-g610/
c ;n$\
6:b=?/>::6g2%*{+}1+!
\gf*+3/

Edit 2: saved 1 byte, thanks to Sp3000

Sok

Posted 2016-05-24T02:51:43.670

Reputation: 5 592

I've seen that you've used 0=? or similar a few times - can you use ?! instead? – Sp3000 – 2016-05-24T16:12:33.083

@Sp3000 Ack, of course, you're right. Thanks, I'll add that in – Sok – 2016-05-24T16:53:36.397

5

MATL, 27 26 bytes

3:10=s2\7M*G12=15*Gt3<*_vs

The input is a column array, that is, values are separated by semicolons.

Try it online! or verify all test cases (this adds a loop to take all inputs, and replaces G by 1$0G to push latest input).

Explanation

3:10=    % Take input implicitly. Compare with range [3 4 ... 10], with broadcast
s        % Sum of each column: how may threes, fours, ... tens there are
2\       % Modulo 2
7M       % Push [3 4 ... 10] again
*        % Element-wise multiply (the sum of this array is the score of 3...10)
G        % Push input again
12=      % Compare with 12, element-wise
15*      % Multiply by 15 (this is the score of 12)
G        % Push input again
t3<      % Duplicate. True for entries 1 or 2
*_       % Multiply and negate (the sum of this array is the score of 1, 2)
v        % Concatenate all stack concents into a vertical array
s        % Sum of array. Implicitly display

Luis Mendo

Posted 2016-05-24T02:51:43.670

Reputation: 87 464

4

Pyth - 37 36 35

This is seems way too large, but FGITW.

J<#h;K-QS2++*15/K12sm*d%/Jd2{J_s@S2

Test Suite.

Maltysen

Posted 2016-05-24T02:51:43.670

Reputation: 25 023

2"This is seems way too large, but FGITW." So golf it first? – cat – 2016-05-24T16:22:04.980

I didn't see this until I had finished my own, but they are nearly identical except using J and K seems totally unnecessary, and also you can golf +_ to - ;) I got 31: +*15/Q12-sm*d%/Qd2{>#2<#11Qs@S2 – FryAmTheEggman – 2016-05-24T17:16:15.227

1@FryAmTheEggman 24: +*15/Q12-s*R%/Qd2}3Ts@S2 – Jakube – 2016-05-25T09:55:19.080

3

JavaScript (ES6), 63 bytes

a=>a.map(e=>r+=e<3?-e:e>10?e-12?0:15:(m[e]^=1)?e:-e,r=0,m=[])|r

Or if you prefer,

a=>a.map(e=>r-=e<3?e:e>10?e-12?0:-15:(m[e]^=1)?-e:e,r=0,m=[])|r

Neil

Posted 2016-05-24T02:51:43.670

Reputation: 95 035

0

Perl 5.10.0 + -n, 115 64 60 56 bytes

$p+=$_-12?$_>2?$_<11?++$l[$_]%2?$_:-$_:0:-$_:15}{say$p

Try it online!

Explanation:

Adding the -n loop around it:

# Used variables:
# $_: input (auto)
# $p: points
# $l[n]: number of occurences of n (for 3-10)
while (<>) { # for every input
    $p += $_ - 12 ? # if the input is not 12 (queen) ...
        $_ > 2 ? # then: if it's > 2 (not ace or 2) ...
            $_ < 11 ? # then: if < 11 (3-10) ...
                ++$l[$_] % 2 ? # then: if it's an odd occurence (1st, 3rd, 5th, ...)
                    $_ # add it
                    : -$_ # else subtract it
            : 0 # no points for other stuff (J, K)
        : -$_ # negative points for ace and 2
    : 15 # 15 points for queen
}
{ # after input:
    say $p # output points
}

wastl

Posted 2016-05-24T02:51:43.670

Reputation: 3 089

0

Perl 5, 74 +1 (-a) = 75 bytes

map$s+=/12/?15:$_<3?-$_:$_<11?$k{$_}?-delete$k{$_}:($k{$_}=$_):0,@F;say $s

Try it online!

Xcali

Posted 2016-05-24T02:51:43.670

Reputation: 7 671

Command line flags are free now! – wastl – 2018-03-22T18:05:14.083