Najlepszy wynik Yahtzee

26

Yahtzee to gra z pięcioma sześciokątnymi kostkami i arkuszem wyników z trzynastoma różnymi polami do wypełnienia wyniku. Każde pole ma swoje własne reguły punktacji:

  • 1s, 2s, 3s, 4s, 5s, 6s wszystkie punkty są równe sumie odpowiednich kości (to znaczy rzut [3, 2, 3, 1, 5] zdobytych jako 3s otrzyma 6 punktów: 3 dla każdego 3).
  • 3 w swoim rodzaju i 4 w swoim rodzaju (jak brzmią, trzy lub cztery kostki rzuciły to samo) zdobywają punkty równe sumie wszystkich pięciu kości.
  • Fula (dwie kości pokazują jedną wartość, pozostałe trzy pokazują inną) osiąga 25 punktów
  • Mała prosta (cztery kolejne wartości) zdobywa 30 punktów
  • Duża prosta (wszystkie kolejne wartości) zdobywa 40 punktów
  • Yahtzee (wszystkie kości mają tę samą wartość) zdobywa 50 punktów

Trzynasta (szansa) ma sens w grze, ale nie tyle w przypadku tego wyzwania; dodatkowo gra ma bonusy za dodatkowe Yahtzees, co nie ma tutaj sensu. Ponieważ wyzwaniem jest ...

Biorąc pod uwagę pięć kości jako dane wejściowe (pięć liczb całkowitych 1-6, jednak dane wejściowe są wygodne, można założyć, że dane wejściowe są zawsze ważne), dają najwyższy możliwy wynik dla tej „ręki”. Do celów tego wyzwania ważne są tylko metody punktacji z powyższej listy (w szczególności szansa nie jest prawidłowym polem punktacji dla tego wyzwania). Wynik powinien być wyprowadzany jako jego dziesiętna wartość liczbowa, niezależnie od tego, czy jest to liczba całkowita, czy reprezentacja ciągu, cokolwiek. Powinien być natychmiast rozpoznawalny jako liczba. Wiodące / końcowe białe znaki są w porządku, chodzi o uzyskanie wyniku, a nie prezentacji.

Code golf, więc wygrywa odpowiedź z najmniejszą liczbą bajtów w danym języku. Standardowe luki zabronione.

Przypadki testowe

(Pamiętaj, że wszystkie są niezależne, wyzwanie polega na zdobyciu jednej „ręki” kości):

in: 1 5 4 3 2
out: 40
in: 1 1 4 3 1
out: 10
in: 2 2 6 5 3
out: 6
in: 2 4 2 4 6
out: 8
in: 1 1 1 1 1
out: 50
in: 5 2 5 3 6
out: 10
in: 1 6 3 4 2
out: 30
in: 1 3 1 1 3
out: 25
in: 6 5 5 6 6
out: 28
in: 1 2 3 5 6
out: 6
brhfl
źródło
3
czy zamiast tego powinniśmy zamknąć starsze pytanie? IMO to lepsze pytanie niż to ...
Giuseppe,
5
IMO to wcale nie duplikat punktacji w grze w yahtzee. To wyraźnie stwierdza, że ​​jest to najwyższy wynik dla jednej ręki, podczas gdy drugie pytanie wymaga podania całego wyniku z listy rzutów kostką. I wreszcie, co najważniejsze, nie widzę żadnych odpowiedzi z możliwego duplikatu, które mogłyby być użyte tutaj w scenariuszu „kopiuj-wklej”. Proszę rozważyć ponowne otwarcie.
DevelopingDeveloper,
2
FWIW, zdawałem sobie sprawę ze starszego pytania, kiedy je zestawiłem. Moje myśli powtórzyły to, co powiedział @DevelopingDeveloper. Po wykonaniu tego raz jako ćwiczenie, znalazłem kilka interesujących okazji, aby zoptymalizować ten proces. Myślę też, że jest to bardziej wymagające wyzwanie.
brhfl,
„Trzynasta (szansa) ma sens w grze, ale nie tyle w przypadku tego wyzwania” Więc to się liczy?
Unihedron

Odpowiedzi:

6

R , 146 141 bajtów

function(d)max(unique(d<-sort(d))*(g=table(d)),any(g>2)*sum(d),all(2:3%in%g)*25,(s=sum((R=diff(d))==1))<4&all(R<2)*30,(s>3)*40,(0==sd(d))*50)

Wypróbuj online!

Outgolfed by plannapus

Pobiera dane wejściowe jako listę i zwraca wynik.

trochę golfa:

function(d){
 d <- sort(d)
 u <- unique(d)                  # unique dice
 g <- table(d)                   # table of counts
 Ns <- u*g                       # scores as 1s, 2s, ... etc.
 NKind <- any(g>2)*sum(d)        # 3 or 4 of a kind if any counts are at least 3
 FHouse <- all(2:3%in%g)*25      # full house is 25 if 2 & 3 are in counts
 R <- diff(d)                    # consecutive differences
 s <- sum(R==1)                  # sum of differences equal to 1
 sStraight <- s<4 &              # if the number of 1s is 3 and
               all(R<2)*30       # no consecutive numbers are 2 apart
 bStraight <- (s>3)*40           # all 1s means big straight
 Yahtzee <- sd(d)==0             # sd = 0 means all are equal
 max(Ns,NKind,FHouse,sStraight,bStraight,Yahtzee)
}

Giuseppe
źródło
f(c(1,2,3,5,6))kończy się niepowodzeniem - powinno dać 6, a zamiast tego daje 30. Wygląda na to, że liczysz, ile par (posortowanie) różni się o jeden, co w rzeczywistości wynosi cztery dla powyższej sekwencji, nawet jeśli nie jest to prosta z czterech. Myślę, że natknąłem się na to, gdy robiłem to jakiś czas temu i prawdopodobnie powinienem dodać to jako przypadek testowy ...
brhfl
@brhfl jest to teraz naprawione.
Giuseppe,
5

Python 2 , 187 184 167 165 bajtów

-17 bajtów dzięki @mypetlion
-2 bajtów dzięki @chrstphrchvz

def f(d):r=range(1,7);c=d.count;m=map(c,r);s=`m`[1::3];return max([i*c(i)for i in r]+[sum(d)*(max(m)>2),25*(set(m)>{2,3}),30*(4*'1'in s),40*(5*'1'in s),50*(5 in m)])

Wypróbuj online!

ovs
źródło
4

R 136 136 bajtów

function(n,y=table(factor(n,1:6)),z=sum(!diff(diff(sort(n)))))max(1:6*y,c(25,sum(n),10*3:5)[c(all(y<4&y-1),any(y>2),z>1,z>2,any(y>4))])

Grał w golfa o 2 bajty dzięki @Giuseppe !

Zębaty,

function(n, #vector of die scores
         y=table(factor(n,1:6)), #Contingency table
         z=sum(!diff(diff(sort(n))))) #Diff of diff of ordered scores
    max(1:6*y,
        c(25,sum(n),10*3:5)*c(all(y<4&y-1), #Full house
                            any(y>2), #3 and 4 of a kind
                            z>1, #Small straight
                            z>2, #Long straight
                            any(y>4))] #Yahtzee

Kilka przypadków testowych:

> f=function(n,y=table(factor(n,1:6)),z=sum(!diff(diff(sort(n)))))max(1:6*y,c(25,sum(n),10*3:5)*c(all(y<4&y-1),any(y>2),z>1,z>2,any(y>4)))
> f(c(2,4,2,4,6))
[1] 8
> f(c(1,2,3,5,6))
[1] 6
> f(c(6,5,5,6,6))
[1] 28
> f(c(6,5,3,1,4))
[1] 30
> f(c(6,5,3,2,4))
[1] 40
plannapus
źródło
1
Huh, zastanawiałem się factorprzez chwilę, zanim się rozproszyłem. Ale myślę, że jeśli zastosuję twoje podejście z( sw mojej odpowiedzi), mogę zagrać w golfa do 134 ...
Giuseppe,
Dodatkowo, możesz zapisać trzy bajty, używając all(y<4&y-1)i używając *zamiast [, i ustawiając yinline zamiast jako argument funkcji, i nadal przechodzi on wszystkie przypadki testowe: Wypróbuj online!
Giuseppe,
zrestrukturyzowałem maxi myślę, że uratowało to bajt przed ustawieniem yinline.
Giuseppe,
3

Partia, 359 bajtów

@echo off
set/at=s=m=r1=r2=r3=r4=r5=r6=0
for %%r in (%*)do set/a"m+=!(m-r%%r),r%%r+=1,t+=%%r,p=s-r%%r*%%r,p&=p>>9,s-=p
goto %m%
:1
if %r1% neq %r6% set s=40&goto g
:2
set/at=r3*r4*(r2*(r1+r5)+r5*r6)
if %t% gtr 0 set s=30
goto g
:3
set/a"s=r1^r2^r3^r4^r5^r6"
if %s%==1 if %t% lss 25 set s=25&goto g
:4
set/as=t
goto g
:5
set s=50
:g
echo %s%

Wyjaśnienie:

@echo off
set/at=s=m=r1=r2=r3=r4=r5=r6=0
for %%r in (%*)do set/a"m+=!(m-r%%r),r%%r+=1,t+=%%r,p=s-r%%r*%%r,p&=p>>9,s-=p
goto %m%

Oblicz liczbę kości dla każdej liczby, plus maksimum, sumę wszystkich kości oraz najwyższą sumę kości o tej samej liczbie.

:1
if %r1% neq %r6% set s=40&goto g

Jeśli wszystkie kości są różne, może to być długa prosta, ale to musi być albo brak, 1albo nie 6.

:2
set/at=r3*r4*(r2*(r1+r5)+r5*r6)
if %t% gtr 0 set s=30
goto g

W przeciwnym razie lub jeśli co najwyżej dwie kości są takie same, może to być krótka prosta. Musi być co najmniej a 3i a, 4a także kombinacja pozostałych czterech liczb.

:3
set/a"s=r1^r2^r3^r4^r5^r6"
if %s%==1 set s=25&goto g

Jeśli są trzy takie same kości, odtąd sprawdź fula 3^2==1. Jednak niektóre pełne domy, takie jak 6s i 5s, mają wyższą ocenę jako 3-w swoim rodzaju.

:4
set/as=t
goto g

W przeciwnym razie lub jeśli są cztery takie same, zdobądź sumę.

:5
set s=50

A jeśli jest ich pięć, to Yahtzee!

:g
echo %s%

Wyprowadź najlepszy wynik.

Neil
źródło
1
Dzięki za przypomnienie mi o potencjalnej pułapce [5,5, 6, 6, 6] - zakopanej jako pełny dom - dodałem to jako przypadek testowy. Wiedziałem, że zapomniałem o kilku dziwnych pobocznych przypadkach.
brhfl
3

Galaretka , 58 bajtów

ċЀ`Ṁ>2ȧS
ṢI=1Ạµ-ƤẸ,E;ṢI$E$;⁸Lƙ`Ṣ⁼2,3¤a3,5,4,2.Ṁ×⁵»Ç»Sƙ`Ṁ$

Wypróbuj online!

Erik the Outgolfer
źródło
Jest to całkowicie poprawne, ale jestem ciekawy i nie znam wystarczająco Jelly, aby samemu to sprawdzić ... dlaczego full house powraca, 25.0podczas gdy żadna inna sprawa nie ma końca .0?
brhfl
@brhfl Cóż, ponieważ jest to wywnioskowane jako 2.5 × 10 = 25.0(arytmetyka zmiennoprzecinkowa), podczas gdy inne, takie jak 30są wywnioskowane jako 3 × 10 = 30(arytmetyka liczb całkowitych).
Erik the Outgolfer,
2
Dzięki! Naprawdę nie sformułowałem dobrze mojego pytania; Byłem bardziej ciekawy, jakiej metody używasz do wykrycia fularza, co skutkuje odmiennym wykonaniem matematyki - ale teraz, gdy o tym myślę, wydaje mi się, że bardziej golfistą jest 2.5, 3, 4, 5 * 10 vs 25, 30, 40, 50. Myślę, że odpowiedziałem na własne pytanie.
brhfl
@brhfl Dokładnie, ponieważ × 10ma 2 bajty, 2.5ma 2 bajty podobnie 25i 3,5,4zapisuje 3 bajty 30,50,40, więc 3 + 0 - 2 = 1 bajt zapisany.
Erik the Outgolfer,
2

Perl 6 , 159 bajtów

->\b{max map {$_(b)},|(1..6).map({*{$_}*$_}),{.kxxv.sum*?.values.grep(*>2)},{25*(6==[*]
.values)},30*?*{3&4&(1&2|2&5|5&6)},40*?*{2&3&4&5&(1|6)},50*(*.keys==1)}

Wypróbuj online!

Ponieważ dane wejściowe można zaakceptować „jednak jest to wygodne”, moja funkcja przyjmuje je jako instancję Bagklasy, która jest kontenerem z mnogością. A Bagjest również pojemnikiem asocjacyjnym; $bag{$key}zwraca ile razy $keywystępuje w torbie.

Większość funkcji to tylko lista funkcji, które oceniają każdą możliwą rękę Yahtzee, zwracając wynik dla tej ręki lub zero, jeśli warunki dla ręki nie są spełnione.

  • |(1..6).map({ *{$_} * $_ })jest listą sześciu funkcji, które oceniają ręce w oparciu o powtarzane przebiegi liczb 1-6. Wiodące |spłaszcza tę listę do listy otaczającej.
  • {.kxxv.sum * ?.values.grep(* > 2) }ocenia 3 i 4 w swoim rodzaju rozdania. .kxxvna a Bagzwraca klucze powtarzane z wielokrotnością każdego, odzyskując pierwotną listę rzutów .sumkostek i oczywiście sumuje kości. Suma ta jest mnożona przez wartość boolowską ( ?), która jest prawdą, jeśli worek .values(tj. Krotność) zawiera wartość większą niż 2.
  • { 25 * (6 == [*] .values) }ocenia układ full house. 25 mnoży się przez wartość logiczną, która jest prawdą, jeśli iloczyn wielokrotności wynosi 6, co dla pięciu kości może się zdarzyć tylko wtedy, gdy jedna ma 3, a druga 2.
  • 30 * ?*{ 3 & 4 & (1 & 2 | 2 & 5 | 5 & 6) }ocenia małą, prostą rękę. To WhateverCodefunkcja; drugą gwiazdą *jest Bag. Wyrażenie pomiędzy nawiasami klamrowymi to połączenie wartości 3 i 4 oraz 1 i 2 lub 2 i 5 lub 5 i 6. Wyszukiwanie tego połączenia w wyniku Bagdaje połączenie odpowiednich krotności. Jeśli wielokrotności 3 i 4 oraz co najmniej jeden z 1 i 2 lub 2 i 5 lub 5 i 6 są niezerowe, połączenie jest prawdziwe po wymuszeniu na wartość logiczną (z ?), a ta wartość logiczna jest mnożona przez 30 aby uzyskać wynik.
  • 40 * ?*{ 2 & 3 & 4 & 5 & (1 | 6) }podobnie ocenia dużą prostą rękę. Jest to prostsze, ponieważ kości muszą zawierać każdą z liczb 2-5 oraz 1 lub 6.
  • 50 * (*.keys == 1)ocenia rękę Yahtzee. Jest to po prostu 50-krotność wartości logicznej, co jest prawdą, jeśli liczba odrębnych kości wynosi jeden.
Sean
źródło
2

Pip , 65 63 bajtów

n:_NgM\,6MXn*\,6AL[2<MXn23=JSNn3<Y#MX Jn^0MXn=5]*[$+g25--y*t50]

Bierze kostkę jako pięć argumentów wiersza poleceń. Wypróbuj online!

Niegolfowane + wyjaśnienie

(To jest oryginalna wersja.)

                    g is list of cmdline args; t is 10 (implicit)

Y                   Yank into y:
  _Ng                function that counts occurrences of its argument in g
 M                   mapped to
  \,6                inclusive range from 1 to 6
                    This gives us how many dice are showing each number 1-6

s:                  Assign to s:
  # MX               length of max of
      Jy ^ 0         join y into string and split on zeros
                    This gives us the length of the longest straight

MX                  Max of
   y * \,6           each die frequency in y, times its value
 AL                  to which list append
   [                 this list:
                      3- and 4-of-a-kind:
    MXy > 2 & $+g      If max frequency is 3 or more, sum of g (else 0)
                      Full house:
    23 = J SNy & 25    Sort y and join into string; if it's 000023, 25 (else 0)
                      Straights:
    s > 3 & --s*t      If s is 4 or more, (s-1)*10 (else 0)
                      Yahtzee:
    MXy = 5 & 50       If max frequency is 5, 50 (else 0)
   ]
                    The result of the last expression is autoprinted
DLosc
źródło
1

Rubinowy , 184 bajty

Pełny program Aby ułatwić testowanie danych wejściowych, dodaj $/=' 'na górze, aby przeczytać w formacie „cyfra oddzielona spacjami”. (191 znaków)

a=$<.map &:to_i
b=a.|c=[]
d=(1..6).map{|x|e=a.count x
c<<x*e
e}
e=a.sum
p !b[1]?50:b[4]&&!(a&[1,6])[1]?40:(1..3).any?{|x|(a&[*x..x+3])[3]}?30:(d-[0,2,3])[0]?d.max>2?e:c.max: [25,e].max

Zerwałem barierę 200 bajtów i z łatwością udało mi się ją zniszczyć, pozostawiając tuzin bajtów!

Wypróbuj online!

Wyjaśnienie

Jednak niezbyt dobry. Mam nadzieję, że masz trochę wiedzy Ruby ~

a=$<.map &:to_i # a: input as [number]*5
b=a.|c=[]       # c: [], b: a.uniq
d=(1..6).map{|x|
    e=a.count x # e: occurrence count in a 
    c<<x*e      # add (number * occurrence count) to c
    e           # return value in d
}
e=a.sum         # e: sum of input
p !b[1] ? 50 :  #   condition to print 50 <= if a.uniq has length 0 (el 1 is nil)
  b[4] &&       #   condition to print 40 <= if a.uniq has length 5 (el 4 exists)
  !(a&[1,6])[1] ? 40 : # <- arr & [mask]  # and a does not have both 1 and 6
  (1..3).any?{|x| # condition to print 30 <= if any of 1..4, 2..5, 3..6
  (a&[*x..x+3])[3]} ? 30 : # [3] to assert entire mask is found in a
  (d-[0,2,3])[0] ? # if, after removing 0 (not found) 2 (a pair) 3 (a triple)
                   # and something is found, this is not full house
  d.max > 2 ?   # is triple / quadruple ?
     e :        # weakly dominating alternatives
     c.max      # choose best by-suit
  : [25,e].max  # choose best by-score
Unihedron
źródło