Meilleur score Yahtzee

26

Yahtzee est un jeu joué avec cinq dés à six faces et une feuille de score avec treize cases différentes pour remplir un score. Chaque case a ses propres règles de score:

  • 1s, 2s, 3s, 4s, 5s, 6s marquent tous des points égaux à la somme des dés respectifs (c'est-à-dire qu'un jet de [3, 2, 3, 1, 5] marqué comme 3s recevrait 6 points: 3 pour chaque 3).
  • 3-of-a-kind et 4-of-a-kind (comme ils sonnent, trois ou quatre dés ont lancé les mêmes) marquent des points égaux à la somme des cinq dés.
  • Full house (deux dés montrent une valeur, les trois autres en montrent une autre) marque 25 points
  • Une petite ligne droite (quatre valeurs consécutives) marque 30 points
  • Une grande ligne droite (toutes les valeurs consécutives) marque 40 points
  • Yahtzee (tous les dés affichent la même valeur) marque 50 points

Le treizième (chance) a du sens dans le jeu, mais pas tant pour ce défi; en outre, le jeu a des bonus pour Yahtzees supplémentaires qui n'ont aucun sens ici. Parce que le défi est ...

Étant donné cinq dés en entrée (cinq entiers 1-6, l'entrée est cependant pratique, vous pouvez supposer que l'entrée est toujours valide), produisez le score le plus élevé possible pour cette `` main ''. Aux fins de ce défi, seules les méthodes de notation dans la liste ci-dessus sont valides (en particulier, le hasard n'est pas une case de score valide pour ce défi). Le score doit être affiché sous la forme de sa valeur numérique décimale, qu'il s'agisse d'un entier ou d'une représentation sous forme de chaîne, quel qu'il soit. Il doit être immédiatement reconnaissable comme un nombre. Les espaces blancs de début / fin sont très bien, il s'agit d'obtenir le score et non la présentation.

Code golf, donc la réponse avec le moins d'octets dans une langue donnée l'emporte. Failles standard interdites.

Cas de test

(Notez que ce sont tous indépendants, le défi est de marquer une «main» de dés):

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
la source
3
devrions-nous plutôt fermer l'ancienne question? OMI, c'est une meilleure question que celle-là ...
Giuseppe
5
IMO ce n'est pas du tout un doublon de score d'une partie de yahtzee Cela indique explicitement que c'est le score le plus élevé pour une main, où l'autre question demande un score entier à partir d'une liste de lancers de dés. Enfin, et surtout, je ne vois aucune réponse de la dupe possible pouvant être utilisée ici dans un scénario "copier-coller". Veuillez envisager de rouvrir.
DevelopingDeveloper
2
FWIW, j'étais au courant de la question la plus ancienne lorsque j'ai remonté celle-ci. Mes pensées ont fait écho à ce que @DevelopingDeveloper a dit. Après avoir fait cela comme un exercice auparavant, j'ai trouvé des opportunités intéressantes pour optimiser ce processus. Je pense aussi que c'est un défi plus ordonné.
brhfl
"La treizième (chance) a du sens dans le jeu, mais pas tant pour ce défi" Alors est-ce compté?
Unihedron

Réponses:

6

R , 146 141 octets

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)

Essayez-le en ligne!

Outgolfed par plannapus

Prend l'entrée sous forme de liste et renvoie le score.

ungolfed un peu:

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
la source
f(c(1,2,3,5,6))échoue - il devrait donner 6 et au lieu de 30. Il semble que ce soit parce que vous comptez combien de paires (post-tri) diffèrent par une, ce qui est en fait quatre pour la séquence ci-dessus, même si ce n'est pas une ligne droite de quatre. Je pense que je suis tombé sur cela quand je l'ai fait comme exercice il y a quelque temps, et je devrais probablement ajouter cela comme cas de test ...
brhfl
@brhfl cela est maintenant corrigé.
Giuseppe
5

Python 2 , 187 184 167 165 octets

-17 octets grâce à @mypetlion
-2 octets grâce à @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)])

Essayez-le en ligne!

ovs
la source
4

R, 136 134 octets

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

Golfé sur 2 octets grâce à @Giuseppe !

Dentelé,

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

Quelques cas de 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
plannapus
la source
1
Huh, j'ai réfléchi factorpendant une seconde chaude avant de me laisser distraire. Mais je pense que si j'utilise votre approche avec z( sdans ma réponse), je peux jouer la mienne à 134 ...
Giuseppe
De plus, vous pouvez enregistrer trois octets en utilisant all(y<4&y-1)et en utilisant *au lieu de [, et en définissant yinline plutôt qu'en tant qu'argument de fonction, et il passe toujours tous les cas de test: Essayez-le en ligne!
Giuseppe
aussi, j'ai restructuré le maxet je pense que cela a sauvé l'octet de la mise en yligne.
Giuseppe
3

Lot, 359 octets

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

Explication:

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

Calculez le nombre de dés pour chaque numéro, plus le maximum, plus le total de tous les dés, plus le total le plus élevé de dés du même nombre.

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

Si tous les dés sont différents, cela peut être une longue ligne droite, mais cela doit être non 1ou non 6.

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

Sinon, ou si au plus deux dés sont identiques, cela peut être une courte ligne droite. Il doit y avoir au moins un 3et un 4et aussi une combinaison des quatre autres nombres.

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

S'il y a trois dés identiques, cherchez une maison pleine, depuis 3^2==1. Cependant, certaines maisons pleines, comme les 6 et les 5, obtiennent un score plus élevé en tant que 3-of-a-kind.

:4
set/as=t
goto g

Sinon, ou s'il y en a quatre de même, marquez le total.

:5
set s=50

Et s'il y en a cinq pareils, alors Yahtzee!

:g
echo %s%

Produisez le meilleur score.

Neil
la source
1
Merci de m'avoir rappelé le piège potentiel [5,5,6,6,6] - classé comme maison pleine - j'ai ajouté ceci comme cas de test. Je savais qu'il y avait quelques cas marginaux étranges que j'oubliais.
brhfl
3

Gelée , 58 octets

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

Essayez-le en ligne!

Erik le Outgolfer
la source
C'est parfaitement valable, mais je suis curieux et je ne connais pas Jelly assez bien pour en discuter par moi-même ... pourquoi le full house revient-il 25.0alors qu'aucun autre cas n'a de fuite .0?
brhfl
@brhfl Eh bien, car il est inféré comme 2.5 × 10 = 25.0(arithmétique flottante), tandis que les autres tels que 30sont inférés comme 3 × 10 = 30(arithmétique entière).
Erik the Outgolfer
2
Merci! Je n'ai pas vraiment bien formulé ma question; J'étais plus curieux de savoir quelle méthode vous utilisez pour détecter une maison pleine qui se traduit par faire les calculs différemment - mais maintenant que j'y pense, je suppose que c'est juste plus golfeur de faire 2,5, 3, 4, 5 * 10 vs 25, 30, 40, 50. Je pense avoir répondu à ma propre question.
brhfl
@brhfl Exactement, puisqu'il × 10s'agit de 2 octets, 2.5est de 2 octets exactement comme 25, et 3,5,4enregistre 3 octets de plus 30,50,40, donc 3 + 0 - 2 = 1 octet enregistré.
Erik the Outgolfer
2

Perl 6 , 159 octets

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

Essayez-le en ligne!

Étant donné que l'entrée peut être acceptée «mais c'est pratique», ma fonction la prend comme une instance de la Bagclasse, qui est un conteneur avec une multiplicité. A Bagest également un conteneur associatif; $bag{$key}renvoie combien de fois $keyse produit dans le sac.

La majeure partie de la fonction n'est qu'une liste de fonctions qui évaluent chaque main Yahtzee possible, renvoyant le score de cette main ou zéro si les conditions de la main ne sont pas remplies.

  • |(1..6).map({ *{$_} * $_ })est une liste de six fonctions qui évaluent les mains sur la base de répétitions des nombres 1-6. Le premier |aplatit cette liste dans la liste environnante.
  • {.kxxv.sum * ?.values.grep(* > 2) }évalue les mains à 3 et 4 exemplaires. .kxxvsur un Bagretourne les touches répétées avec la multiplicité de chacun, récupérant la liste originale des jets de dé, et .sumbien sûr additionne les dés. Cette somme est multipliée par une valeur booléenne ( ?) qui est vraie si le sac .values(c'est-à-dire les multiplicités) contient une valeur supérieure à 2.
  • { 25 * (6 == [*] .values) }évalue la main entière de la maison. 25 est multiplié par une valeur booléenne qui est vraie si le produit des multiplicités est 6, ce qui pour cinq dés ne peut se produire que si l'un est 3 et l'autre est 2.
  • 30 * ?*{ 3 & 4 & (1 & 2 | 2 & 5 | 5 & 6) }évalue la petite main droite. C'est une WhateverCodefonction; la deuxième étoile *est la Bag. L'expression entre les accolades est la jonction des valeurs 3 et 4, et 1 et 2, ou 2 et 5, ou 5 et 6. La recherche de cette jonction dans les Bagrésultats entraîne une jonction des multiplicités correspondantes. Si les multiplicités de 3 et 4, et d'au moins 1 et 2, ou 2 et 5, ou 5 et 6, sont non nulles, la jonction est vraie lorsqu'elle est contrainte à un booléen (avec ?), et ce booléen est multiplié par 30 pour obtenir le score.
  • 40 * ?*{ 2 & 3 & 4 & 5 & (1 | 6) }évalue de même la grande main droite. C'est plus simple car les dés doivent inclure chacun des nombres 2-5 et 1 ou 6.
  • 50 * (*.keys == 1)évalue la main Yahtzee. C'est simplement 50 fois une valeur booléenne, ce qui est vrai si le nombre de dés distincts est égal à un.
Sean
la source
2

Pip , 65 63 octets

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

Prend les dés comme cinq arguments de ligne de commande. Essayez-le en ligne!

Non golfé + explication

(Ceci est la version 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
DLosc
la source
1

Rubis , 184 octets

Programme complet. Pour faciliter le test de l'entrée, ajoutez $/=' 'en haut pour lire au format "chiffre séparé par des espaces". (191 caractères)

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

J'ai posé la barrière de 200 octets et j'ai réussi à la détruire avec une dizaine d'octets restants, en toute simplicité!

Essayez-le en ligne!

Explication

Pas très bon cependant. J'espère que vous avez des connaissances 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
la source