« first day (294 days earlier)      last day (2353 days later) » 

11:54 AM
To contribute in tonight's APL learning session without having 20 SE rep, send an email to adam@… or contact us through our website …dyalog.com
 
12:29 PM
@Adám you separated the email so that it won't get scraped by bots?
like, those crawling bots
 
@EriktheOutgolfer Yes. While at the same time providing both email and website.
@EriktheOutgolfer Btw, name@domain.com is syntactically correct APL. And http://www.domain.com/sub-page/index.html is too.
 
@Adám of course it is
(name @ domain) . com
 
@EriktheOutgolfer Or name @ (domain.com) depending on domain's name class.
 
@Adám wait aren't operators left-associative?
 
@EriktheOutgolfer Yes, but if domain is an object, then . fetches a member before operators even begin to kick in. (Yeah, I know, . is way too overloaded!)
 
12:43 PM
@Adám I see
but that's not the . operator right?
 
#FunctionalProgramming in 17 languages - apl, csharp, elixir, elm, erlang, eta, fsharp, haskell, idris, java, javascript, ocaml, php, purescript, rust, scala & swift under one roof. Don't miss the Fourth edition of @FnConf on 18th Nov https://confengine.com/functional-conf-2017/schedule
Another informal APL learning session is taking place this evening at 18:30 UTC - you can join Adam at https://chat.stackexchange.com/rooms/52405/apl Reading along is open to everyone, but 20 StackExchange reputation points are required to contribute messages to the chat.
 
@Feeds hey, you should include the contact to add access stuff! :-P
 
@EriktheOutgolfer Yeah, the formulation was a bit unfortunate this time. If it had not said anything about access, people would come here and see my message. As it is now, they may give up before discovering that there is a way.
@EriktheOutgolfer No, . when to the right of a namespace is not an operator. However does in a functional manner what . does as syntax:
⎕←('⎕SE'⍎'SALTUtils')⍎'AZaz'
 
@Adám
 ABCDEFGHIJKLMNOPQRSTUVWXYZ
 abcdefghijklmnopqrstuvwxyz
 
@EriktheOutgolfer ^ Which means you can use it with operators (!):
⎕←⊃⍎⍨/'AZaz' 'SALTUtils' '⎕SE'
 
12:55 PM
@Adám
 ABCDEFGHIJKLMNOPQRSTUVWXYZ
 abcdefghijklmnopqrstuvwxyz
 
@Adám SALTUtils?
I'll never get to use SALTUtils, I'm on Linux :(
 
@EriktheOutgolfer So is TIO. SALT is cross-platform.
 
@Adám oh
I probably confused it with other Windows-only stuff such as Conga or Syncfusion
 
1:11 PM
@EriktheOutgolfer Conga and JavaScript-based Syncfusion (part of MiServer, but you the Syncfusion license is included in your Dyalog license) are cross-platform too. AFAIK, just COM, DDE, and .NET are Windows-only.
 
1:32 PM
@EriktheOutgolfer Obfuscated APL.
 
1:53 PM
@Adám nice
50% obfuscated :p
 
@EriktheOutgolfer Why 50%?
 
dyalog←⎕NS(⍎⊢3↑⊢)'com←1' ⍝ Cover for APL's subtraction primitive
this is really to make dyalog.com return 1 so 1/ is an identity
maybe should've said "50% URL"
@Adám
 
@EriktheOutgolfer Yes, well, almost an identity, 1/ (or 1∘/ if you want a proper function) ensures that the argument has rank-1 or higher. In essence, it is like ravel-is-scalar, kind of like how is enclose-if-simple.
@EriktheOutgolfer J can only handle hash-bang scripts because #!/home/fred/j806/bin/jconsole happens to be a valid J expression. #!/home/fred/j64-802/bin/jconsole would cause an error!
 
@Adám that means it can't handle shebang scripts
 
@EriktheOutgolfer I guess that's a yes and no. The official documentation says to create a link file that has no characters that cause problems.
 
2:04 PM
> The workaround is to create a link file that has no characters that cause problems.
is it really so hard to make an exception that if the first line starts with #! then it is to be treated as a shebang?
 
@EriktheOutgolfer Dunno. Marshall and I have made a proposal for #! script support in Dyalog APL. It includes ignoring the first line if it begins with #!. However, it should be noted that beginning an APL statement with #! is way more unlikely than beginning a J statement like that. That being said, one of my main critiques of J is that they sacrificed usability for purity.
 
@Adám does # even do anything in Dyalog APL?
 
@EriktheOutgolfer Yes, it is the root namespace. Also ## is the parent namespace. # is like / and ## like .. and . like / in Posix.
 
@Adám how does it work
 
2:20 PM
Morten is preparing for Code Jugalbandi at @FnConf on Saturday performing with #Dyalog #APL - see here for details https://functionalconf.com/proposal.html?id=4066
 
2:35 PM
@EriktheOutgolfer Try it online!
 
@Adám oh thanks
 
@EriktheOutgolfer Understand?
 
sure, kinda
 
@EriktheOutgolfer If anything is unclear, let me know.
 
@Adám how ⎕NS works, and why it needs
for 1 I get DOMAIN ERROR and for 'a' I get VALUE ERROR
 
2:49 PM
@EriktheOutgolfer ⎕NS is a function which populates a namespace. As right argument, it takes a list of names to stuff into the selected namespace. As left argument, it takes the name of the namespace to populate. If the left argument is a name which has not been defined, it will create a new namespace with that name. In all these cases, it returns the fully qualified name of the updated namespace. If you omit the left argument entirely, it will create a new unnamed namespace and return a ref instead.
@EriktheOutgolfer Full documentation.
@EriktheOutgolfer Oh, ⎕NS has one more trick up its sleeve: If the right argument is a ref, then it copies all the members of that namespace.
 
 
3 hours later…
6:18 PM
To contribute in tonight's APL learning session without having 20 SE rep, send an email to adam@. The domain is dyalog.com.
@ThomasWard Can you grant write access to ชญาดา ไชยเขตร์?
 
1 moment
done
 
@ThomasWard Thanks.
#tio alias view
 
@Adám
Command Aliases:
⍞← -> #TIO do apl-dyalog ⎕←%args%
⎕← -> #TIO run apl-dyalog (⎕NS⍬).⍎'⎕CY''salt''⋄⎕SE.UCMD''box on -fns=on''⊣enableSALT'⋄⎕←%args%

Language Aliases:
apl-dyalog -> [apl]

Message Aliases:
)help -> %handle% [Dyalog APL Language Elements](help.dyalog.com/16.0/Content/Language/Introduction/…)
)ref -> %handle% [Dyalog APL Reference Card](docs.dyalog.com/16.0/ReferenceCard.pdf)
)about -> %handle% You can evaluate an APL expression by typing it into chat prefixed by ⍞←. Use ⎕← instead for boxed display and multi-line results. Do not use mar
 
lurks
 
@Adám btw next time I suggest asking for the chat ID of a user who wants to contribute. they can view their ID by going to their chat profile (click lower-left giant avatar, then click "user profile") and there will be a number in the URL; that's their chat ID you can give to a mod so that they can open this room's access page, then click "add a user" to the right of "Explicit write access" (second from top), and, where it
says "If you have it, enter the chat ID or the user's profile URL here:" type the chat ID and then click on "grant write access"
 
6:27 PM
@EriktheOutgolfer i have a userscript I wrote that lets me extract it with ease when given a user's URL. Wasn't that hard to find :)
but you're right
it makes it a bit easier so we don't have to hunt :)
 
@ThomasWard you'll most probably not always be the mod ;)
 
yep
 
and they're not required to have any userscript at all
and shouldn't be
 
@EriktheOutgolfer Excellent suggestion. I'll keep it in mind for next time.
 
indeed
though I'm happy to share if they DO want it :)
 
6:29 PM
@Adám note that it should be added to the tweet(s?) because it would make the message too long
 
@EriktheOutgolfer Ah, 240 is plenty.
 
@Adám 280
and yeah t.co shortening
 
Welcome to the 5th APL learning session
The last two lessons we went through a bunch of operators. Today, I'm thinking to do two more. Okay?
 
I have and in mind. The first is good for classifying stuff, the second for Game of Life and related problems.
Let's start with – it's fun!
It is called Stencil (as in stencil code) and the symbol is supposed to evoke the picture of a stencil over a paper.
Stencil is a dyadic operator which derives a monadic function. The let operand must be a function and the right operand must be an array.
The right operand specifies what neighbourhoods to apply to. E.g. in Game of Life, the neighbourhoods are 3-by-3 sub-matrices centred on each element in the input array.
The operand gets called dyadically. The right argument is a neighbourhood and the left is information about whether he neighbourhood overlaps an edge of the original argument world.
To see how it works, we'll use {⊂⍵} as left operand. It just encloses the neighbourhood so we can see it. As right operand we use 3 3, i.e. the neighbourhood size:
⎕←4 6⍴⎕A
 
6:37 PM
@Adám
ABCDEF
GHIJKL
MNOPQR
STUVWX
 
The above is our argument.
⎕←({⊂⍵}⌺3 3) 4 6⍴⎕A
 
@Adám
┌───┬───┬───┬───┬───┬───┐
│   │   │   │   │   │   │
│ AB│ABC│BCD│CDE│DEF│EF │
│ GH│GHI│HIJ│IJK│JKL│KL │
├───┼───┼───┼───┼───┼───┤
│ AB│ABC│BCD│CDE│DEF│EF │
│ GH│GHI│HIJ│IJK│JKL│KL │
│ MN│MNO│NOP│OPQ│PQR│QR │
├───┼───┼───┼───┼───┼───┤
│ GH│GHI│HIJ│IJK│JKL│KL │
│ MN│MNO│NOP│OPQ│PQR│QR │
│ ST│STU│TUV│UVW│VWX│WX │
├───┼───┼───┼───┼───┼───┤
│ MN│MNO│NOP│OPQ│PQR│QR │
│ ST│STU│TUV│UVW│VWX│WX │
│   │   │   │   │   │   │
└───┴───┴───┴───┴───┴───┘
 
Here you see that we returned a 4-by-6 matrix of neighbourhoods. Notice that all the neighbourhoods are 3-by-3, even at the edges. They were padded with spaces.
The padding was done sometimes on top, sometimes on left, sometimes on right, and sometimes on the bottom. The information about that is in the left argument () of the operand function:
⎕←({⊂⍺}⌺3 3) 4 6⍴⎕A
 
@Adám
┌────┬────┬────┬────┬────┬─────┐
│1 1 │1 0 │1 0 │1 0 │1 0 │1 ¯1 │
├────┼────┼────┼────┼────┼─────┤
│0 1 │0 0 │0 0 │0 0 │0 0 │0 ¯1 │
├────┼────┼────┼────┼────┼─────┤
│0 1 │0 0 │0 0 │0 0 │0 0 │0 ¯1 │
├────┼────┼────┼────┼────┼─────┤
│¯1 1│¯1 0│¯1 0│¯1 0│¯1 0│¯1 ¯1│
└────┴────┴────┴────┴────┴─────┘
 
So, each cell contains two elements, one for rows, and one for columns. Positive indicates left/top. Negative is right/bottom. The magnitude indicates how many rows/columns were padded.
This fits nicely with the dyadic "Drop" primitive, which takes the number of rows,columns as left argument to drop from the right argument:
⎕←({⊂⍺↓⍵}⌺3 3) 4 6⍴⎕A
 
6:42 PM
@Adám
┌──┬───┬───┬───┬───┬──┐
│AB│ABC│BCD│CDE│DEF│EF│
│GH│GHI│HIJ│IJK│JKL│KL│
├──┼───┼───┼───┼───┼──┤
│AB│ABC│BCD│CDE│DEF│EF│
│GH│GHI│HIJ│IJK│JKL│KL│
│MN│MNO│NOP│OPQ│PQR│QR│
├──┼───┼───┼───┼───┼──┤
│GH│GHI│HIJ│IJK│JKL│KL│
│MN│MNO│NOP│OPQ│PQR│QR│
│ST│STU│TUV│UVW│VWX│WX│
├──┼───┼───┼───┼───┼──┤
│MN│MNO│NOP│OPQ│PQR│QR│
│ST│STU│TUV│UVW│VWX│WX│
└──┴───┴───┴───┴───┴──┘
 
As you can see, the padding was removed.
@all Any questions so far?
 
yes
what "magnitude" are you referring to?
do you mean the sum of the magnitudes?
 
@EriktheOutgolfer The absolute value. Here it was all 1, because 3-by-3 neighbourhoods never need more than a single row and/or column padded.
 
@Adám is version 16, right?
 
@H.PWiz Yes.
 
6:44 PM
@Adám but what is the absolute value of a list?
 
@EriktheOutgolfer All arithmetic functions are scalar, so that's just the absolute value of each element.
 
@Adám so for example how many were padded if you get magnitude 1 1?
 
@EriktheOutgolfer one row and one column
⎕←({⊂⍺}⌺3 5) 4 6⍴⎕A
 
@Adám
┌────┬────┬────┬────┬─────┬─────┐
│1 2 │1 1 │1 0 │1 0 │1 ¯1 │1 ¯2 │
├────┼────┼────┼────┼─────┼─────┤
│0 2 │0 1 │0 0 │0 0 │0 ¯1 │0 ¯2 │
├────┼────┼────┼────┼─────┼─────┤
│0 2 │0 1 │0 0 │0 0 │0 ¯1 │0 ¯2 │
├────┼────┼────┼────┼─────┼─────┤
│¯1 2│¯1 1│¯1 0│¯1 0│¯1 ¯1│¯1 ¯2│
└────┴────┴────┴────┴─────┴─────┘
 
Here you can see that on the far left and right, we had to pad two columns to get a 5-wide neighbourhood centred on the first column.
 
6:48 PM
oh alright
 
@all Btw, feel free to use the APL bot. You can copy my messages beginning with ⎕← and modify to your needs.
 
yeah now it has migrated from AquariusOne to its own, room-specific account
 
@all If you don't have an APL keyboard, you can copy and paste from a "language bar" which you can get from the bot as follows:
)lb
 
@Adám ← +-×÷*⍟⌹○!? |⌈⌊⊥⊤⊣⊢ =≠≤<>≥≡≢ ∨∧⍲⍱ ↑↓⊂⊃⊆⌷⍋⍒ ⍳⍸∊⍷∪∩~ /\\\\⌿⍀ ,⍪⍴⌽⊖⍉ ¨⍨⍣.∘⍤@ ⍞⎕⍠⌸⌺⌶⍎⍕ ⋄⍝→⍵⍺∇& ¯⍬
 
)lb
 
6:50 PM
@MBaas ← +-×÷*⍟⌹○!? |⌈⌊⊥⊤⊣⊢ =≠≤<>≥≡≢ ∨∧⍲⍱ ↑↓⊂⊃⊆⌷⍋⍒ ⍳⍸∊⍷∪∩~ /\\\\⌿⍀ ,⍪⍴⌽⊖⍉ ¨⍨⍣.∘⍤@ ⍞⎕⍠⌸⌺⌶⍎⍕ ⋄⍝→⍵⍺∇& ¯⍬
 
@EriktheOutgolfer All clear?
 
well, sure
 
Now, let's try making game of life.
So here are the rules:
A cell will stay alive with 2 or 3 neighbours.
It will become alive with 3 neighbours.
It will die with fewer than 2 or more than 3 neighbours.
Let's make a world:
⎕←4 5⍴0 0 1 0 0 1 0
 
@Adám
0 0 1 0 0
1 0 0 0 1
0 0 1 0 0
0 1 0 0 1
 
The 1s indicate live cells while the 0s indicate dead cells.
⎕←({⊂⍵}⌺3 3) 4 5⍴0 0 1 0 0 1 0
 
6:57 PM
@Adám
┌─────┬─────┬─────┬─────┬─────┐
│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│
│0 0 0│0 0 1│0 1 0│1 0 0│0 0 0│
│0 1 0│1 0 0│0 0 0│0 0 1│0 1 0│
├─────┼─────┼─────┼─────┼─────┤
│0 0 0│0 0 1│0 1 0│1 0 0│0 0 0│
│0 1 0│1 0 0│0 0 0│0 0 1│0 1 0│
│0 0 0│0 0 1│0 1 0│1 0 0│0 0 0│
├─────┼─────┼─────┼─────┼─────┤
│0 1 0│1 0 0│0 0 0│0 0 1│0 1 0│
│0 0 0│0 0 1│0 1 0│1 0 0│0 0 0│
│0 0 1│0 1 0│1 0 0│0 0 1│0 1 0│
├─────┼─────┼─────┼─────┼─────┤
│0 0 0│0 0 1│0 1 0│1 0 0│0 0 0│
│0 0 1│0 1 0│1 0 0│0 0 1│0 1 0│
│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│
 
Here are our neighbourhoods. We can get the number of neighbours by summing. So we , ravel (make a list) and +/ sum:
⎕←({+/,⍵}⌺3 3) 4 5⍴0 0 1 0 0 1 0
 
@Adám
1 2 1 2 1
1 3 2 3 1
2 3 2 3 2
1 2 2 2 1
 
We also need to know what the current value is. That is the 5th value in the ravelled neighbourhood:
⎕←({5⌷,⍵}⌺3 3) 4 5⍴0 0 1 0 0 1 0
 
@Adám
0 0 1 0 0
1 0 0 0 1
0 0 1 0 0
0 1 0 0 1
 
Now we can say that self←5⌷,⍵ and total←+/,⍵:
⎕←({self←5⌷,⍵ ⋄ total←+/,⍵ ⋄ ⊂self total}⌺3 3) 4 5⍴0 0 1 0 0 1 0
 
7:01 PM
@Adám
┌───┬───┬───┬───┬───┐
│0 1│0 2│1 1│0 2│0 1│
├───┼───┼───┼───┼───┤
│1 1│0 3│0 2│0 3│1 1│
├───┼───┼───┼───┼───┤
│0 2│0 3│1 2│0 3│0 2│
├───┼───┼───┼───┼───┤
│0 1│1 2│0 2│0 2│1 1│
└───┴───┴───┴───┴───┘
 
Here we have the self and the total for each cell.
So the logic will that in the next generation the cell is alive if itself was alive and had 2–3 neighbours, or if it was dead and had 3 neighbours.
That is (self ∧ (total∊2 3)) ∨ ((~self) ∧ (total=3)). Let's plug that in:
⎕←({self←5⌷,⍵ ⋄ total←+/,⍵ ⋄ (self ∧ (total∊2 3)) ∨ ((~self) ∧ (total=3))}⌺3 3) 4 5⍴0 0 1 0 0 1 0
 
s/(total∊2 3)/(total∊3 4) since self isn't subtracted from total
 
@Adám
0 0 0 0 0
0 1 0 1 0
0 1 1 1 0
0 1 0 0 0
 
@EriktheOutgolfer Yes, you're right. Sorry.
⎕←({self←5⌷,⍵ ⋄ total←+/,⍵ ⋄ (self ∧ (total∊3 4)) ∨ ((~self) ∧ (total=3))}⌺3 3) 4 5⍴0 0 1 0 0 1 0
 
@Adám
0 0 0 0 0
0 1 0 1 0
0 1 0 1 0
0 0 0 0 0
 
7:06 PM
That looks better.
This can be golfed muchly, but you get the idea, no?
 
@Adám well, rn the point isn't to golf it :p
 
can do a further trick too. If the right operand is a matrix, then the second row indicates the step size. By default it is 1 in every dimension.
 
@Adám why does stencil 3 3 takes also 2 by 3 or 2 by 2 but not 2 by 1 or 1 by 1?
 
@Uriel padding is explained above
 
@Uriel It doesn't vary size. It always takes the same size, and will pad at the edges.
 
7:09 PM
use ]box on -style=max to see it better
 
@Adám so why not take the 1×1 edges as well?
 
@Uriel Every element of the input gets to be the centre of a neighbourhood.
 
@Adám oh that explains it, tnx
 
@Uriel and then why not get the 1×1 edges formed by those edges as well? as the ones that are formed by the new 1×1 edges? etc.
would be another explanation
 
@EriktheOutgolfer No, it would have been possible to define it so that it begins with a neighbourhood which only has a single element in the top left, the rest being padding.
… but then the result would have a different shape than the argument.
 
7:12 PM
@Adám it would trouble things up
 
If you want to start further out or in, you can pad or remove rows and columns.
⎕←({⊂⍺↓⍵}⌺3 3) ' ',' ',⍨' '⍪' ',⍨4 6⍴⎕A
 
@Adám
┌──┬───┬───┬───┬───┬───┬───┬───┬──┐
│  │   │   │   │   │   │   │   │  │
│ A│ AB│ABC│BCD│CDE│DEF│EF │F  │  │
├──┼───┼───┼───┼───┼───┼───┼───┼──┤
│  │   │   │   │   │   │   │   │  │
│ A│ AB│ABC│BCD│CDE│DEF│EF │F  │  │
│ G│ GH│GHI│HIJ│IJK│JKL│KL │L  │  │
├──┼───┼───┼───┼───┼───┼───┼───┼──┤
│ A│ AB│ABC│BCD│CDE│DEF│EF │F  │  │
│ G│ GH│GHI│HIJ│IJK│JKL│KL │L  │  │
│ M│ MN│MNO│NOP│OPQ│PQR│QR │R  │  │
├──┼───┼───┼───┼───┼───┼───┼───┼──┤
│ G│ GH│GHI│HIJ│IJK│JKL│KL │L  │  │
│ M│ MN│MNO│NOP│OPQ│PQR│QR │R  │  │
 
⎕←({⊂⍵}⌺3 3) ' ',' ',⍨' '⍪' ',⍨4 6⍴⎕A
 
@Adám
┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
│   │   │   │   │   │   │   │   │   │
│   │   │   │   │   │   │   │   │   │
│  A│ AB│ABC│BCD│CDE│DEF│EF │F  │   │
├───┼───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │   │   │
│  A│ AB│ABC│BCD│CDE│DEF│EF │F  │   │
│  G│ GH│GHI│HIJ│IJK│JKL│KL │L  │   │
├───┼───┼───┼───┼───┼───┼───┼───┼───┤
│  A│ AB│ABC│BCD│CDE│DEF│EF │F  │   │
│  G│ GH│GHI│HIJ│IJK│JKL│KL │L  │   │
│  M│ MN│MNO│NOP│OPQ│PQR│QR │R  │   │
├───┼───┼───┼───┼───┼───┼───┼───┼───┤
 
⎕←({⊂⍵}⌺3 3) ' ',' ',⍨' '⍪' '⍪⍨4 6⍴⎕A ⍝ hopefully right this time
 
7:15 PM
@Adám
┌───┬───┬───┬───┬───┬───┬───┬───┐
│   │   │   │   │   │   │   │   │
│   │   │   │   │   │   │   │   │
│  A│ AB│ABC│BCD│CDE│DEF│EF │F  │
├───┼───┼───┼───┼───┼───┼───┼───┤
│   │   │   │   │   │   │   │   │
│  A│ AB│ABC│BCD│CDE│DEF│EF │F  │
│  G│ GH│GHI│HIJ│IJK│JKL│KL │L  │
├───┼───┼───┼───┼───┼───┼───┼───┤
│  A│ AB│ABC│BCD│CDE│DEF│EF │F  │
│  G│ GH│GHI│HIJ│IJK│JKL│KL │L  │
│  M│ MN│MNO│NOP│OPQ│PQR│QR │R  │
├───┼───┼───┼───┼───┼───┼───┼───┤
│  G│ GH│GHI│HIJ│IJK│JKL│KL │L  │
│  M│ MN│MNO│NOP│OPQ│PQR│QR │R  │
 
@Uriel See, that begins with a single element in the corner.
⎕←1 1↓¯1 ¯1↓({⊂⍵}⌺3 3) 4 6⍴⎕A
 
@Adám
┌───┬───┬───┬───┐
│ABC│BCD│CDE│DEF│
│GHI│HIJ│IJK│JKL│
│MNO│NOP│OPQ│PQR│
├───┼───┼───┼───┤
│GHI│HIJ│IJK│JKL│
│MNO│NOP│OPQ│PQR│
│STU│TUV│UVW│VWX│
└───┴───┴───┴───┘
 
And here we only have the completely filled neighbourhoods.
Stencil has one more trick:
⎕←({⊂⍵}⌺(2 2⍴3))7 7⍴⎕A
 
@Adám
┌───┬───┬───┐
│   │   │   │
│ AB│CDE│FG │
│ HI│JKL│MN │
├───┼───┼───┤
│ OP│QRS│TU │
│ VW│XYZ│AB │
│ CD│EFG│HI │
├───┼───┼───┤
│ JK│LMN│OP │
│ QR│STU│VW │
│   │   │   │
└───┴───┴───┘
 
If you use a matrix as right operand, then the first row corresponds to the operands we've been using so far, and the second is the step size in each dimension (here: row,column).
So I used a 2-by-2 matrix of all 3s. I.e. 3-by-3 neighbourhoods going over 3 rows and 3 columns. Thus, we "chop" the argument, with no overlaps.
We can also use even sizes, in which case every "space" between elements (rather than elements themselves) gets to be the centre of a neighbourhood:
⎕←({⊂⍵}⌺(2 2⍴2))6 6⍴⎕A
 
7:21 PM
@Adám
┌──┬──┬──┐
│AB│CD│EF│
│GH│IJ│KL│
├──┼──┼──┤
│MN│OP│QR│
│ST│UV│WX│
├──┼──┼──┤
│YZ│AB│CD│
│EF│GH│IJ│
└──┴──┴──┘
 
⎕←({⊂⍵}⌺(2 4))4 6⍴⎕A
 
@Adám
┌────┬────┬────┬────┬────┐
│ ABC│ABCD│BCDE│CDEF│DEF │
│ GHI│GHIJ│HIJK│IJKL│JKL │
├────┼────┼────┼────┼────┤
│ GHI│GHIJ│HIJK│IJKL│JKL │
│ MNO│MNOP│NOPQ│OPQR│PQR │
├────┼────┼────┼────┼────┤
│ MNO│MNOP│NOPQ│OPQR│PQR │
│ STU│STUV│TUVW│UVWX│VWX │
└────┴────┴────┴────┴────┘
 
…and so on.
@And that's really all there is to Stencil. Any questions?
For a detailed walk-though of the shortest possible Game of Life using Stencil, see the latest Webinar on dyalog.tv.
Can we move on to "Key"?
 
OK. Key is a monadic operator deriving an ambivalent function (i.e. monadic or dyadic depending on usage).
The lone operand must be a function, and it gets called dyadically in a manner not too different from Stencil's left operand.
Let's do the monadic derived function first, i.e. (f⌸) data.
Key will group identical major cells of the data together and call the operand f with the unique element as left argument, and the indices of that element in the data as right argument:
⎕←{⊂⍺⍵}⌸'Mississippi'
 
7:29 PM
@Adám
┌─────┬────────────┬───────────┬────────┐
│┌─┬─┐│┌─┬────────┐│┌─┬───────┐│┌─┬────┐│
││M│1│││i│2 5 8 11│││s│3 4 6 7│││p│9 10││
│└─┴─┘│└─┴────────┘│└─┴───────┘│└─┴────┘│
└─────┴────────────┴───────────┴────────┘
 
So this is telling us that "M" is at index 1, "i" at 2 5 8 11, etc.
@ThomasWard Can you give 320223 access?
 
⎕←,⌸'Mississippi'
 
@Uriel
M 1
i 2  5 8 11
s 3  4 6  7
p 9 10
 
It is very common to use to tally the indices:
 
@Adám done
 
7:32 PM
@ThomasWard Thanks.
⎕←{⍺,≢⍵}⌸'Mississippi'
 
@Adám
M 1
i 4
s 4
p 2
 
So here is the count of each unique element.
E.g. we can use this to remove elements which only occur once:
⍞←{1≠≢⍵}⌸'Mississippi'
 
@Adám 0 1 1 1
 
This is a Boolean for each unique element.
⍞←∪'Mississippi'
 
@Adám Misp
 
7:34 PM
These are the unique elements, monadic .
⍞←0 1 1 1/'Misp'
 
@Adám isp
 
/ filters.
Let's put it all together:
⍞←{({1≠≢⍵}⌸⍵)/∪⍵}'Mississippi'
 
@Adám isp
 
Works on higher rank arrays too (matrices, 3D blocks, etc.) where it will use the major cells (rows for matrices, layers for 3D blocks…) as "items".
⎕←5 3⍴'AAAABCAAAABBAAA'
 
@Adám
AAA
ABC
AAA
ABB
AAA
 
7:37 PM
⎕←{⍺⍵}⌸ 5 3⍴'AAAABCAAAABBAAA'
 
@Adám
┌───┬─────┐
│AAA│1 3 5│
├───┼─────┤
│ABC│2    │
├───┼─────┤
│ABB│4    │
└───┴─────┘
 
@all Any questions about monadic Key?
 
Dyadic Key then.
Behold:
⎕←'Mississippi' {⊂⍺⍵}⌸ ⍳11
 
@Adám
┌─────┬────────────┬───────────┬────────┐
│┌─┬─┐│┌─┬────────┐│┌─┬───────┐│┌─┬────┐│
││M│1│││i│2 5 8 11│││s│3 4 6 7│││p│9 10││
│└─┴─┘│└─┴────────┘│└─┴───────┘│└─┴────┘│
└─────┴────────────┴───────────┴────────┘
 
7:40 PM
⎕←'Mississippi' {⊂⍺⍵}⌸ 'ABCDEFGHIJK'
 
@Adám
┌─────┬────────┬────────┬──────┐
│┌─┬─┐│┌─┬────┐│┌─┬────┐│┌─┬──┐│
││M│A│││i│BEHK│││s│CDFG│││p│IJ││
│└─┴─┘│└─┴────┘│└─┴────┘│└─┴──┘│
└─────┴────────┴────────┴──────┘
 
So, instead of returning the indices of the unique elements (of the right – and only – argument), it returns the elements of the right corresponding to the unique elements of the left.
 
⎕←'Mississippi' {⊂⍺⍵}⌸ ⍳5
 
@EriktheOutgolfer

Rebuilding user command cache... done
Was OFF -fns=off
⍎LENGTH ERROR
 __field_initialize_result_←(⎕NS ⍬).⍎'⎕CY''salt''⋄⎕SE.UCMD''box on -fns=on''⊣enableSALT' ⋄ ⎕←'Mississippi'{⊂⍺ ⍵}⌸⍳5
                                                                                           ∧

Real time: 1.071 s
User time: 0.950 s
Sys. time: 0.068 s
CPU share: 95.03 %
Exit code: 0
 
so...well
 
7:42 PM
@EriktheOutgolfer There must be something to take.
@EriktheOutgolfer Compare:
⎕←'Mississippi' {⊂⍵}⌸ 'ABCDEFGHIJK'
 
@Adám
┌─┬────┬────┬──┐
│A│BEHK│CDFG│IJ│
└─┴────┴────┴──┘
 
with:
⎕←{⊂'ABCDEFGHIJK'[⍵]}⌸'Mississippi'
@DyalogAPL Hello?
)about
 
@Adám You can evaluate an APL expression by typing it into chat prefixed by ⍞←. Use ⎕← instead for boxed display and multi-line results. Do not use markdown. Commands: )lb for language bar, )help for table of language elements, )docs for full documentation, )ref for PDF reference card.
 
⎕←{⊂'ABCDEFGHIJK'[⍵]}⌸'Mississippi'
 
@ThomasWard
┌─┬────┬────┬──┐
│A│BEHK│CDFG│IJ│
└─┴────┴────┴──┘
 
7:45 PM
you're welcome.
 
@DyalogAPL Adám is disappointed at you. :/
 
@ThomasWard Thanks. I guess it had a momentary lapse. APL is over 50 years old.
@all Anyway, is that clear how dyadic Key works?
 
@Adám Either that or there's a timeout waiting to happen in your instanceof TIOBot.
 
Great. What shall we do for the last quarter of an hour?
 
7:48 PM
@ThomasWard simple: restart TIOBot
 
@EriktheOutgolfer tell that to @Adám, he runs it for in here now.
 
I assume it does save to config files, right?
 
it should
i mean except for autojoin and user/password
 
@EriktheOutgolfer It does, but it still has a bug where it fails to read from them.
 
7:50 PM
@EriktheOutgolfer It is running containerised on a remote data centre, so I can't access it. However, if it falls over, Docker will start it again, and I just have to set up the message aliases. It does auto-initialise ⎕← and ⍞← from its config file.
Shall we call it a day then? We've now covered the most essential operators. Maybe next week we'll start ploughing through all the functions to make sure we know them all.
Thank you to all participants. See you next week! Don't hesitate to drop in here during the week. Also, check out the chatbot's profile as I've given it a list of useful APL links.
 
@Adám need me to reset the ACL or want me to leave it alone, for the room?
 
@ThomasWard What is ACL?
 
Access Control List
 
@ThomasWard Oh, I did so already.
 
cool. returns to the shadows
 
8:00 PM
@ngn A:C and C:D is 2*÷8, so is there a way to shorten:
2
A: Paper and Envelope Sizes

AdámAPL (Dyalog), 31 bytes Full program body. Assumes ⎕IO (Index Origin) to be 0, which is default on many systems. Prompts for number, then letter, both from STDIN. Prints to STDOUT. ⌊.2+841 1E3 917[⎕A⍳⍞]×.707*⎕-⍳2 Try it online! A slightly modified version lets us test all possibilities at o...

 
 
3 hours later…
ngn
10:48 PM
@Adám there is: ⌊.2+1E3÷2*8÷⍨('BCA'⍳⍞)+4×⎕-⍳2
 
10:59 PM
@ngn Thanks, I knew I could count on you.
 

« first day (294 days earlier)      last day (2353 days later) »