Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Any other ways to emulate `tr` in J?

Tags:

j

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.

like image 383
JB. Avatar asked Mar 04 '11 22:03

JB.


4 Answers

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
like image 129
MPelletier Avatar answered Nov 05 '22 09:11

MPelletier


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.

like image 20
Eelvex Avatar answered Nov 05 '22 11:11

Eelvex


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.

like image 1
Jesse Millikan Avatar answered Nov 05 '22 09:11

Jesse Millikan


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

   8!:2]_1
-1
like image 1
rdm Avatar answered Nov 05 '22 10:11

rdm