워드 포커, 누가 이기는가?


14

입력은 2 개의 5 글자 단어입니다. 그것들은 실제로 사전 단어 일 필요는 없으며, 각각 다섯 글자, 모두 소문자 또는 모두 대문자, 당신의 선택입니다. 입력 단어에는 AZ 만 표시되며 길이는 항상 5 자입니다.

당신의 프로그램은 포커 핸드 인 것처럼 점수를 매기고 더 높은 핸드를 출력하는 것입니다. 물론 소송은 여기에 적용되지 않고 순위 만 적용되므로 플러시가 없습니다.

일반적인 포커 순위 시스템은 '1 pair', '2 pairs', '3 of a kind', 'straight', 'full house', '4 of a kind', '5 of a kind'및 물론입니다. 손 (또는이 경우 단어)은 아무 가치가 없을 가능성이 있습니다.

관계의 경우 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 글자가 포함되어야합니다.

일반적인 코드 골프 규칙이 적용됩니다. 가장 짧은 코드가 승리합니다.

답변:


4

자바 스크립트 ( 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
ÇÞṪ

"손"목록을 가져 와서 승자 중 하나를 반환하는 모나드 링크.

모두 대문자 또는 모두 소문자 입력에 작동합니다.
(...하지만 그 앞에 추가로 최종 라인, 혼합되지 Œ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에서 만든 것과 비교할 때 너무 짧습니다.
Stephen

3
@StephenS PPCG에 오신 것을 환영합니다. 여기서 골프가 아닌 언어로 무언가를 만들고 누군가가 당신의 언어 이름보다 짧은 Jelly, 05AB1E, Pyth, CJam 등으로 무언가를 만듭니다 : I : P
HyperNeutrino

1
@StephenS-JS는 JS와 경쟁해야합니다. 골프 언어가 다른 언어로 된 솔루션을 제출하는 것을 방해하지 않도록하십시오!
Jonathan Allan

@JonathanAllan 그것은 ~ 25 자로 해결할 수있는 문제를 지나치게 생각하고 추상화하는데 너무 많은 노력을 기울이지 않도록 막아줍니다. 여기에 제가 작업 했던 바이올린이 있습니다. 나는 모든 상용구를 작성했고 실제 코드는 작성하지 않았습니다.
Stephen

이것은 대단하지만 최근에 계산되지 않는 테스트 케이스, 특히 [ "hhhij", "hijkl"]를 추가했습니다. 나는 그것이 당신이 [3,1,1,1,1]으로 똑바로 순위를 매기는 방식 때문이라고 생각합니까?
Octopus

3

자바 스크립트 ( 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의 Ungolfed 코드 및 테스트 사례 : https://jsfiddle.net/CookieJon/8yq8ow1b/

@RickHitchcock 덕분에 바이트를 절약했습니다. @StephenS & @Arnauld


이것은 내가 만들려고했지만 만드는 방법에 대한 단서가 없었습니다.
Stephen

내가 시작하기 전까지는 나도 아니었다! :-)
Bumpy

s=0,h=0=> s=h=0나는 믿는다
Stephen

1
많은 머리카락을 끈 후에 고쳤습니다. 손이 같고 1, 2 위 그룹에서 가장 낮은 문자가 같은 경우 타이 브레이커 결정 킬러 (33 바이트 정도)!
Bumpy

x[v]=x[v]?++x[v]:1x[v]=(x[v]|0)+13 바이트를 절약 할 수 있습니다 .
Rick Hitchcock

2

파이썬 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]

기본 개념에서 자바 스크립트 예제와 유사합니다 (직선을 제외하고 손으로 강도를 정렬 한 다음 순위별로 정렬). 그러나 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

매스 매 티카, 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"]


이것을 온라인으로 테스트하는 방법이 있습니까?
Octopus

2
ctrl + v를 사용한 sandbox.open.wolframcloud.com/app/objects paste는 코드 끝에 입력을 추가하고 shift + enter로 실행
J42161217
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.