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! :-)