Найкраща оцінка Yahtzee


26

Yahtzee - це гра, яка складається з п'яти шестигранних кубиків та табло з тринадцятьма різними полями, щоб заповнити рахунок. Кожне поле має свої власні правила балів:

  • 1s, 2s, 3s, 4s, 5s, 6s всі набрані бали, що дорівнюють сумі відповідних кісток (тобто рулон [3, 2, 3, 1, 5], набраний як 3s, отримає 6 балів: 3 для кожного 3).
  • 3-х у натурі та 4-х у своєму роді (як вони звучать, три чи чотири кубики згорнути однаково) набирають очки, що дорівнює сумі всіх п’яти кубиків.
  • Фулл-хаус (два кубики показують одне значення, інші три показують інше) набирає 25 балів
  • Малий прямий (чотири послідовні значення) набирає 30 балів
  • Великий прямий (всі послідовні значення) набирає 40 балів
  • Яхтзі (усі кубики мають однакове значення) набирає 50 балів

Тринадцята (шанс) має сенс у грі, але не стільки для цього виклику; Крім того, гра має бонуси для додаткових Yahtzees, які тут не мають сенсу. Тому що виклик - це ...

Враховуючи п'ять кісток як вхідні дані (п'ять цілих чисел 1-6, але введення зручно, ви можете припустити, що введення завжди дійсне), виведіть максимально можливий бал для цієї "руки". Для цілей цього виклику справедливі лише методи підрахунку балів у наведеному вище списку (конкретно, шанс не є дійсною шкалою для цього виклику). Оцінка повинна виводитись як її десяткове числове значення, будь то ціле число чи рядкове подання, будь-яке. Його слід негайно розпізнати як число. Простір провідних / кінцевих пробілів чудово, це стосується отримання балів, а не презентації.

Код гольфу, тож відповідь з найменшою кількістю байтів на даній мові виграє. Стандартні лазівки заборонені.

Тестові справи

(Зауважте, що всі вони незалежні. Завдання полягає в тому, щоб набрати одну "руку" кістки):

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
чи варто замість цього закрити старіше питання? ІМО, це питання краще, ніж одне ...
Джузеппе

5
ІМО це зовсім не дублікат рахункової гри yahtzee. Це прямо заявляє, що це найвищий бал для однієї руки, де інше питання запитує весь бал зі списку роликів. Нарешті, і найголовніше, я не бачу жодної відповіді від можливої ​​дупи, яку можна використати тут у сценарії "копіювати-вставити". Будь ласка, подумайте про повторне відкриття.
DevelopingDeveloper


2
FWIW, мені було відомо про старіше питання, коли я склав це. Мої думки перегукувалися з тим, що сказав @DevelopingDeveloper. Зробивши це як вправу один раз раніше, я знайшов цікаві можливості оптимізувати цей процес. Я також просто думаю, що це акуратніше завдання.
brhfl

"Тринадцятий (шанс) має сенс у грі, але не так вже й для цього завдання" Так чи вважається?
Уніхедрон

Відповіді:


6

R , 146 141 байт

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)

Спробуйте в Інтернеті!

Перевершив планнапус

Приймає дані як список і повертає бал.

трохи зомліли:

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))не вдається - він повинен отримати 6, а замість цього врожай 30. Здається, це тому, що ви рахуєте, скільки пар (після сортування) відрізняються одна, що насправді чотири для вищевказаної послідовності, навіть якщо це не пряма з чотирьох. Я думаю, що я зіткнувся з цим, коли це робив як вправу назад, і, мабуть, слід додати це як тестовий випадок ...
brhfl

@brhfl це виправлено зараз.
Джузеппе


4

R, 136 134 байт

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

Поле за 2 байти завдяки @Giuseppe !

Відступ,

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

Кілька тестових випадків:

> 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
Так, я подумав factorпро гарячу секунду, перш ніж відволіктись. Але я думаю, що якщо я скористаюся вашим підходом z( sу своїй відповіді), я можу гольфу до 134 ...
Джузеппе

Крім того, ви можете зберегти три байти, використовуючи all(y<4&y-1)і використовуючи *замість [, і встановивши yвбудований, а не як аргумент функції, і він все одно передає всі тестові випадки: Спробуйте це в Інтернеті!
Джузеппе

Крім того, я реструктурував maxі, я думаю, це врятувало байт від встановлення yвбудованого рядка.
Джузеппе

3

Пакетна, 359 байт

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

Пояснення:

@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

Якщо всі кубики різні, це може бути довга пряма, але це може бути або ні, 1або ні 6.

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

Інакше, або якщо максимум дві кістки однакові, то це все-таки може бути короткою прямою. Повинно бути принаймні a 3і a, 4а також комбінація інших чотирьох чисел.

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

Якщо є три кубики однаково, перевірте, чи немає повного будинку 3^2==1. Однак деякі будинки з повним набором, наприклад, 6 і 5, набирають вищого рівня, як 3-х у своєму роді.

:4
set/as=t
goto g

В іншому випадку, або якщо їх однакові чотири, то підсумовуйте загальну суму.

:5
set s=50

А якщо п’ять однакових, то Яхтзее!

:g
echo %s%

Виведіть найкращий бал.


1
Дякую, що нагадали мені про потенційний [5,5,6,6,6] -захищений підводний камінь - я додав це як тестову справу. Я знав, що було пару дивних випадків бахроми, про які я забував.
brhfl

3

Желе , 58 байт

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

Спробуйте в Інтернеті!


Це цілком справедливо, але мені цікаво, і я не знаю, як Желі достатньо добре, щоб самотужки її витягнути ... Чому повний будинок повертається, 25.0поки жоден інший випадок не має сліду .0?
brhfl

@brhfl Добре, тому що це робиться як 2.5 × 10 = 25.0(плаваюча арифметика), тоді як інші, такі як 30, робиться як 3 × 10 = 30(ціла арифметика).
Erik the Outgolfer

2
Спасибі! Я не дуже добре сказав своє запитання; Мені було цікавіше, який метод ви використовуєте для виявлення аншлагу, який призводить до того, що математику робити по-різному - але тепер, коли я думаю про це, я здогадуюсь, що це просто гольфіст робити 2,5, 3, 4, 5 * 10 проти 25, 30, 40, 50. Подумайте, я відповів на власне запитання.
brhfl

@brhfl Саме так, оскільки × 10це 2 байти, 2.5це 2 байти точно так само 25, і 3,5,4зберігає 3 байти 30,50,40, тому 3 + 0 - 2 = 1 байт збережено.
Ерік Аутгольфер

2

Perl 6 , 159 байт

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

Спробуйте в Інтернеті!

Оскільки введення може бути прийнято "як би зручно", моя функція сприймає його як екземпляр Bagкласу, який є контейнером з кратністю. А Bagтакож є асоціативним контейнером; $bag{$key}повертає, скільки разів $keyтрапляється в сумці.

Основна частина функції - це лише перелік функцій, які оцінюють кожну можливу руку Yahtzee, повертаючи бал за цю руку або нуль, якщо умови для цього не виконуються.

  • |(1..6).map({ *{$_} * $_ })- це список із шести функцій, які оцінюють руки на основі повторних прогонів чисел 1-6. Ведучий |вирівнює цей список у навколишній список.
  • {.kxxv.sum * ?.values.grep(* > 2) }оцінює руки 3- та 4-х в роді. .kxxvпри Bagповерненні клавіш, повторених з кратністю кожного, відновлює початковий список рулонів, і .sumзвичайно підсумовує кістки. Ця сума множиться на булеве значення ( ?), що відповідає дійсності, якщо сумка .values(тобто кратність) містить значення, що перевищує 2.
  • { 25 * (6 == [*] .values) }оцінює повну руку. 25 помножено на булеве значення, що відповідає дійсності, якщо добуток кратності дорівнює 6, що для п’яти кубиків може статися лише в тому випадку, якщо один дорівнює 3, а інший - 2.
  • 30 * ?*{ 3 & 4 & (1 & 2 | 2 & 5 | 5 & 6) }оцінює малу пряму руку. Це WhateverCodeфункція; друга зірка *- це Bag. Вираз між дужками - це з'єднання значень 3 і 4, або 1 і 2, або 2 і 5, або 5 і 6. Шукання цього з'єднання в Bagрезультатах відбувається в стику відповідних кратності. Якщо багатократність 3 і 4, і принаймні один з 1 і 2, або 2 і 5, або 5 і 6 є ненульовими, з'єднання вірно, коли примусово до булевого (з ?), і цей булевий множиться на 30 щоб отримати рахунок.
  • 40 * ?*{ 2 & 3 & 4 & 5 & (1 | 6) }аналогічно оцінює велику пряму руку. Це простіше, оскільки кістки повинні містити кожне з чисел 2-5, або 1, або 6.
  • 50 * (*.keys == 1)оцінює рука Яхтзея. Це просто в 50 разів булеве значення, що відповідає дійсності, якщо кількість різних кісток одна.

2

Піп , 65 63 байти

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

Приймає кістки як п'ять аргументів командного рядка. Спробуйте в Інтернеті!

Ungolfed + пояснення

(Це оригінальна версія.)

                    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

Рубін , 184 байти

Повна програма. Щоб полегшити тестування введення, додайте $/=' 'зверху для читання у форматі "цифра, розділена пробілами". (191 символів)

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

Я поставив перелом бар'єр на 200 байт, і мені вдалося зруйнувати його з десятком байтів, що залишилися, з легкістю!

Спробуйте в Інтернеті!

Пояснення

Не дуже хороший, хоча. Сподіваюся, у вас є деякі знання про Рубі ~

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.