### GolfScript <s>54</s> <s>53</s> 52

**Edit 1:**

I just discovered an error in the code. It did not detect duplicate cards if the duplicates were the first two in the input (because I was using the `*` fold operator and not the `/` each operator for the first loop).

Now I fixed the code and also managed to strip off 1 char in the process. Here's the new version:

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

The input has to be on the stack as a string, in the specified format (example: `'7A UA DA'`).

In case the input is valid, the program prints the total value of the cards.

In case there's at least one duplicate card, the program throws the following exception:

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

**Edit 2:**

After seeing [this post on the meta site][1], I decided to post a description of the code. This also helped me find and fix an error. So, here goes:

	# 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]: https://codegolf.meta.stackexchange.com/questions/88/on-golfscript-and-language-bigotry