1027 lines
23 KiB
Plaintext
1027 lines
23 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Using `x` to Generate Values\n",
|
|
"\n",
|
|
"Cf. jp-reprod.html"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from notebook_preamble import J, V, define"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Consider the `x` combinator:\n",
|
|
"\n",
|
|
" x == dup i"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"We can apply it to a quoted program consisting of some value `a` and some function `B`:\n",
|
|
"\n",
|
|
" [a B] x\n",
|
|
" [a B] a B"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Let `B` function `swap` the `a` with the quote and run some function `C` on it to generate a new value `b`:\n",
|
|
"\n",
|
|
" B == swap [C] dip\n",
|
|
"\n",
|
|
" [a B] a B\n",
|
|
" [a B] a swap [C] dip\n",
|
|
" a [a B] [C] dip\n",
|
|
" a C [a B]\n",
|
|
" b [a B]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Now discard the quoted `a` with `rest` then `cons` `b`:\n",
|
|
"\n",
|
|
" b [a B] rest cons\n",
|
|
" b [B] cons\n",
|
|
" [b B]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Altogether, this is the definition of `B`:\n",
|
|
"\n",
|
|
" B == swap [C] dip rest cons"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"We can make a generator for the Natural numbers (0, 1, 2, ...) by using `0` for `a` and `[dup ++]` for `[C]`:\n",
|
|
"\n",
|
|
" [0 swap [dup ++] dip rest cons]\n",
|
|
"\n",
|
|
"Let's try it:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
" . [0 swap [dup ++] dip rest cons] x\n",
|
|
" [0 swap [dup ++] dip rest cons] . x\n",
|
|
" [0 swap [dup ++] dip rest cons] . 0 swap [dup ++] dip rest cons\n",
|
|
" [0 swap [dup ++] dip rest cons] 0 . swap [dup ++] dip rest cons\n",
|
|
" 0 [0 swap [dup ++] dip rest cons] . [dup ++] dip rest cons\n",
|
|
"0 [0 swap [dup ++] dip rest cons] [dup ++] . dip rest cons\n",
|
|
" 0 . dup ++ [0 swap [dup ++] dip rest cons] rest cons\n",
|
|
" 0 0 . ++ [0 swap [dup ++] dip rest cons] rest cons\n",
|
|
" 0 1 . [0 swap [dup ++] dip rest cons] rest cons\n",
|
|
" 0 1 [0 swap [dup ++] dip rest cons] . rest cons\n",
|
|
" 0 1 [swap [dup ++] dip rest cons] . cons\n",
|
|
" 0 [1 swap [dup ++] dip rest cons] . \n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"V('[0 swap [dup ++] dip rest cons] x')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"After one application of `x` the quoted program contains `1` and `0` is below it on the stack."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"0 1 2 3 4\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('[0 swap [dup ++] dip rest cons] x x x x x pop')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## `direco`"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('direco == dip rest cons')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
" . [0 swap [dup ++] direco] x\n",
|
|
" [0 swap [dup ++] direco] . x\n",
|
|
" [0 swap [dup ++] direco] . 0 swap [dup ++] direco\n",
|
|
" [0 swap [dup ++] direco] 0 . swap [dup ++] direco\n",
|
|
" 0 [0 swap [dup ++] direco] . [dup ++] direco\n",
|
|
"0 [0 swap [dup ++] direco] [dup ++] . direco\n",
|
|
"0 [0 swap [dup ++] direco] [dup ++] . dip rest cons\n",
|
|
" 0 . dup ++ [0 swap [dup ++] direco] rest cons\n",
|
|
" 0 0 . ++ [0 swap [dup ++] direco] rest cons\n",
|
|
" 0 1 . [0 swap [dup ++] direco] rest cons\n",
|
|
" 0 1 [0 swap [dup ++] direco] . rest cons\n",
|
|
" 0 1 [swap [dup ++] direco] . cons\n",
|
|
" 0 [1 swap [dup ++] direco] . \n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"V('[0 swap [dup ++] direco] x')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Making Generators\n",
|
|
"We want to define a function that accepts `a` and `[C]` and builds our quoted program:\n",
|
|
"\n",
|
|
" a [C] G\n",
|
|
" -------------------------\n",
|
|
" [a swap [C] direco]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Working in reverse:\n",
|
|
"\n",
|
|
" [a swap [C] direco] cons\n",
|
|
" a [swap [C] direco] concat\n",
|
|
" a [swap] [[C] direco] swap\n",
|
|
" a [[C] direco] [swap]\n",
|
|
" a [C] [direco] cons [swap]\n",
|
|
"\n",
|
|
"Reading from the bottom up:\n",
|
|
"\n",
|
|
" G == [direco] cons [swap] swap concat cons\n",
|
|
" G == [direco] cons [swap] swoncat cons"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('G == [direco] cons [swap] swoncat cons')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Let's try it out:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[0 swap [dup ++] direco]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('0 [dup ++] G')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"0 1 2\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('0 [dup ++] G x x x pop')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Powers of 2"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"1 2 4 8 16 32 64 128 256\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('1 [dup 1 <<] G x x x x x x x x x pop')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### `[x] times`\n",
|
|
"If we have one of these quoted programs we can drive it using `times` with the `x` combinator."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"23 24 25 26 27 [28 swap [dup ++] direco]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('23 [dup ++] G 5 [x] times')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Generating Multiples of Three and Five\n",
|
|
"Look at the treatment of the Project Euler Problem One in the \"Developing a Program\" notebook and you'll see that we might be interested in generating an endless cycle of:\n",
|
|
"\n",
|
|
" 3 2 1 3 1 2 3\n",
|
|
"\n",
|
|
"To do this we want to encode the numbers as pairs of bits in a single int:\n",
|
|
"\n",
|
|
" 3 2 1 3 1 2 3\n",
|
|
" 0b 11 10 01 11 01 10 11 == 14811\n",
|
|
"\n",
|
|
"And pick them off by masking with 3 (binary 11) and then shifting the int right two bits."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('PE1.1 == dup [3 &] dip 2 >>')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
" . 14811 PE1.1\n",
|
|
" 14811 . PE1.1\n",
|
|
" 14811 . dup [3 &] dip 2 >>\n",
|
|
" 14811 14811 . [3 &] dip 2 >>\n",
|
|
"14811 14811 [3 &] . dip 2 >>\n",
|
|
" 14811 . 3 & 14811 2 >>\n",
|
|
" 14811 3 . & 14811 2 >>\n",
|
|
" 3 . 14811 2 >>\n",
|
|
" 3 14811 . 2 >>\n",
|
|
" 3 14811 2 . >>\n",
|
|
" 3 3702 . \n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"V('14811 PE1.1')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"If we plug `14811` and `[PE1.1]` into our generator form..."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[14811 swap [PE1.1] direco]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('14811 [PE1.1] G')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"...we get a generator that works for seven cycles before it reaches zero:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"3 2 1 3 1 2 3 [0 swap [PE1.1] direco]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('[14811 swap [PE1.1] direco] 7 [x] times')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Reset at Zero\n",
|
|
"We need a function that checks if the int has reached zero and resets it if so."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('PE1.1.check == dup [pop 14811] [] branch')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[14811 swap [PE1.1.check PE1.1] direco]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('14811 [PE1.1.check PE1.1] G')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"3 2 1 3 1 2 3 3 2 1 3 1 2 3 3 2 1 3 1 2 3 [0 swap [PE1.1.check PE1.1] direco]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('[14811 swap [PE1.1.check PE1.1] direco] 21 [x] times')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"(It would be more efficient to reset the int every seven cycles but that's a little beyond the scope of this article. This solution does extra work, but not much, and we're not using it \"in production\" as they say.)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Run 466 times\n",
|
|
"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."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"466\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('7 66 * 4 +')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"If we drive our generator 466 times and sum the stack we get 999."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"metadata": {
|
|
"scrolled": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"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]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"999\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('[14811 swap [PE1.1.check PE1.1] direco] 466 [x] times pop enstacken sum')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Project Euler Problem One"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 21,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('PE1.2 == + dup [+] dip')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Now we can add `PE1.2` to the quoted program given to `G`."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 22,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"233168\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('0 0 0 [PE1.1.check PE1.1] G 466 [x [PE1.2] dip] times popop')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## A generator for the Fibonacci Sequence.\n",
|
|
"Consider:\n",
|
|
"\n",
|
|
" [b a F] x\n",
|
|
" [b a F] b a F"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"The obvious first thing to do is just add `b` and `a`:\n",
|
|
"\n",
|
|
" [b a F] b a +\n",
|
|
" [b a F] b+a"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"From here we want to arrive at:\n",
|
|
"\n",
|
|
" b [b+a b F]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Let's start with `swons`:\n",
|
|
"\n",
|
|
" [b a F] b+a swons\n",
|
|
" [b+a b a F]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Considering this quote as a stack:\n",
|
|
"\n",
|
|
" F a b b+a"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"We want to get it to:\n",
|
|
"\n",
|
|
" F b b+a b"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"So:\n",
|
|
"\n",
|
|
" F a b b+a popdd over\n",
|
|
" F b b+a b"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"And therefore:\n",
|
|
"\n",
|
|
" [b+a b a F] [popdd over] infra\n",
|
|
" [b b+a b F]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"But we can just use `cons` to carry `b+a` into the quote:\n",
|
|
"\n",
|
|
" [b a F] b+a [popdd over] cons infra\n",
|
|
" [b a F] [b+a popdd over] infra\n",
|
|
" [b b+a b F]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Lastly:\n",
|
|
"\n",
|
|
" [b b+a b F] uncons\n",
|
|
" b [b+a b F]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Putting it all together:\n",
|
|
"\n",
|
|
" F == + [popdd over] cons infra uncons\n",
|
|
" fib_gen == [1 1 F]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 23,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('fib == + [popdd over] cons infra uncons')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 24,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('fib_gen == [1 1 fib]')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 25,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"1 2 3 5 8 13 21 34 55 89 [144 89 fib]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('fib_gen 10 [x] times')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Project Euler Problem Two\n",
|
|
"> By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.\n",
|
|
"\n",
|
|
"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 `pop`s it otherwise."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 26,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('PE2.1 == dup 2 % [+] [pop] branch')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"And a predicate function that detects when the terms in the series \"exceed four million\"."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 27,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('>4M == 4000000 >')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"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."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 28,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 29,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"4613732\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('PE2')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Here's the collected program definitions:\n",
|
|
"\n",
|
|
" fib == + swons [popdd over] infra uncons\n",
|
|
" fib_gen == [1 1 fib]\n",
|
|
"\n",
|
|
" even == dup 2 %\n",
|
|
" >4M == 4000000 >\n",
|
|
"\n",
|
|
" PE2.1 == even [+] [pop] branch\n",
|
|
" PE2 == 0 fib_gen x [pop >4M] [popop] [[PE2.1] dip x] primrec"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Even-valued Fibonacci Terms\n",
|
|
"\n",
|
|
"Using `o` for odd and `e` for even:\n",
|
|
"\n",
|
|
" o + o = e\n",
|
|
" e + e = e\n",
|
|
" o + e = o\n",
|
|
"\n",
|
|
"So the Fibonacci sequence considered in terms of just parity would be:\n",
|
|
"\n",
|
|
" o o e o o e o o e o o e o o e o o e\n",
|
|
" 1 1 2 3 5 8 . . .\n",
|
|
"\n",
|
|
"Every third term is even.\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 30,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"1 1 2 [3 2 fib]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('[1 0 fib] x x x') # To start the sequence with 1 1 2 3 instead of 1 2 3."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Drive the generator three times and `popop` the two odd terms."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 31,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"2 [3 2 fib]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('[1 0 fib] x x x [popop] dipd')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 32,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('PE2.2 == x x x [popop] dipd')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 33,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"2 8 34 144 610 2584 10946 46368 196418 832040 [1346269 832040 fib]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('[1 0 fib] 10 [PE2.2] times')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Replace `x` with our new driver function `PE2.2` and start our `fib` generator at `1 0`."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 34,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"4613732\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('0 [1 0 fib] PE2.2 [pop >4M] [popop] [[PE2.1] dip PE2.2] primrec')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## How to compile these?\n",
|
|
"You would probably start with a special version of `G`, and perhaps modifications to the default `x`?"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## An Interesting Variation"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 35,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('codireco == cons dip rest cons')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 36,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
" . [0 [dup ++] codireco] x\n",
|
|
" [0 [dup ++] codireco] . x\n",
|
|
" [0 [dup ++] codireco] . 0 [dup ++] codireco\n",
|
|
" [0 [dup ++] codireco] 0 . [dup ++] codireco\n",
|
|
"[0 [dup ++] codireco] 0 [dup ++] . codireco\n",
|
|
"[0 [dup ++] codireco] 0 [dup ++] . cons dip rest cons\n",
|
|
"[0 [dup ++] codireco] [0 dup ++] . dip rest cons\n",
|
|
" . 0 dup ++ [0 [dup ++] codireco] rest cons\n",
|
|
" 0 . dup ++ [0 [dup ++] codireco] rest cons\n",
|
|
" 0 0 . ++ [0 [dup ++] codireco] rest cons\n",
|
|
" 0 1 . [0 [dup ++] codireco] rest cons\n",
|
|
" 0 1 [0 [dup ++] codireco] . rest cons\n",
|
|
" 0 1 [[dup ++] codireco] . cons\n",
|
|
" 0 [1 [dup ++] codireco] . \n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"V('[0 [dup ++] codireco] x')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 37,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('G == [codireco] cons cons')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 38,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"230 231 232 233 234\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('230 [dup ++] G 5 [x] times pop')"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 2",
|
|
"language": "python",
|
|
"name": "python2"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 2
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython2",
|
|
"version": "2.7.12"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|