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