roman and arabic - some fun(ctions) 
Author Message
 roman and arabic - some fun(ctions)

Here are the results of an exercise using some simple but cute
functions to learn J.  The results were personally quite
rewarding and may be of interest.

I did not "catch on" to J quickly.  However, that is a personal
statement about me, not about J.  My goal has been to become
familiar with large parts of J.  So, considering the richness
of the language and my unfamiliarity with the development of J
concepts (going back many years), I feel that the time has not
been inappropriately long.  (Even a restricted subset makes for
a very powerful programming language, but many among us insist
on learning the whole thing, which is not unreasonable.)  Also,
I feel my familiarity and years of "internalizing" APL in
various dialects has made it more difficult (a situation that
has in fact been reported by others.)  The following exercise
turned out unexpectedly to be a really helpful learning
exercise.

As an exercise in learning J, I translated two simple functions
taken from the Toronto Toolkit, from APL (standard APL). One
function returns the roman numeral equivalent of an arabic
number, the other is the "inverse", giving the arabic
equivalent of a roman numeral.

First I translated the functions.  They were simple functions
of several lines.  (By the way, has anyone made a little
translation table of APL equivalents of the common functions
and idioms for use in translating from APL to J?  Studies have
shown that certain functions and idioms are very common in APL
functions --- the 80/20 "rule".)  If anyone wants to see mine,
send me a line.

For those "translation hackers" who love horror stories about
rewrites, I will mention that even in these small functions I
found some "wierd" APL code.  For example, what do you think
this meant?

(in origin 1)(actually it doesn't matter)
(a,0)[1+ {iota} {rho} a]

If you guessed the following ...

1 {drop} a,0

... then you guessed what I guessed!!  I wonder if I'll ever
find out how that got in there!  It worked, though.

Anyway, the J functions were straightforward translations of
the algorithms, allowing for changing from origin 1 to origin
0, removing "wierd" phrases (see above), and removing some
parameter checking (for simplicity).

   roman 16
xvi
   roman 1995
mcmxcv
   arabic 'xvi'
16
   arabic 'mcmxcv'
1995

Now the original functions expected single numbers only, no
lists or matrices.
Then suddenly I realized I could use "the power of J".  All
of a sudden the stuff I was learning about rank operator and

I could easily apply the functions (now called verbs) to any
array!

   9!:7 '+++++++++|-'
   roman"0 i.10

i
ii
iii
iv
v
vi
vii
viii
ix

   NB. Let's box each result for a neat one-line display.


+-+--+---+----+---+--+---+----+-----+---+
|x|xi|xii|xiii|xiv|xv|xvi|xvii|xviii|xix|
+-+--+---+----+---+--+---+----+-----+---+

   NB. Same idea for several multi-character arguments.

   each =. &.>
   arabic each 'xvi';'xxx';'mcmxcv'
+--+--+----+
|16|30|1995|
+--+--+----+

   NB. This next part took a little experimentation to
   NB. figure out how to return an unboxed result
   NB. There are other ways but I wanted to play with
   NB. the power of adverb operators.

   (arabic &: > " 0) 'xvi';'xxx';'mcmxcv'
16 30 1995

   every =. 1 : 'x. &: > " 0'
   arabic every 'xvi';'xxx';'mcmxcv'
16 30 1995

   NB. Then I got another idea. I mentionned I had always
   NB. considered "roman" and "arabic" as inverses ...

   roman 2001
mmi
   arabic roman 2001
2001
   roman arabic 'mi'
mi

   NB. Now I could show this using the
   NB. Power conjunction (operator).

   NB. Define a function "roman" with inverse "arabic"

   f =. roman :. arabic
   f 16
xvi

   NB. The power _1 is the inverse function, as is usual using
   NB. power notation.

   f^:_1 'xvi'
16
   f^:_1 f 16
16

   NB. This is fun.  I like J.

   NB. The text of the functions.

   roman
+-+-+---------------------------------------------------------+
|3|:|NB. returns roman numeral equivalent for arabic number y.|
| | |NB. highest number in domain is 3999                     |
| | |antibase =. #:                                           |
| | |y =. , y.                                                |
| | |m =. 3 3 3 3,1 3 3 3,1 1 3 3,1 1 1 3,1 0 3 3,0 3 3 3     |
| | |m =. 10 4 $ m, 0 1 3 3, 0 1 1 3, 0 1 1 1, 1 _1 3 3       |
| | |a =. ,(10 10 10 10 antibase y){m                         |
| | |(_1 + (a ~: 3) # a + 2 * <. 0.25 * i. 16) { 'mdclxvi'    |
+-+-+---------------------------------------------------------+
   arabic
+-+-+---------------------------------------------------------+
|3|:|NB. returns arabic number equivalent for roman numeral y.|
| | |NB. arabic is type numeric (base 10), roman is character |
| | |gte  =. >:   NB. (greater than or equal)                 |
| | |drop =. }.                                               |
| | |a =. ('ivxlcdm' i. y.) { 1 5 10 50 100 500 1000          |
| | |+/ a * _1 + 2 * a gte 1 drop a,0                         |
+-+-+---------------------------------------------------------+

--RL



Tue, 27 Jan 1998 03:00:00 GMT  
 roman and arabic - some fun(ctions)

[discussion about "roman" and "arabic" verbs removed]

Quote:

>   NB. Then I got another idea. I mentionned I had always
>   NB. considered "roman" and "arabic" as inverses ...

>   roman 2001
>mmi
>   arabic roman 2001
>2001
>   roman arabic 'mi'
>mi

>   NB. Now I could show this using the
>   NB. Power conjunction (operator).

>   NB. Define a function "roman" with inverse "arabic"

>   f =. roman :. arabic
>   f 16
>xvi

>   NB. The power _1 is the inverse function, as is usual using
>   NB. power notation.

>   f^:_1 'xvi'
>16
>   f^:_1 f 16
>16

>   NB. This is fun.  I like J.

>   NB. The text of the functions.

>   roman
>+-+-+---------------------------------------------------------+
>|3|:|NB. returns roman numeral equivalent for arabic number y.|
>| | |NB. highest number in domain is 3999                     |
>| | |antibase =. #:                                           |
>| | |y =. , y.                                                |
>| | |m =. 3 3 3 3,1 3 3 3,1 1 3 3,1 1 1 3,1 0 3 3,0 3 3 3     |
>| | |m =. 10 4 $ m, 0 1 3 3, 0 1 1 3, 0 1 1 1, 1 _1 3 3       |
>| | |a =. ,(10 10 10 10 antibase y){m                         |
>| | |(_1 + (a ~: 3) # a + 2 * <. 0.25 * i. 16) { 'mdclxvi'    |
>+-+-+---------------------------------------------------------+
>   arabic
>+-+-+---------------------------------------------------------+
>|3|:|NB. returns arabic number equivalent for roman numeral y.|
>| | |NB. arabic is type numeric (base 10), roman is character |
>| | |gte  =. >:   NB. (greater than or equal)                 |
>| | |drop =. }.                                               |
>| | |a =. ('ivxlcdm' i. y.) { 1 5 10 50 100 500 1000          |
>| | |+/ a * _1 + 2 * a gte 1 drop a,0                         |
>+-+-+---------------------------------------------------------+

>--RL

 I think you've come across an interesting area of J -- the ability to
define verbs with their inverses.

To continue with your experimentation with the roman/arabic verbs, where
   roman 16
xvi
   arabic 'xvi'
16

 Combining these two verbs as a single verb with its own inverse leads
to a couple interesting steps.  Rather than your definition of
  f=. roman :. arabic
(ie f is roman, with the inverse arabic), I'll go the other way
around:

   ara=. arabic :. roman   NB.  ara is arabic, with inverse roman

Once you have this definition, you can really take advantage of the
use of &. (under):

   ara 'iv'
4
   'iv'  + &. ara  'iv'       NB.  +&.ara  is addition *under* arabic
viii
   'iv'  * &. ara  'iv'       NB.  multiply roman numerals
xvi
   >: &. ara  'iv'            NB.  increment
v

And, in all the above expressions, you can isolate the "under ara" part
as an adverb, as in:
   rom=. &. ara

Now rom can be used as an adverb on any verb to apply that verb under ara,
ie    f rom   is a roman numeral version of f.  For example:

   !5                         NB.  factorial 5
120
   !rom 'v'                   NB.  same with roman numerals
cxx
   'ii'  ^rom  'viii'         NB.  2 raised to the power 8
cclvi

Of course, *any* verb whose domain includes numbers can be extended
this way:

   double=. 3 : '2 * y.'      NB.  Double, same as monad  +:
   double 20
40
   double rom 'xx'
xl

 Finally, if you have any two verbs which convert to and from a
different number representation, they can be combined together in
this manner to easily extend other J verbs to them:

   base2convert=. #. :. #:     NB. binary to decimal and its inverse
   base2=. &. base2convert     NB. adverb applies verb *under* base 2

   1 1 0 1  *base2  1 0 1 1    NB. 13 times 11 in base 2
1 0 0 0 1 1 1 1
   i. 8                        NB. first 8 decimal numbers
0 1 2 3 4 5 6 7
   i. base2  1 0 0 0           NB. first 1 0 0 0 binary numbers
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1

--



Wed, 28 Jan 1998 03:00:00 GMT  
 roman and arabic - some fun(ctions)

Kirk Iverson writes on Saturday, August 12:

Quote:
> ...
> Finally, if you have any two verbs which convert to and from a
> different number representation, they can be combined together in
> this manner to easily extend other J verbs to them:

>    base2convert=. #. :. #:     NB. binary to decimal and its inverse
>    base2=. &. base2convert     NB. adverb applies verb *under* base 2

>    1 1 0 1  *base2  1 0 1 1    NB. 13 times 11 in base 2
> 1 0 0 0 1 1 1 1
> ...

Since J recognizes #. and #: as an inverse pair, "base2convert"
can be stated simply as #. .  The interpreter also "knows" the
inverse of n&#. .  

As for another use of this construct, E.E. McDonnell pointed
out on 1992-04-05 that J=.1&|.&.#:  (rotate-by-1 under binary
representation) is a solution to the Josephus problem (Graham,
Knuth, and Patashnik, Concrete Mathematics, Sec. 1.3).

As a matter of historical interest, binary representation and
binary value (denoted by the monads encode and decode) were once
defined in APL (see Falkoff, Iverson, and Sussenguth, A Formal
Description of SYSTEM/360, IBM Systems Journal, Volume 3,
Number 3, 1964, Table 1, pp. 200-201), but were later removed
due to space limitations.  And what limitations they were:
at the time, APL was running on a S/360 Model 50 with 256 Kbytes
of main store (nevertheless supporting 24 users simultaneously
with sub-second response).  

The assignment of meanings is resurrected in J:

Word      Monad                   Dyad

#.       base 2                   base
         (binary value)           (decode)

#:       antibase 2               antibase
         (binary representation)  (encode)

(Much of the preceding description first appeared in Vector, Volume 9,
Number 2, 1992-10.)



Thu, 29 Jan 1998 03:00:00 GMT  
 roman and arabic - some fun(ctions)
The following article has apparently met with some mishap on the
ramp to the Information Superhighway.
____________________________________________________________________


 From: Roger Hui <hui>

 Subject: Re: roman and arabic - some fun(ctions)
 Date: Sat, 12 Aug 1995 15:27:25 GMT
 Organization: .

A few comments on Richard Levine's post of Friday, August 11, on Roman
to Arabic numeral translations.

Quote:

> +-+--+---+----+---+--+---+----+-----+---+
> |x|xi|xii|xiii|xiv|xv|xvi|xvii|xviii|xix|
> +-+--+---+----+---+--+---+----+-----+---+


where "each" is as defined later in the msg,  each=. &.> ).

Quote:
>    (arabic &: > " 0) 'xvi';'xxx';'mcmxcv'
> 16 30 1995

arabic&:>"0  can also be stated as  arabic&> .  (And by the way,
'xvi';'xxx';'mcmxcv'  is  ;:'xvi xxx mcmxcv' .)

Quote:
>   NB. Define a function "roman" with inverse "arabic"
>   f =. roman :. arabic

The inverse of f,  g=.arabic :.roman , is quite neat.  For example,

Roman numerals".  Thus:

   g=. f^:_1

   'mvm' +&.g 'v'
mm
   'mm' -&.g 'v'
mcmxcv
   'iii' *&.g 'iv'
xii

cv

The numerals mvm and mcmxcv motivate the composition  =&arabic :

   'mvm' =&arabic 'mcmxcv'
1
   'iv'  =&arabic 'iiii'
1
   'iii' =&arabic 'iv'
0

Quote:
>    arabic
> +-+-+---------------------------------------------------------+
> |3|:|NB. returns arabic number equivalent for roman numeral y.|
> | | |NB. arabic is type numeric (base 10), roman is character |
> | | |gte  =. >:   NB. (greater than or equal)                 |
> | | |drop =. }.                                               |
> | | |a =. ('ivxlcdm' i. y.) { 1 5 10 50 100 500 1000          |
> | | |+/ a * _1 + 2 * a gte 1 drop a,0                         |
> +-+-+---------------------------------------------------------+

The last sentence can be stated more simply in J (or in APL).  
The phrase _1+2*boolean  can have two possible values, _1 where the
argument is 0 and 1 where it is 1.  This is simply  _1^-.boolean .  
In this case, the negation can be finessed by using < instead of >: .
1}.y is just }.y.  Thus, the last sentence can be restated  
+/ a * _1 ^ a < }. a,0

Moreover, the last phrase is a shift, which can be expressed more
explicitly as an infix with a window size of 2, on the operation </ .
So finally:  +/ a * 1 ,~ _1 ^ 2 </\ a  .  One may prefer this or
the last restatement depending on taste.



Sat, 31 Jan 1998 03:00:00 GMT  
 
 [ 4 post ] 

 Relevant Pages 

1. roman and arabic - some fun(ctions)

2. Roman Arabic Conversions

3. programs for roman-arabic conversion

4. Roman-arabic discussion: a pointer

5. count bits, fun fun fun.

6. Python 2: Lexical scoping [Re: Python 2 ideas [Re: access fun ctions vs. directly setting attributes]]

7. FW: Python 2: Lexical scoping [Re: Python 2 ideas [Re: access fun ctions vs. directly setting attributes]]

8. Arabic text

9. Arabic characters in VisualWorks 3.0

10. Hebrew and Arabic

11. Clarion w/ arabic/hebrew

12. How to make Clarion use Arabic?

 

 
Powered by phpBB® Forum Software