Using iteration to compute sequences
Typically, solving an OEIS sequence challenge will require using one of the formulas given on its page. Some of these adapt well for J, and others not so much. Recursive formulas are straight-forward, however, iteration might not be simple. A pattern I've begun to use is
(s(]f)^:[~]) n
] Gets n
s The first value in the sequence
~ Commute the argument order, n is LHS and s is RHS
[ Gets n
^: Nest n times with an initial argument s
(]f) Compute f s
Returns (f^n) s
where s
is the first value in the sequence, f
is a verb that will compute the next term given the previous term, and n
is the zero-based index of the term you want to compute. This method relies on the fact that when computing the power of a dyad, the LHS is bound to the dyad to form a new monad, and that monad is nested on the initial value. The dyad given to the power adverb is a hook where (]f)
is given the index n
on the LHS and the value of a term in the sequence s
. The hook will apply f
on s
as a monad, and then ignore n
to return the result of f s
.
Standard library
Sometimes, you might find that J will have support for a verb in its standard library. For example, most of the bitwise integer operations are bound to names which are shorter than using the primitive call.
AND =: (17 b.) NB. it is actually '$:/ :(17 b.)'
Date and time builtins are also available.
Ranges
If you have a set of values [a, b, c]
and you want to form a range based on their product like [0, 1, 2, ..., a*b*c-1]
, the typical approach would be to find their product and then form a range which might be [:i.*/
which costs 6 bytes. A shorter way is ,@i.
for 4 bytes since i.
can form multidimensional arrays while still counting up, and flattening it will produce an equivalent range.
Printing continuously
A tacit way to print a value and continue to use it without an explicit loop is ([echo)
for a monadic case. echo
is a verb in the standard library that prints its contents to stdout
in the same format used in the interpreter. The hook then passes the same input value out using the left [
verb.
Base 10 digits of an integer
The standard way of acquiring the base 10 digits of an integer is 10#.inv]
which costs 8 bytes, too much! An alternative is to convert it to a string and parse it at rank 0 "."0@":
which saves a byte, but an even better way is ,.&.":
which saves another byte making the final cost 6 bytes instead of 8.
GolfScript gets its own way far too often
w czytaniu w 2019 roku.