Hi,

My solution is based heavily on this: 
http://www.sudleyplace.com/APL/AnatomyOfAnIdiom.ahtml 
<http://www.sudleyplace.com/APL/AnatomyOfAnIdiom.ahtml>

   dfm0=: [ {~ [: ([ i. -.)&>/ ,&# <@$"0 1 [ /:@/:"1@i. , ,: ,~
   dfm1=: [: ; {."1@-.&(,&<"_1 +/@(* +/\"1)@=)
   x=: 'cabd' [ y=: 'cbaab'
   
   x (dfm0 ,: dfm1)~ y          NB. uses same argument order as -.
ab
ab
   18 54 (dfm0 ,: dfm1)&q: 54 18
0
0

3
3
   'aaaa' (dfm0 ,: dfm1)~ 'cbaab'
cbb
cbb

The version from Sudley "labels" the elements as follows:


        a b a c b a  ;  b a a b a a c   Note how the first a is 0
        0 4 1 6 5 2  ;  4 0 1 5 2 3 6   in both arguments, the first
                                        b is 4, etc.

It then does usual set difference -. and proceeds to reindexing into the left 
argument.

The second version is slightly slower but perhaps easier to understand:
You can imagine taking each element of each argument and
giving it a subscript equal to the number of elements which
are equal to it and appear before it:

        a b a c b a  ;  b a a b a a c
        0 0 1 0 1 2  ;  0 0 1 1 2 3 0

It now suffices to remove the right argument from the left using  -. and remove 
the
subscripts from the result.

The second method involves boxed searching under the hood, which takes slightly
longer than a simple search between two integer lists. Thus the first method is
slightly faster.

Louis

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

Reply via email to