First, we put the string on the stack as a vector of ASCII codes.

1: [84, 101, 115, ..., 51] . "Testing, 1, 2, 3 RET

Note that the `"` key, like `$`, initiates algebraic entry so
there was no need to type an apostrophe. Also, Calc didn't mind that
we omitted the closing `"`. (The same goes for all closing delimiters
like `)` and `]` at the end of a formula.

We'll show two different approaches here. In the first, we note that if the input vector is [a, b, c, d], then the hash code is 3 (3 (3a + b) + c) + d = 27a + 9b + 3c + d. In other words, it's a sum of descending powers of three times the ASCII codes.

2: [84, 101, 115, ..., 51] 2: [84, 101, 115, ..., 51] 1: 16 1: [15, 14, 13, ..., 0] . . RET v l v x 16 RET -

2: [84, 101, 115, ..., 51] 1: 1960915098 1: 121 1: [14348907, ..., 1] . . . 3 TAB V M ^ * 511 %

Once again, `*` elegantly summarizes most of the computation.
But there's an even more elegant approach: Reduce the formula
`3 $$ + $` across the vector. Recall that this represents a
function of two arguments that computes its first argument times three
plus its second argument.

1: [84, 101, 115, ..., 51] 1: 1960915098 . . "Testing, 1, 2, 3 RET V R ' 3$$+$ RET

If you did the decimal arithmetic exercise, this will be familiar. Basically, we're turning a base-3 vector of digits into an integer, except that our "digits" are much larger than real digits.

Instead of typing `511 %` again to reduce the result, we can be
cleverer still and notice that rather than computing a huge integer
and taking the modulo at the end, we can take the modulo at each step
without affecting the result. While this means there are more
arithmetic operations, the numbers we operate on remain small so
the operations are faster.

1: [84, 101, 115, ..., 51] 1: 121 . . "Testing, 1, 2, 3 RET V R ' (3$$+$)%511 RET

Why does this work? Think about a two-step computation: 3 (3a + b) + c. Taking a result modulo 511 basically means subtracting off enough 511's to put the result in the desired range. So the result when we take the modulo after every step is,

for some suitable integers m and n. Expanding out by the distributive law yields

The m term in the latter formula is redundant because any contribution it makes could just as easily be made by the n term. So we can take it out to get an equivalent formula with n' = 3m + n,

which is just the formula for taking the modulo only at the end of the calculation. Therefore the two methods are essentially the same.

Later in the tutorial we will encounter **modulo forms**, which
basically automate the idea of reducing every intermediate result
modulo some value *M*.

Go to the first, previous, next, last section, table of contents.