1113 lines
34 KiB
Plaintext
1113 lines
34 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# [Project Euler, first problem: \"Multiples of 3 and 5\"](https://projecteuler.net/problem=1)\n",
|
|
"\n",
|
|
" If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.\n",
|
|
"\n",
|
|
" Find the sum of all the multiples of 3 or 5 below 1000."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"from notebook_preamble import J, V, define"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Let's create a predicate that returns `True` if a number is a multiple of 3 or 5 and `False` otherwise."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('P [3 % not] dupdip 5 % not or')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
" • 80 P\n",
|
|
" 80 • P\n",
|
|
" 80 • [3 % not] dupdip 5 % not or\n",
|
|
"80 [3 % not] • dupdip 5 % not or\n",
|
|
" 80 • 3 % not 80 5 % not or\n",
|
|
" 80 3 • % not 80 5 % not or\n",
|
|
" 2 • not 80 5 % not or\n",
|
|
" False • 80 5 % not or\n",
|
|
" False 80 • 5 % not or\n",
|
|
" False 80 5 • % not or\n",
|
|
" False 0 • not or\n",
|
|
" False True • or\n",
|
|
" True • \n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"V('80 P')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Given the predicate function `P` a suitable program is:\n",
|
|
"\n",
|
|
" PE1 == 1000 range [P] filter sum\n",
|
|
"\n",
|
|
"This function generates a list of the integers from 0 to 999, filters\n",
|
|
"that list by `P`, and then sums the result.\n",
|
|
"\n",
|
|
"Logically this is fine, but pragmatically we are doing more work than we\n",
|
|
"should be; we generate one thousand integers but actually use less than\n",
|
|
"half of them. A better solution would be to generate just the multiples\n",
|
|
"we want to sum, and to add them as we go rather than storing them and\n",
|
|
"adding summing them at the end.\n",
|
|
"\n",
|
|
"At first I had the idea to use two counters and increase them by three\n",
|
|
"and five, respectively. This way we only generate the terms that we\n",
|
|
"actually want to sum. We have to proceed by incrementing the counter\n",
|
|
"that is lower, or if they are equal, the three counter, and we have to\n",
|
|
"take care not to double add numbers like 15 that are multiples of both\n",
|
|
"three and five.\n",
|
|
"\n",
|
|
"This seemed a little clunky, so I tried a different approach.\n",
|
|
"\n",
|
|
"Consider the first few terms in the series:\n",
|
|
"\n",
|
|
" 3 5 6 9 10 12 15 18 20 21 ...\n",
|
|
"\n",
|
|
"Subtract each number from the one after it (subtracting 0 from 3):\n",
|
|
"\n",
|
|
" 3 5 6 9 10 12 15 18 20 21 24 25 27 30 ...\n",
|
|
" 0 3 5 6 9 10 12 15 18 20 21 24 25 27 ...\n",
|
|
" -------------------------------------------\n",
|
|
" 3 2 1 3 1 2 3 3 2 1 3 1 2 3 ...\n",
|
|
"\n",
|
|
"You get this lovely repeating palindromic sequence:\n",
|
|
"\n",
|
|
" 3 2 1 3 1 2 3\n",
|
|
"\n",
|
|
"To make a counter that increments by factors of 3 and 5 you just add\n",
|
|
"these differences to the counter one-by-one in a loop.\n",
|
|
"\n",
|
|
"\n",
|
|
"To make use of this sequence to increment a counter and sum terms as we\n",
|
|
"go we need a function that will accept the sum, the counter, and the next\n",
|
|
"term to add, and that adds the term to the counter and a copy of the\n",
|
|
"counter to the running sum. This function will do that:\n",
|
|
"\n",
|
|
" PE1.1 == + [+] dupdip"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('PE1.1 + [+] dupdip')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
" • 0 0 3 PE1.1\n",
|
|
" 0 • 0 3 PE1.1\n",
|
|
" 0 0 • 3 PE1.1\n",
|
|
" 0 0 3 • PE1.1\n",
|
|
" 0 0 3 • + [+] dupdip\n",
|
|
" 0 3 • [+] dupdip\n",
|
|
"0 3 [+] • dupdip\n",
|
|
" 0 3 • + 3\n",
|
|
" 3 • 3\n",
|
|
" 3 3 • \n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"V('0 0 3 PE1.1')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 6,
|
|
"metadata": {
|
|
"scrolled": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
" • 0 0 [3 2 1 3 1 2 3] [PE1.1] step\n",
|
|
" 0 • 0 [3 2 1 3 1 2 3] [PE1.1] step\n",
|
|
" 0 0 • [3 2 1 3 1 2 3] [PE1.1] step\n",
|
|
" 0 0 [3 2 1 3 1 2 3] • [PE1.1] step\n",
|
|
"0 0 [3 2 1 3 1 2 3] [PE1.1] • step\n",
|
|
" 0 0 3 [PE1.1] • i [2 1 3 1 2 3] [PE1.1] step\n",
|
|
" 0 0 3 • PE1.1 [2 1 3 1 2 3] [PE1.1] step\n",
|
|
" 0 0 3 • + [+] dupdip [2 1 3 1 2 3] [PE1.1] step\n",
|
|
" 0 3 • [+] dupdip [2 1 3 1 2 3] [PE1.1] step\n",
|
|
" 0 3 [+] • dupdip [2 1 3 1 2 3] [PE1.1] step\n",
|
|
" 0 3 • + 3 [2 1 3 1 2 3] [PE1.1] step\n",
|
|
" 3 • 3 [2 1 3 1 2 3] [PE1.1] step\n",
|
|
" 3 3 • [2 1 3 1 2 3] [PE1.1] step\n",
|
|
" 3 3 [2 1 3 1 2 3] • [PE1.1] step\n",
|
|
" 3 3 [2 1 3 1 2 3] [PE1.1] • step\n",
|
|
" 3 3 2 [PE1.1] • i [1 3 1 2 3] [PE1.1] step\n",
|
|
" 3 3 2 • PE1.1 [1 3 1 2 3] [PE1.1] step\n",
|
|
" 3 3 2 • + [+] dupdip [1 3 1 2 3] [PE1.1] step\n",
|
|
" 3 5 • [+] dupdip [1 3 1 2 3] [PE1.1] step\n",
|
|
" 3 5 [+] • dupdip [1 3 1 2 3] [PE1.1] step\n",
|
|
" 3 5 • + 5 [1 3 1 2 3] [PE1.1] step\n",
|
|
" 8 • 5 [1 3 1 2 3] [PE1.1] step\n",
|
|
" 8 5 • [1 3 1 2 3] [PE1.1] step\n",
|
|
" 8 5 [1 3 1 2 3] • [PE1.1] step\n",
|
|
" 8 5 [1 3 1 2 3] [PE1.1] • step\n",
|
|
" 8 5 1 [PE1.1] • i [3 1 2 3] [PE1.1] step\n",
|
|
" 8 5 1 • PE1.1 [3 1 2 3] [PE1.1] step\n",
|
|
" 8 5 1 • + [+] dupdip [3 1 2 3] [PE1.1] step\n",
|
|
" 8 6 • [+] dupdip [3 1 2 3] [PE1.1] step\n",
|
|
" 8 6 [+] • dupdip [3 1 2 3] [PE1.1] step\n",
|
|
" 8 6 • + 6 [3 1 2 3] [PE1.1] step\n",
|
|
" 14 • 6 [3 1 2 3] [PE1.1] step\n",
|
|
" 14 6 • [3 1 2 3] [PE1.1] step\n",
|
|
" 14 6 [3 1 2 3] • [PE1.1] step\n",
|
|
" 14 6 [3 1 2 3] [PE1.1] • step\n",
|
|
" 14 6 3 [PE1.1] • i [1 2 3] [PE1.1] step\n",
|
|
" 14 6 3 • PE1.1 [1 2 3] [PE1.1] step\n",
|
|
" 14 6 3 • + [+] dupdip [1 2 3] [PE1.1] step\n",
|
|
" 14 9 • [+] dupdip [1 2 3] [PE1.1] step\n",
|
|
" 14 9 [+] • dupdip [1 2 3] [PE1.1] step\n",
|
|
" 14 9 • + 9 [1 2 3] [PE1.1] step\n",
|
|
" 23 • 9 [1 2 3] [PE1.1] step\n",
|
|
" 23 9 • [1 2 3] [PE1.1] step\n",
|
|
" 23 9 [1 2 3] • [PE1.1] step\n",
|
|
" 23 9 [1 2 3] [PE1.1] • step\n",
|
|
" 23 9 1 [PE1.1] • i [2 3] [PE1.1] step\n",
|
|
" 23 9 1 • PE1.1 [2 3] [PE1.1] step\n",
|
|
" 23 9 1 • + [+] dupdip [2 3] [PE1.1] step\n",
|
|
" 23 10 • [+] dupdip [2 3] [PE1.1] step\n",
|
|
" 23 10 [+] • dupdip [2 3] [PE1.1] step\n",
|
|
" 23 10 • + 10 [2 3] [PE1.1] step\n",
|
|
" 33 • 10 [2 3] [PE1.1] step\n",
|
|
" 33 10 • [2 3] [PE1.1] step\n",
|
|
" 33 10 [2 3] • [PE1.1] step\n",
|
|
" 33 10 [2 3] [PE1.1] • step\n",
|
|
" 33 10 2 [PE1.1] • i [3] [PE1.1] step\n",
|
|
" 33 10 2 • PE1.1 [3] [PE1.1] step\n",
|
|
" 33 10 2 • + [+] dupdip [3] [PE1.1] step\n",
|
|
" 33 12 • [+] dupdip [3] [PE1.1] step\n",
|
|
" 33 12 [+] • dupdip [3] [PE1.1] step\n",
|
|
" 33 12 • + 12 [3] [PE1.1] step\n",
|
|
" 45 • 12 [3] [PE1.1] step\n",
|
|
" 45 12 • [3] [PE1.1] step\n",
|
|
" 45 12 [3] • [PE1.1] step\n",
|
|
" 45 12 [3] [PE1.1] • step\n",
|
|
" 45 12 3 [PE1.1] • i\n",
|
|
" 45 12 3 • PE1.1\n",
|
|
" 45 12 3 • + [+] dupdip\n",
|
|
" 45 15 • [+] dupdip\n",
|
|
" 45 15 [+] • dupdip\n",
|
|
" 45 15 • + 15\n",
|
|
" 60 • 15\n",
|
|
" 60 15 • \n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"V('0 0 [3 2 1 3 1 2 3] [PE1.1] step')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"So one `step` through all seven terms brings the counter to 15 and the total to 60."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"66.66666666666667"
|
|
]
|
|
},
|
|
"execution_count": 7,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"1000 / 15"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"990"
|
|
]
|
|
},
|
|
"execution_count": 8,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"66 * 15"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"10"
|
|
]
|
|
},
|
|
"execution_count": 9,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"1000 - 990"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": []
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 10,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"9"
|
|
]
|
|
},
|
|
"execution_count": 10,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"999 - 990"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"That means we want to run the full list of numbers sixty-six times to get to 990 and then the first four numbers 3 2 1 3 to get to 999."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 11,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('PE1 0 0 66 [[3 2 1 3 1 2 3] [PE1.1] step] times [3 2 1 3] [PE1.1] step pop')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 12,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"233168\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('PE1')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"This form uses no extra storage and produces no unused summands. It's\n",
|
|
"good but there's one more trick we can apply. The list of seven terms\n",
|
|
"takes up at least seven bytes. But notice that all of the terms are less\n",
|
|
"than four, and so each can fit in just two bits. We could store all\n",
|
|
"seven terms in just fourteen bits and use masking and shifts to pick out\n",
|
|
"each term as we go. This will use less space and save time loading whole\n",
|
|
"integer terms from the list.\n",
|
|
"\n",
|
|
" 3 2 1 3 1 2 3\n",
|
|
" 0b 11 10 01 11 01 10 11 == 14811"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"14811"
|
|
]
|
|
},
|
|
"execution_count": 13,
|
|
"metadata": {},
|
|
"output_type": "execute_result"
|
|
}
|
|
],
|
|
"source": [
|
|
"0b11100111011011"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('PE1.2 [3 & PE1.1] dupdip 2 >>')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 15,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
" • 0 0 14811 PE1.2\n",
|
|
" 0 • 0 14811 PE1.2\n",
|
|
" 0 0 • 14811 PE1.2\n",
|
|
" 0 0 14811 • PE1.2\n",
|
|
" 0 0 14811 • [3 & PE1.1] dupdip 2 >>\n",
|
|
"0 0 14811 [3 & PE1.1] • dupdip 2 >>\n",
|
|
" 0 0 14811 • 3 & PE1.1 14811 2 >>\n",
|
|
" 0 0 14811 3 • & PE1.1 14811 2 >>\n",
|
|
" 0 0 3 • PE1.1 14811 2 >>\n",
|
|
" 0 0 3 • + [+] dupdip 14811 2 >>\n",
|
|
" 0 3 • [+] dupdip 14811 2 >>\n",
|
|
" 0 3 [+] • dupdip 14811 2 >>\n",
|
|
" 0 3 • + 3 14811 2 >>\n",
|
|
" 3 • 3 14811 2 >>\n",
|
|
" 3 3 • 14811 2 >>\n",
|
|
" 3 3 14811 • 2 >>\n",
|
|
" 3 3 14811 2 • >>\n",
|
|
" 3 3 3702 • \n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"V('0 0 14811 PE1.2')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 16,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
" • 3 3 3702 PE1.2\n",
|
|
" 3 • 3 3702 PE1.2\n",
|
|
" 3 3 • 3702 PE1.2\n",
|
|
" 3 3 3702 • PE1.2\n",
|
|
" 3 3 3702 • [3 & PE1.1] dupdip 2 >>\n",
|
|
"3 3 3702 [3 & PE1.1] • dupdip 2 >>\n",
|
|
" 3 3 3702 • 3 & PE1.1 3702 2 >>\n",
|
|
" 3 3 3702 3 • & PE1.1 3702 2 >>\n",
|
|
" 3 3 2 • PE1.1 3702 2 >>\n",
|
|
" 3 3 2 • + [+] dupdip 3702 2 >>\n",
|
|
" 3 5 • [+] dupdip 3702 2 >>\n",
|
|
" 3 5 [+] • dupdip 3702 2 >>\n",
|
|
" 3 5 • + 5 3702 2 >>\n",
|
|
" 8 • 5 3702 2 >>\n",
|
|
" 8 5 • 3702 2 >>\n",
|
|
" 8 5 3702 • 2 >>\n",
|
|
" 8 5 3702 2 • >>\n",
|
|
" 8 5 925 • \n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"V('3 3 3702 PE1.2')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 17,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
" • 0 0 14811 7 [PE1.2] times pop\n",
|
|
" 0 • 0 14811 7 [PE1.2] times pop\n",
|
|
" 0 0 • 14811 7 [PE1.2] times pop\n",
|
|
" 0 0 14811 • 7 [PE1.2] times pop\n",
|
|
" 0 0 14811 7 • [PE1.2] times pop\n",
|
|
" 0 0 14811 7 [PE1.2] • times pop\n",
|
|
" 0 0 14811 • PE1.2 6 [PE1.2] times pop\n",
|
|
" 0 0 14811 • [3 & PE1.1] dupdip 2 >> 6 [PE1.2] times pop\n",
|
|
"0 0 14811 [3 & PE1.1] • dupdip 2 >> 6 [PE1.2] times pop\n",
|
|
" 0 0 14811 • 3 & PE1.1 14811 2 >> 6 [PE1.2] times pop\n",
|
|
" 0 0 14811 3 • & PE1.1 14811 2 >> 6 [PE1.2] times pop\n",
|
|
" 0 0 3 • PE1.1 14811 2 >> 6 [PE1.2] times pop\n",
|
|
" 0 0 3 • + [+] dupdip 14811 2 >> 6 [PE1.2] times pop\n",
|
|
" 0 3 • [+] dupdip 14811 2 >> 6 [PE1.2] times pop\n",
|
|
" 0 3 [+] • dupdip 14811 2 >> 6 [PE1.2] times pop\n",
|
|
" 0 3 • + 3 14811 2 >> 6 [PE1.2] times pop\n",
|
|
" 3 • 3 14811 2 >> 6 [PE1.2] times pop\n",
|
|
" 3 3 • 14811 2 >> 6 [PE1.2] times pop\n",
|
|
" 3 3 14811 • 2 >> 6 [PE1.2] times pop\n",
|
|
" 3 3 14811 2 • >> 6 [PE1.2] times pop\n",
|
|
" 3 3 3702 • 6 [PE1.2] times pop\n",
|
|
" 3 3 3702 6 • [PE1.2] times pop\n",
|
|
" 3 3 3702 6 [PE1.2] • times pop\n",
|
|
" 3 3 3702 • PE1.2 5 [PE1.2] times pop\n",
|
|
" 3 3 3702 • [3 & PE1.1] dupdip 2 >> 5 [PE1.2] times pop\n",
|
|
" 3 3 3702 [3 & PE1.1] • dupdip 2 >> 5 [PE1.2] times pop\n",
|
|
" 3 3 3702 • 3 & PE1.1 3702 2 >> 5 [PE1.2] times pop\n",
|
|
" 3 3 3702 3 • & PE1.1 3702 2 >> 5 [PE1.2] times pop\n",
|
|
" 3 3 2 • PE1.1 3702 2 >> 5 [PE1.2] times pop\n",
|
|
" 3 3 2 • + [+] dupdip 3702 2 >> 5 [PE1.2] times pop\n",
|
|
" 3 5 • [+] dupdip 3702 2 >> 5 [PE1.2] times pop\n",
|
|
" 3 5 [+] • dupdip 3702 2 >> 5 [PE1.2] times pop\n",
|
|
" 3 5 • + 5 3702 2 >> 5 [PE1.2] times pop\n",
|
|
" 8 • 5 3702 2 >> 5 [PE1.2] times pop\n",
|
|
" 8 5 • 3702 2 >> 5 [PE1.2] times pop\n",
|
|
" 8 5 3702 • 2 >> 5 [PE1.2] times pop\n",
|
|
" 8 5 3702 2 • >> 5 [PE1.2] times pop\n",
|
|
" 8 5 925 • 5 [PE1.2] times pop\n",
|
|
" 8 5 925 5 • [PE1.2] times pop\n",
|
|
" 8 5 925 5 [PE1.2] • times pop\n",
|
|
" 8 5 925 • PE1.2 4 [PE1.2] times pop\n",
|
|
" 8 5 925 • [3 & PE1.1] dupdip 2 >> 4 [PE1.2] times pop\n",
|
|
" 8 5 925 [3 & PE1.1] • dupdip 2 >> 4 [PE1.2] times pop\n",
|
|
" 8 5 925 • 3 & PE1.1 925 2 >> 4 [PE1.2] times pop\n",
|
|
" 8 5 925 3 • & PE1.1 925 2 >> 4 [PE1.2] times pop\n",
|
|
" 8 5 1 • PE1.1 925 2 >> 4 [PE1.2] times pop\n",
|
|
" 8 5 1 • + [+] dupdip 925 2 >> 4 [PE1.2] times pop\n",
|
|
" 8 6 • [+] dupdip 925 2 >> 4 [PE1.2] times pop\n",
|
|
" 8 6 [+] • dupdip 925 2 >> 4 [PE1.2] times pop\n",
|
|
" 8 6 • + 6 925 2 >> 4 [PE1.2] times pop\n",
|
|
" 14 • 6 925 2 >> 4 [PE1.2] times pop\n",
|
|
" 14 6 • 925 2 >> 4 [PE1.2] times pop\n",
|
|
" 14 6 925 • 2 >> 4 [PE1.2] times pop\n",
|
|
" 14 6 925 2 • >> 4 [PE1.2] times pop\n",
|
|
" 14 6 231 • 4 [PE1.2] times pop\n",
|
|
" 14 6 231 4 • [PE1.2] times pop\n",
|
|
" 14 6 231 4 [PE1.2] • times pop\n",
|
|
" 14 6 231 • PE1.2 3 [PE1.2] times pop\n",
|
|
" 14 6 231 • [3 & PE1.1] dupdip 2 >> 3 [PE1.2] times pop\n",
|
|
" 14 6 231 [3 & PE1.1] • dupdip 2 >> 3 [PE1.2] times pop\n",
|
|
" 14 6 231 • 3 & PE1.1 231 2 >> 3 [PE1.2] times pop\n",
|
|
" 14 6 231 3 • & PE1.1 231 2 >> 3 [PE1.2] times pop\n",
|
|
" 14 6 3 • PE1.1 231 2 >> 3 [PE1.2] times pop\n",
|
|
" 14 6 3 • + [+] dupdip 231 2 >> 3 [PE1.2] times pop\n",
|
|
" 14 9 • [+] dupdip 231 2 >> 3 [PE1.2] times pop\n",
|
|
" 14 9 [+] • dupdip 231 2 >> 3 [PE1.2] times pop\n",
|
|
" 14 9 • + 9 231 2 >> 3 [PE1.2] times pop\n",
|
|
" 23 • 9 231 2 >> 3 [PE1.2] times pop\n",
|
|
" 23 9 • 231 2 >> 3 [PE1.2] times pop\n",
|
|
" 23 9 231 • 2 >> 3 [PE1.2] times pop\n",
|
|
" 23 9 231 2 • >> 3 [PE1.2] times pop\n",
|
|
" 23 9 57 • 3 [PE1.2] times pop\n",
|
|
" 23 9 57 3 • [PE1.2] times pop\n",
|
|
" 23 9 57 3 [PE1.2] • times pop\n",
|
|
" 23 9 57 • PE1.2 2 [PE1.2] times pop\n",
|
|
" 23 9 57 • [3 & PE1.1] dupdip 2 >> 2 [PE1.2] times pop\n",
|
|
" 23 9 57 [3 & PE1.1] • dupdip 2 >> 2 [PE1.2] times pop\n",
|
|
" 23 9 57 • 3 & PE1.1 57 2 >> 2 [PE1.2] times pop\n",
|
|
" 23 9 57 3 • & PE1.1 57 2 >> 2 [PE1.2] times pop\n",
|
|
" 23 9 1 • PE1.1 57 2 >> 2 [PE1.2] times pop\n",
|
|
" 23 9 1 • + [+] dupdip 57 2 >> 2 [PE1.2] times pop\n",
|
|
" 23 10 • [+] dupdip 57 2 >> 2 [PE1.2] times pop\n",
|
|
" 23 10 [+] • dupdip 57 2 >> 2 [PE1.2] times pop\n",
|
|
" 23 10 • + 10 57 2 >> 2 [PE1.2] times pop\n",
|
|
" 33 • 10 57 2 >> 2 [PE1.2] times pop\n",
|
|
" 33 10 • 57 2 >> 2 [PE1.2] times pop\n",
|
|
" 33 10 57 • 2 >> 2 [PE1.2] times pop\n",
|
|
" 33 10 57 2 • >> 2 [PE1.2] times pop\n",
|
|
" 33 10 14 • 2 [PE1.2] times pop\n",
|
|
" 33 10 14 2 • [PE1.2] times pop\n",
|
|
" 33 10 14 2 [PE1.2] • times pop\n",
|
|
" 33 10 14 • PE1.2 1 [PE1.2] times pop\n",
|
|
" 33 10 14 • [3 & PE1.1] dupdip 2 >> 1 [PE1.2] times pop\n",
|
|
" 33 10 14 [3 & PE1.1] • dupdip 2 >> 1 [PE1.2] times pop\n",
|
|
" 33 10 14 • 3 & PE1.1 14 2 >> 1 [PE1.2] times pop\n",
|
|
" 33 10 14 3 • & PE1.1 14 2 >> 1 [PE1.2] times pop\n",
|
|
" 33 10 2 • PE1.1 14 2 >> 1 [PE1.2] times pop\n",
|
|
" 33 10 2 • + [+] dupdip 14 2 >> 1 [PE1.2] times pop\n",
|
|
" 33 12 • [+] dupdip 14 2 >> 1 [PE1.2] times pop\n",
|
|
" 33 12 [+] • dupdip 14 2 >> 1 [PE1.2] times pop\n",
|
|
" 33 12 • + 12 14 2 >> 1 [PE1.2] times pop\n",
|
|
" 45 • 12 14 2 >> 1 [PE1.2] times pop\n",
|
|
" 45 12 • 14 2 >> 1 [PE1.2] times pop\n",
|
|
" 45 12 14 • 2 >> 1 [PE1.2] times pop\n",
|
|
" 45 12 14 2 • >> 1 [PE1.2] times pop\n",
|
|
" 45 12 3 • 1 [PE1.2] times pop\n",
|
|
" 45 12 3 1 • [PE1.2] times pop\n",
|
|
" 45 12 3 1 [PE1.2] • times pop\n",
|
|
" 45 12 3 • PE1.2 pop\n",
|
|
" 45 12 3 • [3 & PE1.1] dupdip 2 >> pop\n",
|
|
" 45 12 3 [3 & PE1.1] • dupdip 2 >> pop\n",
|
|
" 45 12 3 • 3 & PE1.1 3 2 >> pop\n",
|
|
" 45 12 3 3 • & PE1.1 3 2 >> pop\n",
|
|
" 45 12 3 • PE1.1 3 2 >> pop\n",
|
|
" 45 12 3 • + [+] dupdip 3 2 >> pop\n",
|
|
" 45 15 • [+] dupdip 3 2 >> pop\n",
|
|
" 45 15 [+] • dupdip 3 2 >> pop\n",
|
|
" 45 15 • + 15 3 2 >> pop\n",
|
|
" 60 • 15 3 2 >> pop\n",
|
|
" 60 15 • 3 2 >> pop\n",
|
|
" 60 15 3 • 2 >> pop\n",
|
|
" 60 15 3 2 • >> pop\n",
|
|
" 60 15 0 • pop\n",
|
|
" 60 15 • \n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"V('0 0 14811 7 [PE1.2] times pop')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"And so we have at last:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 18,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('PE1 0 0 66 [14811 7 [PE1.2] times pop] times 14811 4 [PE1.2] times popop')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 19,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"233168\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('PE1')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Let's refactor.\n",
|
|
"\n",
|
|
" 14811 7 [PE1.2] times pop\n",
|
|
" 14811 4 [PE1.2] times pop\n",
|
|
" 14811 n [PE1.2] times pop\n",
|
|
" n 14811 swap [PE1.2] times pop"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 20,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('PE1.3 14811 swap [PE1.2] times pop')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Now we can simplify the definition above:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 21,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('PE1 0 0 66 [7 PE1.3] times 4 PE1.3 pop')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 22,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"233168\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('PE1')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Here's our joy program all in one place. It doesn't make so much sense, but if you have read through the above description of how it was derived I hope it's clear.\n",
|
|
"\n",
|
|
" PE1.1 == + [+] dupdip\n",
|
|
" PE1.2 == [3 & PE1.1] dupdip 2 >>\n",
|
|
" PE1.3 == 14811 swap [PE1.2] times pop\n",
|
|
" PE1 == 0 0 66 [7 PE1.3] times 4 PE1.3 pop"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Generator Version\n",
|
|
"It's a little clunky iterating sixty-six times though the seven numbers then four more. In the _Generator Programs_ notebook we derive a generator that can be repeatedly driven by the `x` combinator to produce a stream of the seven numbers repeating over and over again."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 23,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('PE1.terms [0 swap [dup [pop 14811] [] branch [3 &] dupdip 2 >>] dip rest cons]')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 24,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"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 [dup [pop 14811] [] branch [3 &] dupdip 2 >>] dip rest cons]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('PE1.terms 21 [x] times')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"We know from above that we need sixty-six times seven then four more terms to reach up to but not over one thousand."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 25,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"466\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('7 66 * 4 +')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Here they are..."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 26,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"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\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('PE1.terms 466 [x] times pop')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"### ...and they do sum to 999."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 27,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"999\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('[PE1.terms 466 [x] times pop] run sum')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Now we can use `PE1.1` to accumulate the terms as we go, and then `pop` the generator and the counter from the stack when we're done, leaving just the sum."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 28,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"233168\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('0 0 PE1.terms 466 [x [PE1.1] dip] times popop')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# A little further analysis renders iteration unnecessary.\n",
|
|
"Consider finding the sum of the positive integers less than or equal to ten."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 29,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"55\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('[10 9 8 7 6 5 4 3 2 1] sum')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Instead of summing them, [observe](https://en.wikipedia.org/wiki/File:Animated_proof_for_the_formula_giving_the_sum_of_the_first_integers_1%2B2%2B...%2Bn.gif):\n",
|
|
"\n",
|
|
" 10 9 8 7 6\n",
|
|
" + 1 2 3 4 5\n",
|
|
" ---- -- -- -- --\n",
|
|
" 11 11 11 11 11\n",
|
|
" \n",
|
|
" 11 * 5 = 55\n",
|
|
"\n",
|
|
"From the above example we can deduce that the sum of the first N positive integers is:\n",
|
|
"\n",
|
|
" (N + 1) * N / 2 \n",
|
|
"\n",
|
|
"(The formula also works for odd values of N, I'll leave that to you if you want to work it out or you can take my word for it.)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 30,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"define('F dup ++ * 2 floordiv')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 31,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
" • 10 F\n",
|
|
" 10 • F\n",
|
|
" 10 • dup ++ * 2 floordiv\n",
|
|
"10 10 • ++ * 2 floordiv\n",
|
|
"10 11 • * 2 floordiv\n",
|
|
" 110 • 2 floordiv\n",
|
|
"110 2 • floordiv\n",
|
|
" 55 • \n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"V('10 F')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Generalizing to Blocks of Terms\n",
|
|
"We can apply the same reasoning to the PE1 problem.\n",
|
|
"\n",
|
|
"Between 0 and 990 inclusive there are sixty-six \"blocks\" of seven terms each, starting with:\n",
|
|
"\n",
|
|
" [3 5 6 9 10 12 15]\n",
|
|
" \n",
|
|
"And ending with:\n",
|
|
"\n",
|
|
" [978 980 981 984 985 987 990]\n",
|
|
" \n",
|
|
"If we reverse one of these two blocks and sum pairs..."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 32,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[[978 15] [980 12] [981 10] [984 9] [985 6] [987 5] [990 3]]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('[3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 33,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"[993 992 991 993 991 992 993]\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('[3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip [sum] map')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"(Interesting that the sequence of seven numbers appears again in the rightmost digit of each term.)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 34,
|
|
"metadata": {
|
|
"scrolled": true
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"6945\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('[ 3 5 6 9 10 12 15] reverse [978 980 981 984 985 987 990] zip [sum] map sum')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Since there are sixty-six blocks and we are pairing them up, there must be thirty-three pairs, each of which sums to 6945. We also have these additional unpaired terms between 990 and 1000:\n",
|
|
"\n",
|
|
" 993 995 996 999\n",
|
|
" \n",
|
|
"So we can give the \"sum of all the multiples of 3 or 5 below 1000\" like so:"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 35,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"233168\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"J('6945 33 * [993 995 996 999] cons sum')"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"It's worth noting, I think, that this same reasoning holds for any two numbers $n$ and $m$ the multiples of which we hope to sum. The multiples would have a cycle of differences of length $k$ and so we could compute the sum of $Nk$ multiples as above.\n",
|
|
"\n",
|
|
"The sequence of differences will always be a palidrome. Consider an interval spanning the least common multiple of $n$ and $m$:\n",
|
|
"\n",
|
|
" | | | | | | | |\n",
|
|
" | | | | |\n",
|
|
" \n",
|
|
"Here we have 4 and 7, and you can read off the sequence of differences directly from the diagram: 4 3 1 4 2 2 4 1 3 4.\n",
|
|
" \n",
|
|
"Geometrically, the actual values of $n$ and $m$ and their *lcm* don't matter, the pattern they make will always be symmetrical around its midpoint. The same reasoning holds for multiples of more than two numbers."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# The Simplest Program"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Of course, the simplest joy program for the first Project Euler problem is just:\n",
|
|
"\n",
|
|
" PE1 == 233168\n",
|
|
"\n",
|
|
"Fin."
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Python 3 (ipykernel)",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.7.10"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|