Jonah
Jonah

Reputation: 16222

J string manipulation using only builtins

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

Answers (2)

Tikkanz
Tikkanz

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

bob
bob

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

Related Questions