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


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.