Miglior punteggio Yahtzee


26

Yahtzee è una partita giocata con cinque dadi a sei facce e un foglio di punteggio con tredici caselle diverse per riempire un punteggio. Ogni scatola ha le sue regole di punteggio:

  • 1s, 2s, 3s, 4s, 5s, 6s totalizzano tutti i punti pari alla somma dei rispettivi dadi (ovvero, un tiro di [3, 2, 3, 1, 5] segnato come 3s riceverà 6 punti: 3 per ogni 3).
  • 3-of-a-kind e 4-of-a-kind (mentre suonano, tre o quattro dadi lanciati allo stesso modo) ottengono punti pari alla somma di tutti e cinque i dadi.
  • Il full house (due dadi mostrano un valore, gli altri tre mostrano un altro) segna 25 punti
  • La scala piccola (quattro valori consecutivi) segna 30 punti
  • La scala grande (tutti i valori consecutivi) segna 40 punti
  • Yahtzee (tutti i dadi mostrano lo stesso valore) segna 50 punti

La tredicesima (possibilità) ha senso nel gioco, ma non tanto per questa sfida; inoltre il gioco ha dei bonus per Yahtze extra che non hanno senso qui. Perché la sfida è ...

Dato cinque dadi come input (cinque numeri interi 1-6, l'input è comunque conveniente, puoi supporre che l'input sia sempre valido), ottieni il punteggio più alto possibile per quella 'mano'. Ai fini di questa sfida, sono validi solo i metodi di punteggio nella lista sopra (in particolare, chance non è una casella di punteggio valida per questa sfida). Il punteggio deve essere emesso come valore numerico decimale, indipendentemente dal fatto che si tratti di un intero o di una sua rappresentazione in forma di stringa. Dovrebbe essere immediatamente riconoscibile come un numero. Lo spazio bianco iniziale / finale va bene, si tratta di ottenere il punteggio e non la presentazione.

Codice golf, quindi vince la risposta con il minor numero di byte in una determinata lingua. Scappatoie standard vietate.

Casi test

(Nota che sono tutti indipendenti, la sfida è quella di segnare una 'mano' di dadi):

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

3
dovremmo invece chiudere la domanda precedente? IMO questa è una domanda migliore di quella ...
Giuseppe,

5
IMO questo non è affatto un duplicato del punteggio una partita di yahtzee Questo afferma esplicitamente che è il punteggio più alto per una mano, dove l'altra domanda chiede un punteggio intero da un elenco di tiri di dado. Infine, e soprattutto, non vedo alcuna risposta dal possibile duplicato che può essere utilizzato qui in uno scenario "copia-incolla". Si prega di considerare la riapertura.
DevelopingDeveloper


2
FWIW, ero consapevole della domanda più vecchia quando ho messo insieme questa. I miei pensieri hanno fatto eco a ciò che ha detto @DevelopingDeveloper. Avendo già fatto questo esercizio una volta, ho trovato alcune interessanti opportunità per ottimizzare questo processo. Penso anche che questa sia una sfida più ordinata.
brhfl,

"La tredicesima (possibilità) ha senso nel gioco, ma non tanto per questa sfida" Quindi è contata?
Unihedron,

Risposte:


6

R , 146 141 byte

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)

Provalo online!

Superato da Plannapus

Prende l'input come elenco e restituisce il punteggio.

ungolfed un po ':

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)
}


f(c(1,2,3,5,6))fallisce - dovrebbe produrre 6 e invece produce 30. Sembra che tu stia contando quante coppie (post-ordinamento) differiscono per una, che in realtà è quattro per la sequenza sopra, anche se non è una scala di quattro. Penso di essermi imbattuto in questo quando ho fatto questo come esercizio poco tempo fa, e probabilmente dovrei aggiungerlo come caso di prova ...
brhfl

@brhfl questo è stato risolto ora.
Giuseppe,

5

Python 2 , 187 184 167 165 byte

-17 byte grazie a @mypetlion
-2 byte grazie a @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)])

Provalo online!


4

R, 136 134 byte

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))])

Abbattuto di 2 byte grazie a @Giuseppe !

rientrato,

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

Alcuni casi di test:

> 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

1
Ehm, ho pensato factorper un secondo caldo prima di distrarmi. Ma penso che se uso il tuo approccio con z( snella mia risposta), posso giocare a golf fino a 134 ...
Giuseppe,

Inoltre, puoi salvare tre byte usando all(y<4&y-1)e usando *invece di [, e impostando yinline piuttosto che come argomento di funzione, e passa comunque tutti i casi di test: provalo online!
Giuseppe,

inoltre, ho ristrutturato maxe penso che abbia salvato il byte dall'impostazione in ylinea.
Giuseppe,

3

Lotto, 359 byte

@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%

Spiegazione:

@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%

Calcola il numero di dadi per ciascun numero, più il massimo, più il totale di tutti i dadi, più il totale più alto di dadi dello stesso numero.

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

Se tutti i dadi sono diversi, questo potrebbe essere un lungo rettilineo, ma deve esserci o no 1o no 6.

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

Altrimenti, o se al massimo due dadi sono uguali, allora potrebbe essere comunque una scala corta. Ci devono essere almeno una 3e una 4e anche una combinazione degli altri quattro numeri.

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

Se ci sono tre dadi uguali, controlla un full, da allora 3^2==1. Tuttavia, alcuni full, come 6s e 5s, ottengono un punteggio più alto del 3-of-a-kind.

:4
set/as=t
goto g

Altrimenti, o se ce ne sono quattro uguali, allora segna il totale.

:5
set s=50

E se ce ne sono cinque uguali, allora Yahtzee!

:g
echo %s%

Ottieni il punteggio migliore.


1
Grazie per avermi ricordato la potenziale insidie ​​[5,5,6,6,6] classificata come full-house - Ho aggiunto questo come caso di prova. Sapevo che c'erano un paio di strani casi marginali che stavo dimenticando.
brhfl,

3

Gelatina , 58 byte

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

Provalo online!


È perfettamente valido, ma sono curioso e non conosco Jelly abbastanza bene da sostenerlo da solo ... perché la casa intera ritorna 25.0mentre nessun altro caso ha il finale .0?
brhfl,

@brhfl Bene, perché è inferito come 2.5 × 10 = 25.0(float arithmetic), mentre gli altri come 30sono inferiti come 3 × 10 = 30(integer arithmetic).
Erik the Outgolfer,

2
Grazie! Non ho davvero espresso bene la mia domanda; Ero più curioso di sapere quale metodo stai usando per rilevare una full house che si traduce nel fare la matematica in modo diverso - ma ora che ci penso, immagino che sia solo più golfista fare 2,5, 3, 4, 5 * 10 vs 25, 30, 40, 50. Penso di aver risposto alla mia domanda.
brhfl,

@brhfl Esattamente, poiché × 10è 2 byte, 2.5è uguale a 2 byte 25e 3,5,4salva 3 byte 30,50,40, quindi 3 + 0 - 2 = 1 byte salvato.
Erik the Outgolfer,

2

Perl 6 , 159 byte

->\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)}

Provalo online!

Poiché l'input può essere accettato "comunque è conveniente", la mia funzione lo prende come un'istanza della Bagclasse, che è un contenitore con molteplicità. A Bagè anche un contenitore associativo; $bag{$key}restituisce quante volte si $keyverifica nella borsa.

La maggior parte della funzione è solo un elenco di funzioni che valutano ogni possibile mano Yahtzee, restituendo il punteggio per quella mano o zero se le condizioni per la mano non sono soddisfatte.

  • |(1..6).map({ *{$_} * $_ })è un elenco di sei funzioni che valutano le mani in base a ripetute serie dei numeri 1-6. Il leader |appiattisce questo elenco nell'elenco circostante.
  • {.kxxv.sum * ?.values.grep(* > 2) }valuta le mani 3 e 4 di un tipo. .kxxvsu a Bagrestituisce i tasti ripetuti con la molteplicità di ciascuno, recuperando la lista originale dei tiri di dado e, .sumnaturalmente, somma i dadi. Quella somma viene moltiplicata per un valore booleano ( ?) che è vero se la borsa .values(cioè le molteplicità) contiene un valore maggiore di 2.
  • { 25 * (6 == [*] .values) }valuta la mano della casa piena. 25 viene moltiplicato per un valore booleano che è vero se il prodotto delle molteplicità è 6, che per cinque dadi può avvenire solo se uno è 3 e l'altro è 2.
  • 30 * ?*{ 3 & 4 & (1 & 2 | 2 & 5 | 5 & 6) }valuta la piccola mano dritta. È una WhateverCodefunzione; la seconda stella *è la Bag. L'espressione tra le parentesi graffe è la giunzione dei valori 3 e 4 e 1 e 2, oppure 2 e 5, oppure 5 e 6. Cercare questa giunzione nei Bagrisultati in una giunzione delle corrispondenti molteplicità. Se le mulitplicity di 3 e 4, e almeno una di 1 e 2, o 2 e 5, o 5 e 6, sono diverse da zero, la giunzione è vera quando costretta a un booleano (con ?), e questo booleano viene moltiplicato per 30 per ottenere il punteggio.
  • 40 * ?*{ 2 & 3 & 4 & 5 & (1 | 6) }allo stesso modo valuta la grande mano dritta. È più semplice perché i dadi devono includere ciascuno dei numeri 2-5 e 1 o 6.
  • 50 * (*.keys == 1)valuta la mano Yahtzee. È semplicemente 50 volte un valore booleano che è vero se il numero di dadi distinti è uno.

2

Pip , 65 63 byte

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

Prende i dadi come cinque argomenti della riga di comando. Provalo online!

Ungolfed + spiegazione

(Questa è la versione originale.)

                    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

1

Rubino , 184 byte

Programma completo. Per semplificare il test dell'input, aggiungi $/=' 'in alto per leggere nel formato "cifra separata da spazi". (191 caratteri)

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

Ho impostato la rottura della barriera di 200 byte e sono riuscito a distruggerlo con una dozzina di byte rimasti, con facilità!

Provalo online!

Spiegazione

Non molto buono però. Spero che tu abbia qualche conoscenza di 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.