Skip to main content
better way of testing for duplicates
Source Link
marinus
  • 31.3k
  • 7
  • 73
  • 112

APL (5454 48)

There has to be a shorter way of selecting the card value, but I don't see it.

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

You get a DOMAIN ERROR if there's a duplicate card.

Explanation:

  • A←⍞~' ': store () into A a line of user input () without (~) the spaces.
  • 2,⍨2÷⍨⍴A: a two-element list, containing the length of () A divided by (÷⍨) 2, followed by (,⍨) the number 2. (So, if the input is UA OB DL KH the list is (4, 2)).
  • ,/A⍴⍨↓A⍴⍨: define a matrix (), with the dimensions of that list, containing the values of A. Then join the elements of its rows together (,/), giving a list of lists, for example ['UA','OB','DL','KH'].
  • A←: Store this list in A.
  • (⍳⍴A)≡A⍳AA≡∪A: ⍳⍴A is a list from 1 to () the length () of A, and A⍳A∪A is a list of the indexlist of the first occurrenceunique elements in A of each element of A. These two lists areIf this is equal iffto A, there are no duplicates in A. The equality test ()and this returns 1 if they are equal (so no duplicates) and, otherwise 0 if not.
  • ÷: divide what's on the left (which does the actual calculation) by the result of the equality test. So if there are no duplicates, the score is unchanged, and if there are duplicates you get a DOMAIN ERROR because of the division by zero.
  • ⊃¨A: A list giving the first element () of each element (¨) of A. So this drops the suit letter, leaving the score letter. (UODK)
  • 'D0.....KOU.'⍳: gives the index of each of the score letters in this string, returns 12 for values not in the string. (10 9 1 8)
  • +/12-: subtract all of these from 12, and then add them together. (2 + 3 + 11 + 4 = 20)

APL (54)

There has to be a shorter way of selecting the card value, but I don't see it.

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

You get a DOMAIN ERROR if there's a duplicate card.

Explanation:

  • A←⍞~' ': store () into A a line of user input () without (~) the spaces.
  • 2,⍨2÷⍨⍴A: a two-element list, containing the length of () A divided by (÷⍨) 2, followed by (,⍨) the number 2. (So, if the input is UA OB DL KH the list is (4, 2)).
  • ,/A⍴⍨: define a matrix (), with the dimensions of that list, containing the values of A. Then join the elements of its rows together (,/), giving a list of lists, for example ['UA','OB','DL','KH'].
  • A←: Store this list in A.
  • (⍳⍴A)≡A⍳A: ⍳⍴A is a list from 1 to () the length () of A, and A⍳A is a list of the index of the first occurrence in A of each element of A. These two lists are equal iff there are no duplicates in A. The equality test () returns 1 if they are equal (so no duplicates) and 0 if not.
  • ÷: divide what's on the left (which does the actual calculation) by the result of the equality test. So if there are no duplicates, the score is unchanged, and if there are duplicates you get a DOMAIN ERROR because of the division by zero.
  • ⊃¨A: A list giving the first element () of each element (¨) of A. So this drops the suit letter, leaving the score letter. (UODK)
  • 'D0.....KOU.'⍳: gives the index of each of the score letters in this string, returns 12 for values not in the string. (10 9 1 8)
  • +/12-: subtract all of these from 12, and then add them together. (2 + 3 + 11 + 4 = 20)

APL (54 48)

There has to be a shorter way of selecting the card value, but I don't see it.

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

You get a DOMAIN ERROR if there's a duplicate card.

Explanation:

  • A←⍞~' ': store () into A a line of user input () without (~) the spaces.
  • 2,⍨2÷⍨⍴A: a two-element list, containing the length of () A divided by (÷⍨) 2, followed by (,⍨) the number 2. (So, if the input is UA OB DL KH the list is (4, 2)).
  • ↓A⍴⍨: define a matrix (), with the dimensions of that list, containing the values of A. Then join the elements of its rows together (), giving a list of lists, for example ['UA','OB','DL','KH'].
  • A←: Store this list in A.
  • A≡∪A: ∪A is the list of unique elements in A. If this is equal to A, there are no duplicates and this returns 1, otherwise 0.
  • ÷: divide what's on the left (which does the actual calculation) by the result of the equality test. So if there are no duplicates, the score is unchanged, and if there are duplicates you get a DOMAIN ERROR because of the division by zero.
  • ⊃¨A: A list giving the first element () of each element (¨) of A. So this drops the suit letter, leaving the score letter. (UODK)
  • 'D0.....KOU.'⍳: gives the index of each of the score letters in this string, returns 12 for values not in the string. (10 9 1 8)
  • +/12-: subtract all of these from 12, and then add them together. (2 + 3 + 11 + 4 = 20)

Source Link
marinus
  • 31.3k
  • 7
  • 73
  • 112

APL (54)

There has to be a shorter way of selecting the card value, but I don't see it.

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

You get a DOMAIN ERROR if there's a duplicate card.

Explanation:

  • A←⍞~' ': store () into A a line of user input () without (~) the spaces.
  • 2,⍨2÷⍨⍴A: a two-element list, containing the length of () A divided by (÷⍨) 2, followed by (,⍨) the number 2. (So, if the input is UA OB DL KH the list is (4, 2)).
  • ,/A⍴⍨: define a matrix (), with the dimensions of that list, containing the values of A. Then join the elements of its rows together (,/), giving a list of lists, for example ['UA','OB','DL','KH'].
  • A←: Store this list in A.
  • (⍳⍴A)≡A⍳A: ⍳⍴A is a list from 1 to () the length () of A, and A⍳A is a list of the index of the first occurrence in A of each element of A. These two lists are equal iff there are no duplicates in A. The equality test () returns 1 if they are equal (so no duplicates) and 0 if not.
  • ÷: divide what's on the left (which does the actual calculation) by the result of the equality test. So if there are no duplicates, the score is unchanged, and if there are duplicates you get a DOMAIN ERROR because of the division by zero.
  • ⊃¨A: A list giving the first element () of each element (¨) of A. So this drops the suit letter, leaving the score letter. (UODK)
  • 'D0.....KOU.'⍳: gives the index of each of the score letters in this string, returns 12 for values not in the string. (10 9 1 8)
  • +/12-: subtract all of these from 12, and then add them together. (2 + 3 + 11 + 4 = 20)