Bir poker elindeki son kartı seçin


31

Poker elleri şu şekilde en iyiden en kötüye doğru sıralanır:

  1. Düz gömme - aynı sırayla beş sıralı kart
  2. Dörtlü - aynı değerde dört kart ve başka bir değerde bir kart
  3. Full ev - bir rütbe üç kart ve iki rütbe kart
  4. Flush - aynı takımdan beş kart
  5. Düz - beş sıralı kart
  6. Üçlü - aynı değerde üç kart ve iki değerde iki kart
  7. İki çift - aynı değerde iki kart, başka bir değerde iki kart ve üçüncü bir değerde bir kart
  8. Bir çift - aynı değerde iki kart ve diğer üç değerde üç kart
  9. Yüksek kart - sıralı veya aynı takımdan olmayan ve hiçbiri aynı sıralamada olmayan beş kart

  • Sıra = Karttaki sayı (A, K, Q, J, 10, 9, 8, 7, 6, 5, 4, 3, 2). 10 yerine T kullanmayı seçebilirsiniz.
  • Kıyafet = kalpler (h), maça (lar), kulüpler (c) ve elmaslar (d).

As, Ahem en yüksek hem de en düşük sayı olabilir (1 veya 14).

Bir kart iki harfle As(maça ası), Jc(kulüplerin Jack'i), 7h(kalplerin 7'si) vb. İle tanımlanabilir.


Meydan okuma:

Dağıtıcıdan dört kart alırsınız (dört giriş dizesi). Alabileceğiniz en son kartı bulun ve çıkarın.

Eşit derecede iyi kartlar varsa, hangisini seçeceğinizi seçebilirsiniz.

Giriş ve çıkış biçimleri isteğe bağlıdır, ancak bireysel kartları yukarıda gösterildiği gibi tespit edilmelidir Jcve 2h.


Test durumları:

Ah Kh Jh 10h
Qh

7d 8h 10c Jd
9d (or 9h, 9c, 9s)

Js 6c 10s 8h
Jc (or Jh, Jd)

Ac 4c 5d 3d
2h (or 2d, 2c, 2s)

5s 9s Js As
Ks

2h 3h 4h 5h
6h

Js Jc Ac Ah
As (or Ad)  <- Note that AAAJJ is better than AAJJJ because A is higher than J

10d 9d 5h 9c
9h (or 9s)

Ah Ac Ad As
Ks (or Kd, Kh, Kc)

4d 5h 8c Jd
Jc (or Js, Jh)

Bu kod golf, bu yüzden bayt cinsinden en kısa gönderim kazanıyor.

Yanıtlar:


13

Pyth, 73 bayt

eo_S+*-5l@\AN}SPMJ+NZSM.:+\AT5+-4l{eMJlM.gPkJ-sM*=T+`M}2Tc4"JQKA""hscd"=Zc

Bu oldukça korkunç. Kartları ayrıştırmak, değerleri sıralamak, ... Her şey çok fazla karakter alıyor. Ancak yaklaşım ilginç.

Çevrimiçi deneyin: Gösteri veya Test Paketi

Açıklama:

52 kartın tümünü üretiyorum, girişin dört kartını çıkartıyorum, her kart için bir puan üretiyorum (elin puanı) ve kartı maksimum puanla basıyorum.

Skor biraz garip. Tamamen farklı iki elin skorunu karşılaştırırsam, yanlış galibi seçebilir. Örneğin, bir düz 4 as atardı. Ancak, ilk 4 kart her iki elinde de aynıysa çalışır. Ve hesaplanan puanım aslında bir değer değil, bir değerler listesidir:

  • G: Öncelikle 5 kartı rütbelere göre gruplandırıyorum ve uzunluklarını aldım: 5h 5d 6c 5s Jd -> [3, 1, 1]
  • F: Sonra bu listeye 4 eksi farklı süit ekledim. Flush -> 3eklenir, not flush -> 2/1/0eklenir.
  • S: Başka bir numara ekle. 0düz 4değilse, düzse A2345veya 5daha yüksek bir düzse.

Bu 4-7 sayılar listesi azalan düzende sıralanır ve azami değere sahip liste seçilir.

Bu neden işe yarıyor? Burada her tür için olası yapılandırmaları görüyorsunuz. Sayıların yanındaki harf, size bu sayının hangi kuralla üretildiğini söyler.

  • Düz floş: [5S, 3F, 1G, 1G, 1G, 1G, 1G]veya[4S, 3F, 1G, 1G, 1G, 1G, 1G]
  • Bir tür dört: [4G, 1G, 0F, 0S]
  • Tam ev: [3G, 2G, 1F, 0S]veya[3G, 2G, 0F, 0S]
  • Flush: [3F, 1G, 1G, 1G, 1G, 1G, 0S]
  • Düz: [5S, 2F, 1G, 1G, 1G, 1G, 1G], [5S, 1F, 1G, 1G, 1G, 1G, 1G], [5S, 1G, 1G, 1G, 1G, 1G, 0F], [4S, 2F, 1G, 1G, 1G, 1G, 1G], [4S, 1F, 1G, 1G, 1G, 1G, 1G],[4S, 1G, 1G, 1G, 1G, 1G, 0F]
  • Üçlü: [3G, 1G, 1G, 1F, 0S],[3G, 1G, 1G, 0F, 0S]
  • İki çift: [2G, 2G, 2F, 1G, 0S], [2G, 2G, 1F, 1G, 0S],[2G, 2G, 1G, 0F, 0S]
  • Bir çift: [2G, 2F, 1G, 1G, 1G, 0S], [2G, 1G, 1G, 1G, 1F, 0S],[2G, 1G, 1G, 1G, 0F, 0S]
  • Yüksek kart: [2F, 1G, 1G, 1G, 1G, 1G, 0S], [1F, 1G, 1G, 1G, 1G, 1G, 0S],[1G, 1G, 1G, 1G, 1G, 0S, 0F]

Pyth, element-wise listelerini karşılaştırır. Bu nedenle, Düz bir sifonun her zaman bir tür Dört'ü yeneceği açıktır. Tipik poker kurallarının çoğu bu listelerde açıktır. Bazıları çelişkili görünüyor.

  • Dümdüz bir dördü veya bir Dolu evin karşısında bir Kazanç kazanır: Sorun değil. Dördüncü bir tür / Full evin nehir kartına sahip olma şansına sahipseniz, aynı anda dümdüz bir şekilde gidemezsiniz (zaten elinizde 2 veya 3 farklı süitiniz olduğundan).
  • Düz bir floşa karşı kazanır. Nehir kartıyla aynı hizada ve dümdüz bir ulaşabiliyorsanız, aynı zamanda dümdüz bir floş yapabilirsiniz. Düz floş hem düz hem de floştan daha iyi bir skora sahiptir.
  • Bir çift [2G, 2F, 1G, 1G, 1G, 0S], iki çift eline karşı kazanır. Ayrıca sorun yok. Nehir kartıyla iki çift alırsanız, nehirden en az bir çift aldığınızdan. Ancak bu, üç türden daha iyi olabileceğiniz anlamına gelir. Yani iki çift aslında cevap asla olmayacak.
  • Yüksek kart [2F, 1G, 1G, 1G, 1G, 1G, 0S]bazı çift ellere karşı kazanır. Eğer elde edebileceğiniz en iyi puan bu ise, nehirden önce bir takım 3 kart ve bir takım farklı bir kartınız olacak. Ancak o zaman bu iki süitten birine ve daha önce görünen bir değere sahip olan kartı seçebilirsiniz [2F, 2G, ...].

Yani bu, doğru çözüm türünü seçer. Ama en iyi çifti nasıl bulabilirim (4 olasılıktan), en iyisini nasıl seçerim? Çünkü iki farklı bir çift çözüm aynı puana sahip olabilir.

Bu kolay. Pyth, sabit sıralama yapılmasını garanti eder (en fazla çekerken). Bu yüzden basit sırayla kartları oluşturmak 2h 2s 2c 2d 3h 3s ... Ad. Böylece en yüksek değerli kart otomatik olarak maksimum olur.

Uygulama ayrıntıları

=ZcGiriş dizesini böler ve kartların listesini içinde saklar Z. =T+`M}2Tc4"JQKA"rütbe listesini oluşturur ['2', ..., '10', 'J', 'Q', 'K', 'A']ve bunları saklar T. -sM*T..."hscd"Zrütbenin her birleşimini süitler ile oluşturur ve kartlarını kaldırır Z.

o...kalan kartları şu lM.gPkJşekilde sıralar : sıra gruplarının uzunluğu, +-4l{eMJlM4 uzunluk ekler (süitler), +*-5l@\AN}SPMJ+NZSM.:+\AT5süite bağlı olarak 0/4/5 ekler ("A" + T uzunluğunun her alt dizesini oluşturur, elin olup olmadığını kontrol et bunlardan biri (elin sıralanması ve tüm alt grupların sıralanması gerekir), karttaki 5 - "A" sayısı ile çarpın), _Sliste azalmasını sıralar.

e maksimumu seçin ve yazdırın.


2
Çok yaratıcı ve harika bir açıklama!
Greg Martin,

4

JavaScript (ES6), 329 324 317 312 309 bayt

H=>[..."cdhs"].map(Y=>[...L="AKQJT98765432"].map(X=>~H.indexOf(X+=Y)||([...H,X].map(([R,S])=>a|=eval(S+'|=1<<L.search(R)',F|=S!=H[0][1]),F=a=c=d=h=s=0),x=c|d,y=h|s,c&=d,h&=s,p=c|x&y|h,t=c&y|h&x,(S=a-7681?((j=a/31)&-j)-j?F?c&h?2e4+a:t?t^p?3e4+t:7e4:p?8e4+p:M:4e4+a:F?5e4+a:a:F?6e4:1e4)<M&&(R=X,M=S))),M=1/0)&&R

Nasıl çalışır

Destedeki kalan her kart için bir el puanı hesaplarız S. Puan ne kadar düşükse, el o kadar iyidir.

Skoru hesaplamak için kullanılan değişkenler

  • F: el floş ise sahte
  • c: Kulüplerin bit maskesi
  • d: Elmas bit maskesi
  • h: Hearts bitmask
  • s: Maça bit maskesi
  • x = c | d: Kulüplerin VEYA Elmasların bit maskesi
  • y = h | s: Hearts VEYA Maça bit maskesi
  • a: tüm kombine takımların bit maskesi
  • p = c & d | x & y | h & s: çift bit maskesi (1)
  • t = c & d & y | h & s & x: üçlü bir bit maskesi (1)

(1) Bu formülleri birkaç yıl önce yazdım ve birkaç poker motorunda kullandım. Çalışıyorlar. :-)

Diğer formüller

  • c & d & h & s: dört tür bir bit maskesi
  • a == 7681: özel düzlem için test "A, 2, 3, 4, 5" (0b1111000000001)
  • ((j = a / 31) & -j) == j: tüm diğer sertlikleri test et

Puan tablosu

Value    | Hand
---------+--------------------------------------------
0   + a  | Standard Straight Flush
1e4      | Special Straight Flush "A, 2, 3, 4, 5"
2e4 + a  | Four of a Kind
3e4 + t  | Full House
4e4 + a  | Flush
5e4 + a  | Standard Straight
6e4      | Special Straight "A, 2, 3, 4, 5"
7e4      | Three of a Kind
8e4 + p  | Pair
Max.     | Everything else

Not: En iyi seçeneğimiz olamayacak olan İkili Çift ile ilgilenmek zorunda değiliz. (Zaten bir çiftimiz varsa, onu Üçlü Bire Dönüştürebiliriz. Ve zaten iki çiftimiz varsa, onları Tam Ev haline getirebiliriz.)

Test durumları


3

JavaScript (ES6), 307 349

Bu oldukça hantal ve en iyi yaklaşım olduğundan emin değilim. Belki de biraz golf oynayabilir.

h=>(r='_23456789TJQKAT',R=x=>r.search(x[0]),M=i=>[...'hcds'].some(s=>h.indexOf(j=h[i][0]+s)<0)&&j,[u,v,w,y]=h.sort((a,b)=>R(a)-R(b)).map(x=>R(x)),[,,d,e,f,g,k]=[...new Set(h+h)].sort(),q=10-u-v-w,s=(z=y>12)&q>0?q:y-u<5&&u*5+q-y,d>r?z?'Kh':'Ah':f>r?M((e>r?v<w:u<v)+1):s?r[s]+g:k?M(3):r[13-z-(w>11)-(v>10)]+g)

Daha az golf oynadı

h=>(
  // card rank, 1 to 13, 0 unused
  // fake rank 14 is T, to complete a straight JQKA?
  // as I always try to complete a straight going up
  r = '_23456789TJQKAT', 

  // R: rank a card
  R = x => r.search(x[0]),  

  // M: find a missing card (to complete a same-rank set like a poker)
  // look for a card with the same rank of the card at position i
  // but with a suit not present in the hand
  M = i => [...'hcds'].some(s => h.indexOf(j=h[i][0]+s) < 0) && j,
  h.sort((a, b) => R(a)-R(b) ), // sort hand by rank
  [u,v,w,y] = h.map(x=>R(x)),   // rank of cards 0..3 in u,v,w,y

  // Purpose: look for duplicate rank and/or duplicate suits
  // Put values and suits in d,e,f,g,k, with no duplicates and sorted
  // suits are lowercase and will be at right end
  [,,d,e,f,g,k] = [...new Set(h+h)].sort(),

  // Only if all ranks are different: find the missing value to get a straight
  // or 0 if a straight cannot be obtained
  // The first part manages the A before a 2
  q = 10-u-v-w, s = y>12&q>0 ? q : y - u < 5 && u * 5 + q - y,

  d > r // d is lowercase -> all cards have the same rank
    ? u < 13 ? 'Ah' : 'Kh' // add a K to a poker of A, else add an A
    : e > r // e is lowercase -> 2 distinct ranks
      ? M(v<w ? 2 : 1) // go for a poker or a full house
      : f > r // f is lowercase -> 3 distinct ranks, we have a pair
        ? M(u<v ? 2 : 1) // find the pair and go for 3 of a kind
        : s // all different ranks, could it become a straight?
          ? r[s] + g // if there is only a suit, it will be a flush straight too
          : k // if there are 2 or more different suits
            ? M(3) // go for a pair with the max rank
            : r[13-(y>12)-(w>11)-(v>10)]+g // flush, find the max missing card
)

Ölçek

F=
h=>(r='_23456789TJQKAT',R=x=>r.search(x[0]),M=i=>[...'hcds'].some(s=>h.indexOf(j=h[i][0]+s)<0)&&j,[u,v,w,y]=h.sort((a,b)=>R(a)-R(b)).map(x=>R(x)),[,,d,e,f,g,k]=[...new Set(h+h)].sort(),q=10-u-v-w,s=(z=y>12)&q>0?q:y-u<5&&u*5+q-y,d>r?z?'Kh':'Ah':f>r?M((e>r?v<w:u<v)+1):s?r[s]+g:k?M(3):r[13-z-(w>11)-(v>10)]+g)

output=x=>O.textContent+=x+'\n'

;`Ah Kh Jh Th -> Qh
7d 8h Tc Jd -> 9d 9h 9c 9s
Js 6c Ts 8h -> Jc Jh Jd
Ac 4c 5d 3d -> 2h 2d 2c 2s
5s 9s Js As -> Ks
2h 3h 4h 5h -> 6h
Js Jc Ac Ah -> As Ad
Td 9d 5h 9c -> 9h 9s
Ah Ac Ad As -> Ks Kd Kh Kc
4d 5h 8c Jd -> Jc Js Jh`
.split('\n')
.forEach(s=>{
  var o = s.match(/\w+/g) // input and output
  var h = o.splice(0,4) // input in h, output in o
  var hs = h+''
  var r = F(h)
  var ok = o.some(x => x==r)
  
  output((ok?'OK ':'KO ')+ hs + ' -> ' + r)
})
<pre id=O></pre>


Her iki yaklaşımımızın da benzer boyutlara yaklaştığını görmek komik. :-) Performans bilge, yine de kesinlikle daha hızlısın.
Arnauld,

@Arna bazı 4 bayt daha tıraş etmeyi başardım. Sıra sende
edc65
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.