Word Poker、誰が勝つか?


13

入力は2つの5文字の単語になります。それらは実際には辞書の単語である必要はなく、それぞれ5文字だけで、すべて小文字またはすべて大文字で選択できます。入力ワードには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

入力と出力の両方の文字の順序は無関係であるため、出力の順序は入力と異なる場合がありますが、同じ文字のインベントリが存在する必要があります。

出力には、正確に5文字が含まれている必要があります。

通常の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)

ゴルフをしていない:

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、ハンドのランキングを決定します。

ここに画像の説明を入力してください

(私がz3.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
ÇÞṪ

「ハンド」のリストを取り、勝者(の1つ)を返すモナドリンク。

すべて大文字またはすべて小文字の入力で機能します。
(...最後の行の先頭にŒ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へようこそ。ここでは、ゴルフ以外の言語で何かを作成してから、ゼリー、05AB1E、Pyth、CJamなどで、あなたの言語名よりも短いものを作成します
。I

1
@StephenS-JSはJSと競合する必要があります。ゴルフ言語が他の言語でよく考えられた解決策を提出することを思いとどまらせないでください!
ジョナサンアラン

それはoverthinkingと〜25文字で解くことができる問題を抽象化にあまり力を入れてから私を抑止@JonathanAllan、ここフィドルだ、私が上で働いていた-私はすべての定型と実際のコードのどれを書いた
スティーブン

これは素晴らしいですが、最近["hhhij"、 "hijkl"]を計算しないテストケースを最近追加しました。ストレートを[3,1,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バイトかそこらのためだけ!!):
Bumpy

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"]


これをオンラインでテストする方法はありますか?
タコ

1
sandbox.open.wolframcloud.com/app/objects ctrl + vで貼り付け、コードの最後に入力を追加し、shift + enterで実行します
J42161217
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.