I wrote:
>ASCII85 provides an example of J's stark beauty:
> ascii85 =: (33 + 85 #.^:_1: 256 #. _4 ]\ ])&.(a.&i.)
>The example would be even more compelling if it were invertible.
A J puzzle:
Write an invertible ASCII85 verb in the most concise
manner possible.
Verbs with "natural" inverses are strongly preferred,
as opposed to verbs whose obverse is specified with
:. .
The input is a literal vector, the output is either a
(CR)LF delimited literal vector, or a literal table.
The vector form is preferred but not required.
Your output's lines (or items) may never be more than
than 80 bytes long (including delimiter, if any).
Bonus points if they're between 70 and 75 bytes long.
Hints:
* You can read about ASCII85 on Wikipedia:
http://en.wikipedia.org/wiki/Ascii85
* You can test candidate solutions with
~addons\convert\misc\ascii85.ijs
* If y is a literal vector, then the phrases
256 #. _4 ]\ y and _2 (3!:4) y convert it into
a non-negative integer vector.
Both phrases are invertible, and the latter is shorter.
However the latter also requires 0=4|#y . If your
input's length is not a multiple of 4, then it will require
padding. However, dynamic (as opposed to fixed) padding is
not invertible (and it requries care wrt endianness).
* Both 85&#.^:_1 y and (5#85)&#: y convert integer vectors
into tables of integers < 85 . The latter is shorter,
has more invertible forms, and will always have 5={:@$ .
For example, using the last two observations, we could write a terser version
of ascii85 than given above:
ascii85b =: a. {~ 33 + (5#85) #: _2&(3!:4)
But it fails when 0~:4|#y . Even when it succeeds, its output has shape N,5
which is inefficient when converted to a newline-delimited vector (i.e. it
inserts a newline for every 4 bytes of input, which represents a 25-50%
expasion, defeating the advantage of using ASCII85 over, say, Base64).
How much better can you do?
-Dan
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm