{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Euler Problem 11\n", "\n", "In the 20×20 grid below, four numbers along a diagonal line have been marked in red.\n", "\n", "~~~\n", "08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08\n", "49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00\n", "81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65\n", "52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91\n", "22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80\n", "24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50\n", "32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70\n", "67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21\n", "24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72\n", "21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95\n", "78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92\n", "16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57\n", "86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58\n", "19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40\n", "04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66\n", "88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69\n", "04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36\n", "20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16\n", "20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54\n", "01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48\n", "~~~\n", "\n", "The product of these numbers is $26 × 63 × 78 × 14 = 1788696$.\n", "\n", "What is the greatest product of four adjacent numbers in the same direction (up, down, left, right, or diagonally) in the 20×20 grid?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We start by parsing the array into three lists of lists (horizontal, diagonal, vertical).\n", "\n", "97, 17, 79, 11, 89, 44, 38, 94, 78, 0, 62, 54, 58, 4, 27, 53, 36, 1, 1, 1]" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [], "source": [ "s = \"\"\"\n", "08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08\n", "49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00\n", "81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65\n", "52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91\n", "22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80\n", "24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50\n", "32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70\n", "67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21\n", "24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72\n", "21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95\n", "78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92\n", "16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57\n", "86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58\n", "19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40\n", "04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66\n", "88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69\n", "04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36\n", "20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16\n", "20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54\n", "01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48\n", "\"\"\"\n", "\n", "def get_index(xs, index, default):\n", " if index < 0:\n", " return default\n", " try:\n", " return xs[index]\n", " except IndexError:\n", " return default\n", "\n", "hss = [list(map(int, h.split())) for h in s.split('\\n') if h]\n", "vss = [list(vs) for vs in zip(*hss)]\n", "# diagonal from top left to bottom right\n", "dss = [[get_index(hs, -19 + i + j, 1) for j, hs in enumerate(hss)] for i in range(39)]\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I really love the way we retrieve the vertical list. (We need the ugly conversion to list because otherwise we cannot concatenate them.) It is at the limit of my mental capabilities to understand why this works. But actually it is quite straight forward. If we provide two lists, zip creates a two-tuple for each field in the lists. If we provide n lists, zip creates a n-tuple for each field in the lists. Easy.\n", "\n", "Now we create big list of lists and search each one for the greates four product and then get the maximum. Straight forward. We borrow the find product function from problem 8 because I like it." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [], "source": [ "xss = hss + vss + dss\n", "\n", "def product(xs):\n", " from operator import mul\n", " from functools import reduce\n", " return reduce(mul, xs, 1)\n", "\n", "def get_largest_product_of_n_digits(xs, n):\n", " return max([product(xs[i:i + n]) for i in range(len(xs))])\n", "\n", "s = max([get_largest_product_of_n_digits(xs, 4) for xs in xss])\n", "assert(s != 70600674)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Okay, I am actually really dumb. I forgot about the other diagonal. I think I have made the same mistake back when I solved this for the first time. So let's get the missing dss and get the solution." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "70600674\n" ] } ], "source": [ "# diagonal from bottom left to top right\n", "hss.reverse()\n", "dss = [[get_index(hs, -19 + i + j, 1) for j, hs in enumerate(hss)] for i in range(39)]\n", "\n", "s = max([get_largest_product_of_n_digits(ds, 4) for ds in dss])\n", "assert(s == 70600674)\n", "print(s)" ] } ], "metadata": { "completion_date": "Sun, 31 Aug 2014, 07:39", "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": [ "brute force", "product", "matrix", "tricky", "diagonal" ] }, "nbformat": 4, "nbformat_minor": 0 }