[Question]
  [
*Disclaimer: ModTen is a fictional card game which was created for the sole purpose of this challenge.*
## The rules of ModTen
*ModTen* is played with a standard 52-card deck. Because the full rules are yet to be invented, we're going to focus on the hand ranking exclusively.
[![Jack & Three, suited](https://i.stack.imgur.com/4xgGc.png)](https://i.stack.imgur.com/4xgGc.png)
*A winning hand in ModTen. Graphics from [Wikipedia](https://en.wikipedia.org/wiki/Standard_52-card_deck#Rank_and_color).*
### Card values
The cards have the following values:
* **2** to **9**: worth their face value
* **Ten**: 0 point
* **Jack**: 3 points
* **Queen** or **King**: 8 points
* **Ace**: 9 points
### Hand values
* A *ModTen* hand is made of **two cards**. The base value of a hand is obtained by multiplying the value of both cards together and keeping the last digit only (i.e. applying a modulo 10).
For instance, the value of **7**♥ - **Q**♣ is "\$6\$", because \$(7\times8)\bmod 10=6\$.
* The only other rule in *ModTen* is that **suited cards** are worth more than unsuited ones. By convention, we are going to append a **"s"** to the value if both cards are of the same suit.
For instance, the value of **9**♠ - **5**♠ will be noted as "\$5\text{s}\$", because \$(9\times5)\bmod 10=5\$ and the cards are suited.
### Hand ranking and winner
The above rules result in 18 distinct hand ranks which are summarized in the following table, from strongest to lowest (or rarest to most common). The probabilities are given for information only.
Given two hands, the hand with the lowest rank wins. If both hands are of the same rank, then it's a draw (there's no tie breaker).
```
 hand rank | hand value(s) | deal probability
-----------+---------------+------------------
     1     | 9s            | 0.30%
     2     | 3s            | 0.60%
     3     | 1s            | 0.90%
     4     | 7s            | 1.21%
     5     | 5s            | 1.51%
     6     | 3             | 1.81%
     7     | 9             | 2.26%
     8     | 8s            | 2.71%
     9     | 6s            | 3.02%
    10     | 1 or 7        | 3.62% each
    11     | 2s or 4s      | 3.92% each
    12     | 5             | 4.98%
    13     | 0s            | 5.43%
    14     | 8             | 8.14%
    15     | 6             | 9.95%
    16     | 2             | 11.76%
    17     | 4             | 13.57%
    18     | 0             | 16.74%
```
## The challenge
Given two *ModTen* hands, output one of **three consistent values** of your choice to tell whether:
* the first player wins
* the second player wins
* it's a draw
The following rules apply:
* A card must be described by its rank in upper case (`2`, `3`, ..., `9`, `T`, `J`, `Q`, `K` or `A`) followed by its suit in lower case (`c`, `d`, `h` or `s`, for clubs, diamonds, hearts and spades).
* You may use `"10"` instead of `"T"` but any other substitution is prohibited.
* As long as the above rules are followed, you may take the hands in any reasonable and unambiguous format. You are allowed to take the rank and the suit as two distinct characters rather than a single string.
Some valid input formats are:
	+ `"7c Qh 8s Ks"`
	+ `[["7c","Qh"], ["8s","Ks"]]`
	+ `[[['7','c'], ['Q','h']], [['8','s'], ['K','s']]]`
	+ etc.
* Instead of using 3 consistent distinct values, your output may also be **negative**, **positive** or **zero**. Please specify the output format used in your answer.
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'").
## Test cases
Player 1 wins
```
["Js","3s"], ["Ks","Kh"]
["7h","9h"], ["9s","7c"]
["Ah","5s"], ["Ts","8s"]
["Ts","8s"], ["Jh","2s"]
["4h","8s"], ["Qh","Ks"]
```
Player 2 wins
```
["Th","8d"], ["6s","Kd"]
["Jc","5c"], ["3s","9s"]
["Jc","Jd"], ["9h","Ah"]
["2d","4d"], ["3h","3s"]
["5c","4c"], ["3c","2c"]
```
Draw
```
["Js","3s"], ["3d","Jd"]
["Ah","Ac"], ["3d","9s"]
["Qc","Kc"], ["6d","4d"]
["2d","3d"], ["3s","2s"]
["Ts","9c"], ["4h","5d"]
```
  
[Answer]
# [Python 3](https://docs.python.org/3/), ~~114~~ 110 bytes
```
lambda m,n:p(*n)-p(*m)
R=b"T 2J45UNK9RL<3SLM;QAK:O>=/678"
v=R.find
p=lambda i,s,j,t:R[s==t::2][v(j)*v(i)%10+3]
```
[Try it online!](https://tio.run/##fZFba4MwGIbv/RVBGGrnDk20rW4OhF1pd6hzV06GmkosrZN@0tJf76yRRbp1N4E8vCeS6lCzr5I0ufPRrJNNShO00Uu7UkeldtWeG00KnFQOEfYM8/3Zt4L5PXmbP90tXN9@eXBuJtOZLO2c4DovSipVTh9S6KCv9NoOInCc2rZxHO3UlTbaqYV2Mb69JHFTL6H@zBJYwhg5KJIQilLFAwKKjlLFB58psc7plFmsoxZMs5Yijl1mcnEIMxC4ux2xx/AAG6zHC@a3WIolsQCLBSGb0U42AZ/@LPAyM@soAQsG1ONai7liLaYGp4QRoTUzo0/IcHZST/94AEI9Ue8ytzfTQf0i8zmdHBtFPenrAQttCBbXGsykXb1UbYuyVuXXdXJYbtEY7YsSbFmT8q8tqlFRosEP2W0K1@fqqNa0Uzf@z43Puh@3yf6Mif4yNd8 "Python 3 – Try It Online")
@Arnauld proposed the idea of merging the card value and rank table strings. After some attempts I managed to craft a merged string `R="T 2J45UNK9RL<3SLM;QAK:O>=/678"`, which has the same length as the original card value string. The substring `R[6:25]="UNK9RL<3SLM;QAK:O>=/"` serves as the rank table as well as a card value lookup table for `3`, `9`, `A`, `K`, and `Q`. The ASCII-value decoding of the new rank table has the same ranking effect as the previous rank table.
Using byte strings as input saves 4 bytes.
Using `cmp` in Python 2 can reduce the solution to 102 bytes, as shown by [@xnor's solution](https://tio.run/##fZFda4MwGIXv/RVBGH5MtjXRtro5EHal3YfOXTkZLqnE0triKy399U4j09HSXebhnDwJZ3es@bbETe5@Nuts880yPXboZqfqSZSA69aOg9Nkr640fa8W2tXk7pqk@bZChQHGyqhRUaI41aTIlWOEfdP6eAnsaPFA3hfP96EXOK@P7u10NpelvRvd5EXJmnoJ9RfNYAkT5KJEQihRfCCgGEgJIOBKagg24zbvmA0z2jIkoMctEYxhDgMUhxb6HI/Q5D0MedBCKZVGLx68MZ@zLjSFgP16fWrRjhGwYWS@yNncG96HmSkY4WTIWdTsuxTTEyk7@yxh/iD1uNcX2SgNaSDYtBMNUtJLAQ@5GGyRM7nFhFTaVUVZq/LbOjsuKzRBh6IER9akbjgx2Z8NnPaOPp@req1pp238XxtfbD9V2eFCiZ2Vmh8).
---
# [Python 3](https://docs.python.org/3/), ~~165~~ ~~142~~ ~~130~~ 129 bytes
```
lambda m,n:p(*n)-p(*m)
v="T 23456789   J    QA        K".find
p=lambda i,s,j,t:ord("HC92FA51GAB4E893D760"[s==t::2][v(j)*v(i)%10])
```
[Try it online!](https://tio.run/##fZFba4MwGIbv/RUfwlCLG22i9QBeuHUH9GaF3nUyXFKJpbXFL7Ts13caOx0tXSCBPLxvnoTsv6XYVfRURB@nTb794jls7Srcm6PKum/WraUdIn0BhDru1PMDAEiaCfMYziPVH4qy4to@OvdLG@21LcNdzU397SkgL7E7eY0fnWc/oDNvOtaXGEUyDEm2PJhra3QwS@tuMs6sk1yh/GQ5rnACESw1gKWRIEXDBiPFVBiZrZgnAtGyAD3WMFAwFq4KLtDHHqpNAxNBBuiIDs5F2kAt0wYv6b0L4fM2NMWU/3oT5rKWUQxwYInKBSLu70e4oxgVtM@5zOm6jLALKb96LOVJL41F3BX5IJ2zVLFpK@qltJMi6XMLDFTOES5XUm1fl5U09fdN/r2qYQLHssJQt7RiV4OEsoI/fxA2Z3T5whxJy7psk//a5GZ7VufHGyV@VTr9AA "Python 3 – Try It Online")
*-23 bytes thanks to @Jonathan Allan*
*-2 bytes thanks to @ovs*
*-1 byte thanks to @mypetlion*
### Ungolfed:
```
f = lambda hand1, hand2: get_rank(*hand2) - get_rank(*hand1)
def get_rank(v1, suit1, v2, suit2):
    get_card_value = "T 23456789   J    QA        K".find
    # rank_table = [[17,9,15,5,16,11,14,9,13,6],[12,2,10,1,10,4,8,3,7,0]]
    # rank_table = ("H9F5GBE9D6","C2A1A48370") # Base-18 encoding of ranks
    rank_table = "HC92FA51GAB4E893D760" # Interleaved base-18 encoding
    # ASCII-value decoding has the same ranking effect as base-18 decoding
    return ord(rank_table[suit1 == suit2::2][get_card_value(v2) * get_card_value(v1) % 10])
```
The function `f` takes two arguments representing the hand of player 1 and player 2. It returns a positive, negative, or zero value in the case of a player 1 win, a player 2 win, or a draw, correspondingly. Each hand is encoded as a single string, e.g. "7cQh".
[Answer]
# x86-16 machine code, ~~87~~ 83 bytes
**Binary:**
```
00000000: e807 0050 e803 005a 3ac2 ad2c 3092 ad2c  ...P...Z:..,0..,
00000010: 30bb 3501 3af4 7503 bb3f 01e8 0a00 92e8  0.5.:.u..?......
00000020: 0600 f6e2 d40a d7c3 b106 bf49 01f2 aee3  ...........I....
00000030: 038a 4504 c312 0a10 0611 0c0f 0a0e 070d  ..E.............
00000040: 030b 020b 0509 0408 0124 1a21 1b11 0003  .........$.!....
00000050: 0808 09                                  ...
```
**Unassembled:**
```
E8 010A         CALL GET_HAND           ; score first hand, ranked score into AL 
50              PUSH AX                 ; save score
E8 010A         CALL GET_HAND           ; score second hand 
5A              POP  DX                 ; restore first hand into DL 
3A C2           CMP  AL, DL             ; compare scores - result in CF, OF and ZF
            GET_HAND:                   ; 4 char string to ranked score ("9s7c" -> 6)
AD              LODSW                   ; load first card string 
2C 30           SUB  AL, '0'            ; ASCII convert 
92              XCHG DX, AX             ; store in DX 
AD              LODSW                   ; load second card string 
2C 30           SUB  AL, '0'            ; ASCII convert 
BB 0139         MOV  BX, OFFSET R       ; first, point to non-suited table 
3A F4           CMP  DH, AH             ; is it suited?
75 03           JNZ  NO_SUIT 
BB 0143         MOV  BX, OFFSET RS      ; point to suited table 
            NO_SUIT: 
E8 012C         CALL GET_VALUE          ; get face card value in AL 
92              XCHG DX, AX             ; swap first and second cards 
E8 012C         CALL GET_VALUE          ; get face card value in AL 
F6 E2           MUL  DL                 ; multiply values of two cards 
D4 A0           AAM                     ; AL = AL mod 10
D7              XLAT                    ; lookup value in rank score table 
C3              RET                     ; return to caller
            GET_VALUE:                  ; get value of a card (2 -> 2, J -> 3, A -> 9)
B1 06           MOV  CL, 6              ; loop counter for scan
BF 014D         MOV  DI, OFFSET V       ; load lookup table 
F2/ AE          REPNZ SCASB             ; scan until match is found 
E3 03           JCXZ NOT_FOUND          ; if not found, keep original numeric value
8A 45 04        MOV  AL, BYTE PTR[DI+4] ; if found, get corresponding value 
            NOT_FOUND:
C3              RET                     ; return to program
R    DB   18, 10, 16, 6, 17, 12, 15, 10, 14, 7     ; unsuited score table
RS   DB   13, 3, 11, 2, 11, 5, 9, 4, 8, 1          ; suited score table
V    DB   'J'-'0','Q'-'0','K'-'0','A'-'0','T'-'0'  ; face card score table
     DB   3, 8, 8, 9, 0
```
Input is as a string such as `Js3sKsKh`, at pointer in `SI`. Output is `ZF = 0 and SF = OF` (test with `JG`) if player 1 wins, `SF ≠ OF` (test with `JL`) if player 2 wins or `ZF` (test with `JE`) if a draw.
**Output using DOS test program:**
[![enter image description here](https://i.stack.imgur.com/sIXAP.png)](https://i.stack.imgur.com/sIXAP.png)
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), ~~41~~ 37 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
•V›{₆Ÿ&∊WÍj¸•19вyεø`Ës‘ßŒQ‘ŽćS‡Pθ«}èÆ
```
-4 bytes thanks to *@Grimy*.
Input as a list of list of list of characters, like the third example input format in the challenge description. I.e. P1 `7c Qh` & P2 `8s Ks` would be input as `[[["7","c"],["Q","h"]],[["8","s"],["K","s"]]]`. (And uses `"10"` for `10`.)
Outputs a negative integer if player 1 wins; a positive integer if player 2 wins; or 0 if it's a draw.
[Try it online](https://tio.run/##yy9OTMpM/f//UcOisEcNu6ofNbUd3aH2qKMr/HBv1qEdQGFDywubPM9tPbwj4XB38aOGGYfnH50UCKSP7j3SHvyoYWHAuR2HVtceXnG47f//6OhoJXMlHaVkpVidaKVAICtDKRbIjFayALKLwaLeEFZsLAA) or [verify all test cases](https://tio.run/##yy9OTMpM/V9Waa@k8KhtkoKSfeX/Rw2Lwh417Kp@1NR2dIfao46u8MO9WYd2AIUNLS9sqjy39fCOhMPdxY8aZhyef3RSIJA@uvdIe/CjhoUB53YcWl17eMXhtv86fnamh6dlHtpmX/s/GgiUvJR0lIqVYnWilYwhLCAzWskbLgpiZQBFY3UUQMrNIVyghCVUAqTcEq4cJJ@MUO4IV26KZLqhAVy9BVQYqh6LjA7UkRBjjFDVm8AlkJUHwkW9sRiPUJ8CVW@G4tsUhHoviG@gzk@GKjeGK7dENR6h3AvJdEu4nY6oYWkEUaQD8UYKkukZKBECVW4KN90EzTHJ8KBJRnUMZsQaw@30QvWqI4orkzGUo3k1EG6tN5JyMwwfYXjVGM2rxdiiFSkZWCIZb4KSmlJQUyXENYFIqdICJVrBxscCAA).
**Explanation:**
```
•V›{₆Ÿ&∊WÍj¸•  # Push compressed integer 36742512464916394906012008
 19в           # Convert it to base-19 as list:
               #   [18,10,16,6,17,12,15,10,14,7,13,3,11,2,11,5,9,4,8,1]
Iε             # Push the input, and map each of its hands to:
  ø            #  Zip/transpose the hand; swapping rows/columns
               #   i.e. [["8","s"],["K","s"]] → [[["8","K"],["s","s"]]
   `           #  Push them separated to the stack
    Ë          #  Check if the two suits in the top list are equal (1/0 for truthy/falsey)
    s          #  Swap to get the list with the two values
     ‘ßŒQ‘     #  Push dictionary string "JAKEQ"
     ŽćS       #  Push compressed integer 39808
     ‡         #  Transliterate these characters to these digits
      P        #  Now take the product of the two values in the list
       θ       #  Only leave the last digit (basically modulo-10)
    «          #  And merge it to the 1/0
               #  (now we have the hand values of both players,
               #   where instead of a trailing "s" we have a leading 1)
 }è            # After the map: index each value into the earlier created integer-list
               # (now we have the hand rank of both players)
   Æ           # And then reduce the resulting integers by subtracting
               # (after which the result is output implicitly)
```
[See this 05AB1E tip of mine (sections *How to use the dictionary?* *How to compress large integers?* and *How to compress integer lists?*)](https://codegolf.stackexchange.com/a/166851/52210) to understand why `•V›{₆Ÿ&∊WÍj¸•` is `36742512464916394906012008`, `•V›{₆Ÿ&∊WÍj¸•19в` is `[18,10,16,6,17,12,15,10,14,7,13,3,11,2,11,5,9,4,8,1]`, `‘ßŒQ‘` is `"JAKEQ"`, and `ŽćS` is `39808`.
[Answer]
# [Nibbles](http://golfscript.com/nibbles), 31 27 bytes
```
`/.$=+*`*.`'$`r:`#$10$~,`$$`D22-859ff1e2379fa8205a46a3
```
Thats 32 nibbles of code followed by a number that is stored as 22 hex digits. Making 54 half byte instructions in the binary form. (Nibbles isn't on TIO yet).
I found this to be a pretty cool problem. My first instinct was rather than hardcode the hand orders, calculate it! By finding how common each is, but this turned out to be longer surprisingly.
It works by converting each hand to an integer 1-20 and then looking it up it up in a table to find its relative goodness. Finally those goodnesses are subtracted so that equal hands are 0, player 1 wins positive, and player 2 wins negative.
Let's break down the code:
```
`D 22 859ff1e2379fa8205a46a3
```
becomes that data in base 22, which is
```
[5,0,18,8,7,2,19,12,7,1,14,6,9,3,15,8,10,4,20,11]
```
This code just maps on each hand and does a fold on the result
```
`/      special fold
  .$    map on input (for each hand)
    ...
  -     subtract (the type of special fold)
```
Now for the code that converts hand to a unique number for that suitedness and mod10. Multiply the product by 2 to make space for the suitedness value of 1 or 2 without conflict (this is similar to other solutions).
```
+
 * [product mod 10]
  ~     2
, `$ $  length of the unique suites
```
To calculate the hand value mod 10:
```
`*             product
  .            map
   `' $        transpose of input hand [("J",'c'), ("10",'d')] becomes
               (["J","10"],"cd") and since this is a tuple, it returns
               the first value, setting $ to be "cd" (used later)
   `r          read a number from a string in base 10
     :         list concat of
      `# $ 10  hash of the hand value mod 10 (this is to convert JQKA)
      $        the hand value string
```
Finally this is looked up in the table by just looking up the value at an index with `=`
There's a couple of cool tricks here. One is how the hash value becomes the right answer mod 10. It uses the data as salt, but the data is also being used to extract our table. This is why the table was in base 22 when we only needed base 20. It gave us some degrees of freedom to brute for search for different representations that will still give the right answer. On average we need about 10000 degrees of freedom. Since JQKA all have to go to the correct number (1/10 chance each).
This was found with brute force search using this code:
```
.| . | `*.,4`,21 ==\$`<@  # n-b=18
    `@ 22
    ..%"13,18,3,10,11,16,2,6,11,17,5,12,9,15,4,10,8,14,1,7" ',' - 18`r$
    +- 5 ?:@0~ +-@$1 $
 ==."JQKA"
  `#~ : o$ @ 10
:3:8:8 9
hex$
```
Another cool trick is how the card value is parsed. Essentially what we want to do is say if it is an integer than use its value, otherwise the hash value. But it is shorter to just always put the hash in front of the value and parse the result. Like so: "J" -> "3J", "5" becomes "[something]5". In the first case the J is ignored because it isn't a digit. In the second case the [something] doesn't matter because the complete value is still 5 mod 10.
Also note that we don't actually ever need to do mod 10 on the product because the size of the table we are looking is size 20 and wraps (and we've multiplied by 2).
To invoke it pass the hands as command line args. List of List of tuple of Str, Char.
For example:
```
nibbles hardcode.nbl "[[(\"7\",'c'),(\"Q\",'h')],[(\"8\",'s'),(\"K\",'s')]]"
```
This problem shows off the power of a deterministic hash function already, but there's a cool idea that could improve it further but it would be computationally intractable unless the hash function can be reversed without using brute force!
The idea is rather than look up the hand in a list of goodnesses, take the hash of it. You just need to find salt that happens to give the right ordering (it doesn't have to use values 0-17).
This would be shorter because the current encoding takes
log(18)\*20=83 bits but the new one would be
```
log(18!)+log(n)*2+log2(n^18*(n-18)!/n!)
```
Where n is the base to use in the hash mod. The higher it is the less likely you'll have collisions, but also the less likely you'll manage to get those two hands that are equivalent to map to the same value. This value is maximized by n being 117, giving 68 bits (but really n is another degree of freedom in the search so it could be fewer bits).
This would lead to a 2 byte savings on average! (In data alone, not counting the degrees of freedom for n, you also wouldn't need the \* ~ and = instructions).
The ultimate reason less information is needed is because a list stores exact values but all we really need is an order.
This problem has inspired me to try to design a hash function that can be reversed so that a solution like this (and others for other problems) can be realized without brute force. It has gotten pretty mathy, especially when the base we are talking about isn't a prime number, but it is something I intend to revisit and hopefully write a paper and add it into nibbles!
[Answer]
# [PHP](https://php.net/), ~~212~~ ~~185~~ ~~178~~ 149 bytes
```
while($p=$argv[++$x])$$x=ord(rjpfqlojngmckbkeidha[(($v=[J=>3,Q=>8,K=>8,A=>9])[$p[0]]?:$p[0])*($v[$p[2]]?:$p[2])%10+($p[1]==$p[3])*10]);echo${1}-${2};
```
[Try it online!](https://tio.run/##dZJvb5swEMZfx5/ihDwFFqYW6D@WkSovKk3JpCVS3zGrYtitSRNgmCaZonz27AxORjrtDebu57vn7pFLWR6@3JeyJITWQtUKIogJAbi4gHKZ/BYVeLDJcoWpmPRiiK2JslwrUBZzMZjqYCotBsxt8a3ETChbHGp8m3bwWONrU/2o8Z3q4FNG44m@63fxlezguQ6mBkP7@Tu2/27sx6aUt6U3zdi803mS6rnSFgcah@o9npjqULcad5f2OWauDA6kMeh8Ll4lm/@4GHDT/dymcdrBZ@PM9ThTg2@O4ufjBLyzjP@PyaGpbiy95qdpCWFDQp6LSiSptMG8ikQBraIRrYQCB3aE9EQqC5h9nT09fP/mgjVrXbewZb99MX237x9/9O59FtMKJU815gfVekYOUE8raLXa6LRCC1XkTyJPCy5sWjso@KO2dGUPnVXZ6m2Z1ALSYrVKcg7LLBeQVC8KsDE0G@BNipl17DF84osiy7FPfMmc4Yn4XeJpctjIbImCZdTeGAzoljmUbqOi4na1KJ9/LYtF/rJKX3@@iozLJLZtuo7iSTQK3Hk0unOn@jOORiFzYlqiILv/3JzOR7ypU75J@cz54F0OUA3FowiPAC95ekRtAd15@0905@@Hh96Z@UcX0DhRg8jXWVXkK5HXmH7LMWfTotnSBOtusHV0@Z4Qsj/8AQ "PHP – Try It Online")
* -7 bytes thanks to @Night2!
* -29 bytes by ASCII encoding the table instead of array
Input is via command line. Output to `STDOUT` is **negative** if player 1 wins, **positive** if player 2 wins, `0` if tie. Example:
```
$ php modten.php Js3s KsKh
-1
```
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), ~~101~~ ~~100~~ ~~94~~ 88 bytes
*-1 byte thanks to Jo King*
```
{[-] .map:{'HC92FA51GAB4E893D76'.ords[[*](.[*;0]>>.&{TR/JQKA/3889/})%10*2+[eq] .[*;1]]}}
```
[Try it online!](https://tio.run/##ZZK9boMwFIX3PoWXJkApfwaCW4rk/stMVN0QQ6QmU6OkZIoQD9ItEmoerC9CMe6NDWzm@OOce7jsVuVn2G4OaLZGd22VXxfI2ix3N9X89YF4zzRwX@i9/xQR/LgI59a2/NjnuVFoVm7cOkWSWLPq/c1mWUptHEXErvVL1zG8q3z11Tl1kFsUdd3ulwdkdRHrbXmhaTFDv9/HxEQx7g@6ibQ4BY0ffhJdNzm56B86lQiVkwRIftkASYEMpKfrABoJUaATmbMM3vdU1AdVITPQ0onpGT0JNFRLnQBl/dz/ozaCxEAS1fRMMulJIIeqH8rrgU71JYmBxKpnAJ7@ML2B8o2aPl4ThhymNqLqTM2IHDTKICmVZDiafdQIDxsdJ0uS@yTS1Ff/B27a/gE "Perl 6 – Try It Online")
Takes input as `f(((<J ♠>, <3 ♠>), (<10 ♠>, <K ♥>)))` using `10` for Ten. Returns a value < 0 if player 1 wins, > 0 if player 2 wins, 0 if it's a draw.
### Explanation
```
{
  [-]  # subtract values
  .map:{  # map both hands
    'HC92FA51GAB4E893D76'.ords[  # lookup rank in code point array
      [*](  # multiply
        .[*;0]  # card ranks
        >>.&{TR/JQKA/3889/}  # translate J,Q,K,A to 3,8,8,9
      )
      %10*2  # mod 10 times 2
      +[eq] .[*;1]  # plus 1 if suited
    ]
  }
}
```
[Answer]
# [C (gcc)](https://gcc.gnu.org/), ~~172~~ ~~167~~ ~~165~~ ~~164~~ 162 bytes
```
char*v="T 23456789   J    QA        K";p(char*l){return"A<92?:51@:;4>893=760"[(l[1]==l[3])+(index(v,l[2])-v)*(index(v,*l)-v)%10*2];}f(char*s){return p(s+5)-p(s);}
```
[Try it online!](https://tio.run/##XY1Lr5swEIXX8a84chUJ8qiCgSSEkFu2sIqUHWWBbFIjURoxebS6ym9Ph7S5Umv5MT5nzjd6/k3rx6em0@3F1NjS2TQ/PtvdQ9uqn1wTeYDyg3C5WkcAMj7Yp/i7chmfnGdj67739fnSdzLdRuptE3pfNnGwW0d@slouZOG0hVcmSVv4pTt1ms7UP53rrC1U6c6v7uRDYRD/x95iosr4fvwDpxccJ4emoTvnx43vj6Y743vVdI6LdzEaWkGFtyhjMbrZpq0d0lV3dOSYMKavnZyBeGOK0EWSQD1jo4HS13Rpz0hwHMgsnnqWh2jA2YA2/wNmr8gOC7xBntrqV93Dw63pSGLzsrf/2OrDlqavbnIYdRf3R0Y@IafcipWNLCJaaYjUhoQDrQnieWdWcRlYLvc2J3Gwa4Ml5UZkOtTwKSKuMoPIplYoExj41icR6oBdrbR4jvFNZpidsmY4sde5xpKbOeFzghSTKdIIbGh@Aw "C (gcc) – Try It Online")
4 bytes shaved off thanks to the amazing @ceilingcat!
Basically a port of @Joel's Python3 solution, but without the base18 encoding. Expects the input as one string with a space separating the hands of the two players, and outputs an integer that is positive, negative or zero to indicate player 1 wins, player 2 wins or if it's a draw.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 46 bytes
```
“T0J3Q8K8A9”yⱮZV€P$Eƭ€)%⁵UḌị“©N¿!Æßvṅ?żṀ’b18¤I
```
[Try it online!](https://tio.run/##y0rNyan8//9Rw5wQAy/jQAtvC0fLRw1zKx9tXBcV9qhpTYCK67G1QFpT9VHj1tCHO3oe7u4GKj600u/QfsXDbYfnlz3c2Wp/dM/DnQ2PGmYmGVocWuL5////aCXzDCUdJe9ipVidaCWTYiDbEcgGAA "Jelly – Try It Online")
A full program taking as its argument for example `["7h","Ks"],["4s","Ts"]` and printing zero if both players draw, positive if player 1 wins and negative if player 2 wins. 
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 97 bytes
```
≔”)¶＆sＮψU↓”ζＦ¹³Ｆ¹³Ｆ⁻⁴⁼ικ⊞υ⁺÷λ³⊗﹪Π⁺§ζι§ζκχ≔”A↘τ[⁵ＰkxτG”ε≔⁰δＦ⟦θη⟧≦⁻№υ⁺⁼§ι¹§ι³⊗﹪Π⁺§ζ⌕ε§ι⁰§ζ⌕ε§ι²χδＩδ
```
[Try it online!](https://tio.run/##jZBBS8MwGIbv/oqPnb7AJ7RrnR2eyqYwZ6EDb8NDbTIbDIlrkiH78zVd3dw8iKcv4X2TPE/qpmprU6muy62VbxpH4yS9mdxm0yjJsumIYM/urjamBYwTBpeLQmpvMSW43/pKWZQE74wxKL1t0BOUKsQL7eZyJ7lARZAwgrnxr0pwLAz3ymDZhlk7PJRzt9BcfOKeQIbq2ba/mCCOwghAv2GfH1fLPMCKnywi4Ef09ZageWFQVB9D@iQ2bsAnmBmv3Qn3W@X4clCKz0Bkr/B/hwepOYqL49HB4@/OuJc82Q4eZSsD5ayyDnn4ga5b1csaJjzl3fVOfQE "Charcoal – Try It Online") Link is to verbose version of code. Takes input as two strings of 4 characters e.g. `QcKc` `6d4d` and outputs a signed integer. Explanation:
```
≔”)¶＆sＮψU↓”ζ
```
Compressed string `2345678903889` represents the card values.
```
Ｆ¹³Ｆ¹³
```
Loop over each possible pair of values.
```
Ｆ⁻⁴⁼ικ
```
Loop over each possible second card suit. Without loss of generality we can assume that the first card has suit 3, so the second card suit can range from 0 to 3 unless the values are the same in which case it can only range from 0 to 2.
```
⊞υ⁺÷λ³⊗﹪Π⁺§ζι§ζκχ
```
Compute the modified score of the hand, which is the value of the hand doubled, plus 1 if the suits are the same (i.e. the second card has suit 3).
```
≔”A↘τ[⁵ＰkxτG”ε
```
Compressed string `23456789TJQKA` represents the card characters. The input cards are looked up in this string and then the position is used to index into the first string to get the card's value.
```
≔⁰δ
```
Initialise the result to 0.
```
Ｆ⟦θη⟧
```
Loop over the two hands.
```
≦⁻№υ⁺⁼§ι¹§ι³⊗﹪Π⁺§ζ⌕ε§ι⁰§ζ⌕ε§ι²χδ
```
Calculate the modified score of the hand, and thus its frequency, and subtract the result from this.
```
Ｉδ
```
Output the frequency difference.
[Answer]
# [C# (Visual C# Interactive Compiler)](http://www.mono-project.com/docs/about-mono/releases/5.0.0/#csc), 139 bytes
```
x=>x.Sum(n=>(i++%2*2-1)*(n[1]==n[3]?"":" 


")[n.Aggregate(1,(a,b)=>a*(b>85?1:b>83?0:b>74?8:b>73?3:b>64?9:b-48))%10]);int i
```
[Try it online!](https://tio.run/##jZJba9swGIbvfbPz1u4oBAUpdUpt2Ymd1DaGbTD7pmW5C2EoshIZWg38OUvH6G/PZHvQOe0OV5/Qw/vy6CBgKKDcfdxocfbpg95cyYovL@UZ1FWp17Fd6jpeRbvrKL4@@by5IjqKSXl8fOQO3KFDB0TPnUUU6TlbJPjVo8OHh09ePH7@AE8wOnj79N3LNwevn2E61yfpel3JNa8lcWzC7SWNYj4gyzjwE2diBktOzRh7SdAMljAzRl4STpZDL6D0yDld0KmRQeVuan3jFaol1F8EBwkOipCW2/nih4V@LXAGDLCNcA65wjf2LRirUDUghLEwAN2SVPltZAYB9Em7Y0im3D3iqY5cqNwQ62Zfzb1HbaaCosmMIC96apnwRQMYhLAHsjYRqrR/GLfwWsAU6yd84XVVwhX3eRV/uTJWZH2vVKVdWbHndSHyFowajb4X67zA7SdmELYJT/lF52Wdm39WE3x@yb/LCjloW2qYYDq1Vl8ryYUirTkq9e8vTk1lF1yRmtI7Ne5/1bh/rHlf8e2/0sWd9O4n "C# (Visual C# Interactive Compiler) – Try It Online")
[Answer]
# [Perl 5](https://www.perl.org/) `-p`, 107 bytes
```
$a=A;y/ATJQK/90388/;${$a++}=substr"IAG6HCFAE7D3B2B59481",($1eq$3).$&*$2%10,1while/.(.) (.)(.)/g;$_=$A cmp$B
```
[Try it online!](https://tio.run/##JcjLCoJAGEDhvU8xyF9oXsZxshRxMXYfaRG0D1NJwdIcIyJ69SYhON/mtEVXe1JCGrHwhdmRHxIcONT3cQhvSA3jE4nHWfSdumOb2XaxZqv5ksZu7AVTn6imBqS4A9VtGE/AHRHHJM@yqgtsa7aOBkP4EsIpAoayawuxlFwgKsxEoKRUeIa8zKQCBUL5f5ojnn@btq@am5DW3rMd4kirrX8 "Perl 5 – Try It Online")
### Input:
```
As 4d,Th 8c
```
(Actually, the comma can be any character.)
### Output:
```
-1  Player one wins
 0  Draw
 1  Player two wins
```
]