Счетчик очков для ската


11

Ваша задача - написать небольшую программу, которая подсчитывает очки руки Skat. В колоде Скат есть карты от 7 до 10, Джек, Королева, Король и Туз (называемые Унтер, Обер, Кениг и Даус). Мы используем немецкие костюмы с желудями, листьями, сердцами и колокольчиками вместо треф, пиков, сердец и бриллиантов. Очки определяются по номеру на карточке:

  • 7, 8 и 9 - 0 очков
  • Унтер 2 балла
  • Обер 3 очка
  • Кениг 4 очка
  • 10 - это 10 баллов
  • Даус 11 очков.

Ввод, вывод

Формат ввода состоит из двух символов, первый представляет значение, а второй обозначает масть:

  • 7, 8 и 9 обозначают их сами
  • 0 (ноль) означает 10
  • Unter, Ober, König и Daus названы в честь их первых букв (U, O и D)
  • То же самое для желудей, листьев, сердец и живота (A, L, H и B)

Входные данные представляют собой одну строку карточек, разделенных одним пробелом. Вы можете взять ввод откуда угодно, аргументы командной строки тоже подойдут. Выходом является значение руки, либо распечатанное, либо возвращенное в качестве кода выхода. Вывод вашей программы должен показывать ошибку, если какая-либо карта появляется дважды в руке. (Так что 7A 0L 7Aдолжен вернуть ошибку вместо 10). Также можно выйти с кодом завершения 255 вместо того, чтобы показывать ошибку, если это стандартный способ вашей программы для вывода результата.

Примеры

  • 7A 8A 9A UA OA KA 0A DA 7L 8L 9L UL OL KL 0L DL 7H 8H 9H UH OH KH 0H DH 7B 8B 9B UB OB KB 0B DBдает 120
  • 7A 8L 0K DB 8L выдает ошибку
  • UA OB DL KHдает 20

правила

  • Код гольф: выигрывает самый короткий код
  • Применяются обычные правила игры в гольф
  • Программа должна работать на все руки, а не только на примерах
  • GIGO: если ввод неверен, вывод может быть произвольным

В порядке ли дополнительный вывод в stderr (например, предупреждения)?
Вентеро

@Ventero: Да, это так. Любой способ ошибиться - это нормально, но пользователь должен четко видеть, что произошла ошибка.
FUZxxl

Джек, Королева и Туз называются Унтер, Обер, Кинг и Даус? Король должен быть там?
Ry-

@ minitech Нет, это не так.
FUZxxl

2
Я полагаю, что вы имеете в виду "колокола", а не "животы". Очень разные, это.
Boothby

Ответы:


2

APL ( 54 48)

Там должно быть коротким путем выбора значения карты, но я не вижу его.

(+/12-'D0.....KOU.'⍳⊃¨A)÷A≡∪A←↓A⍴⍨2,⍨2÷⍨⍴A←⍞~' '

Вы получаете, DOMAIN ERRORесли есть дубликат карты.

Объяснение:

  • A←⍞~' ': store ( ) в Aстроку пользовательского ввода ( ) без ( ~) пробелов.
  • 2,⍨2÷⍨⍴A: двухэлементный список, содержащий длину ( ), Aразделенную на ( ÷⍨) 2, за которой следует ( ,⍨) число 2. (Таким образом, если входной сигнал представляет UA OB DL KHсобой список (4, 2)).
  • ↓A⍴⍨: определить matrix ( ) с измерениями этого списка, содержащими значения A. Затем соединить элементы его строк вместе ( ), дав, например, список списков ['UA','OB','DL','KH'].
  • A←: Сохранить этот список в A.
  • A≡∪A: ∪Aсписок уникальных элементов в A. Если он равен A, дубликатов нет, и это возвращает 1, иначе 0.
  • ÷: разделить то, что слева (что делает фактический расчет) на результат теста на равенство. Таким образом, если дубликатов нет, результат остается неизменным, а при наличии дубликатов вы получаете оценку DOMAIN ERRORиз-за деления на ноль.
  • ⊃¨A: Список, в котором указан первый элемент ( ) каждого элемента ( ¨) в A. Таким образом, это исключает букву масти, оставляя букву партитуры. ( UODK)
  • 'D0.....KOU.'⍳: дает индекс каждой из букв счета в этой строке, возвращает 12 для значений не в строке. ( 10 9 1 8)
  • +/12-: вычтите все это из 12, а затем сложите их вместе. ( 2 + 3 + 11 + 4 = 20)


Мне совершенно не хватало того, что ваш ответ самый короткий.
FUZxxl

10

Ruby 1.9, 52 символа

Ввод через аргументы командной строки. Я предполагаю, что сообщение об ошибке, когда наличие дублирующих карт не имеет значения, поэтому просто жалуется на ошибку преобразования eval / type.

p eval$*.uniq!||$*.map{|i|"..UOK#$<.0D"=~/#{i}?/}*?+

Пример использования:

$ ruby1.9 skatscore.rb 7A 8A 9A UA OA KA 0A DA 7L 8L 9L UL OL KL 0L DL 7H 8H 9H UH OH KH 0H DH 7B 8B 9B UB OB KB 0B DB
120

$ ruby1.9 skatscore.rb 7A 7A
skatscore.rb:1:in `eval': can't convert Array into String (TypeError)
    from skatscore.rb:1:in `<main>'

С одной стороны, я думаю, что неопределенная ошибка переменной для дубликатов карт является довольно слабой. С другой стороны, это не нарушает правила, поэтому это довольно умно.
Игби Большой человек

1
@Charles: Поскольку спецификация вызывает только с ошибкой, я думаю , что ошибка именно в значительной степени не имеет значения. И если есть короткие методы создания какой-либо ошибки, то, наверное, все будет в порядке.
Джои

6

Scala, 87 82 персонажа

args.distinct(args.size-1);println(args.map(a=>1+" UOK     0D".indexOf(a(0))).sum)

Выдает исключение на повторных картах.


4

Haskell, 122 108 107 символов

import List
main=interact$f.words
f x|nub x==x=show$sum$map(maybe 0 id.(`elemIndex`"  UOK     0D").head)x

error""короче чем undefined. Сохраните один символ, используя interact.
FUZxxl

@FUZxxl: использование interactэтого не будет печатать новую строку , поэтому я не уверен, что это приемлемо. Тем не менее, я смог сэкономить гораздо больше, используя неполный шаблон вместо undefined.
Хаммар

Где я сказал, что нужен перевод строки? Я не могу вспомнить
FUZxxl

2

GolfScript 54 53 52

Изменить 1:

Я только что обнаружил ошибку в коде. Он не обнаружил дубликаты карт, если дубликаты были первыми двумя на входе (потому что я использовал *оператор сгиба, а не /оператор каждого для первого цикла).

Теперь я исправил код, а также смог убрать 1 символ в процессе. Вот новая версия:

' '/{1$1$?){]?}{\+}if}/2%{"UOK0D"\?).0>+.4>5*+}%{+}*

Входные данные должны быть в стеке в виде строки в указанном формате (пример:) '7A UA DA'.

Если введенные данные верны, программа напечатает общую стоимость карточек.

Если есть хотя бы одна дублирующаяся карта, программа выдает следующее исключение:

(eval):1:in `block in initialize': undefined method `class_id' for nil:NilClass (NoMethodError)

Изменить 2:

Увидев этот пост на мета-сайте , я решил опубликовать описание кода. Это также помогло мне найти и исправить ошибку. Итак, здесь идет:

# Initially, we epect the input string to be on the stack
# Example: "7A UA DA"

' '/            # split the input string by spaces
                # now we have on the stack an array of strings
                # (in our example: ["7A" "UA" "DA"])

# {1$1$?)!{\+}{]?}if}/  -> this piece of code checks for duplicate cards
#
# The trailing symbol (/) is the 'each' operator, meaning that the 
# preceding code block (enclosed in curly brackets) will be executed 
# for every cards in the previous array.
#
# Before each execution of the code block, the current card value
# is pushed on the stack.
#
# Basically what this code does is concatenate cards into a string
# and checks whether the current card is contained in the accumulated
# value.
#
# So, for each card, this is what we execute:

1$              # copies the concatenated string on top of the stack
                # (initially this is an empty string)

1$              # copies the current card on top of the stack

?               # returns (places on the stack) the 0-based index where 
                # the current card is found in the concatenated string
                # or -1 if not found

)               # increments the topmost stack value
                # Now we have 0 if the card is not a duplicate
                # or a value greater than 0 otherwise

{]?}{\+}if      # if the current stack value is non-0 (duplicate)
                # then execute the first code {]?} (generates an error)
                # Otherwise, if the card is valid, execute the {\+} block.
                # What this code does is essentially concatenate the current 
                # card value:
                #    \ -> swaps the two topmost stack values; now we have
                #         the concatenated string and the current card value
                #    + -> this is the concatenation operator

# After the previous code block finishes execution (in case the input is)
# valid, we end up having the concatenated card values on the stack
# In our example, this value is "DAUAUB7A".

# The next code fragment is the one that computes the card values
# This is the code: 2%{"UOK0D"\?).0>+.4>5*+}%{+}*

# And this is how it can be broken down:

2%              # takes only the even indexed chars from the existing string 
                # in our case, "DAUA7A" -> "DU7"
                # Only these characters are important for determining the 
                # card values.

# The following piece of code is:
# {"UOK0D"\?).0>+.4>5*+}%

# This code performs a map; it takes the individual chars,
# computes the corresponding numeric value for each of them and outputs an
# array containing those values

# This is achieved using the map operator (%) which evaluates the preceding 
# code block, delimited by curly braces, so, essentially this is the code that 
# computes the value for a card:
# "UOK0D"\?).0>+.4>5*+
# It can be broken down like this:

"UOK0D"         # pushes the "UOK0D" string on the stack
\               # swaps the two topmost stack values
                # Now, these values are: "UOK0D" and "l" 
                # (where "l" represents the current letter
                # that gives the card its value: U,O,K,0,D,7,8...)

?               # Find the index of the card's letter in the
                # "UOK0D" string.
                # Remember, this is 0-based index, or -1 if not found.

)               # increment the index value
                # Now we have the following value:
                #     1 if the card is U
                #     2 if the card is O
                #     3 if the card is K
                #     4 if the card is 0
                #     5 if the card is D
                #     0 if it is anything else

.0>+            # if the current value is greater than 0,
                # add 1 to it.

.4>5*+          # if the current value is greater than 4,
                # add 5 to it.

# Passing through these steps, we now have the following value:
#     2  if the card is U
#     3  if the card is O
#     4  if the card is K
#     10 if the card is 0
#     11 if the card is D
#     0  if it is anything else
# This is the exact value we were looking for.

# Now we have an array containing the value of each card.
# in our example, [0, 2, 11]
# The next piece of code is easy:

{+}*            # uses the * (fold) operator to add up all the
                # values in the array.

# This leaves the total value of the cards on the stack,
# which is exactly what we were looking for (0+2+11=13).

# Golfscript is awesome! :-)

1

Python, 114 символов

i=input().split();print(sum(int(dict(zip('7890UOKD','000A234B'))[x[0]],16)for x in i)if len(i)<=len(set(i))else'')

К сожалению, indexметод списков в Python вызывает ошибку, если элемент не найден, а не возвращает отрицательное значение, и для импорта defaultdictпотребуется больше символов, чем будет сохранено.


1

eTeX, 201 символ (не считая двух нерелевантных разрывов строк)

\def~#1#2{\catcode`#113\lccode`~`#1\lowercase{\def~}##1 {\ifcsname
#1##1 ~\D\fi\if\csname#1##1 ~\fi+"#2}}~70~80~90~0A~U2~O3~K4~DB\def
\a[#1]{\let~\endcsname\write6{^^J \the\numexpr#1 }\end}\expandafter\a

Используется как etex filename.tex [UA OB DL KH] . Необходимо поместить аргумент в квадратные скобки: в противном случае eTeX не может определить, что мы достигли конца списка аргументов.

РЕДАКТИРОВАТЬ: как разрешено в постановке вопроса, неправильный ввод может вызвать () ошибку. Например, etex filename.tex [OK]ужасно падает (потому что Kэто не правильный цвет).


Не работает на моей машине.
FUZxxl

@FUZxxl. Какой выход etex -v? Что за сообщение об ошибке (примерно)? Код должен быть помещен в файл (с именем filename.texили чем-либо еще, оканчивающимся на .tex) и использовать это имя в командной строке etex filename.tex [<argument>]. (извините за перепост того же комментария, я забыл " @FUZxxl")
Бруно Ле Флох

Пожалуйста, смотрите здесь: hpaste.org/48949
FUZxxl

@FUZxxl. Спасибо за ваш отзыв. Kне является допустимым цветом, и замена его Xв ваших примерах удаляет ошибки (с ошибкой, Kпотому что эта буква имеет другое значение, Кинг). Я мог бы сделать ошибку менее ужасной, добавив \stringперед каждым ##1, но это будет стоить еще 12 символов.
Бруно Ле Флох

Сожалею. Я неправильно набрал пример. Это работает сейчас. Сожалею.
FUZxxl

1

PowerShell, 79 80

($a=$args|sort)|%{$s+=(10,11+4..0)['0DKOU'.IndexOf($_[0])]}
$s/("$a"-eq($a|gu))

Броски »Попытка делить на ноль.«, Если карты появляются дважды.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.