Any other ways to emulate `tr` in J?

436 Views Asked by At

I picked up J a few weeks ago, about the same time the CodeGolf.SE beta opened to the public.

A recurrent issue (of mine) when using J over there is reformatting input and output to fit the problem specifications. So I tend to use code like this:

( ] ` ('_'"0) ) @. (= & '-')

This one untested for various reasons (edit me if wrong); intended meaning is "convert - to _". Also come up frequently: convert newlines to spaces (and converse), merge numbers with j, change brackets.

This takes up quite a few characters, and is not that convenient to integrate to the rest of the program.

Is there any other way to proceed with this? Preferably shorter, but I'm happy to learn anything else if it's got other advantages. Also, a solution with an implied functional obverse would relieve a lot.

4

There are 4 best solutions below

3
On BEST ANSWER

It sometimes goes against the nature of code golf to use library methods, but in the string library, the charsub method is pretty useful:

   '_-' charsub '_123'
 -123
   ('_-', LF, ' ') charsub '_123', LF, '_stuff'
 -123 -stuff
0
On

rplc is generally short for simple replacements:

  'Test123' rplc 'e';'3'
  T3st123

Amend m} is very short for special cases:

 '*' 0} 'aaaa'
 *aaa
 '*' 0 2} 'aaaa'
 *a*a
 '*&' 0 2} 'aaaa'
 *a&a

but becomes messy when the list has to be a verb:

b =: 'abcbdebf'
'L' (]g) } b
aLcLdeLf

where g has to be something like g =: ('b' E. ]) # ('b' E. ]) * [: i. #.

There are a lot of other "tricks" that work on a case by case basis. Example from the manual:

To replace lowercase 'a' through 'f' with uppercase 'A' through 'F' in a string that contains only 'a' through 'f': ('abcdef' i. y) { 'ABCDEF' Extending the previous example: to replace lowercase 'a' through 'f' with uppercase 'A' through 'F' leaving other characters unchanged: (('abcdef' , a.) i. y) { 'ABCDEF' , a.

0
On

You might want to consider using the 8!:2 foreign:

   8!:2]_1
-1
2
On

I've only dealt with the newlines and CSV, rather than the general case of replacement, but here's how I've handled those. I assume Unix line endings (or line endings fixed with toJ) with a final line feed.

  • Single lines of input: ".{:('1 2 3',LF) (Haven't gotten to use this yet)
  • Rectangular input: (".;._2) ('1 2 3',LF,'4 5 6',LF)
  • Ragged input: probably (,;._2) or (<;._2) (Haven't used this yet either.)
  • One line, comma separated: ".;._1}:',',('1,2,3',LF)

This doesn't replace tr at all, but does help with line endings and other garbage.