Poker Kata, Siapa yang Menang?

13

Inputnya adalah dua kata lima huruf. Mereka sebenarnya tidak harus menjadi kata-kata kamus, hanya lima huruf, masing-masing huruf kecil atau huruf besar semua, pilihan Anda. Hanya AZ yang akan muncul dalam kata-kata input dan panjangnya akan selalu 5 karakter.

Program Anda adalah untuk menilai mereka berdua seolah-olah mereka tangan poker dan menghasilkan tangan yang lebih tinggi. Tentu saja setelan tidak akan berlaku di sini, hanya peringkat sehingga tidak ada flush.

Sistem peringkat poker khas berjalan: '1 pasang', '2 pasang', '3 dari jenis', 'lurus', 'rumah penuh', '4 dari jenis', '5 dari jenis', dan tentu saja ada kemungkinan tangan (atau kata dalam kasus ini) tidak bernilai apa-apa.

Dalam kasus ikatan , huruf lebih dekat ke A dianggap lebih tinggi, sehingga sepasang As mengalahkan sepasang B. Dalam beberapa kasus kedua tangan mungkin identik, tetapi dalam urutan yang berbeda (atau tidak), dalam hal ini keluaran baik tangan atau versi terpaksa.

Halaman eksternal ini berisi informasi tentang cara mengidentifikasi pemenang dan terutama membahas ikatan dalam peringkat tertentu, jika Anda tidak terbiasa dengan cara mencetak gol poker.

Dalam hal lurus : huruf-huruf harus bersebelahan dalam alfabet dan tidak diperbolehkan melilit. Jadi 'defgh' dalam urutan apa pun adalah lurus, 'xyzab' tidak.

Contoh cara mencetak satu tangan:

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

Jadi program ini benar-benar akan menghasilkan hasil seperti ini:

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

Urutan huruf dalam input dan output tidak relevan, sehingga urutan dalam output Anda dapat berbeda dari input, tetapi inventaris huruf yang sama harus ada.

Keluaran harus mengandung tepat lima huruf - tidak lebih, tidak kurang.

Aturan codegolf biasa berlaku. Kode terpendek menang.

Gurita
sumber

Jawaban:

4

JavaScript ( 224 218 213 byte)

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)

Tidak Disatukan:

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
)

Setelah map()berlari, n + ztentukan peringkat tangan:

masukkan deskripsi gambar di sini

(Anda bisa mengerti mengapa saya menginisialisasi zke 3.5.)

Dalam kasus dasi, Object.keys(o).sort()digunakan untuk menentukan peringkat tangan yang lebih tinggi.

Potongan:

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
sumber
3

Jelly ,  28 27 29  27 byte

+2 & kemudian -2 memperbaiki bug, lalu kembali bermain golf.

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

Tautan monadik yang mengambil daftar "tangan" dan mengembalikan (salah satu) pemenang.

Berfungsi untuk input huruf besar semua atau huruf besar semua.
(... tapi tidak tercampur, untuk itu tambahkan baris terakhir dengan Œlatau Œu).

Cobalah online! atau lihat test suite .

Bagaimana?

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
sumber
Sangat pendek dibandingkan dengan apa yang saya buat di JS 0.o
Stephen
3
@StephenS Selamat datang di PPCG, tempat Anda membuat sesuatu dalam bahasa non-golf dan kemudian seseorang membuat sesuatu dalam Jelly, 05AB1E, Pyth, CJam, dll yang lebih pendek dari nama bahasa Anda: I: P
HyperNeutrino
1
@StephenS - JS harus bersaing dengan JS. Jangan biarkan bahasa golf menghalangi Anda mengirimkan solusi yang dipikirkan dengan baik dalam bahasa lain!
Jonathan Allan
@ Jonathan Allan itu menghalangi saya dari menempatkan terlalu banyak upaya untuk terlalu banyak berpikir dan mengabstraksi masalah yang dapat diselesaikan dalam ~ 25 karakter, inilah biola yang sedang saya kerjakan - saya menulis semua pelat dan tidak ada kode yang sebenarnya
Stephen
Ini luar biasa, tetapi saya baru-baru ini menambahkan test case yang tidak dihitung, khususnya ["hhhij", "hijkl"]. Saya pikir itu karena cara Anda memberi peringkat lurus sebagai [3,1,1,1,1]?
Gurita
3

JavaScript ( 250 247 232 byte)

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)

Kode & uji kasus yang tidak digabungkan di JSFiddle: https://jsfiddle.net/CookieJon/8yq8ow1b/

Menyimpan beberapa byte dengan terima kasih kepada @RickHitchcock. @StephenS & @Arnauld

Bergelombang
sumber
Ini yang saya coba buat tapi tidak tahu bagaimana membuatnya.
Stephen
Saya juga tidak sampai setelah saya mulai! :-)
Bumpy
s=0,h=0=> s=h=0Saya percaya
Stephen
1
Diperbaiki sekarang setelah banyak mencabut rambut. Menentukan tie-breaker dalam kasus di mana tangan adalah sama DAN karakter terendah dalam kelompok terbesar 1 & 2 adalah sama adalah pembunuhnya (33 byte atau lebih HANYA untuk itu !?) :-(
Bumpy
x[v]=x[v]?++x[v]:1bisa menjadi x[v]=(x[v]|0)+1, menghemat 3 byte.
Rick Hitchcock
2

Python 2.7, 242 223 byte

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]

Mirip dalam konsep dasar dengan contoh javascript (urutkan berdasarkan kekuatan tangan dengan pengecualian untuk lurus; lalu menurut peringkat); tetapi mengambil keuntungan dari collections.CounterSayangnya, .most_commontidak memiliki perilaku yang diinginkan; jadi harus menambahkan kunci pengurutan khusus.

Sunting: sedikit lebih banyak kode golf untuk mengurangi 19 byte.

Batalkan kode golf

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
sumber
1

Mathematica, 635 byte

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

.
.
Formulir input

["abcde", "kkekk"]

J42161217
sumber
Apakah ada cara untuk menguji ini secara online?
Octopus
1
sandbox.open.wolframcloud.com/app/objects tempel dengan ctrl + v tambahkan input di akhir kode dan jalankan dengan shift + enter
J42161217