Skatのスコアカウンター


11

あなたの仕事は、Skatの手のポイントを数える小さなプログラムを書くことです。Skatデッキには7〜10枚のカード、Jack、Queen、King、Ace(Unter、Ober、König、Dausと呼ばれる)があります。クラブ、スペード、ハート、ダイアモンドの代わりに、ドングリ、葉、ハート、ベルのあるドイツのスーツを使用します。ポイントはカードの番号によって決まります:

  • 7、8、9は0ポイントです
  • ウンターは2ポイントです
  • Oberは3ポイントです
  • ケーニヒは4ポイントです
  • 10は10ポイントです
  • ダウスは11ポイントです。

入出力

入力形式は2つの記号で構成されます。最初の記号は値を表し、2番目の記号はスーツを表します。

  • 7、8、および9はそれらの自己を表します
  • 0(ゼロ)は10を表します
  • ウンター、オーバー、ケーニヒ、ダウスは、最初の文字(U、O、D)にちなんで命名されています
  • ドングリ、葉、ハート、ベリーについても同じ(A、L、H、B)

入力は、単一の空白で区切られた単一行のカードです。どこからでも入力を取得できますが、コマンドライン引数も使用できます。出力は手の値であり、出力されるか、終了コードとして返されます。手にカードが2回表示された場合、プログラムの出力にエラーが表示される必要があります。(したがって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 DB120を与える
  • 7A 8L 0K DB 8L エラーを与える
  • UA OB DL KH20を与える

ルール

  • コードゴルフ:最短のコードが勝ちます
  • 通常のゴルフ規則が適用されます
  • プログラムは、例だけでなく、すべての人のために機能する必要があります
  • GIGO:入力が無効な場合、出力は任意である可能性があります

stderrへの追加出力(警告など)は大丈夫ですか?
ヴェンテロ

@Ventero:はい、そうです。エラーを発生させる方法は何でも構いませんが、エラーがあることはユーザーにはっきりと見える必要があります。
-FUZxxl

ジャック、クイーン、エースはウンター、オーバー、キング、ダウスと呼ばれていますか?王はそこにいるはずですか?
Ry-

@minitechいいえ、そうではありません。
-FUZxxl

2
私はあなたが「鐘」ではなく「鐘」を意味すると信じています。非常に異なる、それ。
ブースバイ

回答:


2

APL(54 48)

カードの値を選択する方法はもっと短くする必要がありますが、わかりません。

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

DOMAIN ERROR重複するカードがある場合に取得します。

説明:

  • A←⍞~' ':()をスペースなしで()Aユーザー入力の行に保存します。~
  • 2,⍨2÷⍨⍴A2つの要素のリストの長さ(を含むA(で割った値÷⍨が続く)2、( ,⍨)番号2を(入力されたのであれば、UA OB DL KHリスト(4、2))。
  • ↓A⍴⍨Aの値を含むそのリストの次元で行列()を定義します。次に、その行の要素を結合し()、リストのリストを与えます['UA','OB','DL','KH']
  • A←:このリストをAに保存します。
  • A≡∪A∪AAの一意の要素のリストです。これがAに等しい場合、重複はなく、1を返します。それ以外の場合は0を返します。
  • ÷:左側にあるもの(実際の計算を行うもの)を等価性テストの結果で除算します。したがって、重複がない場合、スコアは変更されず、重複がある場合DOMAIN ERROR、ゼロによる除算によりaを取得します。
  • ⊃¨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

ハスケル、 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。を使用して1つの文字を保存しますinteract
-FUZxxl

@FUZxxl:これを使用しinteractても改行は出力されないので、それが受け入れられるかどうかはわかりません。ただし、の代わりに不完全なパターンを使用することで、さらに多くの節約ができましたundefined
ハンマー

どこで改行が必要だと言ったのですか?思い出せません。
-FUZxxl

2

GolfScript 54 53 52

編集1:

コードにエラーを発見しました。重複が入力の最初の2つである場合、重複カードを検出しませんでした(最初のループで各演算子では*なく、fold演算子を使用していた/ため)。

今、私はコードを修正し、その過程で1文字を取り除くこともできました。新しいバージョンは次のとおりです。

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

入力は、指定された形式(例:)で文字列としてスタック上になければなりません'7A UA DA'

入力が有効な場合、プログラムはカードの合計値を印刷します。

重複するカードが少なくとも1つある場合、プログラムは次の例外をスローします。

(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'')

残念ながら、indexPythonのリストのメソッドは、負の値を返すのではなく要素が見つからない場合にエラーを発生させ、インポートdefaultdictには保存するよりも多くの文字が必要になります。


1

eTeX、201文字(2つの無関係な改行をカウントしない)

\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その文字にはキングという別の意味があるためクラッシュします)。\stringeachの前に追加することでエラーの恐ろしさを減らすことができました##1が、それはさらに12文字のコストがかかりました。
ブルーノルフロック

ごめんなさい。例の入力ミス。今は動作します。ごめんなさい。
FUZxxl

1

PowerShell、79 80

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

投げる»ゼロで割ろうとしました。«カードが2回現れる場合。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.