Geoff Canyon <[EMAIL PROTECTED]> wrote:
> I'm trying to write a monadic function that will take a number,
> create a list of that number times 1..6, with each number's
> characters sorted, and return whether they are all the same. So f 17
> would look at the list 17 34 15 68 58 012 and return 0. Here's my
> closest attempt so far:
>
> =/ /:~ each ": each <"0 (>:i.6)*]
>
> <"0 (>:i.6)*26 returns
>
> +--+--+--+---+---+---+
> |26|52|78|104|130|156|
> +--+--+--+---+---+---+
>
> But
>
> f=:<"0 (>:i.6)*]
> f 26
> 0 1 1 1 1 1
>
> That looks to me like < is being treated dyadically, and returning
> false, true, true, etc. What do I need to do to force it to box instead?
You have fallen into a common J pitfall.
In trains of odd length (for example, (a b c d e f g)), the verbs are
arranged as a series of forks (in this case, (a b (c d (e f g))).
The odd-numbered terms (a, c, e, g) operate on the given parameter,
while the even-numbered terms (b, d, f) operate on the results of those verbs.
However, if a train has an even length, the leftmost verb create a hook
(a b c d e f) becomes (a (b c (d e f)).
which can sometimes be useful, but more often than not is the result of an
error.
A hook (a b) is equivalent to the fork ([ a [EMAIL PROTECTED])
If you want to use a monadic verb within a fork, or train of forks,
rather than using a hook, you should use a capped fork ([: a b)
f=:[: <"0 (>:i.6)*]
f 26
+--+--+--+---+---+---+
|26|52|78|104|130|156|
+--+--+--+---+---+---+
You can also use a@:b which is equivalent (or [EMAIL PROTECTED] if b is known
to have infinite rank):
f=:<"0@:((>:i.6)*])
although in this particular case, use of the capped fork is probably better,
since it avoids a klunky set of parentheses, and as the two are equivalent,
which to use is often a matter of style.
In monadic trains, you can slso replace forks of the form (constant dyad ])
with the bond (constant&dyad) which can sometimes clarify matters,
although in this particular case, it doesn't really buy you anything.
>=/ /:~ each ": each NB. seems to work, but is there a better way than
>two eaches?
>
> Finally, putting it all together:
>
> f=: =/ /:~ each ": each <"0 (>:i.6)*]
> f 4
> |domain error: f
> | f 4
Since this train contains a lot of monadic verbs, it needs a lot of capped
forks:
f=: [: =/ [: /:~ each [: ": each [: <"0 (>:i.6)*]
f 4
0
(which is equivalent to Roger's use of conjunctions):
f=: =/ @: (/:~ each) @: (": each) @: (<"0) @: ((>:i.6)*])
> 1. So what _does_ =/ mean?
The result has a technically-defined meaning, but it is generally not
useful for anything except booleans.
In mots cases, it will complare the leftmost two items
and produce a boolean result. It will then compare this boolean with
the previous value (which will likely be 0 if that value is of
some other type than boolean.)
In general, f/ produces less than useful results if f's output
type is different than it input types. This can be doubly true if
the parameters themselves have different types and/or shapes.
(+/ */ +./ ,/ ,&.</ etc. are useful; =/ e./ i./ ":/ generally aren't)
Sometimes such verbs can be useful with parameters of restricive domains.
Since verbs like = ~: < <: > >: return booleans, =/ ~:/ etc. are useful on
boolean lists (for example, = is equivalent to exclusive-nor, ~: is
equivalent to exlcusive-or).
Since i. and i: return indices and { uses them,
{/ and i./ and i:/ could be useful on permutations.
There are three special cases that apply to all lists:
f/ a list of length 2 just applies f between the two items. This works for all
verbs.
f/ a list of length 1 just returns that item, and the verb f is not actually
used at all
f/ a list of length 0 returns the identity for f (only a few verbs have
identities).
> 2. If it doesn't mean anything, is it possible for me (any user) to
> define =/=:1&=#] ? (apparently not)
Primitives cannot be assigned nor reassigned
> 3. Is there a way to compose my two lines above into a single command?
> 4. To avoid all the @: above, should I be looking for ways to turn it
> into forks and/or hooks?
See above.
> I have to add: my brain hurts! (in a good way)
Yes, J has a habit of doing that. It seems to activate different
parts of the brain than procedural languages. This is one reason I love it :)
-- Mark D. Niemiec <[EMAIL PROTECTED]>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm