Word Poker, kto wygrywa?

14

Dane wejściowe będą składały się z dwóch pięciu liter. W rzeczywistości nie muszą to być słowa słownikowe, tylko pięć liter, każda mała lub cała wielka, twój wybór. W słowach wejściowych pojawi się tylko AZ i zawsze będą one miały długość 5 znaków.

Twój program polega na zdobyciu ich obu tak, jakby to były ręce pokera, i uzyskanie wyższego układu. Oczywiście kolory nie będą tu obowiązywać, tylko rankingi, więc nie ma kolorów.

Typowy system rankingowy pokera to: „1 para”, „2 pary”, „3 w swoim rodzaju”, „strita”, „full house”, „4 w swoim rodzaju”, „5 w swoim rodzaju” i oczywiście istnieje możliwość, że ręka (lub słowo w tym przypadku) może być nic nie warta.

W przypadku remisów litery bliższe A są uważane za wyższe, więc para As bije parę Bs. W niektórych przypadkach obie ręce mogą być identyczne, ale w innej kolejności (lub nie), w takim przypadku wypisuje albo rękę, albo jej wersję.

Ta zewnętrzna strona zawiera informacje o tym, jak zidentyfikować zwycięzcę, a zwłaszcza dotyczy powiązań w ramach konkretnych rankingów, na wypadek, gdybyś nie był zaznajomiony z tym, jak zdobywać układy w pokerze.

W przypadku prostych : litery muszą przylegać do alfabetu i nie mogą się zawijać. Zatem „defgh” w dowolnej kolejności jest prostą, „xyzab” nie jest.

Przykłady, jak zdobyć jedną rękę:

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

Tak więc program faktycznie wygeneruje takie wyniki:

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

Kolejność liter zarówno na wejściu, jak i na wyjściu jest nieistotna, więc kolejność na wyjściu może być inna niż na wejściu, ale musi istnieć taki sam spis liter.

Wynik musi zawierać dokładnie pięć liter - nie więcej, nie mniej.

Obowiązują zwykłe zasady gry w codegolf. Najkrótszy kod wygrywa.

Ośmiornica
źródło

Odpowiedzi:

4

JavaScript ( 224 218 213 bajtów)

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)

Nie golfowany:

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
)

Po map()uruchomieniu n + zokreśla ranking rozdania:

wprowadź opis zdjęcia tutaj

(Możesz zrozumieć, dlaczego zainicjowałem wersję z3.5).

W przypadku remisu Object.keys(o).sort()służy do ustalenia ręki o wyższym rankingu.

Skrawek:

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

Rick Hitchcock
źródło
3

Galaretka ,  28 27 29  27 bajtów

+2, a następnie -2 napraw błąd, a następnie ponownie zagraj w golfa.

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

Monadyczny link zawierający listę „rozdań” i zwracający (jednego) zwycięzcę.

Działa dla wprowadzania wielkich lub LUB małych liter.
(... ale nie mieszane, w tym celu wstaw ostatnią linię za pomocą Œllub Œu).

Wypróbuj online! lub zobacz pakiet testowy .

W jaki sposób?

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)
Jonathan Allan
źródło
Tak cholernie krótko w porównaniu do tego, co robię w JS 0.o
Stephen
3
@StephenS Witamy w PPCG, gdzie tworzysz coś w jakimś języku innym niż golfowy, a następnie ktoś robi coś w Jelly, 05AB1E, Pyth, CJam itp., Który jest krótszy niż nazwa Twojego języka: I: P
HyperNeutrino
1
@StephenS - JS powinien konkurować z JS. Nie pozwól, aby języki gry w golfa zniechęcały Cię do przesyłania dobrze przemyślanych rozwiązań w innych językach!
Jonathan Allan
@JonathanAllan odstrasza mnie od wkładania zbyt wiele wysiłku w przemyślenie i wyodrębnienie problemu, który można rozwiązać za pomocą ~ 25 znaków, oto skrzypce, nad którą pracowałem - napisałem całą płytkę i żaden z faktycznego kodu
Stephen
To jest niesamowite, ale ostatnio dodałem testowy przypadek, którego nie można obliczyć, a konkretnie [„hhhij”, „hijkl”]. Myślę, że to z powodu sposobu, w jaki oceniasz strita jako [3,1,1,1,1]?
Ośmiornica
3

JavaScript ( 250 247 232 bajty)

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)

Nieprzeczytany kod i przypadki testowe w JSFiddle: https://jsfiddle.net/CookieJon/8yq8ow1b/

Zaoszczędziłem trochę bajtów dzięki @RickHitchcock. @StephenS & @Arnauld

Wyboisty
źródło
To właśnie starałem się zrobić, ale nie miałem pojęcia, jak to zrobić.
Stephen
Nie zrobiłem tego dopiero po rozpoczęciu! :-)
Wyboisty
s=0,h=0=> s=h=0Wierzę
Stephen
1
Naprawiono teraz po dużym pociągnięciu za włosy. Określenie remisu w przypadkach, gdy ręka jest taka sama ORAZ najniższe znaki w 1. i 2. największej grupie były takie same, to zabójca (dla tego 33 bajtów TYLKO !?) :-(
Wyboisty
x[v]=x[v]?++x[v]:1może stać x[v]=(x[v]|0)+1, oszczędzając 3 bajty.
Rick Hitchcock
2

Python 2.7, 242 223 bajty

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]

Podobne w podstawowej koncepcji do przykładów javascript (sortuj według siły ręki z wyjątkiem prostych, a następnie według rangi); ale korzystanie z collections.CounterNiestety .most_commonnie ma pożądanego zachowania; więc musiałem dodać niestandardowy klucz sortowania.

Edycja: trochę więcej golfa, aby skrócić 19 bajtów.

Kod bez golfa

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]
Chas Brown
źródło
1

Mathematica, 635 bajtów

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]])&

.
.
Formularz wejściowy

[„abcde”, „kkekk”]

J42161217
źródło
Czy istnieje sposób na przetestowanie tego online?
Ośmiornica
2
sandbox.open.wolframcloud.com/app/objects wklej za pomocą ctrl + v dodaj dane wejściowe na końcu kodu i uruchom za pomocą shift + enter
J42161217