Назвіть руку покеру - видання 7 карт


11

Змагання:

У цьому запитанні: Назвіть руку покеру, яку вам довелося взяти в покер на п’ять картках, і визначте її. Це питання схоже з двома поворотами:

По-перше, вихід буде в усіх нижчих регістрах. Це дозволяє отримати більше гольфу, оскільки вам не доведеться турбуватися про капіталізацію flushтаstraight

high card
one pair
two pair
three of a kind
straight
flush
full house
four of a kind
straight flush
royal flush

По-друге, маючи популярність Техаського Холдему та 7 карт-студ, ми, тут, за кодом гольфу, повинні мати змогу забити сім- покерну руку, я прав? Забиваючи сім карт вручну, використовуйте п’ять найкращих карт для своєї руки і ігноруйте дві, які вам не потрібні.

Довідка:

Список рук у покер: http://en.wikipedia.org/wiki/List_of_poker_hands

Введення (підняте безпосередньо з попереднього потоку)

7 карток з аргументів stdin або командного рядка. Картка - це два букви на формі RS, де R - ранг, а S - масть. В рядах є 2- 9(номер картки), T(десять), J(Jack), Q(Queen), K(король), A(Ace). У костюми є S, D, H, Cдля лопати, бубни, черви і клубів відповідно.

Приклад карт

5H - five of hearts
TS - ten of spades
AD - ace of diamonds

Приклад введення => бажаний вихід

3H 5D JS 3C 7C AH QS => one pair
JH 4C 2C 9S 4H JD 2H => two pair
7H 3S 7S 7D AC QH 7C => four of a kind
8C 3H 8S 8H 3S 2C 5D => full house
AS KC KD KH QH TS JC => straight

Зауважте, у другому прикладі є насправді три пари, але ви можете використовувати лише п’ять карток, так що це two pair. У п’ятому прикладі є і а, three of a kindі straightможливі, але straightкраще, тому виведіть straight.

Оцінка балів

Це , тому найкоротший код виграє!

Еррата

  1. Ви не можете використовувати зовнішні ресурси.
  2. Туз - як високий, так і низький для прямих.

Ніцца; Я таємно сподівався, що хтось підбере м’яч. Просто хотів зазначити, що в оригінальному питанні (уточненому в коментарі) у мене не було жодних обмежень щодо використання великих літер, тому ви могли (і більшість / усе це зробили) вивести "Straight Flush". IMHO з великої літери виглядає краще.
daniero

Ви кажете ввести (підняті безпосередньо з попереднього потоку) 5 карт. Я думаю, ти мав намір змінити це на 7.
Рівень річки Св.

@steveverrill Ви можете самостійно редагувати публікації під час обміну стеками. Хоча я зробив це для вас тут
durron597

Чи дозволяються зовнішні ресурси? Існують таблиці пошуку, які дозволять вам просто шукати кожну карту в руці і отримувати силу рук.
Кендалл Фрей

Чи може туз бути низьким і високим для прямих?
Нік Т

Відповіді:


4

Рубін 353

Це ґрунтувалося на відповіді Хрона від початкового запитання.

Це сприймає дані як аргументи командного рядка. В основному ми просто перебираємо всі комбінації розміром 5, щоб отримати тип руки. Кожен тип руки був змінений так, що починається з числа. ("Королівський флеш" -> "0royal 4flush", "high card" -> "9high card"). Це дозволяє нам сортувати рядки, які були повернуті. Перший рядок після сортування - найкращий можливий хід. Тож ми друкуємо це після вилучення всіх рядків з рядка.

o,p=%w(4flush 1straight)
f=/1{5}|1{4}0+1$/
puts $*.combination(5).map{|z|s=[0]*13;Hash[*z.map{|c|s['23456789TJQKA'.index c[0]]+=1;c[1]}.uniq[1]?[f,'5'+p,?4,'2four'+a=' of a kind',/3.*2|2.*3/,'3full house',?3,'6three'+a,/2.*2/,'7two pair',?2,'8one pair',0,'9high card']:[/1{5}$/,'0royal '+o,f,p+' '+o,0,o]].find{|r,y|s.join[r]}[1]}.sort[0].gsub(/\d/,'')

Приємно. Gsub в кінці може бути просто суб-прав?
bazzargh

@bazzargh ні, не потрібно видаляти всі номери. Код об'єднує 4flush з 1straight або 0royal, щоб отримати "0royal 4 flush" або "1straight 4flush". Якщо ми використовуємо лише підпункт, 4 не буде видалено.
FDinoff

Дає неправильний результат для AS QS JS TS 9S 5H 5D. Це коштуватиме вам персонажа!

@ WumpusQ.Wumbley Хм, здається, це помилка в початковому коді. Я спробую з’ясувати, у чому проблема пізніше.
FDinoff

5

Haskell 618 603 598 525 512 504 480 464

Картки, взяті як рядок введення. Я думаю, що я переграв це до гольфу, але легко будете побитий рубіном тощо, використовуючи той самий трюк: якщо ви генеруєте всі перестановки, ви отримуєте вперед типи, на які хочете шукати прямі, плюс зворотні види, які ви хочете для тестування N свого роду.

import Data.List
m=map
z=take 5
q=m(\x->head[n|(f,n)<-zip"A23456789TJQK"[1..],f==x!!0])
l=m length
v=" of a kind"
w="flush"
y="straight"
c f s p r|f&&r="9royal "++w|f&&s='8':y++" "++w|f='5':w|s||r='4':y|True=case p of 4:_->"7four"++v;3:2:_->"6full house";3:_->"3three"++v;2:2:_->"2two pair";2:_->"1one pair";_->"0high card"
d x=c([5]==l(group$m(!!1)x))(q x==z[head(q x)..])(l$group$q x)$q x==1:[10..13]
k h=tail$maximum$m(d.z)$permutations$words h
main=interact k

Відредагований, щоб вбудувати "пару" та використовувати числові префікси після перегляду запису @ FDinoff, також склав функції карти для гоління ще одного знака.


Ви можете врятувати собі пару символів (приблизно 5 я думаю), якщо ви позбудетесь від u. "one pair","two pair"тоді коротшеu=" pair" ... "one"++u,"two++u
FDinoff

Так, я щойно змінив цю інформацію, прочитавши ваш код. Також техніка префіксу чисел врятує мене ще 5
1414

2

C ++, 622 553 символів

чотири непотрібні нові рядки, додані нижче для наочності.

#include"stdafx.h"
#include"string"
std::string c=" flush",d=" of a kind",e="straight",z[10]={"high card","one pair","two pair","three"+d,e,c,"full house","four"+d,e+c,"royal"+c},
x="CDHSA23456789TJQK";char h[99];int main(){__int64 f,p,t,g,u,v,w,l=1,a=78517370881,b=a+19173960,i,j,q=0;gets_s(h,99);for(i=28;i-->7;){f=p=0;
for(j=7;j--;)if(j!=i%7&j!=(i+i/7)%7){f+=l<<x.find(h[j*3+1])*6;p+=l<<x.find(h[j*3])*3-12;}
v=p&b*2;u=v&v-1;w=p&p/2;g=p*64&p*8&p&p/8&p/64;f&=f*4;t=f&&p==a?9:f&&g?8:p&b*4?7:u&&w?6:f?5:g||p==a?4:w?3:u?2:v?1:0;
q=t>q?t:q;}puts(z[q].c_str());}

Все змінилося у версії для гольфу:

Rev 1: Змінено всі числові змінні на __int64для одного оголошення.

Ред. 1: Приріст для гольфу та стан forпетель

Ред. 0: Змінені восьмеричні константи на десяткові.

Rev 0: Змінено ifоператори на завдання з умовним оператором. Rev 1: Переставлене далі в єдиний вираз для t. Для цього потрібна нова змінна vдля одного з проміжних значень

Rev 0: Видалений багатослівний вихід. Виводить лише найкращу загальну руку.

Rev 0: Увімкнено стискання вихідного тексту (складно на C, оскільки ви не можете об'єднати рядки за допомогою оператора +.) Написання "flush" лише один раз врятувало мене 12 символів, але коштувало мені 15, що зробило мені 3 символи гіршими від загальної кількості. Тому я просто написав це 3 рази замість цього. Версія 1: використовується std::stringзамість того, char[]як запропонував FDinoff, що дає змогу об'єднатися з +.

Невикористана версія, 714 символів, що не мають коментованого простору.

Проведіть всі 21 можливі руки, які можна зробити з 7 карт, і кожен раз відхиляє 2 картки. Костюм і ранг п'яти обраних карток підсумовуються змінними f і p з різною восьмигранною цифрою для кожного костюма / звання. Для визначення типу руки виконуються різні бітові операції, які потім зберігаються в t (усі 21 можливості виводяться у версії без вогків.) Нарешті, виводиться найкраща можлива рука.

#include "stdafx.h"
#include "string.h"

char x[] = "CDHSA23456789TJQK", h[99], z[10][99] = 
{ "high card", "one pair", "two pair","three of a kind", "straight","flush","full house","four of a kind","straight","royal" };

int main(void)
{
        int i,j,q=0;                  //i,j:loop counters. q:best possible hand of 7 card   
        scanf_s("%s/n", &h, 99); getchar();
        for (i = 7; i < 28; i++){

          //f,p: count number of cards of each suit (2 octal digits) and rank (1 octal digit.)
          //t: best hand for current 5 cards. g:straight flag. u,w: flags for pairs and 3's.   
          //l: constant 1 (64bit leftshift doesn't work on a literal.) 
          //octal bitmasks: a=ace high straight, b=general purpose

            __int64 f=0,p=0,t=0,g,u,w,l=1,a=01111000000001,b=a+0111111110;

           for (j = 0; j < 7; j++){
               if (j != i %7 & j != (i+i/7) %7){

                   f += l << (strchr(x,h[j*3+1])-x)*6;
                   p += l << (strchr(x,h[j*3])-x-4)*3;

                   printf_s("%c%c ",h[j*3], h[j*3+1]);
               }
           }

           w=p&b*2;                          //if 2nd bit set we have a pair
           if (w) t=1;
           u= w & w-1;                       //if there is only one pair w&w-1 evaluates to 0; +ve for 2 pair.
           if (u) t=2;
           w = p & p/2;                      // if 2nd and 1st bit set we have 3 of kind. 
           if (w) t=3;
           g = p*64 & p*8 & p & p/8 & p/64;  // detects all straights except ace high. pattern for ace high in a.
           if (g||p==a) t=4;
           f&=f*4;                           //for a flush we want 5 cards of the same suit, binary 101
           if (f) t=5;
           if (u&&w) t=6;                    //full house meets conditions of 2 pair and 3 of kind
           if (p & b*4) t=7;                 //four of a kind
           if (f && g) t=8;                  //straight flush
           if (f && p==a) t=9;               //royal flush
           printf_s("%s %s \n",z[t],t>7?z[5]:"");
           q=t>q?t:q;
        }   
        printf_s("%s %s",z[q],q>7?z[5]:"");
        getchar();
}

Невикольований вихід

введіть тут опис зображення


Оскільки ви кажете, що використовуєте c ++, ви можете використовувати, <string>що підтримує + для об'єднання рядків. Що означає, що ви, ймовірно, могли б використовувати <iostream>та використовувати. coutОднак я насправді не знаю, чи хтось із них призведе до меншої кількості символів.
FDinoff

@FDinoff, що я міг би заощадити: " pair flush flush straight of a kind"= 35 символів. Після того, як #includeзаощадження будуть мінімальними, вам доведеться розглянути додаткові ",=+та декларації констант. Крім того, я новачок у C ++ і борюся з налаштуваннями IDE та компілятора (це змушує мене використовувати, scanf_sа printf_sзамість старих "небезпечних" версій, а допомога щодо її виправлення обходить кола.) coutМоже допомогти трохи, це на моєму список справ, але, ймовірно, для іншої програми. Що вбиває coutдля мене те, що using namespace stdя не знаю, чи є спосіб уникнути написання всього цього.
Річка Рівня Св.

Ви майже ніколи не потребуєте printf та scanf, оскільки використовуєте c ++. Є й інші (безпечніше) робити те саме. Ви можете використовувати, std::coutщоб обійтиusing namespace std
FDinoff

@FDinoff thx для підказки. В останньому редагуванні я зберег 18 байт з різною обробкою рядків: gets_s& puts, плюс std::stringдля об'єднання, а значить, я повинен перетворити char*на вихід. Гольф, який я опублікував, працює з просто stringчи просто iostream.Bizarrely, я повинен включати обидва для використання <<>>операторів із cin/cout& std::strings. Загалом, використання обох #includes виходить на 5 байт гірше, хоча я можу оголосити hяк std::stringі уникати окремої charдекларації. Передбачувано я не можу знайти перелік того, що namespace stdдопомагає (або пояснення щодо оператора.)
Level River St

@FDinoff Я погоджуюся, я б зазвичай не використовував scanfі gets, за винятком гольфу, де програми в будь-якому разі є досить небезпечними. Я міг би скоротити на 5 байт, -s,99якщо міг використовувати getsзамість gets_s, але компілятор не можу мені дозволити. Що мене дивує - наскільки небезпечні C / C ++ взагалі! Кілька тижнів тому це б шокувало мене, коли я виявив, що _int64 x=1<<yдає неправильну відповідь на y більше 31 року. Але зараз я просто м'яко роздратований. Побачивши речі з підписками масиву, що виходять за межі без повідомлення про помилку, я звик до цього. Чи є якийсь спосіб покращити перевірку?
Річка Рівня Св.

2

perl (> = 5,14), 411 403 400 397 400

Редагувати : вкладений суб, який називався лише один раз, заощадивши 8 символів.
Редагування 2 : вилучено .""те, що залишилося з ранньої спроби
Правка 3 : замість тимчасової змінної, яка зберігає оригінал $_, використовуйте її, щоб зробити її непотрібною. Чистий прибуток 3 символи.
Редагування 4 : виправлена ​​помилка виявлення переповненого аншлагу (2х натур). коштують 3 символи.

Не зовсім переможець, але прямий детектор - це цікава концепція, я думаю.

sub
j{join"",sort@_}sub
o{j(map{{A=>10}->{$_},11+index(j(2..9).TJQKA,$_)}$h=~/(.(?=@_))/g)=~/.*(..)(??{j
map$1+$_.'.*',1..4})/?$1:()}$h=$_=<>;if(j(/(\S)\b/g)=~/(.)\1{4}/){$w=$_==19?royal:straight
for
o$f=$1}$_=j(/\b(\S)/g)=~s/(.)\1*/length$&/rge;$k=" of a kind";print$w?"$w flush":/4/?four.$k:/3.*2|[23].*3/?"full house":$f?flush:(o".")?straight:/3/?three.$k:/2.*2/?"two pair":/2/?"one pair":"high card"

Розширена версія:

# We'll be doing a lot of sorting and joining
sub j {
  return join "", sort @_;
}

# r() expects $_ to contain a rank, and converts it to a numeric code. The
# code starts at 10 so the numbers will sort correctly as strings, and a list
# of 2 values is returned because A is both 10 and 23. All other ranks have
# undef as the first value and their proper 11..22 value as the second value.
sub r {
  return ({A=>10}->{$_}, 11+index(j(2..9).TJQKA,$_));
}

# Sequence-detector. Factored into a sub because it's run twice; once over
# the ranks in the flush suit to find a straight flush and once over all the
# ranks to find a straight. On successful match, returns the lowest rank of
# the straight (in the 10..23 representation).
# Required parameter: the suit to search, or "." for all suits.
sub o {
  j(map r,$h=~/(.(?=@_))/g)          # The list of ranks, in increasing order,
                                     # with ace included at both ends...
    =~                               # ...is matched against...
  /.*(..)(??{j map$1+$_.'.*',1..4})/ # ...a pattern requiring 5 consecutive
                                     # numbers.
  ?$1:()
  # A note about this regexp. The string we're matching is a bunch of numbers
  # in the range 10..23 crammed together like "121314151619" so you might
  # worry about a misaligned match starting on the second digit of one of the
  # original numbers. But since that would make every pair of digits in the
  # match end with a 1 or a 2, there's no way 5 of them will be consecutive.
  # There are no false matches.
  # Another note: if we have a royal flush and also have a 9 in the same
  # suit, we need to return the T rank, not the 9, which is why the regexp
  # starts with a .*
}

# Read a line into $_ for immediate matching with /.../ and also save it into
# $h because $_ will be clobbered later and we'll need the original string
# afterwards.
$h = $_ = <>;

if(j(/(\S)\b/g) =~ /(.)\1{4}/) { # flush detector: sorted list of all suits
                                 # contains 5 consecutive identical chars
  # $f=$1 comes first, so $f will be true later if there's a flush.
  # Then o() is called with the flush suit as arg to detect straight flush.
  # If there's no straight flush, o() returns the empty list and for loop
  # runs 0 times, so $w is not set. If there is a straight flush, the return
  # value of o() is compared to 19 to detect royal flush.
  $w = ($_==19 ? "royal" : "straight")
    for o($f=$1);
}

$_ =
  j(/\b(\S)/g)                 # Get the sorted+joined list of ranks...
    =~ s/(.)\1*/length $&/rge; # ... and turn it into a list of sizes of
                               # groups of the same rank. The /r flag
                               # requires perl 5.14 or newer.

print
  $w             ? "$w flush" :
  /4/            ? "four of a kind" :
  /3.*2|[23].*3/ ? "full house" :
  $f             ? "flush" :
  (o".")         ? "straight" :
  /3/            ? "three of a kind" :
  /2.*2/         ? "two pair" :
  /2/            ? "one pair" :
                   "high card"

1

JavaScript 600

використання з nodeJS: node code.js "7H 3S 7S 7D AC QH 7C"

function a(o){s="";for(k in o)s+=o[k];return s}
b=process.argv[2]
c={S:0,H:0,D:0,C:0}
v={A:0,K:0,Q:0,J:0,T:0,"9":0,"8":0,"7":0,"6":0,"5":0,"4":0,"3":0,"2":0}
d=b.split(" ")
for(i=d.length;i--;){e=d[i];c[e[1]]++;v[e[0]]++}
c=a(c);v=a(v)
f=g=h=j=k=l=m=false
if((st=c.indexOf(5))!=-1)g=!g
if(v.match(/[1-9]{5}/))h=!h
if(st==0)f=!f
if(v.indexOf(4)!=-1)j=!j
if(v.indexOf(3)!=-1)k=!k
if(n=v.match(/2/g))if(n)if(n.length>=2)m=!m;else l=!l
p=" of a kind"
q="Flush"
r="Straight"
console.log(f&&g?"Royal "+q:h&&g?r+" "+q:j?"Four"+p:k&&(l||m)?"Full House":g?q:h?r:k?"Three"+p:m?"Two pairs":l?"Pair":"High card")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.