Bridge Hand Scoring
Jelly, 27 25 21 bytes
Thanks @Dennis for -3 bytes!
L_5.AḞW+“JQKA”i$€Sµ€S
This takes input as a list of lines. To take input as a multiline string, precatenate a ṣ⁷µ
.
Making a table of the frequency points:
Cards: 0 1 2 3 4 5 6 ... 4+k
Points: 3 2 1 0 0 1 2 ... k
we can see that they're equal to abs(c-3.5)-.5
, where c is the number of cards. Since each line contains two extra characters, and the number of points is always an integer, this is floor(abs(l-5.5))
where l is the line length.
Note that Jelly's indices are 1-based, and also the behavior of vectorized functions on mismatched dimensions: the extra elements of the longer list are unaffected. So [1] + [3,2,0,0]
gives [4,2,0,0]
.
µ The program is two monadic fs applied in turn; an atop.
L_5.AW+“JQKA”i$€S Helper function:
€ For €ach line:
L Get the line Length.
_5. Subtract 5.5 (Numeric literals' decimal parts default to .5)
A Apply Absolute value
Ḟ Floor
W Then Wrap it in an array. "S:AKQT6" gives [1].
“JQKA”i$ Monadic function: index into the string "JQKA".
€ Apply ^ over €ach char of the line; [3,2,0,0,0].
+ Add the two arrays together; [4,2,0,0,0].
S Sum; 6.
S Main link: Sum all results
Try it here.
ES6, 107 99 89 bytes
s=>(t=0,[...s].map(c=>t+="JQKA".search(c)+1),s.split`
`.map(l=>t+=(l=l.length-6)^l>>4),t)
Pyth, 27 25 24 bytes
sms+a5.5ldshMxL"JQKA"d.z
We calculate the values separately for each suit, then add them.
s m sum of map lambda d: (d is a line of input)
+ add the
s a floor of the absolute difference between
5.5 5.5
l d and len(d)
s hM xL to the sum of the indices each incremented by one
"JQKA" of each char in d in the string "JQKA"
d
.z
Test suite.