190 lines
4.7 KiB
Plaintext
190 lines
4.7 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Euler Problem 18\n",
|
|
"\n",
|
|
"By starting at the top of the triangle below and moving to adjacent numbers on the row below, the maximum total from top to bottom is 23.\n",
|
|
"\n",
|
|
"~~~\n",
|
|
" 3\n",
|
|
" 7 4\n",
|
|
" 2 4 6\n",
|
|
" 8 5 9 3\n",
|
|
"~~~\n",
|
|
"\n",
|
|
"That is, 3 + 7 + 4 + 9 = 23.\n",
|
|
"\n",
|
|
"Find the maximum total from top to bottom of the triangle below:\n",
|
|
"\n",
|
|
"~~~\n",
|
|
"75\n",
|
|
"95 64\n",
|
|
"17 47 82\n",
|
|
"18 35 87 10\n",
|
|
"20 04 82 47 65\n",
|
|
"19 01 23 75 03 34\n",
|
|
"88 02 77 73 07 63 67\n",
|
|
"99 65 04 28 06 16 70 92\n",
|
|
"41 41 26 56 83 40 80 70 33\n",
|
|
"41 48 72 33 47 32 37 16 94 29\n",
|
|
"53 71 44 65 25 43 91 52 97 51 14\n",
|
|
"70 11 33 28 77 73 17 78 39 68 17 57\n",
|
|
"91 71 52 38 17 14 91 43 58 50 27 29 48\n",
|
|
"63 66 04 68 89 53 67 30 73 16 69 87 40 31\n",
|
|
"04 62 98 27 23 09 70 98 73 93 38 53 60 04 23\n",
|
|
"~~~\n",
|
|
"\n",
|
|
"NOTE: As there are only 16384 routes, it is possible to solve this problem by trying every route. However, [Problem 67](https://projecteuler.net/problem=67), is the same challenge with a triangle containing one-hundred rows; it cannot be solved by brute force, and requires a clever method! ;o)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"This is incredibly simple we simply from bottom to top choosing the higher value for each mini-tree.\n",
|
|
"\n",
|
|
"For example,\n",
|
|
"\n",
|
|
"~~~\n",
|
|
" 95 64\n",
|
|
"17 47 82\n",
|
|
"~~~\n",
|
|
"\n",
|
|
"will become:\n",
|
|
"\n",
|
|
"~~~\n",
|
|
" 142 146\n",
|
|
"~~~"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {
|
|
"collapsed": true
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"t = \"\"\"\n",
|
|
"75\n",
|
|
"95 64\n",
|
|
"17 47 82\n",
|
|
"18 35 87 10\n",
|
|
"20 04 82 47 65\n",
|
|
"19 01 23 75 03 34\n",
|
|
"88 02 77 73 07 63 67\n",
|
|
"99 65 04 28 06 16 70 92\n",
|
|
"41 41 26 56 83 40 80 70 33\n",
|
|
"41 48 72 33 47 32 37 16 94 29\n",
|
|
"53 71 44 65 25 43 91 52 97 51 14\n",
|
|
"70 11 33 28 77 73 17 78 39 68 17 57\n",
|
|
"91 71 52 38 17 14 91 43 58 50 27 29 48\n",
|
|
"63 66 04 68 89 53 67 30 73 16 69 87 40 31\n",
|
|
"04 62 98 27 23 09 70 98 73 93 38 53 60 04 23\n",
|
|
"\"\"\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"def reduce_rows(xs, ys):\n",
|
|
" \"\"\" xs is lower row and ys is upper row \"\"\"\n",
|
|
" assert(len(xs) == len(ys) + 1)\n",
|
|
" return [max([xs[i] + ys[i], xs[i + 1] + ys[i]]) for i in range(len(ys))]\n",
|
|
" \n",
|
|
"assert(reduce_rows([17, 47, 82], [95, 64]) == [142, 146])"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Okay, now all we have to do is the parsing and then a simple fold."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 3,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"xss = [list(map(int, xs.split())) for xs in t.split(\"\\n\") if xs]\n",
|
|
"xss.reverse()\n",
|
|
"from functools import reduce\n",
|
|
"s = reduce(reduce_rows, xss[1:], xss[0])[0]\n",
|
|
"assert(s == 1074)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"Okay, let's put this into a nice function an then solve [problem 67](EulerProblem067) right away."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 4,
|
|
"metadata": {
|
|
"collapsed": false
|
|
},
|
|
"outputs": [
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"1074\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"def find_greatest_path_sum_in_triangle_string(ts):\n",
|
|
" from functools import reduce\n",
|
|
" xss = [list(map(int, xs.split())) for xs in ts.split(\"\\n\") if xs]\n",
|
|
" xss.reverse()\n",
|
|
" r = lambda xs, ys: [max([xs[i] + ys[i], xs[i + 1] + ys[i]]) for i in range(len(ys))]\n",
|
|
" return reduce(r, xss[1:], xss[0])[0]\n",
|
|
"\n",
|
|
"print(find_greatest_path_sum_in_triangle_string(t))"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"completion_date": "Thu, 4 Sep 2014, 20:38",
|
|
"kernelspec": {
|
|
"display_name": "Python 3",
|
|
"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.5.4"
|
|
},
|
|
"tags": [
|
|
"fold",
|
|
"reduce",
|
|
"search"
|
|
]
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 0
|
|
}
|