Starting with

'k v'=. xs
n=. >./k
k2=. 1+i.n

For the second row, the first approach that comes to mind is to treat it as an association:

v2=. (k i. k2) { v , 0

Then recombine as k2 ,: v2. An alternative, slightly less nice, is to add the requisite number of zeroes onto the end and then sort:

missing=. k2 -. k
v2=. (k , missing) /: (v , (#missing)#0)

Or recombine before sorting:

xs2=. /:~&.|: (k , missing) ,: (v , (#missing)#0)

Your idea to combine with an existing bed of zeroes is workable too; don't use take and drop, though, but amend:

v2=. v (k-1)} n#0

(The k-1 being necessary only because your indices start at 1.)

Or, use a complex left argument to # to pad the result with zeroes in the appropriate places:

v2=. (1 j. _1 + 2 -~/\ 0,k) # v

Though this has one pitfall: it doesn't work if there is a gap at the _beginning_ of k (e.g., the first element is 2 rather than 1), because the padding is added after the replicated element.

How did you end up with this array in the first place? It looks a bit like a histogram showing how frequently some event happened on each day of the month. Assuming so, there is a trick to avoid the problem in the first place. Consider the following example histogram (only going up to 7 for brevity, and starting from zero rather than one out of sensibility):

   a=. 0 0 0 1 1 3 6 6 6 6
   #/.~ a
3 2 1 4

Here 2, 4, and 5 didn't show up in the histogram, even though we would like to know that they appeared zero times. The solution is to add one of each element we are interested in, and then subtract it after:

   _1 + #/.~ (i.7) , a
3 2 0 1 0 0 4

Prepending i.7 rather than appending it also ensures that the result histogram comes out in order, even if a happened not to be.

 -E

Sun, 23 Jul 2023, Fr. Daniel Gregoire wrote:

Hi!

(Apologies if this is a double-post, I believe I sent it before I was
officially on the mailing list, and I don't see it in the archives).

Given:

|:xs

1   23
2    4
3    5
4   10
5  397
6    3
7  190
8   44
9    4
10    5
11   13
12 1011
13   10
14 1119
15   72
16    1
17    1
19    6
21    3
22    2
23    1
26    2
28    2
29    2
30    1
31    2


I'd like $xs to be 2 31 but you can see that 18, 20, 24, 25, and 27
are "missing".


I'd like to "fill the holes" so the first row of xs is all the
integers 1 through 31 sequentially, and to put corresponding zeros in
the second row where I've filled the holes in the first.


My thoughts have centered around using (1+i.31),.31#0 to have a 2 by
31 array with all zeros in the second row, and then shifting my
original to find the non-sequential parts with something like:


(1|.{.xs) - {.xs


But then I'm struggling to reason about a non-loopy way to put it all
together. Any help is greatly appreciated.


Kind regards,

Daniel
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to