Word Poker, кто победит?

13

На входе будут два пятибуквенных слова. На самом деле они не должны быть словарными словами, просто любые пять букв каждое, все строчные или прописные, на ваш выбор. Во входных словах будет отображаться только AZ, и они всегда будут иметь длину 5 символов.

Ваша программа состоит в том, чтобы забить их обоих, как если бы они были покерными руками и вывести более высокую руку. Конечно, костюмы здесь не применимы, только рейтинги, поэтому нет флешей.

Типичная система рейтинга в покере: «1 пара», «2 пары», «3 в своем роде», «стрит», «фулл-хаус», «4 в своем роде», «5 в своем роде» и, конечно, есть вероятность, что рука (или слово в этом случае) может ничего не стоить.

В случае связей буквы ближе к A считаются более высокими, поэтому пара As побеждает пару B. В некоторых случаях обе руки могут быть идентичны, но в разном порядке (или нет), в этом случае выведите либо руку, либо ее пересмотренную версию.

Эта внешняя страница содержит информацию о том, как определить победителя, и, в частности, адреса связей в конкретных рейтингах, если вы не знакомы с тем, как набирать покерные комбинации.

В случае прямых : буквы должны быть смежными в алфавите и не допускаются для переноса. Таким образом, «defgh» в любом порядке является прямым, «xyzab» - нет.

Примеры того, как забить одну руку:

word   | scored as
---------------------
ccccc  | 5 of a kind     <-- highest ranking
woooo  | 4 of a kind
opopo  | full house
vurst  | straight
vovvu  | 3 of a kind
ppoww  | 2 pairs
upper  | 1 pair
kjsdf  | high card only (in this case D) <-- lowest ranking

Таким образом, программа на самом деле даст такие результаты:

input        |  output
-----------------------
voviu,kjsdf  |  voviu     because a pair beats nothing 
opoqo,upper  |  opoqo     because 3 of a kind beats a pair
woooo,ggegg  |  ggegg     because 4 Gs beats 4 Os
queue,hopup  |  queue     because 2 pairs beats 1 pair
lodpl,ddkop  |  ddkop     because pair DD beats pair LL
huhyg,hijht  |  huhyg     both have pair HH, but G beats I
ddffh,ccyyz  |  ccyyz     both have 2 pairs, but CC(yyz) beats DD(ffh)
okaok,nkunk  |  nkunk     KK ties with KK, but NN beats OO
abcdf,bcdef  |  bcdef     because it is a straight
qtery,retyq  |  qtery     identical! so doesnt matter
abedc,vyxwz  |  abedc     because it is a "higher" straight
hhhij,hijkl  |  hijkl     because straight beats 3 of a kind
aaabb,zzzzz  |  zzzzz     because nothing beats 5 of a kind

Порядок букв как на входе, так и на выходе не имеет значения, поэтому порядок вывода может отличаться от ввода, но должен присутствовать один и тот же перечень букв.

Вывод должен содержать ровно пять букв - ни больше, ни меньше.

Обычные правила Codegolf применяются. Самый короткий код выигрывает.

Осьминог
источник

Ответы:

4

JavaScript ( 224 218 213 байт)

s=>t=>(v=s=>(o={},l=n=0,z=3.5,[...s].sort().map(c=>(n+=o[c]=-~o[c],z*=!l|l+1==(l=c.charCodeAt()))),[n+z,Object.keys(o).sort((a,b)=>o[b]-o[a]||(o[b]>o[a]?1:-1))]),w=v(s),x=v(t),w[0]>x[0]||w[0]==x[0]&&w[1]<x[1]?s:t)

Ungolfed:

s=>t=>(
  v=s=>(
    o={},
    l=n=0,
    z=3.5,
    [...s].sort().map(c=>(
      n+=o[c]=-~o[c],
      z*=!l|l+1==(l=c.charCodeAt())
    )),
    [n+z,Object.keys(o).sort((a,b)=>o[b]-o[a]||(o[b]>o[a]?1:-1))]
  ),
  w=v(s),x=v(t),
  w[0]>x[0] || w[0]==x[0] && w[1]<x[1] ? s : t
)

После map()пробежек n + zопределяет рейтинг руки:

введите описание изображения здесь

(Вы можете понять, почему я инициализировал zдо 3.5.)

В случае ничьей, Object.keys(o).sort()используется для определения руки с более высоким рейтингом.

Отрывок:

f=

s=>t=>(v=s=>(o={},l=n=0,z=3.5,[...s].sort().map(c=>(n+=o[c]=-~o[c],z*=!l|l+1==(l=c.charCodeAt()))),[n+z,Object.keys(o).sort((a,b)=>o[b]-o[a]||(o[b]>o[a]?1:-1))]),w=v(s),x=v(t),w[0]>x[0]||w[0]==x[0]&&w[1]<x[1]?s:t)

console.log(/voviu/.test(f('voviu')('kjsdf')))       //because a pair beats nothing 
console.log(/opoqo/.test(f('opoqo')('upper')))       //because 3 of a kind beats a pair
console.log(/ggegg/.test(f('woooo')('ggegg')))       //because 4 Gs beats 4 Os
console.log(/queue/.test(f('queue')('hopup')))       //because 2 pairs beats 1 pair
console.log(/ddkop/.test(f('lodpl')('ddkop')))       //because pair DD beats pair LL
console.log(/huhyg/.test(f('huhyg')('hijht')))       //both have pair HH, but G beats I
console.log(/ccyyz/.test(f('ddffh')('ccyyz')))       //both have 2 pairs, but CC(yyz) beats DD(ffh)
console.log(/nkunk/.test(f('okaok')('nkunk')))       //KK ties with KK, but NN beats OO
console.log(/bcdef/.test(f('abcdf')('bcdef')))       //because it is a straight
console.log(/qtery|retyq/.test(f('qtery')('retyq'))) //identical! so doesnt matter
console.log(/abedc/.test(f('abedc')('vyxwz')))       //because it is a "higher" straight
console.log(/hijkl/.test(f('hhhij')('hijkl')))       //because straight beats 3 of a kind
console.log(/zzzzz/.test(f('aaabb')('zzzzz')))       //because nothing beats 5 of a kind

Рик Хичкок
источник
3

Желе ,  28 27 29  27 байт

+2 и затем -2 исправить ошибку, а затем повторно сыграть в гольф.

FI=1ȦḤW
OµNĠLÞṚịµL€+Ç,N
ÇÞṪ

Монадическая ссылка, берущая список «рук» и возвращающая (одного из) победителей.

Работает для ввода в верхнем или нижнем регистре.
(... но не смешанный, для этого добавьте последнюю строку с помощью Œlили Œu).

Попробуйте онлайн! или посмотрите набор тестов .

Как?

FI=1ȦḤW - Link 1, straight offset: grouped and reverse sorted hand ordinals
        -                     e.g. [[-101],[-100],[-99],[-98],[-97]]
F       - flatten                  [-101,-100,-99,-98,-97]
 I      - increments               [1,1,1,1]
  =1    - equal 1? (vectorises)    [1,1,1,1]
    Ȧ   - any and all?             1
     Ḥ  - double                   2
      W - wrap in a list           [2]
        -   The purpose of this is so that when "a" from Link 2 represents a straight we
        -   get [2], whereas for any other hand we get [0]. Adding the [2] to [1,1,1,1,1]
        -   (the lengths of a straight's groups) yields [3,1,1,1,1], placing it between
        -   three of a kind, [3,1,1], and a full house, [3,2], as required.

OµNĠLÞṚịµL€+Ç,N - Link 2, hand rank key function: list of characters       e.g. "huhyg"
O               - cast to ordinals                                [104,117,104,121,103]
 µ              - monadic chain separation, call that o
  N             - negate (to give them a reverse-sort order) [-104,-117,-104,-121,-103]
   Ġ            - group indices by value                            [[4],[2],[1,3],[5]]
     Þ          - sort by key function:
    L           -   length                                          [[4],[2],[5],[1,3]]
      Ṛ         - reverse                                           [[1,3],[5],[2],[4]]
       ị        - index into o                       [[-104,-104],[-103],[-117],[-121]]
        µ       - monadic chain separation (call that a)
         L€     - length of €ach                                              [2,1,1,1]
            Ç   - call last link (2) as a monad -> [isStraight? * 2]                [0]
           +    - addition (vectorises)                                       [2,1,1,1]
              N - negate o                                [[104,104],[103],[117],[121]]
             ,  - pair                        [[2,1,1,1],[[104,104],[103],[117],[121]]]
                -   now sorting by this will first be comparing the hand class, and if
                -   and only if they match comparing the card values in the required order.

ÇÞḢ - Main link: list of lists of characters (list of hands)
 Þ  - sort by key function:
Ç   -   last link (2) as a monad
  Ṫ - tail (best or an equal-best hand)
Джонатан Аллан
источник
Так чертовски мало по сравнению с тем, что я делаю в JS 0.o
Стивен
3
@StephenS Добро пожаловать в PPCG, где вы делаете что-то на языке, не относящемся к гольфу, а затем кто-то делает что-то на Jelly, 05AB1E, Pyth, CJam и т. Д., Которое короче, чем название вашего языка: I: P
HyperNeutrino
1
@StephenS - JS должен конкурировать с JS. Не позволяйте языкам игры в гольф удерживать вас от предоставления продуманных решений на других языках!
Джонатан Аллан
@JonathanAllan, это удерживает меня от чрезмерных усилий по переосмыслению и абстрагированию проблемы, которая может быть решена с помощью ~ 25 символов, вот скрипка, над которой я работал - я написал весь шаблон и ни один из фактического кода
Стивен
Это здорово, но я недавно добавил тестовый пример, который не вычисляется, а именно ["hhhij", "hijkl"]. Я думаю, это из-за того, как вы оцениваете стрит как [3,1,1,1,1]?
Осьминог
3

JavaScript ( 250 247 232 байта)

S=d=>(x={},l=99,h=s=0,[...d].map(v=>x[v]=-~x[v]),Object.keys(x).map(v=>(c=91-v.charCodeAt(),t=x[v],s+=1e4**t,c<x[t]?0:x[t]=c,g=(h=c>h?c:h)-(l=c<l?c:l))),[5,4,3,2,1].map(v=>s+=0|x[v]**v),s+(s<5e7&&g<5?1e13:0)),C=a=>b=>(S(a)>S(b)?a:b)

Разоблаченный код и контрольные примеры в JSFiddle: https://jsfiddle.net/CookieJon/8yq8ow1b/

Сохранено несколько байтов благодаря @RickHitchcock. @StephenS & @Arnauld

неровный
источник
Это то, что я пытался сделать, но понятия не имел, как сделать.
Стивен
И не раньше, чем я начал! :-)
Неровный
s=0,h=0=> s=h=0Я верю
Стивен
1
Исправлено теперь после долгих потянув за волосы. Определение тай-брейка в тех случаях , когда рука одинакова и самые низкие символы в 1 - й и 2 - й крупнейших групп то же самое было киллер (33 байт или так только для этого !?) :-(
Неровный
x[v]=x[v]?++x[v]:1может стать x[v]=(x[v]|0)+1, экономя 3 байта.
Рик Хичкок
2

Python 2,7, 242 223 байта

from collections import*
s=sorted
f=lambda x,y:s(map(lambda h:(lambda (r,n):((3,1.5)if len(r)==5 and ord(r[0])+4==ord(r[4])else n,[-ord(d) for d in r],h))(zip(*s(Counter(h).items(),key=lambda z:(-z[1],z[0])))),(x,y)))[1][2]

Схожи в базовом понятии с примерами javascript (сортировка по силе руки, за исключением стритов; затем по рангу); но, пользуясь преимуществом collections.CounterК сожалению, .most_commonне совсем желаемое поведение; поэтому пришлось добавить пользовательский ключ сортировки.

Изменить: немного больше кода игры в гольф, чтобы сократить 19 байтов.

Код без гольфа

from collections import Counter

def convertHand(h):
    # first get item counts, appropriately ordered; e.g. cbabc -> (('b',2), ('c',2),('a',1))
    sortedPairs = sorted(Counter(h).items(),key=lambda x:(-x[1],x[0]))

    # 'unzip' the tuples to get (('b','c','a'), (2,2,1))
    ranks, numberFound = zip(*sortedPairs) 

    if len(ranks)==5:
        # no pairs; is it a straight? well, since they are in increasing order...
        if ord(ranks[0])+4 == ord(ranks[4]):
            # replace numberFound with something that will sort above 3 of a kind but below full house
            numberFound = (3,1.5)

    # invert the values of the ranks, so they are in decreasing, rather then increasing order
    ranks = [-ord(r) for r in ranks]

    # arrange tuples so we can sort by numberFound, and then ranks; and keep a reference to the hand
    return (numberFound, ranks, h)

# put it all together...
def f(x,y):
    hands = [convertHand(h) for h in (x,y)]
    rankedHands = sorted(hands)
    return rankedHands[1][2]
Час Браун
источник
1

Mathematica, 635 байт

H[x_]:=Block[{t},T=Sort@ToCharacterCode[x];L=Last/@Tally@T;t=0;S=Count;If[S[L,2]==1,t=1];If[S[L,2]==2,t=2];If[S[L,3]==1,t=3];If[S[Differences@T,1]==4,t=4];If[S[L,2]==1&&S[L,3]==1,t=5];If[S[L,4]==1,t=6];If[S[L,5]==1,t=7];t];F[K_,v_]:=First@Flatten@Cases[Tally@K,{_,v}];B=ToCharacterCode;(Z=Sort@B@#1;Y=Sort@B@#2;a=H[#1];b=H[#2];If[a>b,P@#1,If[a<b,P@#2]]If[a==b&&a==0,If[Z[[1]]<Y[[1]],P@#1,P@#2]];If[a==b&&(a==1||a==2),If[F[Z,2]<F[Y,2],P@#1,If[F[Z,2]==F[Y,2],If[F[Z,1]<F[Y,1],P@#1,P@#2],P@#2]]];If[a==b&&(a==3||a==5),If[F[Z,3]<F[Y,3],P@#1,P@#2]];If[a==b&&a==6,If[F[Z,4]<F[Y,4],P@#1,P@#2]];If[a==b&&(a==7||a==4),If[Tr@Z<Tr@Y,P@#1,P@#2]])&

,
,
Форма ввода

["abcde", "kkekk"]

J42161217
источник
Есть ли способ проверить это онлайн?
Осьминог
1
sandbox.open.wolframcloud.com/app/objects paste с помощью ctrl + v добавьте ввод в конец кода и запустите с помощью shift + enter
J42161217