what does 1: mean in the verb train (100 $ - {. 1:)"0 - j

the j solution to the 100 doors problem in rosetta code is ~:/ (100 $ - {. 1:)"0 >:i.100
>: i. 100 means 'make a list of numbers from 1 to 100'
(100 $ - {. 1:)"0 >: i. 100 means 'make a list of 100 lists, where each position represents an integer, and make every nth position 1'
~:/ (100 $ - {. 1:)"0 >: i. 100 means 'turn on only the numbers that have a one in their column only once' which are the squares.
but the verb train (100 $ - {. 1:) has me mystified... What does 1: mean? I found the : verb in nuvoc, but I did not see this specific application there. How are the verbs grouped?

Related

What is the "j" expression for the "maximum consecutive ones" problem?

In the paper "Combinatory Logic and Combinators in Array Languages" they give a solution in APL:
vec ← 1 1 0 1 1 1 0 0 0 1
⍝ split (partition) on zeroes
⊆⍨vec
┌───┬─────┬─┐
│1 1│1 1 1│1│
└───┴─────┴─┘
⍝ size of each sublist
≢ ̈⊆⍨vec
2 3 1
⍝ max reduction
⌈/≢¨⊆⍨vec
3
For clarity, they also note:
The final maximum consecutive ones APL solution can be translated for those who don’t read APL:
reduce(max, map(length, W(partition, vec)))
So, how would one express the following in J?
⌈/≢¨⊆⍨vec
The ⊆ symbol seems to be a "partition" operator. It's not clear this exists in J but I may have just missed it. Curious what the above expression would be in "J".
Dan Bron's answer in the comments is the way to go for sure. I did a video on this problem and if you are interested you can watch me walk through the different options. https://www.youtube.com/watch?v=lbi_PMVbeaQ The version I ended preferring was
t=:[: >./ [: #;. _2 ,&0
but I also look at
t=:[: {: [: $ [: ];. _2 ,&0
as an alternative.
To provide a different point of view, the maximum number of 1s in a row is also the maximum of the difference between consecutive indices of 0s in the array (minus one), for which J (almost) has a primitive: I. (up to a -.). So the following works too:
t=: [: -&1 [: >./ [: 2&(-~/;._3) [: I. -.

A better way to rotate columns of a matrix independently

As part of my journey to learn j I implemented a technique for computing the area of a polygon I came across in Futility Closet. I came up with a solution, but it's quite inelegant, so I'm interested in better methods:
polyarea =: -:#((+/#((1&{&|:)*(0{&|:1&|.)))-(+/#((0&{&|:)*(1{&|:1&|.))))
y =: 2 7 9 5 6,.5 7 1 0 4
polyarea y
20
This technique rotates one column and takes the dot product of the columns, then does the same after rotating the other column. The area is half the difference of these two results.
Interested in suggestions!
I think that their technique boils down to using the determinant to find the area of the polygon http://mathworld.wolfram.com/PolygonArea.html
But using the Futility Closet technique I would first close the polygon by adding the first point to the end.
y =: 2 7 9 5 6,.5 7 1 0 4
close=: (, {.)
close is a hook that takes the first pair and appends it to the end
Then take the determinants two points at a time, which is essentially what they are doing with their columns and rotations
dets=: 2 (-/ . *)\ close
dets takes the determinant of each pair of points - result is negative if the points are in clockwise order
Then take those values and process for the answer.
clean=: |#:-:#:(+/)
clean sums up the determinants, divides by 2 and returns the absolute value of the result.
clean #: dets y
20
To see the result in complete tacit form we can lean on the f. adverb (Fix) to flatten our definitions.
clean #: dets f.
|#:-:#:(+/)#:(2 -/ .*\ (, {.))
It is just a different way of looking at what they are doing, but it allows J to use the . conjunction (Dot Product) and \ adverb (Infix) to handle all of those rotations with determinants.
Hope this helps.

Mapping of elements by number of occurrences in J

Using J language, I wish to attain a mapping of the counts of elements of an array.
Specifically, I want to input a lowercased English word with two to many letters and get back each pair of letters in the word along with counts of occurences.
I need a verb that gives something like this, in whatever J structure you think is appropriate:
For 'cocoa':
co 2
oc 1
oa 1
For 'banana':
ba 1
an 2
na 2
For 'milk':
mi 1
il 1
lk 1
For 'to':
to 1
(For single letter words like 'a', the task is undefined and will not be attempted.)
(Order is not important, that's just how I happened to list them.)
I can easily attain successive pairs of letters in a word as a matrix or list of boxes:
2(] ;._3)'cocoa'
co
oc
co
oa
]
2(< ;._3)'cocoa'
┌──┬──┬──┬──┐
│co│oc│co│oa│
└──┴──┴──┴──┘
But I need help getting from there to a mapping of pairs to counts.
I am aware of ~. and ~: but I don't just want to return the unique elements or indexes of duplicates. I want a mapping of counts.
NuVoc's "Loopless" page is indicating that / (or /\. or /\) are where I should be looking for accumulation problems. I am familiar with / for arithmetic operations on numeric arrays, but for u/y I don't know what u would have to be to accumulate the list of pairs of letters that would make up y.
(NB. I can already do this in "normal" languages like Java or Python without help. Similar questions on SO are for languages with very different syntax and semantics to J. I am interested in the idiomatic J approach to this sort of problem.)
To get the list of 2-letter combinations I'd use dyadic infix (\):
2 ]\ 'banana'
ba
an
na
an
na
To count occurrences the primitive that immediately comes to mind is key (/.)
#/.~ 2 ]\ 'banana'
1 2 2
If you want to match the counts to the letter combinations you can extend the verb to the following fork:
({. ; #)/.~ 2 ]\ 'banana'
┌──┬─┐
│ba│1│
├──┼─┤
│an│2│
├──┼─┤
│na│2│
└──┴─┘
I think that you are looking to map counts of unique items to the items. You can correct me if I am wrong.
Starting with
[t=. 2(< ;._3)'cocoa'
┌──┬──┬──┬──┐
│co│oc│co│oa│
└──┴──┴──┴──┘
You can use ~. (Nub) to return the unique items in the list
~.t
┌──┬──┬──┐
│co│oc│oa│
└──┴──┴──┘
Then if you compare the nub to the boxed list you get a matrix where the 1's are the positions that match the nub to the boxed pairs in your string
t =/ ~.t
1 0 0
0 1 0
1 0 0
0 0 1
Sum the columns of this matrix and you get the number of times each item of the nub shows up
+/ t =/ ~.t
2 1 1
Then box them so that you can combine the integers along side the boxed characters
<"0 +/ t =/ ~.t
┌─┬─┬─┐
│2│1│1│
└─┴─┴─┘
Combine them by stitching together the nub and the count using ,. (Stitch)
(~.t) ,. <"0 +/ t =/ ~.t
┌──┬─┐
│co│2│
├──┼─┤
│oc│1│
├──┼─┤
│oa│1│
└──┴─┘
[t=. 2(< ;._3)'banana'
┌──┬──┬──┬──┬──┐
│ba│an│na│an│na│
└──┴──┴──┴──┴──┘
(~.t) ,. <"0 +/ t =/ ~.t
┌──┬─┐
│ba│1│
├──┼─┤
│an│2│
├──┼─┤
│na│2│
└──┴─┘
[t=. 2(< ;._3)'milk'
┌──┬──┬──┐
│mi│il│lk│
└──┴──┴──┘
(~.t) ,. <"0 +/ t =/ ~.t
┌──┬─┐
│mi│1│
├──┼─┤
│il│1│
├──┼─┤
│lk│1│
└──┴─┘
Hope this helps.

I want to get result in one line. I don't need new dimensions

(1:)`(3:)#.(1&=)"0 i.2
1 3
(1:,2:)`(3:)#.(1&=)"0 i.2
1 2
3 0
I want to get
1 2 3
Without new dimensions. Without zeros.
The shape changes dramatically between (1:) and (1:,2:).
$ 1: 'a'
$ 1 $ 1: 'a'
1
$ (1:,2:) 'a'
2
(1&$ 1:)`(1&$ 3:)#.(1&=)"0 i.2
1
3
There's probably a better way, but to my way of thinking, you're generating arrays of unequal length, which should be boxed, and then you want to turn them into a single list.
Thus:
; ((1:,2:)`(3:))#.(1&=)"0&.> i.2
1 2 3
Which can be refactored and improved a bit:
;#:((1:,2:)`(3:)#.(1&=)each) i.2
1 2 3
You could have used (1:,2:,3:) 'ignored argument' to form the list, but that doesn't address why you were using #.
Dane's comment about boxing intermediate results and then razing the resulting list is relevant if you want to merge irregularly shaped results. (Which might be what you were trying for, here.)

First position occurrences in a list of lists

So i have for example this list [[2,1,3],[1,2,3],[2,3,1],[3,1,2]]. What I want from it is to get a list which tells me how many times each of the numbers (in this example just 3) comes in the first position.
length $ filter (\a -> head a == ???) ([[2,1,3],[1,2,3],[2,3,1],[3,1,2]])
The ??? should be 1-2-3, so my result will be [1,2,1] - 1 list has 1 in first position, 2 have the 2 as first position and 1 has 3 as first position.
I am a new to Haskell and I am trying to figure out the proper definition!
Do not try to solve this at once. Start by just creating a list of list beginnings.
So that you get:
[2,1,2,3]
You can then sort, group and count later.

Resources