Table of contents

Beginner J: Dealing Cards

videoyt

%3 cluster_a9d1cd55_b25d_491f_aefd_f3d79085eb7a Beginner J: Dealing Cards cluster_5b8375e6_8a03_402f_be5c_aad6fd19bbb6 Code _9dd8f637_fc36_403f_afa8_d7f33d7f0844 Chap 2. Enumeration _6823a3eb_4911_4a73_89bd_4c115e65e5a9 Chap 5. Permutations _525765f7_55d9_4428_8536_fe993f96d2fc Chap 4. Shuffling _596e383d_3bf6_41eb_8d02_8974572f4638 Chap 7. Anagrams _9e017f8d_49ca_4af4_8ebd_8d31a9e68550 Chap 3. Card lookup _d453d577_4f7e_4a50_a30d_56720f54e1ce J (programming language) _9e017f8d_49ca_4af4_8ebd_8d31a9e68550->_d453d577_4f7e_4a50_a30d_56720f54e1ce _ff2d9687_e515_4012_8747_2e78d1a3b886 Chap 1. The deck _4f3fda90_85d2_4774_8bde_bb82ece96bfb Chap 6. Permutation table __0:cluster_a9d1cd55_b25d_491f_aefd_f3d79085eb7a->_d453d577_4f7e_4a50_a30d_56720f54e1ce

A introductory video, on which the narrator gives a step by step explanation on how a deck of cards can be modelled in J and how some basic operations like item lookups or shuffling can be done on that language.

It's feels like a great introduction to the programming language, as it gives an idea on how operations work in J.

Code

Chap 1. The deck

These are some personal notes as I typed the code along the video. Go see the video, is pretty quick!

suits =: 'cdhs'  NB. A standard card deck has 4 suits: Clubs, Diamons, Hearts, Spades
ranks =: '23456789TJQKA'  NB. 13 numbers of cards

NB. Show all combinations with the catalog `{` operator
|: { ranks; suits

┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│2c│3c│4c│5c│6c│7c│8c│9c│Tc│Jc│Qc│Kc│Ac│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│2d│3d│4d│5d│6d│7d│8d│9d│Td│Jd│Qd│Kd│Ad│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│2h│3h│4h│5h│6h│7h│8h│9h│Th│Jh│Qh│Kh│Ah│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│2s│3s│4s│5s│6s│7s│8s│9s│Ts│Js│Qs│Ks│As│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘

NB. The `;` puts the two strings into boxes
ranks ; suits

┌─────────────┬────┐
│23456789TJQKA│cdhs│
└─────────────┴────┘

NB. Catalog `{` takes every combination of the boxed values
{ ranks; suits

┌──┬──┬──┬──┐
│2c│2d│2h│2s│
├──┼──┼──┼──┤
│3c│3d│3h│3s│
├──┼──┼──┼──┤
│4c│4d│4h│4s│
├──┼──┼──┼──┤
│5c│5d│5h│5s│
├──┼──┼──┼──┤
│6c│6d│6h│6s│
├──┼──┼──┼──┤
│7c│7d│7h│7s│
├──┼──┼──┼──┤
│8c│8d│8h│8s│
├──┼──┼──┼──┤
│9c│9d│9h│9s│
├──┼──┼──┼──┤
│Tc│Td│Th│Ts│
├──┼──┼──┼──┤
│Jc│Jd│Jh│Js│
├──┼──┼──┼──┤
│Qc│Qd│Qh│Qs│
├──┼──┼──┼──┤
│Kc│Kd│Kh│Ks│
├──┼──┼──┼──┤
│Ac│Ad│Ah│As│
└──┴──┴──┴──┘

NB. Then `|:` transposes it
|: { ranks; suits

┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
│2c│3c│4c│5c│6c│7c│8c│9c│Tc│Jc│Qc│Kc│Ac│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│2d│3d│4d│5d│6d│7d│8d│9d│Td│Jd│Qd│Kd│Ad│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│2h│3h│4h│5h│6h│7h│8h│9h│Th│Jh│Qh│Kh│Ah│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
│2s│3s│4s│5s│6s│7s│8s│9s│Ts│Js│Qs│Ks│As│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘

s: |: { ranks; suits

`2c `3c `4c `5c `6c `7c `8c `9c `Tc `Jc `Qc `Kc `Ac
`2d `3d `4d `5d `6d `7d `8d `9d `Td `Jd `Qd `Kd `Ad
`2h `3h `4h `5h `6h `7h `8h `9h `Th `Jh `Qh `Kh `Ah
`2s `3s `4s `5s `6s `7s `8s `9s `Ts `Js `Qs `Ks `As

NB. Now let's save the result
by_suit =: , s: |: { ranks; suits
by_rank =: , s: { ranks; suits

deck =: by_rank

Chap 2. Enumeration

#deck  NB. Size of the array

52

4 {. deck  NB. First 4 elements

`2c `2d `2h `2s

_4 {. deck  NB. Last 4 elements

`Ac `Ad `Ah `As

23 { deck  NB. Get card num. 23

`7s

NB. Indexes start at 0
0 51 { deck  NB. Get first card and last (num. 15)

`2c `As

_1 { deck  NB. Can also get the last like this

`As

Chap 3. Card lookup

NB. To find a card (which is a Symbol) we cannot use directly strings
'Qh'

Qh

NB. We have to box the string
<'Qh'

┌──┐
│Qh│
└──┘

NB. Then pass it to `s:`
s:<'Qh'

`Qh
NB. Or use a space as "fret" character, which allows us to define
NB. multiple symbols at once (note no `<`)
s:' Qh As 3d'

`Qh `As `3d
NB. Find the symbols in the deck
deck i. s:' Qh As 3d'

42 51 5

  • At this point the video explains why the use of symbols is preferred ( https://youtu.be/eXGKK8BkCkg?t=115 ) The reason is that requires less typing than boxed strings, and unboxed strings (in other cases, but not here) might have different lengths. J arrays have to be rectangular, so it seems it's not a good practice to build string matrices in general (and symbols seem a better fit here).

Chap 4. Shuffling

NB. Get a random number less than 52
? 52

16

NB. Get a random card
(? 52) { deck

`Ks

NB. Alternative form
deck {~ ? 52

`7c

NB. Get multiple random numbers, without duplicates
5 ? 52

41 24 31 9 38

  • At this point the video explains how to get random numbers with duplicates https://youtu.be/eXGKK8BkCkg?t=182

  • Personal curiosity... what happens if we ask for more random numbers than is possible to have unduplicated? We get an error

NB. Get more unduplicated random numbers than there are possible
10 ? 5

|domain error
  |   10    ?5

  • Back to the video...

NB. Get multiple random cards
deck {~ 5 ? 52

`Tc `Kh `Jd `As `8c

NB. Get all cards randomized
deck {~ 52 ? 52

`Tc `4c `5c `5d `6h `Jd `Kc `Js `2c `9d `Kh `9c `7c `Qd `Ah `6s `Td `7h `Th `9h `5s `Kd `3h `8c `Qh `6d `Qs `8h `As `8d `9s `Ts `Ac `4d `7d `4s `3s `Jh `Jc `2s `2h `4h `Ad `3c `3d `2d `5h `7s `8s `6c `Qc `Ks

NB. Simplified, the `~` passes the same argument to the two sides of a verb.
NB. But the `~` on the `{` verb swaps the arguments!
deck {~ ?~ 52

`Td `Kd `3s `6d `Tc `As `8d `4d `3c `5c `Ac `Ad `4c `4h `8s `Qh `Kh `Qd `2d `2c `4s `3h `Kc `Qs `Ts `6c `2h `6h `Qc `7d `Jh `7h `9h `2s `5d `9s `3d `Jd `9c `5s `8h `6s `9d `Ks `7s `7c `5h `Jc `8c `Th `Ah `Js

  • The video explains the difference in the usage of ~ in the { and ? verbs: https://youtu.be/eXGKK8BkCkg?t=232

    • The ? only has an argument on the right hand side

    • The { has an argument on both sides

NB. Define dealing as function (no explanation 😅)
deal =: {{ deck {~ y ? 52 }}
deal 5

`8d `6s `Qs `4s `Ks

NB. To shuffle the deck, deal all cards    
shuffle =: deal @ 52
shuffle''

`3h `8c `3c `Qs `Kd `Qc `Qd `Kh `2s `2h `6s `7s `7c `7h `7d `Ks `8s `9c `5d `6h `4c `4h `8h `2c `5h `9s `Jd `Ad `9h `Qh `5s `3s `5c `9d `Kc `Td `6c `As `Js `Tc `Jh `Jc `6d `3d `Ts `8d `4s `2d `4d `Ac `Ah `Th

Chap 5. Permutations

NB. There are 52! (factorial) ways to arrange 52 cards
!52

8.06582e67

NB. If we put a `x`, it will use extended-precision values
!52x

80658175170943878571660636856403766975289505440883277824000000000000

NB. Pick an option of those 52!
?!52x

17561385888986298727929420478959982424017302243773033650782731200417

Chap 6. Permutation table

NB. As a test, let's build a table where each row is a permutation of a,b,c,d
t =. (A.~i.@!@#) 'ABCD'

NB. Let's see the first 4
4 {. t

ABCD
ABDC
ACBD
ACDB

NB. Permutation of 4 elements, means it should have 4! (24 elements)
#t

24

NB. Itemizing and box each row to make it vertical
<@,."1 t

┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
│A│A│A│A│A│A│B│B│B│B│B│B│C│C│C│C│C│C│D│D│D│D│D│D│
│B│B│C│C│D│D│A│A│C│C│D│D│A│A│B│B│D│D│A│A│B│B│C│C│
│C│D│B│D│B│C│C│D│A│D│A│C│B│D│A│D│A│B│B│C│A│C│A│B│
│D│C│D│B│C│B│D│C│D│A│C│A│D│B│D│A│B│A│C│B│C│A│B│A│
└─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘

NB. We can generate a specific permutation on demand using `A` (for anagram).
NB. These are the first and the last
'ABCD' A.~ 0 _1

ABCD
DCBA

Chap 7. Anagrams

NB. The generator line expands like this...
NB. Original
t =. (A.~ i.@!@#) 'ABCD'

NB. The monadic hook (parens) mirror right argument to the left, so it's the same as
t =.  'ABCD' A.~ i.@!@#  'ABCD'

NB. The tild swaps the arguments, so...
t =.  (i.@!@# 'ABCD') A.  'ABCD'

NB. The `@` signs compose a pipeline, but 'ABCD' is a noun and if we have verbs applied to a noun the form a pipeline anyway, so...
t =.  (i.!# 'ABCD') A.  'ABCD'

NB. Lets focus on the first part
NB. Length of the noun
# 'ABCD'

NB. Factorial
! # 'ABCD'

NB. Count up to (the factorial of the length of the noun)
i.!# 'ABCD'

NB. Finally anagram (A.) generates the anagrams with those indices from the noun on the right.

4

24

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

Back to the cards...

  • The video proposes [ https://youtu.be/eXGKK8BkCkg?t=470 ] that there has to be an anagram index which generates the deck sorted by suits. We can use the function Anagram index (the monadic form of A.) to find it.

NB. Indices for the cards sorted by suit
deck i. by_suit

0 4 8 12 16 20 24 28 32 36 40 44 48 1 5 9 13 17 21 25 29 33 37 41 45 49 2 6 10 14 18 22 26 30 34 38 42 46 50 3 7 11 15 19 23 27 31 35 39 43 47 51

NB. Anagram index for that combination
A. deck i. by_suit

95006884258421706712867864411498469354251805306060528141852620800

NB. If we want to shuffle the deck we can just extract a permutation from the table at random
deck A.~ ? !52x

`Qs `7d `4h `Kh `5d `8h `5h `8d `5s `5c `9h `Ks `8s `Ac `6h `4s `2c `7h `9c `7s `3c `9s `Kd `6c `Jd `Ts `6s `3h `4d `2s `Tc `Js `3s `2h `7c `As `4c `Jh `9d `Th `8c `2d `Kc `Qc `3d `Qd `Td `Jc `Ah `6d `Ad `Qh