Điểm số cho Skat


11

Nhiệm vụ của bạn là viết một chương trình nhỏ, tính điểm của một tay Skat. Một bộ bài Skat có các thẻ từ 7 đến 10, Jack, Queen, King và Ace (được gọi là Unter, Ober, König và Daus). Chúng tôi sử dụng bộ đồ Đức, có Acorns, Lá, Trái tim và Chuông thay vì Câu lạc bộ, Spades, Trái tim và Kim cương. Điểm được xác định bằng số trên thẻ:

  • 7, 8 và 9 là 0 điểm
  • Unter là 2 điểm
  • Ober là 3 điểm
  • König là 4 điểm
  • 10 là 10 điểm
  • Daus là 11 điểm.

Đầu ra đầu vào

Định dạng đầu vào bao gồm hai biểu tượng, biểu tượng đầu tiên đại diện cho giá trị, trong khi biểu tượng thứ hai là viết tắt của phù hợp:

  • 7, 8 và 9 đứng cho họ tự
  • 0 (không) là viết tắt của 10
  • Unter, Ober, König và Daus được đặt theo tên của các chữ cái đầu tiên (U, O và D)
  • Tương tự cho Acorns, Lá, Trái tim và Bụng (A, L, H và B)

Đầu vào là một dòng thẻ duy nhất, cách nhau bởi một khoảng trắng. Bạn có thể lấy đầu vào từ bất cứ đâu, đối số dòng lệnh cũng không sao. Đầu ra là giá trị của tay, được in ra hoặc trả lại dưới dạng mã thoát. Đầu ra của chương trình của bạn phải hiển thị lỗi, nếu có bất kỳ thẻ nào xuất hiện hai lần trong tay. (Vì vậy, 7A 0L 7Aphải trả lại một lỗi thay vì 10). Bạn cũng có thể thoát ra với mã thoát là 255 thay vì hiển thị lỗi, nếu đây là cách mặc định của chương trình để đưa ra kết quả.

Ví dụ

  • 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 DBcho 120
  • 7A 8L 0K DB 8L báo lỗi
  • UA OB DL KHcho 20

Quy tắc

  • Code golf: Mã ngắn nhất thắng
  • Quy tắc golf thông thường áp dụng
  • Chương trình phải làm việc cho tất cả các tay, không chỉ các ví dụ
  • GIGO: Nếu đầu vào không hợp lệ, đầu ra có thể tùy ý

Đầu ra bổ sung cho thiết bị lỗi chuẩn (ví dụ: cảnh báo) có ổn không?
Ventero

@Ventero: Vâng, đúng vậy. Bất kỳ cách nào để sửa lỗi là được, nhưng nó phải được hiển thị rõ ràng cho người dùng, rằng có lỗi.
FUZxxl

Jack, Queen và Ace được gọi là Unter, Ober, King và Daus? Là một vị vua được cho là ở đó?
Ry-

@minitech Không, không phải vậy.
FUZxxl

2
Tôi tin rằng bạn có nghĩa là "chuông", không phải "bụng". Rất khác nhau, đó.
gian hàng

Câu trả lời:


2

APL ( 54 48)

Phải một cách ngắn hơn để chọn giá trị thẻ, nhưng tôi không thấy nó.

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

Bạn nhận được DOMAIN ERRORnếu có một thẻ trùng lặp.

Giải trình:

  • A←⍞~' ': store ( ) vào Amột dòng đầu vào của người dùng ( ) không có ( ~) khoảng trắng.
  • 2,⍨2÷⍨⍴A: danh sách hai phần tử, chứa độ dài của ( ) Achia cho ( ÷⍨) 2, theo sau là ( ,⍨) số 2. (Vì vậy, nếu đầu vào là UA OB DL KHdanh sách là (4, 2)).
  • ↓A⍴⍨: xác định một ma trận ( ), với các kích thước của danh sách đó, chứa các giá trị của A. Sau đó nối các phần tử của các hàng với nhau ( ), ví dụ, đưa ra một danh sách các danh sách ['UA','OB','DL','KH'].
  • A←: Lưu trữ danh sách này trong A.
  • A≡∪A: ∪Alà danh sách các phần tử duy nhất trong A. Nếu giá trị này bằng A, không có trùng lặp và điều này trả về 1, nếu không thì 0.
  • ÷: chia những gì ở bên trái (tính toán thực tế) cho kết quả của phép thử đẳng thức. Vì vậy, nếu không có trùng lặp, điểm số không thay đổi và nếu có trùng lặp, bạn nhận được a DOMAIN ERRORvì chia cho số không.
  • ⊃¨A: Một danh sách đưa ra phần tử đầu tiên ( ) của mỗi phần tử ( ¨) của A. Vì vậy, phần này sẽ bỏ chữ cái phù hợp, để lại chữ cái. ( UODK)
  • 'D0.....KOU.'⍳: đưa ra chỉ mục của từng chữ cái trong chuỗi này, trả về 12 cho các giá trị không nằm trong chuỗi. ( 10 9 1 8)
  • +/12-: trừ tất cả những thứ này từ 12, rồi cộng chúng lại với nhau. ( 2 + 3 + 11 + 4 = 20)


Tôi hoàn toàn bỏ lỡ rằng câu trả lời của bạn là ngắn nhất.
FUZxxl

10

Ruby 1.9, 52 ký tự

Nhập thông qua đối số dòng lệnh. Tôi giả sử thông báo lỗi khi có thẻ trùng lặp không thành vấn đề, vì vậy nó chỉ phàn nàn về lỗi chuyển đổi eval / type.

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

Ví dụ sử dụng:

$ 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>'

Một mặt tôi nghĩ rằng lỗi biến không xác định cho các thẻ trùng lặp là hơi khập khiễng. Mặt khác, nó không phá vỡ các quy tắc, vì vậy nó khá thông minh.
Igby Largeeman

1
@Charles: Kể từ spec chỉ đòi hỏi một lỗi, tôi đoán những gì lỗi chính xác là khá nhiều không liên quan. Và nếu có các phương pháp ngắn để tạo ra bất kỳ lỗi nào, điều đó sẽ ổn thôi, tôi đoán vậy.
Joey

6

Scala, 87 82 ký tự

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

Ném một ngoại lệ trên thẻ lặp đi lặp lại.


4

Haskell, 122 108 107 ký tự

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

error""ngắn hơn undefined. Lưu một char bằng cách sử dụng interact.
FUZxxl

@FUZxxl: Sử dụng interactnó sẽ không in một dòng mới, vì vậy tôi không chắc liệu điều đó có được chấp nhận hay không. Tuy nhiên, tôi đã có thể tiết kiệm nhiều hơn bằng cách sử dụng một mẫu không hoàn chỉnh thay vì undefined.
hammar

Tôi đã nói ở đâu, rằng một dòng mới là cần thiết? Tôi không thể nhớ.
FUZxxl

2

GolfScript 54 53 52

Chỉnh sửa 1:

Tôi chỉ phát hiện ra một lỗi trong mã. Nó không phát hiện các thẻ trùng lặp nếu các bản sao là hai đầu tiên trong đầu vào (vì tôi đang sử dụng *toán tử gấp chứ không phải /mỗi toán tử cho vòng lặp đầu tiên).

Bây giờ tôi đã sửa mã và cũng quản lý để loại bỏ 1 char trong quá trình này. Đây là phiên bản mới:

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

Đầu vào phải nằm trên ngăn xếp dưới dạng chuỗi, theo định dạng đã chỉ định (ví dụ '7A UA DA':).

Trong trường hợp đầu vào hợp lệ, chương trình sẽ in tổng giá trị của thẻ.

Trong trường hợp có ít nhất một thẻ trùng lặp, chương trình sẽ ném ngoại lệ sau:

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

Chỉnh sửa 2:

Sau khi thấy bài đăng này trên trang web meta , tôi quyết định đăng một mô tả về mã. Điều này cũng giúp tôi tìm và sửa lỗi. Vì vậy, ở đây đi:

# 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

Con trăn, 114 ký tự

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

Thật không may, indexphương pháp danh sách trong Python gây ra lỗi nếu không tìm thấy phần tử thay vì trả về giá trị âm và việc nhập defaultdictsẽ yêu cầu nhiều ký tự hơn mức tiết kiệm.


1

eTeX, 201 ký tự (không tính hai lần ngắt dòng không liên quan)

\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

Được sử dụng như etex filename.tex [UA OB DL KH]. Đặt đối số trong ngoặc là cần thiết: nếu không, eTeX không có cách nào xác định rằng chúng tôi đã đạt đến cuối danh sách đối số.

EDIT: như được cho phép trong tuyên bố của câu hỏi, đầu vào không chính xác có thể gây ra (một) lỗi. Chẳng hạn, etex filename.tex [OK]sự cố khủng khiếp (vì Kkhông phải là màu hợp lệ).


Không hoạt động trên máy của tôi.
FUZxxl

@FUZxxl. Đầu ra của là etex -vgì? Thông báo lỗi (đại khái) là gì? Mã phải được đặt trong một tệp (có tên filename.texhoặc bất kỳ thứ gì khác kết thúc .tex) và sử dụng tên đó trong dòng lệnh etex filename.tex [<argument>]. (xin lỗi vì đăng lại cùng một bình luận, tôi đã quên " @FUZxxl")
Bruno Le Floch

Xin vui lòng xem tại đây: hpaste.org/48949
FUZxxl

@FUZxxl. Cảm ơn phản hôi của bạn. Kkhông phải là màu hợp lệ và việc thay thế nó bằng Xcác ví dụ của bạn sẽ loại bỏ các lỗi (nó bị lỗi Kvì chữ đó có nghĩa khác, King). Tôi có thể làm cho lỗi ít kinh khủng hơn bằng cách thêm vào \stringtrước mỗi lỗi ##1, nhưng điều đó sẽ tốn thêm 12 ký tự.
Bruno Le Floch

Lấy làm tiếc. Tôi đã đánh lạc hướng ví dụ. Nó hoạt dộng bây giờ. Lấy làm tiếc.
FUZxxl

1

PowerShell, 79 80

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

Ném »Đã cố chia cho số không.« Nếu thẻ xuất hiện hai lần.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.