This function accepts two integers on the stack and increments or
+decrements one of them such that the new pair of numbers is the next
+coordinate pair in a square spiral (like the kind used to construct an
+Ulam Spiral).
If all you're trying to do is generate the first N points in the spiral
+(without the original problem's constraint of masking to an N x M
+region), the code becomes very simple:
+
+
+
void spiral(const int N)
+{
+ int x = 0;
+ int y = 0;
+ for(int i = 0; i < N; ++i)
+ {
+ cout << x << '\t' << y << '\n';
+ if(abs(x) <= abs(y) && (x != y || x >= 0))
+ x += ((y >= 0) ? 1 : -1);
+ else
+ y += ((x >= 0) ? -1 : 1);
+ }
+}
We need a function that computes abs(x) <= abs(y), we can use ii to
+apply abs to both values and then compare them
+with <=:
+
+
[abs] ii <=
+
+
+
I've defined two short-circuiting Boolean combinators && and || that
+each accept two quoted predicate programs, run the first, and
+conditionally run the second only if required (to compute the final
+Boolean value). They run their predicate arguments nullary.
We can assemble the three functions we just defined in quotes and give
+them them to the ifte combinator. With some arrangement to show off
+the symmetry of the two branches, we have:
As I was writing this up I realized that, since the && combinator
+doesn't consume the stack (below its quoted args), I can unquote the
+predicate, swap the branches, and use the branch combinator instead of
+ifte:
So that's an example of Joy code. It's a straightforward translation of
+the original. It's a little long for a single definition, you might
+break it up like so:
This way it's easy to see that the function is a branch with two
+quasi-symmetrical paths.
+
We then used this function to make a simple generator of coordinate
+pairs, where the next pair in the series can be generated at any time by
+using the x combinator on the generator (which is just a quoted
+expression containing a copy of the current pair and the "stepper
+function" to generate the next pair from that.)
This function accepts two integers on the stack and increments or
+decrements one of them such that the new pair of numbers is the next
+coordinate pair in a square spiral (like the kind used to construct an
+Ulam Spiral). For more information see Square Spiral Example Joy Code
defstringy(re):''' Return a nice string repr for a regular expression datastructure. '''
@@ -180,10 +180,10 @@ only, these datastructures are immutable.
I=(0|1)*
-
I=(KSTAR,(OR,O,l))
+
I=(KSTAR,(OR,O,l))
-
printstringy(I)
+
printstringy(I)
.
@@ -198,13 +198,13 @@ only, these datastructures are immutable.
# R ∧ I = I ∧ R = R# R ∧ ϕ = ϕ ∧ R = ϕ_and=curry(_compaction_rule,AND,I,phi)
@@ -325,7 +325,7 @@ derivation.
We can save re-processing by remembering results we have already
computed. RE datastructures are immutable and the derv() functions
are pure so this is fine.
-
classMemo(object):
+
classMemo(object):def__init__(self,f):self.f=f
@@ -347,7 +347,7 @@ are pure so this is fine.
Start at a and follow the transition arrows according to their
@@ -555,18 +555,18 @@ a --1--> ∂1(a)
You can see the one-way nature of the g state and the hij “trap”
in the way that the .111. on the left-hand side of the &
disappears once it has been matched.
defexplore(re):# Don't have more than 26 states...names=defaultdict(iter(ascii_lowercase).next)
@@ -592,7 +592,7 @@ disappears once it has been matched.
returntable,accepting
-
table,accepting=explore(it)
+
table,accepting=explore(it)table
@@ -618,7 +618,7 @@ disappears once it has been matched.
('j',1):'h'}
-
accepting
+
accepting
{'h','i'}
@@ -629,7 +629,7 @@ disappears once it has been matched.
Little helpers to process the iterator of our data (a “stream” of “1”
and “0” characters, not bits.)
-
getch=lambdaI:int(next(I))
+
getch=lambdaI:int(next(I))def_1(I):
@@ -735,7 +735,7 @@ and “0” characters, not bits.)
code. (You have to imagine that these are GOTO statements in C or
branches in assembly and that the state names are branch destination
labels.)
-
In the PE1 problem we are asked to sum all the multiples of three and
five less than 1000. It’s worked out that we need to use all seven
numbers sixty-six times and then four more.
-
J('7 66 * 4 +')
+
J('7 66 * 4 +')
466
If we drive our generator 466 times and sum the stack we get 999.
Now we can add PE1.2 to the quoted program given to G.
-
J('0 0 0 [PE1.1.check PE1.1] G 466 [x [PE1.2] dip] times popop')
+
J('0 0 0 [PE1.1.check PE1.1] G 466 [x [PE1.2] dip] times popop')
233168
@@ -351,13 +351,13 @@ numbers sixty-six times and then four more.
fib_gen==[11F]
-
define('fib == + [popdd over] cons infra uncons')
+
define('fib == + [popdd over] cons infra uncons')
-
define('fib_gen == [1 1 fib]')
+
define('fib_gen == [1 1 fib]')
-
J('fib_gen 10 [x] times')
+
J('fib_gen 10 [x] times')
123581321345589[14489fib]
@@ -373,21 +373,21 @@ not exceed four million, find the sum of the even-valued terms.
Now that we have a generator for the Fibonacci sequence, we need a
function that adds a term in the sequence to a sum if it is even, and
pops it otherwise.
-
define('PE2.1 == dup 2 % [+] [pop] branch')
+
define('PE2.1 == dup 2 % [+] [pop] branch')
And a predicate function that detects when the terms in the series
“exceed four million”.
-
define('>4M == 4000000 >')
+
define('>4M == 4000000 >')
Now it’s straightforward to define PE2 as a recursive function that
generates terms in the Fibonacci sequence until they exceed four million
and sums the even ones.