Golf Golf!

This is my first challenge, so please be gentle! The challenge is to write a program that will output the correct score for a layout in the card game "Golf."

The card game Golf has many variations. The house rules I use follow the standard rules for Six-Card Golf given by Pagat, with one slight difference. There is already a similar challenge here but I think this one is more interesting because it requires you to take the orientation of the cards into account.

Each player has a 2x3 layout of cards. By the end of each round all cards are turned face up and scored as follows:

• Each ace counts 1 point.
• Each two counts minus two points.
• Each numeral card from 3 to 10 scores face value.
• Each Jack or Queen scores 10 points.
• Each King scores zero points.
• A pair of equal cards in the same column scores zero points for the column (even if the equal cards are twos).
• A set of three equal cards in the same row scores zero points for the row (even if the equal cards are twos).

Input

The input can be a string or array of any kind.

Output

An integer representing the score of the Golf hand.

Examples

These examples use the notation A23456789TJQK but you need not use that notation in your answer.

Layout
AK3
J23

Score
9
-----------------------
Layout
25Q
25J

Score
20
-----------------------
Layout
T82
T8A

Score
-1
-----------------------
Layout
QQQ
234

Score
5
-----------------------
Layout
TJQ
QTJ

Score
60
-----------------------
Layout
888
382

Score
1
-----------------------
Layout
888
888

Score
0


This is code golf, so the shortest answer in bytes wins!

• Shouldn't the first example score 9? – Jonathan Allan Sep 21 '19 at 12:23
• Nice first challenge! As a slight note, the "(even if the equal cards are twos)" parts are unnecessary and slightly confusing in this challenge, since the resulting score isn't compared with other players' scores. Instead, you may want to clarify that the all-equal column and row scores override the individual scores of the cards in their respective column or row. – Erik the Outgolfer Sep 21 '19 at 12:29
• "...or array of any kind" - must the content be characters (or may we circumvent the mapping of characters to values)? – Jonathan Allan Sep 21 '19 at 12:37
• @JonathanAllan Hm, it does say "These examples use the notation A23456789TJQK but you need not use that notation in your answer." – Erik the Outgolfer Sep 21 '19 at 12:41
• I'd suggest adding a test case with a column AND a row being equal, like JJJ 2J2 -> -4. – Jonathan Allan Sep 21 '19 at 13:40

Jelly, 9 bytes

n/aEÐḟẎḞS


Try it online!

-1 thanks to Jonathan Allan.

Takes input in the form of [[A, B, C], [D, E, F]], where each of A, ..., F are elements in $$\(1,-2,3,4,5,6,7,8,9,10,10.1,10.2,0)\$$, representing values $$\A,2,3,4,5,6,7,8,9,T,J,Q,K\$$ respectively.

f m=sum[min 10k|r<-m,o<-m,any(/=r!!0)r,(j,x)<-zip o r,j/=x,(k,c)<-zip[-2..]"2 KA 3456789TJQ",c==x]


Try it online!

Takes advantage of the fact there are only two rows. We double iterate over the rows taking a row r and a row o. When they are the same row the result will always be zero (due to the "columns" matching) so we will only consider the two iterations in which r and o refer to distinct rows. I zero out rows by first checking whether any entries in the row are not equal to the first. If the row is all equal this will be false and the list will be empty, with a sum of 0. Otherwise I zip this row with the other and iterate over the pairs that aren't equal (this zeroes out equal columns in a similar manner). Finally I index a list of card ranks starting with -2 padding with spaces as necessary to map each rank to its score. I just have to use min 10 to clamp that index to make jacks and queens cost 10 rather than 11 and 12.

EDIT: thanks to @xnor for taking off 4 bytes! I didn't know you could put identifiers directly after number literals that's really cool!

EDIT2: Thanks again to @xnor for another 5 bytes! Great idea to iterate over the rows like that

• Nice solution! Two smaller optimizations: you don't need the space after 10, and it's shorter to omit the @(a:_) and instead write r!!0 for a. – xnor Sep 22 '19 at 2:53
• Another thought: since a%a and b%b are zero, it looks like you can define f directly by iterating over pairs of lines like this. – xnor Sep 22 '19 at 5:02

Charcoal, 50 bytes

Ｆ²⊞υＳ≔⁰ζＦ⭆υΦι∧⊙ι¬⁼λν⊙υ¬⁼λ§νμ≡ι2≧⁻²ζA≦⊕ζKω≧⁺∨ΣιχζＩζ


Try it online! Link is to verbose version of code. Explanation:

Ｆ²⊞υＳ


Read the layout into an array.

≔⁰ζ


Initialise the score to zero.

Ｆ⭆υΦι∧⊙ι¬⁼λν⊙υ¬⁼λ§νμ


Filter on the input, removing characters that equal all of the characters in its row or column.

≡ι


Switch over each remaining character.

2≧⁻²ζ


2 scores -2.

A≦⊕ζ


A scores 1. (These 4 bytes could be removed if 1 was used to denote 1, but IMHO that's an abuse of the input format.)

Kω


Do nothing for K.

≧⁺∨Σιχζ


Otherwise digits score their value and other letters score 10.

Ｉζ


Cast the sum to string for implicit print.

J, 39 28 bytes

[:+/@,]<.@*]+:&(1=#@~.)"1/|:


Try it online!

Credit to Erik the Outgolfer and Jonathan Allen for the input encoding idea.

explanation

A very "J" solution. I'll explain by example...

Let's take the input:

AK3
J23


and apply this encoding:

┌─┬──┬─┬─┬─┬─┬─┬─┬─┬──┬────┬────┬─┐
│A│2 │3│4│5│6│7│8│9│T │J   │Q   │K│
├─┼──┼─┼─┼─┼─┼─┼─┼─┼──┼────┼────┼─┤
│1│_2│3│4│5│6│7│8│9│10│10.1│10.2│0│
└─┴──┴─┴─┴─┴─┴─┴─┴─┴──┴────┴────┴─┘


which produces:

   1  0 3
10.1 _2 3


Let's look at the first part of the solution, eliding some detail to start:

] (...)"1/ |:


This says take the input ] and its transpose |: and create a "multiplication table" of all the combinations, except instead of multiplication we'll apply the verb in parenthesis. The rank "1 specifier ensures that we take all combinations of rows from both arguments, but since the rows of the transpose are the columns of the original matrix, this means we'll be taking all combinations of rows and columns. That is, we'll be doing:

  Rows                            Cols
┌─────────┐                     ┌──────┐
│1 0 3    │                     │1 10.1│
├─────────┤  "times" table      ├──────┤
│10.1 _2 3│                     │0 _2  │
└─────────┘                     ├──────┤
│3 3   │
└──────┘

which produces:

┌───────────────────────┬─────────────────────┬────────────────────┐
│┌─────┬────┬──────┐    │┌─────┬────┬────┐    │┌─────┬────┬───┐    │
││1 0 3│verb│1 10.1│    ││1 0 3│verb│0 _2│    ││1 0 3│verb│3 3│    │
│└─────┴────┴──────┘    │└─────┴────┴────┘    │└─────┴────┴───┘    │
├───────────────────────┼─────────────────────┼────────────────────┤
│┌─────────┬────┬──────┐│┌─────────┬────┬────┐│┌─────────┬────┬───┐│
││10.1 _2 3│verb│1 10.1│││10.1 _2 3│verb│0 _2│││10.1 _2 3│verb│3 3││
│└─────────┴────┴──────┘│└─────────┴────┴────┘│└─────────┴────┴───┘│
└───────────────────────┴─────────────────────┴────────────────────┘


Now the verb we apply to each of these combos is +:&(1=#@~.) and this verb returns false if "either argument consists of a single repeated item" and true otherwise. It does this by taking the nub, or uniq ~., asking if its length is one 1=#, and taking the nor of the result +:.

That is, this will return a boolean mask with the same shape as the input matrix, but with zeros for any item in a row or column of all equal items.

1 1 0
1 1 0


Now we simply mutliply the original matrix by this mask and take the floor ]<.@*:

1   0 0
10 _2 0


and then flatten and sum the result of that: +/@,

9


JavaScript (ES6),  97 95  93 bytes

Takes input as an array of 2 arrays of 3 characters.

a=>a.map((r,i)=>r.map((c,j)=>t-=c!=a[i^1][j]&r!=c+[,c,c]?{K:[],2:2,A:-1}[c]||-c||~9:0),t=0)|t


Try it online!

Commented

a =>                        // a[] = input
a.map((r, i) =>           // for each row r[] at position i:
r.map((c, j) =>         //   for each card c at position j in r[]:
t -=                  //     update t:
c != a[i ^ 1][j] &  //       if c is not equal to the sibling card in the other row
r != c + [, c, c] ? //       and r is not made of 3 times the same card:
{ K: [],          //         add 0 point for a King (but [] is truthy)
2: 2,           //         subtract 2 points for a Two
A: -1           //         add 1 point for an Ace
}[c]              //
|| -c             //         or add the face value
|| ~9             //         or add 10 points (Jack or Queen)
:                   //       else:
),                      //   end of inner map()
) | t                     // end of outer map; return t


Japt, 22 bytes

c xÈf *YgUïUÕ me_â Ê>1


Try it

PHP, 145 109 bytes

After using the default A23456789TJQK coding for inputs and not getting a good result, I switched to using this coding similar to other answers:

A |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |  T |    J |    Q | K
1 | -2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 10.1 | 10.2 | 0


Input is a two dimensional array in this format: [[1,0,3],[10.1,-2,3]]. Basically checks the row (using min and max) and the column for each card to not contain equal values and then adds card value to the total score and at the end prints integer portion of the total score.

function($a){for(;$x++<2;)for($i=3;$i--;)min($r=$a[$x-1])-max($r)&&$r[$i]-$a[$x%2][$i]&&$s+=$r[$i];echo\$s^0;}


Try it online! (Note: TIO for PHP is broken at the moment, because of a wrong version upgrade, but should come back OK)

Python 3, 79 bytes

lambda d:sum([({*a}!={x}!={y})*int(x)for a,b in(d,d[::-1])for x,y in zip(a,b)])


Try it online!

Uses the same input format as some other answers, values $$\1,-2,3,4,5,6,7,8,9,10,10.1,10.2,0\$$ for the cards.

Python 3, 118 bytes

lambda d:sum([({*a}!={x}!={y})*[10,10,10,1,0,-2,int(x,36)]['TJQAK2'.find(x)]for a,b in(d,d[::-1])for x,y in zip(a,b)])


Try it online!

Kotlin, 159 bytes

Lambda takes 1.3456789TJQ0 as input. The outer code takes A23456789TJQK as input, converts the ace, two, and king so the math works out, and displays the cards & score.

{d:List<String>->Int
var s=0
for(r in 0..1)for(c in 0..2)if((d[r][0]!=d[r][1]||d[r][1]!=d[r][2])&&d[0][c]!=d[1][c]){
val n=d[r][c]-'0'
s+=if(n>9)
10
else
n}
s}


Try it online!