« first day (1055 days earlier)      last day (1600 days later) » 

8:00 PM
@EdgyNerd Do you understand the function for finding the primes until N?
⍞←{⍸2=+/∘.{{⍵=⌊⍵}⍺÷⍵}⍨⍳⍵}14
 
@Adám 2 3 5 7 11 13
 
{{⍵=⌊⍵}⍺÷⍵} so this checks if ⍺ is divisible by ⍵
 
Yes.
And then ∘.{⍵=⌊⍵}⍺÷⍵} is a divisibility table:
⎕←∘.{⍵=⌊⍵}⍺÷⍵}⍨⍳10
 
@Adám
SYNTAX ERROR
 
Oops.
 
8:02 PM
missing bracket
 
⎕←{∘.{⍵=⌊⍵}⍺÷⍵}⍨⍳10
 
@Adám
SYNTAX ERROR
 
Meh.
⎕←∘.{{⍵=⌊⍵}⍺÷⍵}⍨⍳10
 
@Adám
1 0 0 0 0 0 0 0 0 0
1 1 0 0 0 0 0 0 0 0
1 0 1 0 0 0 0 0 0 0
1 1 0 1 0 0 0 0 0 0
1 0 0 0 1 0 0 0 0 0
1 1 1 0 0 1 0 0 0 0
1 0 0 0 0 0 1 0 0 0
1 1 0 1 0 0 0 1 0 0
1 0 1 0 0 0 0 0 1 0
1 1 0 0 1 0 0 0 0 1
 
Third time's the charm.
OK and by summing each row we find the number of divisors for each number:
⎕←+/∘.{{⍵=⌊⍵}⍺÷⍵}⍨⍳10
 
8:03 PM
@Adám
1 2 2 3 2 4 2 4 3 4
 
And by comparing to 2 we find the primes:
⎕←2=+/∘.{{⍵=⌊⍵}⍺÷⍵}⍨⍳10
 
@Adám
0 1 1 0 1 0 1 0 0 0
 
⎕← ⍳10∘.{⍵*⍺}⍳10
 
@EdgyNerd
LIMIT ERROR
 
∘. confuses me
 
8:04 PM
@EdgyNerd You're missing parenthesis around (⍳10) on the left. Also, did you mean × and not *?
 
⎕← (⍳10)∘.{⍵×⍺}⍳10
 
@EdgyNerd
 1  2  3  4  5  6  7  8  9  10
 2  4  6  8 10 12 14 16 18  20
 3  6  9 12 15 18 21 24 27  30
 4  8 12 16 20 24 28 32 36  40
 5 10 15 20 25 30 35 40 45  50
 6 12 18 24 30 36 42 48 54  60
 7 14 21 28 35 42 49 56 63  70
 8 16 24 32 40 48 56 64 72  80
 9 18 27 36 45 54 63 72 81  90
10 20 30 40 50 60 70 80 90 100
 
The the indices of the 1s are the primes:
⎕←⍸2=+/∘.{{⍵=⌊⍵}⍺÷⍵}⍨⍳10
 
@Adám
2 3 5 7
 
Is that clear so far?
 
8:06 PM
kinda
is the thing make by ∘. a list of lists?
 
@EdgyNerd Oh, I'm sorry, I complete forgot that we never delved more into APL's array model. Silly me.
 
oh ok
 
OK, so APL arranges all data in arrays, which are "rectangular" collections of elements arranged along 0 or more axes. Note that this is very different from what e.g. Python and JavaScript call "arrays".
 
so ∘. makes a 2 axis array
 
Yes. So far you've met zero-dimensional numbers and characters, i.e. simple numbers and characters, and also one-dimensional collections we've called lists.
In fact, it makes a new array that has as many dimensions as the left argument has plus the number of dimensions of the right argument. Two lists with one dimension each gives a 2D result.
It kind of has to, if you think about it, to make sure every element from the left gets paired up with every element from the right.
 
8:11 PM
⎕←5∘.{⍺+⍵}1 2 3
 
@EdgyNerd
6 7 8
 
⎕←1 2 3∘.{⍺+⍵}1 2 3
 
@EdgyNerd
2 3 4
3 4 5
4 5 6
 
You can also make your own multi-dimensional arrays by using the (Greek Rho for Reshape) which takes the length of each dimension as left argument and the data to fill with as right argument:
⎕←2 3⍴'hello'
 
@Adám
hel
loh
 
8:12 PM
oh ok
 
We can even do 3D:
⎕←2 3 4⍴⍳12
 
@Adám
1  2  3  4
5  6  7  8
9 10 11 12

1  2  3  4
5  6  7  8
9 10 11 12
 
oh wow
 
Each "table" here constitutes a layer in the 3D array.
 
I'm kinda curious
can it do 4d
 
8:13 PM
Try it! (but keep your numbers small)
 
⎕←2 2 3 4⍴⍳48
 
@EdgyNerd
 1  2  3  4
 5  6  7  8
 9 10 11 12

13 14 15 16
17 18 19 20
21 22 23 24


25 26 27 28
29 30 31 32
33 34 35 36

37 38 39 40
41 42 43 44
45 46 47 48
 
oh ok, that makes sense
 
So each table is a layer in a block, and each block is just one part of a "hyper-block" or whatever.
 
yeah
I've got to go for about 10 minutes, can we continue after that?
 
8:14 PM
Sure. Ping me.
 
@Adám ok I'm here now
 
Great.
So, does ∘.IsDivisibleBy make sense now?
 
yeah
 
And how about membership using ∘.=?
 
⎕←1∘.=1 2 3 1 5 1
 
8:25 PM
@EdgyNerd
1 0 0 1 0 1
 
ok that makes sense
 
OK, and how about ⌈/3 4 5∘.=2 3 5?
 
would that give 0 0 1
since it checks the max of the left list against the right list
 
Right, so do understand the method: 1. get primes until max, 2. see if argument elements are in the list?
 
yeah
 
8:29 PM
@EdgyNerd I think you have = confused with ∘.=though I may just not be understanding what you're doing
 
⎕←⌈/3 4 5=2 3 5
 
@EdgyNerd
1
 
@Quintec nope that doesn't work
 
Ah well, maybe you've made a slight computation error, it's not 0 0 1
 
⎕←⌈/3 4 5∘.=2 3 5
 
8:33 PM
@EdgyNerd
1 0 1
 
oh wait
what?
 
⍞←3 4 5∘.=2 3 5
 
What's the problem?
 
@frank 0 1 0
 
@frank Use ⎕← to allow multi-line output.
 
8:34 PM
⎕←3 4 5∘.=2 3 5
 
@frank
0 1 0
0 0 0
0 0 1
 
ah yea thats what I thought
 
⎕←(⌈/3 4 5)∘.=2 3 5
 
@EdgyNerd
0 0 1
 
@EdgyNerd Here it all is as a bunch of small functions.
 
8:35 PM
oh right
I got function precedence wrong
 
⌈/ applies to each list individually in a list of lists
 
@frank Nope, but it does apply individually to each row of an array. Matrices (tables) are not vectors of vectors (lists of lists).
 
@Adám that makes a lot of sense now
also
 
ah yes I suppose so
 
wait what does +/ do to a table?
 
8:37 PM
@EdgyNerd Sums each row. In fact, +/ always sums each row, no matter the shape of the argument.
 
oh ok
 
⎕←block←2 3 4⍴⍳12 ⋄ ⎕←+/block
 
@Adám
1  2  3  4
5  6  7  8
9 10 11 12

1  2  3  4
5  6  7  8
9 10 11 12
10 26 42
10 26 42
 
oh so is there a meaningful difference between a matrix and a list of lists?
 
Here ^^, there are six rows, three in the top layer and three in the bottom layer.
 
8:38 PM
⎕←+/[1] 2 2 2⍴⍳8
 
@Quintec
 6  8
10 12
 
@frank Yes. Every element of an array can by any array. So an element of a list can be a list. Or a matrix for that sake.
⎕←(1 2 3)(4 5 6) ⊣ 'list of two lists'
 
@Adám
┌─────┬─────┐
│1 2 3│4 5 6│
└─────┴─────┘
 
⎕←2 3⍴⍳6 ⊣ 'matrix'
 
@Adám
1 2 3
4 5 6
 
8:40 PM
ok, I understand the primes thing now
what next?
 
@frank And of course we have a pair of functions to transform between those. Note that the matrix has two dimensions while the list of lists only has one dimension. increases the number of dimensions (if possible) by "opening up" elements. decreases the number of dimensions (if possible):
⎕←↑(1 2 3)(4 5 6)
 
@Adám
1 2 3
4 5 6
 
⎕←↓2 3⍴⍳6
 
@Adám
┌─────┬─────┐
│1 2 3│4 5 6│
└─────┴─────┘
 
Ah, thats very interesting
 
8:42 PM
@EdgyNerd Well, much of what you've been doing exists as built-ins. E.g. membership is which is a symbol you might have seen before? It looks like an E for "Element of".
 
⎕←1∊1 2 3
 
⍞←(⍳10)∊2 3 5 7
 
@EdgyNerd
1
@Adám 0 1 1 0 1 0 1 0 0 0
 
Note that only "maps" its left argument but treats its right argument as a whole, as opposed to = which maps both sides and which doesn't map any.
@EdgyNerd You're not quite done with primes yet!
 
⎕←1 0 1=0 1 0 ⋄ ⎕←1 0 1∊0 1 0
 
8:44 PM
@frank
0 0 0
1 1 1
 
@Adám oh no
 
Let's learn a new powerful but simple function; "drop":
⍞←4↓'mississippi'
 
@Adám issippi
 
If you give it a negative number, it drops from the end:
⍞←¯4↓'mississippi'
 
@Adám mississ
 
8:45 PM
oh ok
so instead of 1+⍳10 I can do 1↓⍳10
wait no
 
The first gives 10 elements (2…11) and the second gives 9 (2…10)
 
yeah
 
So now let's rethink our definition of a prime. See, a prime is simply a number you cannot make by multiplying two numbers, except 1 and the number itself.
So the multiplication table doesn't contain any primes, but it actually has to contain all non-primes, that is, if we remove the trivial 1,2,3,… row and column.
@EdgyNerd Task: write IsPrime which works on multiple numbers using and the above definition of a prime.
 
⎕←{⍳⍵⍵}10
 
@EdgyNerd
·{⍳⍵⍵}··10
 
8:50 PM
wait no
⎕←{⍵ .o × ⍵}10
 
Uh, ⍵⍵ means something very different from ⍵ ⍵, but right, that isn't what you need anyway.
 
@EdgyNerd
SYNTAX ERROR
 
@EdgyNerd ∘.
 
oh yeah oops
⎕←{⍵ ∘. × ⍵}10
 
@EdgyNerd
100
 
8:51 PM
You're missing
 
⎕←{⍳⍵ ∘. × ⍳⍵}10
 
@EdgyNerd
WS FULL
 
And order of operations: ()
 
⎕←{(⍳⍵) ∘. × ⍳⍵}10
 
@EdgyNerd
 1  2  3  4  5  6  7  8  9  10
 2  4  6  8 10 12 14 16 18  20
 3  6  9 12 15 18 21 24 27  30
 4  8 12 16 20 24 28 32 36  40
 5 10 15 20 25 30 35 40 45  50
 6 12 18 24 30 36 42 48 54  60
 7 14 21 28 35 42 49 56 63  70
 8 16 24 32 40 48 56 64 72  80
 9 18 27 36 45 54 63 72 81  90
10 20 30 40 50 60 70 80 90 100
 
8:52 PM
do I need to use drop for this?
 
You do. Since you want to avoid the first row and column.
That is, you want to avoid any multiplication by 1.
 
⎕←{↓/1↓/(⍳⍵) ∘. × ⍳⍵}10
 
@EdgyNerd
┌┬┬┬┬┬┬┬┬┬┐
│││││││││││
└┴┴┴┴┴┴┴┴┴┘
 
oh
 
Whoa, what‽
 
8:53 PM
⎕←{↓/(⍳⍵) ∘. × ⍳⍵}10
 
Hey, check this out:
⍞←1↓⍳10
 
@Adám 2 3 4 5 6 7 8 9 10
 
oh right
idk why I thought I needed /
⎕←{1↓(1↓⍳⍵) ∘. × ⍳⍵}10
 
Me neither ⍨
 
@EdgyNerd
 3  6  9 12 15 18 21 24 27  30
 4  8 12 16 20 24 28 32 36  40
 5 10 15 20 25 30 35 40 45  50
 6 12 18 24 30 36 42 48 54  60
 7 14 21 28 35 42 49 56 63  70
 8 16 24 32 40 48 56 64 72  80
 9 18 27 36 45 54 63 72 81  90
10 20 30 40 50 60 70 80 90 100
 
8:54 PM
Uh, I think you have one 1↓ in the wrong place there.
 
doesn't that drop the first column / row
oh wait
⎕←{1↓(⍳⍵) ∘. × ⍳⍵}10
 
@EdgyNerd
 2  4  6  8 10 12 14 16 18  20
 3  6  9 12 15 18 21 24 27  30
 4  8 12 16 20 24 28 32 36  40
 5 10 15 20 25 30 35 40 45  50
 6 12 18 24 30 36 42 48 54  60
 7 14 21 28 35 42 49 56 63  70
 8 16 24 32 40 48 56 64 72  80
 9 18 27 36 45 54 63 72 81  90
10 20 30 40 50 60 70 80 90 100
 
Ah, you could go that route, but there's an easier way.
 
⎕←1↓{1↓(⍳⍵) ∘. × ⍳⍵}10
 
@EdgyNerd
 3  6  9 12 15 18 21 24 27  30
 4  8 12 16 20 24 28 32 36  40
 5 10 15 20 25 30 35 40 45  50
 6 12 18 24 30 36 42 48 54  60
 7 14 21 28 35 42 49 56 63  70
 8 16 24 32 40 48 56 64 72  80
 9 18 27 36 45 54 63 72 81  90
10 20 30 40 50 60 70 80 90 100
 
8:55 PM
how?
 
Instead of removing a row and column, just remove the 1 from ⍳10 so you don't end up multiplying by it anywhere.
 
⎕←{1↓(1↓⍳⍵) ∘. × ⍳⍵}10
 
@EdgyNerd
 3  6  9 12 15 18 21 24 27  30
 4  8 12 16 20 24 28 32 36  40
 5 10 15 20 25 30 35 40 45  50
 6 12 18 24 30 36 42 48 54  60
 7 14 21 28 35 42 49 56 63  70
 8 16 24 32 40 48 56 64 72  80
 9 18 27 36 45 54 63 72 81  90
10 20 30 40 50 60 70 80 90 100
 
isn't that what I did before?
oh wait
⎕←{1↓(⍳⍵) ∘. × 1↓⍳⍵}10
 
@EdgyNerd
 4  6  8 10 12 14 16 18  20
 6  9 12 15 18 21 24 27  30
 8 12 16 20 24 28 32 36  40
10 15 20 25 30 35 40 45  50
12 18 24 30 36 42 48 54  60
14 21 28 35 42 49 56 63  70
16 24 32 40 48 56 64 72  80
18 27 36 45 54 63 72 81  90
20 30 40 50 60 70 80 90 100
 
8:57 PM
lol, FWIW, i tried this and accidentally got factors instead: {∪∊⍸⍵⍷∘.×⍨⍳⍵}
 
ok what now?
do I have to remove the last row/column?
 
@EdgyNerd That works, but you're actually still multiplying with 1 from the left side, and then the leftmost 1↓ drops the first row.
@EdgyNerd No, because they contain products which must then be non-primes.
How about simply:
⎕←∘.×⍨1↓⍳10
 
@Adám
 4  6  8 10 12 14 16 18  20
 6  9 12 15 18 21 24 27  30
 8 12 16 20 24 28 32 36  40
10 15 20 25 30 35 40 45  50
12 18 24 30 36 42 48 54  60
14 21 28 35 42 49 56 63  70
16 24 32 40 48 56 64 72  80
18 27 36 45 54 63 72 81  90
20 30 40 50 60 70 80 90 100
 
The coolest emoticon in APL
 
oh yeah
 
8:59 PM
@Quintec Absolutely. My favourite.
 
I forgot about ⍨
 
That's the expression you should have when you forget about it. And the expression it has when forgotten about.
 
now can you simply check if the number is in that table?
 

« first day (1055 days earlier)      last day (1600 days later) »