How to remove an element from a list in J by index? - j

The rather verbose fork I came up with is
({. , (>:#[ }. ]))
E.g.,
3 ({. , (>:#[ }. ])) 0 1 2 3 4 5
0 1 2 4 5
Works great, but is there a more idiomatic way? What is the usual way to do this in J?

Yes, the J-way is to use a 3-level boxing:
(<<<5) { i.10
0 1 2 3 4 6 7 8 9
(<<<1 3) { i.10
0 2 4 5 6 7 8 9
It's a small note in the dictionary for {:
Note that the result in the very last dyadic example, that is, (<<<_1){m , is all except the last item.
and a bit more in Learning J: Chapter 6 - Indexing: 6.2.5 Excluding Things.

Another approach is to use the monadic and dyadic forms of # (Tally and Copy). This idiom of using Copy to remove an item is something that I use frequently.
The hook (i. i.##) uses Tally (monadic #) and monadic and dyadic i. (Integers and Index of) to generate the filter string:
2 (i. i.##) 'abcde'
1 1 0 1 1
which Copy (dyadic #) uses to omit the appropriate item.
2 ((i. i.##) # ]) 0 1 2 3 4 5
0 1 3 4 5
2 ((i. i.##) # ]) 'abcde'
abde

Related

Open boxes with a custom padding value in J

Unboxing or opening boxes with different sizes causes padding with 0 for numerals and a space with literals:
v=.1 4 8 ; 2 6 4 ; 6 8 4 5; 7 8 9; 6 3 7 4 9
>v
1 4 8 0 0
2 6 4 0 0
6 8 4 5 0
7 8 9 0 0
6 3 7 4 9
The fit (!.) conjunction is usually the thing to use for these things, but
>!. _1 v
Is not supported and throws a domain error.
I've got this, but with very large arrays it's not very fast:
(>./ # every y) {.!. _1 every y
Is there an efficient way to define the padding value for opening boxes?
Setting
f =: 3 :'(>./ # every y) {.!. _1 every y'
g =: _1&paddedOpen
and (in the same spirit as your f):
h =: 3 : '((>./# &> y)&($!._1))#> y'
I get the following performances for time and space:
(100&(6!:2) ,: 7!:2) &.> 'f L';'g L';'h L'
┌─────────┬─────────┬─────────┐
│ 0.045602│0.0832403│0.0388146│
│4.72538e6│1.76356e7│4.72538e6│
└─────────┴─────────┴─────────┘
where L is a large array:
L =. (<#(+i.)/)"1 ? 50000 2 $ 10
You can slightly improve f by making it terse; for example:
f =: ] {.!._1&>~ >./#:(#&>)
I don't think that there is much room for more improvements.
My guess is that doing the padding directly will be the path to efficiency, especially if the need is restricted to a specific structure of data (as perhaps suggested by your example.) This solution has not been subjected to performance analysis, but it shows one way to do the padding yourself.
Here I'm making the assumption that the task involves always going from boxed lists to a table, and that the data is always numeric. Additional assert. statements may be worth adding to qualify that the right argument is as expected.
v=.1 4 8 ; 2 6 4 ; 6 8 4 5; 7 8 9; 6 3 7 4 9 NB. example data
paddedOpen=: dyad define
assert. 0 = # $ x
Lengths=. #&> y
PadTo=. >./ Lengths
Padding=. x #~&.> PadTo - Lengths
y ,&> Padding
)
_1 paddedOpen v
1 4 8 _1 _1
2 6 4 _1 _1
6 8 4 5 _1
7 8 9 _1 _1
6 3 7 4 9
It is only important to first pad with a customized value when the default value cannot be used as an intermediary. If the default value can be used in passing, it will be faster to let the default padding occur then replace all default values with the preferred value. From the nature of your question I assume the default value has meaning in the main domain, so simple replacement won't serve.
Please leave comments informing us of the relative performance of different techniques, or at least whether one does or does not prove fast enough for your purposes.

How to generate all possible combinations of values from n different sets?

I have n sets, each having n1,n2,n3...nN distinct members.
How do I generate n1*n2*n3...*nN possible combinations from them
e.g
[6] [4 5] [1 2 3 4]
will give
6 4 1
6 4 2
6 4 3
6 4 4
6 5 1
6 5 2
6 5 3
6 5 4
I want to do this in matlab, but a normal algorithm would also be fine
An easy solution is to simulate a sum !
Start with a list of indices 0 0 0, corresponding to the indices of your values. That leads you to the value 6 4 1 in your example.
then add 1.
You now have indices 001, so 642
and so on.
at 004, you overflow, so your indices become 010, having 6 5 1
Keep doing that, and keep a counter of the visited possibilites. There are 1 * 2 * 4 possibilities, so it's easy to know when you are done.
I think you're looking for Cartesian product of sets:
This should help:
cartprod(N1,N2,N3, ...)
http://www.mathworks.com/matlabcentral/fileexchange/5475-cartprod-cartesian-product-of-multiple-sets
There's another one here
set = {n1, n2, n3, ...}
allcomb(set{:})

How can I implement a grouping algorithm in J?

I'm trying to implement A006751 in J. It's pretty easy to do in Haskell, something like:
concat . map (\g -> concat [show $ length g, [g !! 0]]) . group . show
(Obviously that's not complete, but it's the basic heart of it. I spent about 10 seconds on that, so treat it accordingly.) I can implement any of this fairly easily in J, but the part that eludes me is a good, idiomatic J algorithm that corresponds to Haskell's group function. I can write a clumsy one, but it doesn't feel like good J.
Can anyone implement Haskell's group in good J?
Groups are usually done with the /. adverb.
1 1 2 1 </. 'abcd'
┌───┬─┐
│abd│c│
└───┴─┘
As you can see, it's not sequential. Just make your key sequential like so (essentially determining if an item is different from the next, and do a running sum of the resulting 0's and 1's):
neq =. 13 : '0, (}. y) ~: (}: y)'
seqkey =. 13 : '+/\neq y'
(seqkey 1 1 2 1) </. 'abcd'
┌──┬─┬─┐
│ab│c│d│
└──┴─┴─┘
What I need then is a function which counts the items (#), and tells me what they are ({. to just pick the first). I got some inspiration from nubcount:
diffseqcount =. 13 : ',(seqkey y) (#,{.)/. y'
diffseqcount 2
1 2
diffseqcount 1 2
1 1 1 2
diffseqcount 1 1 1 2
3 1 1 2
If you want the nth result, just use power:
diffseqcount(^:10) 2 NB. 10th result
1 3 2 1 1 3 2 1 3 2 2 1 1 3 3 1 1 2 1 3 2 1 2 3 2 2 2 1 1 2
I agree that /. ( Key ) is the best general method for applying verbs to groups in J. An alternative in this case, where we need to group consecutive numbers that are the same, is dyadic ;. (Cut):
1 1 0 0 1 0 1 <(;.1) 3 1 1 1 2 2 3
┌─┬─────┬───┬─┐
│3│1 1 1│2 2│3│
└─┴─────┴───┴─┘
We can form the frets to use as the left argument as follows:
1 , 2 ~:/\ 3 1 1 1 2 2 3 NB. inserts ~: in the running sets of 2 numbers
1 1 0 0 1 0 1
Putting the two together:
(] <;.1~ 1 , 2 ~:/\ ]) 3 1 1 1 2 2 3
┌─┬─────┬───┬─┐
│3│1 1 1│2 2│3│
└─┴─────┴───┴─┘
Using the same mechanism as suggested previously:
,#(] (# , {.);.1~ 1 , 2 ~:/\ ]) 3 1 1 1 2 2 3
1 3 3 1 2 2 1 3
If you are looking for a nice J implementation of the look-and-say sequence then I'd suggest the one on Rosetta Code:
las=: ,#((# , {.);.1~ 1 , 2 ~:/\ ])&.(10x&#.inv)#]^:(1+i.#[)
5 las 1 NB. left arg is sequence length, right arg is starting number
11 21 1211 111221 312211

Force array instead of matrix in J for "i."

The i. primitive produces a list of integers:
i. 10
0 1 2 3 4 5 6 7 8 9
If I want to produce several short lists in a row, I do this:
;i."0 each [ 2 3 4
0 1 0 1 2 0 1 2 3
(the result I want)
Boxing (that each) is a crutch here, because without it, i."0 produces a matrix.
i."0 [ 2 3 4
0 1 0 0
0 1 2 0
0 1 2 3
(the result I don't want)
Is there a better way to not have i."0 format the output to a matrix, but an array?
No, I believe you can't do any better than your current solution. There is no way for i."0 to return a vector.
The "0 adverb forces i. to accept scalars, and i. returns vectors. i. has no way of knowing that your input was a vector rather than a scalar. According to The J primer the result shape is the concatenation of the frame of the argument and the result.
The shortest "box-less" solution I've found so far is
(*#$"0~#&,i."0) 2 3 4
which is still longer than just using ;i. each 2 3 4

Most concise J syntax for creating a numeric matrix

Imagine that I want to take the numbers from 1 to 3 and form a matrix such that each possible pairing is represented, e.g.,
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
Here is the monadic verb I formulated in J to do this:
($~ (-:## , 2:)) , ,"0/~ 1+i.y
Originally I had thought that ,"0/~ 1+i.y would be sufficient, but unfortunately that produces the following output:
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
In other words, its shape is 3 3 2 and I want something whose shape is 9 2. The only way I could think of to fix it is to pour all of the data into a new shape. I'm convinced there must be a more concise way to do this. Anyone know?
Reshaping your intermediate result can be simplified. Removing the topmost axis is commonly done with ,/ so in your case the completed phrase could be ,/ ,"0/~ 1+i.y
One way (which uses { as a monad in its capacity for permutation cataloguing):
>,{ 2#<1+i.y
EDIT:
Some fun to be had with this scheme:
All possible permutations:
>,{ y#<1+i.y
Configurable number in sequence:
>,{ x#<1+i.y
I realize this question is old, but there is a simpler way to do it: count to 9 in trinary, and add 1.
1 + 3 3 #: i.9
1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
The 3 3 & #: gives you two digits. The general 'base 3' verb is 3 & #.^:_1.

Resources