#+title: beginner j : dealing cards * init : @cls @hide("jp-editor") @show("jp-editor") @move("jp-editor", 38, 570, 400) @move("jp-editor", 38, 1080, 400) : NB. kludge to move the cursor to the bottom of the repl. : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : @pause(5000) * the deck : @cls @title("the deck") Let's say you want to deal some cards. A standard deck has four suits: clubs, diamonds, hearts, and spades. : . ?suits =: 'cdhs'? : suits =: 'cdhs' Then there are thirteen ranks: deuce through ten, jack, queen, king, and Ace. : . ?ranks =: '1?X?23456789T?_?JQKA'? : ranks =: '23456789TJQKA' We can use the catalog operator (that's the left curly brace here) to see every combination: : . ?|: ?_?{?_? ranks;?_? suits? : |: { ranks; suits The semicolon there puts the two strings into boxes, : . ^bbbbXXXXX$ : ranks; suits Then catalog takes every combination of the boxed values. : . ^bb?{ ? : { ranks; suits Then transpose turns that on it side just to make it look nicer. : . ^ bbb?|: ? : |: { ranks; suits Okay, so let's convert those boxed strings to symbols... : . ^0?s: ? : s: |: { ranks; suits ... flatten it with ravel ... : . ^0?, ?$ : , s: |: { ranks; suits and then give it a name: : . ^0?by_suit =: ?$ : by_suit =: , s: |: { ranks; suits : . ?by_suit? : by_suit If you'd prefer to have it sorted by rank instead of by suit, just remove the transpose: : . ^^bb0>>>xxxx?rank?www>xxx$ : by_rank =: , s: { ranks ; suits : . ?by_rank? : by_rank Anyway, let's call that our deck. : . ^0?deck =: ? : deck =: by_rank @sync * enumeration : @cls @title("enumeration") If we did that right, we'd expect to have 52 cards: The hash operator gives us the length of an array. : . ?# deck? : # deck So that looks good. We can grab the first four cards with "take" or left-curly dot. : . ^0x?4 {.?$ : 4 {. deck Since the deck is sorted by rank, that gives us the twos, or "deuces". If we want the aces, we can deal from the bottom of the deck. : . ^0?_? : _4 {. deck NB. _4 is negative four If we want to know what card is card number 23 is, we can just extract it. : . ?23 { deck? : 23 { deck Array indices start at zero, so that deuce of clubs up there is card zero, and the ace of spades is 51. : . ^0xx?0 51? : 0 51 { deck J complains if you ask for an entry that's out of range. : . ^0xx>x?2? : 52 { deck You can ask for negative one through negative 52 though. : . ^0?_1 _?w : _1 _52 { deck @pause(750) @sync * card lookup : @cls @title("card lookup") So now we can map numbers to cards. But what if we want to go the other way? Let's say we want to find the queen of hearts: : . ?'Qh'? : 'Qh' This here is a string, but our deck is actually an array of symbols. We can't match strings and symbols directly, so we need a symbol. Unfortunately, J doesn't have a syntax for writing symbols. But they're still pretty easy to construct. We can either use less than to box the string, : . ^0?>x>? ? : s:' Qh' That extra space is called a fret character, and it acts like a delimiter for defining multiple symbols at once. : . ^$? : >,{ranks;suits : . ^0?(?$?) i. ?__?>'Qh';"?X?'?As';'? : (>,{ranks;suits) i. >'Qh';'As';'3d' I guess really I just kinda prefer symbols, so that's what I went with. @sync * shuffling : @cls @title("shuffling") Okay, so if you want to pick a random number in J, use the question mark. : . ??? 52? : ? 52 Of course, you'll get a different number each time: : . ^ : ? 52 : . ^ : ? 52 There is also question mark dot that uses a fixed seed for the random number generator, but I'm not going to mess with that here. : . ^b?.? : ?. 52 NB. ?. uses a fixed seed : . ^b?.? : ?. 52 : . ^ : ?. 52 Okay, so given a random card number we can extract the card with from. : . ^0>x?~? : deck {~ ?~ 52 Whenever you want to pass the same argument to both sides of a verb, you can use a tilde: So that means the same thing. To recap, the tilde on the question mark makes it reflexive, so we're still passing in 52 on both sides. The tilde on the curly brace is swapping the arguments, so that we don't have to put parentheses around everything. The difference is that the question mark only has an argument on the right hand side, whereas the curly brace has an argument on both sides. The deck is on the left and the shuffled indices are on the right. So reading right to left, it says deal 52 numbers from a set of 52 numbers then extract the cards in those positions from the deck. Anyway, if I were going to write a function to deal cards, it would probably look something like this. : . ^0?deal =: {{ ?$? }}?bbx?A.? : 'ABCD' A.~ 0 _1 ... we can use capital A-dot to generate that permutation on demand. The "A" is for anagram. @sync * anagrams : @cls @title("anagrams") Let's take another look at how we defined t: : . ^^^^^^^^^^^^^^ : t =. (A.~i.@!@#) 'ABCD' This part in parentheses is a hook made of two verbs. : . ^0ww>>>>>? ? : t =. (A.~ i.@!@#) 'ABCD' A monadic hook is just another way to copy the right argument over to the left, so if we expand the hook it looks like this. : . ^0ww? 'ABCD'?>xwwX$ : t =. 'ABCD' A.~ i.@!@# 'ABCD' @pause(1000) And the tilde is swapping the arguments, so we can expand that: : . ^0ww? (i.@!@#?w?)?wX>xxxxxxx$ : t =. (i.@!@# 'ABCD') A. 'ABCD' @pause(1000) And now on the left we have the at signs composing three verbs together into a pipeline. But 'ABCD' is a noun and when you have a sequence of verbs applied directly to a noun, they form a pipeline anyway, so we can get rid of the at signs. : . ^0www<xxxxxxxxxxx?0 1 2 . . . ?XXXXXX?22 23 : (0 1 2 22 23) A. 'ABCD' So anagram takes some numbers on the left and a sequence on the right, and returns the permutation corresponding to that number. : . ^0xwwwxxxxxxx : 0 1 2 A. 'ABCD' It also takes the length of the sequence into account: : . ^