Reputation: 16222
You are given a string like ))()(())(
, and you wish to remove all instances of ()
from the string, which in this case means these two instances:
))()(())(
^^ ^^
leaving only ))()(
.
I know you can use the library function stringreplace, or you could load up a regex library, but I want to know is if there is a concise way of accomplishing this the the J builtin operators exclusively?
I should clarify that my own solution was:
#~(-.@+._1&|.)@('()'&E.)
which I consider verbose -- so any similar solutions would not qualify as "concise" in my book. I'm really asking if there is a way to use a builtin (or maybe a simple combination of 2) to solve this directly. I expect this answer is no.
Upvotes: 2
Views: 144
Reputation: 2463
I think you are right that there is no ultra-concise way of expressing the operation you want to perform using just J primitives. The version I came up was very much like the one Dan, suggested above.
However given that a built in library verb rplc
(based on stringreplace
) performs exactly the operation you are after, I'm not sure why it would be better to replace it with a primitive.
'))()(())(' rplc '()';''
))()(
Having said that, if you can come up with a compelling case, then there is probably no reason it couldn't be added.
Upvotes: 3
Reputation: 4302
Not sure how concise it is, but I think that this will work:
deparen=. (-.@:(+/)@:(_1&|. ,: ])@:E. # ])
'()' deparen '))()(())('
))()(
Essentially the work is done by -. @: (+/) @: (_1&|. ,: ] )@:E
. to create a bit string that removes the '()'
instances using #
(Copy) on the right argument.
E.
identifies the positions of '()'
using a bit string. Shift and laminate to get positions of '('
and ')'
, add them together to have 1 1
in the string where ever there is a '()'
and then negate so these positions become 0 0
and are removed using Copy
Upvotes: 2