12
\$\begingroup\$

Mahjong is a tile game that is immensely popular in Asia. It is typically played with four players, and the goal of the game is to be the first person to complete a valid hand using the tiles. In mahjong there are three tile suits plus honour tiles — for this challenge we will only consider hands formed using tiles from a single suit.

Tiles are numbered from 1 to 9, and there are exactly four copies of each tile. A valid hand consists of four sets of three and a pair, for a total of fourteen tiles.

A set of three can be either:

  • A triplet, three of the same tile (e.g. 444), or
  • A sequence of three consecutive tiles (e.g. 123 or 678 but not 357). Sequences do not wrap (so 912 is invalid).

A pair is simply two identical tiles (e.g. 55).

The challenge

Given a valid hand of fourteen tiles, determine its score based on the following criteria:

Condition                Description                                 Point/s
-------------------------------------------------------------------------------
Straight                 Contains the sequences 123 456 789          1
Identical sequences      Contains two identical sequences            1
All simples              Only 2-8, no 1s or 9s                       1
All sequences            All sets of three are sequences             1
All triplets             All sets of three are triplets              2
Flush                    Single-suit hand (always applies)           5

(Scoring here is based off Japanese mahjong rules, but heavily simplified to make the spec less messy.)

The score of a hand is the sum of points for the conditions it satisfies. If a hand can be decomposed in more than one way, take the highest scoring decomposition.

The input hand is guaranteed to be valid, i.e. fourteen tiles from 1 to 9 and each tile appearing at most four times, and may be assumed to be already sorted. Input is a list of digits (as a string or a single flat list of integers) via STDIN, function argument or command line. Output may be to STDOUT or return value.

Test cases

22233355777888  ->  8  # 222 333 55 777 888, flush + all simp. + all trip.
11112345678999  ->  6  # 111 123 456 789 99, flush + straight
11123456788999  ->  5  # 111 234 567 88 999, flush only (no straight)
23344455566788  ->  7  # 234 345 456 567 88, flush + all simp. + all seq.
33334444555566  ->  8  # 33 345 345 456 456, flush + all simp. + all seq. + identical seq.
11122233377799  ->  7  # 111 222 333 777 99, flush + all trip. (no identical seq.)
12344556678889  ->  8  # 123 456 456 789 88, flush + all seq. + straight + identical seq.
11344556678999  ->  5  # 11 345 456 678 999, flush only (no identical seq.)
22233344455566  ->  8  # 222 333 444 555 66, flush + all simp. + all trip.
11112233344555  ->  5  # 111 123 234 345 55, flush only

For the fifth example, despite having two pairs of identical sequences, only one needs to be present to attain the point. The decomposition 345 345 345 345 66 would score the same, while 333 345 444 555 66 scores worse.

Scoring

This is , so the solution in the fewest bytes wins. Standard loopholes apply.


Related challenge: What are you waiting for? (A mahjong solver)

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

J (241 byes)

You need the latest version of J installed.

i=:>:@i.9
q=:,/^:4>@:{(i.9);(i.;i.;i.;i.)16
s=:3 :'(>./((5+([:(*./)(3*i.3)&e.)+(-.@:(-:~.))+((*./)@:(6&>:))+2*((*./)@:(6&<)))"1(}."1(y(-:/:~"1)"1((([:{&(i,.i){.),[:,/[:{&(((>:@i.7)+"0 1(i.3)),|:3 9$i)}.)"1 q))#q)))+([:(*./)[:-.((1 9)&e.))y'

Call the function s with a list of integers. For example, the following example script verifies the test cases above:

#!/usr/bin/jconsole
i=:>:@i.9
q=:,/^:4>@:{(i.9);(i.;i.;i.;i.)16
s=:3 :'(>./((5+([:(*./)(3*i.3)&e.)+(-.@:(-:~.))+((*./)@:(6&>:))+2*((*./)@:(6&<)))"1(}."1(y(-:/:~"1)"1((([:{&(i,.i){.),[:,/[:{&(((>:@i.7)+"0 1(i.3)),|:3 9$i)}.)"1 q))#q)))+([:(*./)[:-.((1 9)&e.))y'


echo (s 2 2 2 3 3 3 5 5 7 7 7 8 8 8)=8
echo (s 1 1 1 1 2 3 4 5 6 7 8 9 9 9)=6
echo (s 1 1 1 2 3 4 5 6 7 8 8 9 9 9)=5
echo (s 2 3 3 4 4 4 5 5 5 6 6 7 8 8)=7
echo (s 3 3 3 3 4 4 4 4 5 5 5 5 6 6)=8
echo (s 1 1 1 2 2 2 3 3 3 7 7 7 9 9)=7
echo (s 1 2 3 4 4 5 5 6 6 7 8 8 8 9)=8
echo (s 1 1 3 4 4 5 5 6 6 7 8 9 9 9)=5
echo (s 2 2 2 3 3 3 4 4 4 5 5 5 6 6)=8
echo (s 1 1 1 1 2 2 3 3 3 4 4 5 5 5)=5

exit''
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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