Current issue

Vol.26 No.4

Vol.26 No.4

Volumes

© 1984-2024
British APL Association
All rights reserved.

Archive articles posted online on request: ask the archivist.

archive/24/1

Volume 24, No.1

  • Proof for author
  • 0.3

Functional calculation

2: The year 1997

by Neville Holmes (neville.holmes@utas.edu.au)

Functional calculation does with operations applied to functions and numbers what numerical calculation does with functions applied to numbers. In preceding articles an introduction was given to what could be done with one commonly available tool for functional calculation, using a notation called J, then details were given of simple numerical calculation. This article is intended to allow the reader to consider how simple numerical calculation can be done in J by showing numeric expressions to produce whole numbers below 100 starting from the digits of the number 1997.

Numerical calculations

Preceding articles have introduced numerical calculation using the interpreter for the J notation. This article gives a change of pace in which the notation already introduced is used in modest examples so that the reader can get used to its differences from the more usual (though inconsistent) mathematical notation.

To set up some simple examples, expressions to produce all the non-negative integers of fewer than three digits are to be sought. There are several restrictions.

Firstly, only the following scalar primitive functions are to be used, though clearly many of them are not very useful – there are more comparisons than are needed, and nand and nor have very restricted domains.

+ conjugate add +. GCD +: double nor
- negate subtract -. not -: halve
* signum times *. LCM *: square nand
% reciprocal divide %: square root root
| magnitude residue
^ exp power ^. loge logarithm
= equal
< less than <. floor lesser <: decrement not more
> more than >. ceiling greater >: increment not less
~: not equal
! factorial choices o. pi times circular p: prime
[ (same) (left)

Secondly, only the digits 1 9 9 and 7 must be used as arguments, all those digits, and only in the sequence given. Thus up to four arguments may be used in an expression, but no argument may be a list, that is, all arguments must be scalar. The significance of this will be clearer later.

In the following, two expressions are given for each number, both because there is room for them, and to add interest. The reader should, as an exercise, look for solutions better in some way than those given – there should be plenty, and looking for them should lead to insights, whether the search is successful or not.

One avenue to explore is the use of numbers other than simple integers. These are avoided in the examples but, for instance, 19+<.|9j7 gives 30 using only three functions, which is fewer than in the expressions given below. Similarly, >.%:1p9-9p7 uses fewer functions to get 52 than do the examples.

Making 1997 give 0 to 19

Taking the four digits 1 9 9 and 7, in that sequence, combine them using J functions and operations, in as short and simple an expression as possible, to yield each of the numbers between 0 and 19 (here, 99 later), and to yield them as scalars using only scalar arguments and scalar functions. (As a matter of aesthetics, parentheses and decimal points are also avoided as far as possible. Also as a matter of style, the negative sign is avoided and subtraction or negation is used to similar effect.)

0 19=97 ˆ.*1997 10 19-9>.7 |1-9+9-7
1 *1997 199>7 11 19-9-*7 19--:9+7
2 19|97 +:*1997 12 1+9+9-7 19-9|7
3 19-9+7 199-*:+:7 13 -:19+9|7 1*9+%:9+7
4 19|9ˆ7 1+%:9s<.97 14 199|+:7 1+9+%:9+7
5 19-+:9|7 19|>.ˆ.97 15 >.19%9%7 1+9+>.ˆ.97
6 19|9*7 1+9-%:9+7 16 19|9+7 <.19*9ˆ.7
7 1!9-9-7 19|9!+:7 17 1+9+9|7 19-9-7
8 1+9|97 19|%:>:9*7 18 19-*97 1+9+9-*7
9 19<.9>.7 19-9+*7 19 1*p:9-9-7 1+9+9>.7

Two expressions are given in the table for each number. Several expressions use only the one primitive function, but none needs more than four.

Expressions abound for 0 and 1, particularly expressions using functions that yield logical values. Thus 1>997 and 199<7 yield 0, while 19<97 and 19+.97 yield 1. The restriction of yielding a scalar rules out /:1997 and =1997 which otherwise give a quite respectable 0 and 1. Also, #1997 gives a scalar 1, and #19 97 gives a scalar 2, but the restriction on scalar components rules the second of these two possibilities out of order.

Certain components of expressions are repeatedly used in the table above. Thus, 199| (and 19|) is used to pass over the digits of the left argument of | when the value of its right argument is lower than that of its left. In particular, 9|7 simply yields 7. Otherwise, <. or >. are widely used where the digits to the right or left of the <. or >. are to be ignored and the simpler and more pleasing | won’t serve instead. Notice, though, that the instances of 19| in 19|9ˆ7 and 19|9*7 and 19|9!+:7 are not ignorant.

Expressions starting with monadic increment (>:) and decrement (<:) functions can often make a shorter expression than the example given, but since these will only be trivially different from neighbouring expressions they are avoided if possible. Monadic halve (-:) and double (+:) are useful, but these are also a bit trivial for generating smaller or larger numbers.

The year 1997 is interesting in the scope it gives for the square root function (%:). In the above, %:9<.97 is used to give 3, %:9+7 is used to give 4, and %:>:9*7 is used to give 8. In fact -:9+7 and 9-*7 also give 8, but maybe not so cutely. Otherwise, >.*:1.997 could have been used for 4 and >.ˆ.1997 for 8, both of which are quite interesting.

Making 1997 give 20 to 99

Making numbers beyond 19 follows a similar pattern, and it is convenient here to take them twenty at a time. Of course, expressions starting 19+ will be common in the next table.

2019+9>719+*973019+9++:*71+9++:9+*7
2119+9-719+>:*9731<.19*9%:7<.%:-:1997
22<.-:%:1997>:19+9-7321+<.%:997+:19|9+7
2319+%:9+7p:1+9-9-733>.19ˆ.ˆ971+9>.+:9+7
2419-9-+:719+p:9+734+:19-9-71!<.9*9ˆ.!7
2519+9|<:71!9+9+73519+9+7>.19+ˆ.9ˆ7
261+9+9+719+9|736+:19-*971!9*>.9ˆ.!7
2719+-:9+719+9-*7371+-:9+9*7>.ˆ.199ˆ7
2819+9>.71+99|!<:7381+p:9+9-719*9-7
29>.199%719+9+*739-:-19-97<:+:19+9>7

At a pinch, all the numbers here, and in the next table for that matter, can be constructed from the solutions of the previous table by doubling (monadic +:) possibly combined with incrementing (monadic >:) or decrementing (monadic <:). However, these solutions will only reluctantly be used here, in the absence of some other expression.

Getting these larger values is somewhat more difficult, so it useful more often to go to non-integer intermediate values and then use the floor (<.) or ceiling (>.) function to get an integer. There are no solutions given in the 20-39 table which need only the one function, but quite a few need only two. On the other hand, no solutions need more than five functions.

40+:19+*971-9-<.-:9750-:1+99>.71-9-9+*:7
411!<.9*ˆ.971+9+-:<:9*7511+99-*:719++:9+7
42+:19+9-719+9++:752+:1+9+9+71+>.99%ˆ.7
43>.%:19*971*<.9*9ˆ.!>:7531*-:99+7|1+9-9*7
44-19-9*7<.%:1997541+-:9+97-.1+9-9*7
45>.%:1997>.ˆ.19!97551-9-9*7-.1*9-9*7
461!-:99-719+9+p:7561+-.9-9*719+>:9*-:>:7
471+-:99-71!>.9*ˆ.+:9757-:1+99++:719*<.9ˆ.!7
481+>.*:ˆ.997-1-9-9-*:758-:19+9719>.9+*:7
49*:199<.7-:1+9>.97591+9+-:>:9719-9-*:7

For the 40s and 50s, 9*7 gives 63 to work down from, and -:97 and -:99 gets into the high 40s, as does *:7. At least one expression is given for each of these numbers which does not need more than four primitive functions.

60>.19*o.9>71+<.+:%:9*9770+:19+9+7|1-<.9*%:9*7
61-:199|!>:7>.%:+:19*9771-1-9+9*7-:>.ˆ.%:19ˆ97
6219>.<:9*7-:>:199|!<:772-.1-9+9*71*-:9*9+7
631>.9*9<.7-.1-9>.9*7731+9+9*719+9*<:7
641+9>.9*71+9+9*<:774>.19*9ˆ.!7<.19++:ˆ.9!7
65199|!7199|!+:775-:199-*:719+9+p:+:7
66-1-9+9+*:71*<.9*%:9*<:77619*%:9+719*>.9ˆ.!7
6719+<.-:9719+-:<:9777>.19*o.9%7>.+:1+%:99*7
6819+>.-:9719+-:>:9778-19-9719+p:9+7
69>.19*ˆ9%719++:9++:779-.19-97>.19*ˆ.9*>:7

For the 60s and 70s, 9*7 provides a good starting point. Of interest are the two expressions for 65, which look the same but are interestingly different, and otherwise only 78 and 79 have expressions with only two primitive functions. There is plenty of room for improvement here, though only 66 is shown as needing more than five primitive functions.

801-+:9--:971*99-p:790>.+:%:199719+<.9ˆˆ.7
811>.9*9>.7-.1-9+9*>:7911+99|!7-1-99-7
8219+9*71+9+9*>:7921!99-7-.1-99-7
83>:19+9*71++:<.9*ˆ.97931+99-71--:>:9-+:97
84+:+:19+9-71+>.+:9*ˆ.9794>:1+99-71--:<:9-+:97
851!99-+:7<.19*ˆ9%<:79519*>.ˆ.9719*>:%:9+7
86<.19*ˆ.971+99-+:796-1-9>.97-:199-7
87|1+9-97>.19*ˆ.979719>.97|1-99-*7
88-.1+9-97>.1*9*%:97981+9>.97-.1-99-*7
891-9-97-:<:199|!>:+:7991>.99>.7-:199-*7

The 80s and 90s often use 99 or 97 and work down from there. This gives the quite short expressions shown here for 89 and 97, though 9*7 and 199 find occasional use.

In this group of numbers there is the one expression with only one primitive function, seven with two, lots with three, but the improvement to be sought is in those with five or six primitive functions.

Further examples

The examples given above can only suggest how arithmetic functions can be used in a simple to produce a variety of numbers. The reader is urged to consider the examples above with a J interpreter to hand, to try the examples out, to check them, and to try to find expressions that are better or in some way more interesting than those given here. When generating these numbers begins to pall, the reader perhaps should go on to consider how to generate the three digit numbers using the same rules. This could start 1+99>.7 then 199-+:*:7.

Alternatively, expressions might be sought for other years. Some years will present special challenges. The following table gives a start for the year 2000, in which a choice is made between 0=0, 0!0 and 0ˆ0 to give a 1 largely on aesthetic grounds.

0200=0ˆ.*20001020%+:0=020->.o.o.0!0
1*2000200ˆ011-:20++:0!0<.ˆ+:*:200+0
22+0-0*0+:*20001220-<.o.ˆ0=0+:<.%:%:2000
32+0=0+02!>.0+ˆ0=013<.+:%:%:2000p:<.ˆ.200-0
42*+:0<0!0>.ˆ.20+0=014<.%:200+0<.ˆ.-:*:2000
5<.ˆ.200+020-<.ˆˆ0=015>.%:200-0<.+:ˆ.2000
6<.%:%:2000>.ˆ.200+016>.ˆ.*:200020->.o.0=0
7<.ˆ.2000>.ˆ.-:20001720->:+:0!0>.+:ˆ.+:2000
82ˆp:0+0!02ˆ0]>:+:0=01820-+:0=0>.!o.%:2000
9<.-:20-0!0>.ˆ.p:20001920-0!0>.ˆ.p:*:2000

Apart from reducing the number of possibilities, having all those nought digits tends to give unsightly numbers like 00 and 000 which are therefore avoided here as far as is convenient. Thus, although 2+000 would be technically correct for 2, the expression 2+0-0*0 is shown, though many similar ones would be just as satisfactory. Not having a 1 at the front also reduces the possibilities a lot!

Another amusing possibility, though ultimately monotonous because expressions are restricted to monadic functions, is to try to develop all the numbers from only a single zero. A start to this is given in the following, and the aesthetic choice is between !0, ˆ0, >:0, and -.0 to get the initial 1, or p:0 to get an initial 2.

0|0*010>.*:o.!0>.o.o.>:0
1!0ˆ011<.-:ˆo.ˆ0p:+:p:0
2+:-.0p:012-:!+:+:!0-:>.ˆo.-.0
3p:-.0>.ˆˆ013<.*:>:ˆˆ0p:p:p:0
4*:+:!0>.o.>:014+:<.!o.!0+:<.*:ˆˆ0
5>:+:+:>:0p:p:015<.ˆˆˆ0<:*:*:+:!0
6!>:+:!0+:>:+:-.016*:*:>:>:0*:+:+:-.0
7<.ˆ+:ˆ0p:p:ˆ017<.o.+:ˆˆ0p:+:p:ˆ0
8<.o.ˆˆ0>.ˆp:018+:>.o.ˆˆ0+:*:>:+:!0
9*:>:+:!0>.o.ˆˆ019<:<.ˆ>.ˆ!0p:p:>:p:0

The shortness of some of expressions given here comes often from using the o. and ˆ functions to bump up values quickly, then using floor (>.) or ceiling (<.) functions to get integers. Otherwise p: can be used most conveniently. Of course, where an expression starts with <. the next higher number can be got by substituting a >. and vice versa, mutatis mutandis.

The expressions given in these last two tables were selected unsystematically and hastily. The assiduous reader should have an interesting but fruitful time looking for improved and extended expressions.

 

script began 7:32:54
caching off
debug mode off
cache time 3600 sec
indmtime not found in cache
cached index is fresh
recompiling index.xml
index compiled in 0.1847 secs
read index
read issues/index.xml
identified 26 volumes, 101 issues
array (
  'id' => '10500050',
)
regenerated static HTML
article source is 'XHTML'
completed in 0.209 secs