Cf. jp-reprod.html
-.. code:: python
+.. code:: ipython2
from notebook_preamble import J, V, define
Let’s try it:
-.. code:: python
+.. code:: ipython2
V('[0 swap [dup ++] dip rest cons] x')
After one application of ``x`` the quoted program contains ``1`` and
``0`` is below it on the stack.
-.. code:: python
+.. code:: ipython2
J('[0 swap [dup ++] dip rest cons] x x x x x pop')
``direco``
----------
-.. code:: python
+.. code:: ipython2
define('direco == dip rest cons')
-.. code:: python
+.. code:: ipython2
V('[0 swap [dup ++] direco] x')
G == [direco] cons [swap] swap concat cons
G == [direco] cons [swap] swoncat cons
-.. code:: python
+.. code:: ipython2
define('G == [direco] cons [swap] swoncat cons')
Let’s try it out:
-.. code:: python
+.. code:: ipython2
J('0 [dup ++] G')
[0 swap [dup ++] direco]
-.. code:: python
+.. code:: ipython2
J('0 [dup ++] G x x x pop')
Powers of 2
~~~~~~~~~~~
-.. code:: python
+.. code:: ipython2
J('1 [dup 1 <<] G x x x x x x x x x pop')
If we have one of these quoted programs we can drive it using ``times``
with the ``x`` combinator.
-.. code:: python
+.. code:: ipython2
J('23 [dup ++] G 5 [x] times')
And pick them off by masking with 3 (binary 11) and then shifting the
int right two bits.
-.. code:: python
+.. code:: ipython2
define('PE1.1 == dup [3 &] dip 2 >>')
-.. code:: python
+.. code:: ipython2
V('14811 PE1.1')
If we plug ``14811`` and ``[PE1.1]`` into our generator form…
-.. code:: python
+.. code:: ipython2
J('14811 [PE1.1] G')
…we get a generator that works for seven cycles before it reaches zero:
-.. code:: python
+.. code:: ipython2
J('[14811 swap [PE1.1] direco] 7 [x] times')
We need a function that checks if the int has reached zero and resets it
if so.
-.. code:: python
+.. code:: ipython2
define('PE1.1.check == dup [pop 14811] [] branch')
-.. code:: python
+.. code:: ipython2
J('14811 [PE1.1.check PE1.1] G')
[14811 swap [PE1.1.check PE1.1] direco]
-.. code:: python
+.. code:: ipython2
J('[14811 swap [PE1.1.check PE1.1] direco] 21 [x] times')
five less than 1000. It’s worked out that we need to use all seven
numbers sixty-six times and then four more.
-.. code:: python
+.. code:: ipython2
J('7 66 * 4 +')
If we drive our generator 466 times and sum the stack we get 999.
-.. code:: python
+.. code:: ipython2
J('[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times')
3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 [57 swap [PE1.1.check PE1.1] direco]
-.. code:: python
+.. code:: ipython2
J('[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times pop enstacken sum')
Project Euler Problem One
-------------------------
-.. code:: python
+.. code:: ipython2
define('PE1.2 == + dup [+] dip')
Now we can add ``PE1.2`` to the quoted program given to ``G``.
-.. code:: python
+.. code:: ipython2
J('0 0 0 [PE1.1.check PE1.1] G 466 [x [PE1.2] dip] times popop')
F == + [popdd over] cons infra uncons
fib_gen == [1 1 F]
-.. code:: python
+.. code:: ipython2
define('fib == + [popdd over] cons infra uncons')
-.. code:: python
+.. code:: ipython2
define('fib_gen == [1 1 fib]')
-.. code:: python
+.. code:: ipython2
J('fib_gen 10 [x] times')
function that adds a term in the sequence to a sum if it is even, and
``pop``\ s it otherwise.
-.. code:: python
+.. code:: ipython2
define('PE2.1 == dup 2 % [+] [pop] branch')
And a predicate function that detects when the terms in the series
“exceed four million”.
-.. code:: python
+.. code:: ipython2
define('>4M == 4000000 >')
generates terms in the Fibonacci sequence until they exceed four million
and sums the even ones.
-.. code:: python
+.. code:: ipython2
define('PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec')
-.. code:: python
+.. code:: ipython2
J('PE2')
Every third term is even.
-.. code:: python
+.. code:: ipython2
J('[1 0 fib] x x x') # To start the sequence with 1 1 2 3 instead of 1 2 3.
Drive the generator three times and ``popop`` the two odd terms.
-.. code:: python
+.. code:: ipython2
J('[1 0 fib] x x x [popop] dipd')
2 [3 2 fib]
-.. code:: python
+.. code:: ipython2
define('PE2.2 == x x x [popop] dipd')
-.. code:: python
+.. code:: ipython2
J('[1 0 fib] 10 [PE2.2] times')
Replace ``x`` with our new driver function ``PE2.2`` and start our
``fib`` generator at ``1 0``.
-.. code:: python
+.. code:: ipython2
J('0 [1 0 fib] PE2.2 [pop >4M] [popop] [[PE2.1] dip PE2.2] primrec')
An Interesting Variation
------------------------
-.. code:: python
+.. code:: ipython2
define('codireco == cons dip rest cons')
-.. code:: python
+.. code:: ipython2
V('[0 [dup ++] codireco] x')
0 [1 [dup ++] codireco] .
-.. code:: python
+.. code:: ipython2
define('G == [codireco] cons cons')
-.. code:: python
+.. code:: ipython2
J('230 [dup ++] G 5 [x] times pop')