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

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. -.

Related

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.

Inversions in a binary string

How many inversions are there in a binary string of length n ?
For example , n = 3
000->0
001->0
010->1
011->0
100->2
101->1
110->2
111->0
So total inversions are 6
The question looks like a homework, that's why let me omit the details. You can:
Solve the problem as a recurrency (see Толя's answer)
Make up and solve the characteristic equation, get the solution as a close formula with some arbitrary constants (c1, c2, ..., cn); as the matter of fact you'll get just one unknown constant.
Put some known solutions (e.g. f(1) = 0, f(3) = 6) into the formula and find out all the unknown coefficients
The final answer you should get is
f(n) = n*(n-1)*2**(n-3)
where ** means raising into power (2**(n-3) is 2 in n-3 power). In case you don't want to deal with recurrency and the like stuff, you can just prove the formula by induction.
It is easy recurrent function.
Assume that we know answer for n-1.
And after ato all previous sequences we add 0 or 1 as first character.
if we adding 0 as first character that mean that count of inversions will not be changed: hence answer will be same as for n-1.
if we adding 1 as first character that mean count of inversions will be same as before and will be added extra inversion equals to count of 0 into all previous sequences.
Count of zeros ans ones in sequences of length n-1 will be:
(n-1)*2^(n-1)
Half of them is zeros it will give following result
(n-1)*2^(n-2)
It means that we have following formula:
f(1) = 0
f(n) = 2*f(n-1) + (n-1)*2^(n-2)

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.)

Counting number of times an atom occurs in a table in J language

In J, to count the number of times an element occurs in a list in J is:
count =: 4 : '+/x=y'"0 1.
Alternatively, one can use the "member of interval" E. What is the equivalent expression, in J, for counting the number of times an "atom" occurs in a table?
I am also curious why the rank of "count" is given as 1 0 1, when it is specifically defined as a dyad. Why is the monad rank 1 also included? Can "count", as defined above be used as a monad?
I think what you are looking for is to make the table into a list using (Ravel) monadic ','and then proceed as before. So count becomes:
count=: +/#: (= ,) NB. tacit
count=: 4 : '+/ x = ,y' NB. explicit
Cheers, bob

Counting quantifiers - how

Let's say, I have to model a checkerboard and I want to say that at least 5 squares on the "A" vertical are empty. How do I do that in Alloy? Any other example with numbers different from 0 or 1 would be good. In other words, what do I do when "some" is not precise enough?
Thanks!
You can use the cardinality operator (#) to make assertions about the number of tuples in a relation, e.g.,
#r >= 5
says that the relation r must have at least 5 tuples.
You can also use the cardinality operator with an arbitrary expression, e.g.,
#board.cells >= 5
or
#{c: Cell | c in board.cells and ...} >= 5

Resources