Hacker News new | ask | show | jobs
by perturbation 4515 days ago
f p=2,3:2 s q=1 x "f f=3:2 q:f(asterisk)f>p!'q s q=p#f" w:q p,?$x\8+18

(Not sure if this is going to mess up the formatting, so apologies in advance). This (shamelessly stolen from a usenet sig) will print out a table of primes with formatting. Adding a quit based on max prime size is left as exercise to the reader.

Explanation: f = for, but basically used as a while loop since we don't have a terminate condition ('p' is used as the counter variable and we would normally have an upper limit, but since we don't it will keep iterating until something breaks)

We're setting the variable 'p' to 2 on first iteration of the loop, 3 on the next, and then going up by 2 on subsequent.

Then, we're setting the variable 'q' to 1.

'x' is short for XECUTE. It looks at the string following it and executes it as code.

"f f=3:2 q:f(asterisk)f>p!'q s q=p#f"

This is another loop, with the variable 'f' used as the counter, starting at 3 and incrementing by 2.

Each loop iteration, it checks if f^2 is greater than p or if q == 0. If not, it proceeds to set q to p modulo f.

To sum things up: We quit the loop if either we've checked all candidates (excluding evens) up to ~sqrt(p) or if one of these evenly divides p (that is, modulo 0).

The tricky bit:

w:q p,?$x\8+18

w:q == WRITE, using the value of 'q' as a post-conditional, only to be executed for non-zero values of q.

If we write, we will write 'p', setting the position of the cursor with '?' (syntax particular to write) using the '$x' variable (built-in for the current cursor position).

Note: $x\8+18 evaluates to (($x INTEGER DIV 8)+1)8

First line:

GTM>f p=2,3:2 s q=1 x "f f=3:2 q:ff>p!'q s q=p#f" w:q p,?$x\8+18

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71

Edit: Formatting is messed up. (asterisk == '* '). I could have escaped, but didn't want to add whitespace.

1 comments

That's actually more readable than APL, and once you said "f = for" I automatically made the mental association "s = set" and "x = execute". It wasn't actually that hard to figure out the rest from that...

and something about that code reminds me of vi commands.