{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "This problem is very similar to [Problem 15](https://xojoc.pw/challenges/euler/15). We build a DAG and then find the longest path taking in consideration the weight of each node.\n", "This algorithm solves [Problem 67](https://xojoc.pw/challenges/euler/67) too." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1074\n", "7273\n" ] } ], "source": [ "import networkx as nx\n", "from urllib.request import urlopen\n", "\n", "\n", "def read_triangle(file):\n", " triangle_data = \"\"\n", " try:\n", " with open(file) as f:\n", " triangle_data = f.read()\n", " except FileNotFoundError:\n", " with urlopen(\"https://xojoc.pw/challenges/euler/\" + file) as response:\n", " triangle_data = response.read().decode()\n", "\n", " return [[int(n) for n in line.split(' ')] for line in triangle_data[:-1].split('\\n')]\n", "\n", "\n", "def build_graph(triangle):\n", " g = nx.DiGraph()\n", "\n", " def T(n):\n", " return n * (n + 1) // 2\n", "\n", " def i(row, col):\n", " return 1 + T(row) + col\n", "\n", " for r in range(len(triangle)):\n", " for c in range(r + 1):\n", " g.add_node(i(r, c), weight=triangle[r][c])\n", "\n", " for r in range(len(triangle)-1):\n", " for c in range(r+1):\n", " g.add_edge(i(r, c), i(r + 1, c))\n", " g.add_edge(i(r, c), i(r + 1, c + 1))\n", "\n", " return g\n", "\n", "\n", "def longest_path(g):\n", " sorted_nodes = list(nx.topological_sort(g))\n", " first_node = sorted_nodes[0]\n", " node_weights = nx.get_node_attributes(g, 'weight')\n", " cache = {}\n", " for n in reversed(sorted_nodes):\n", " max_weight = 0\n", " for s in g.successors(n):\n", " max_weight = max(cache[s], max_weight)\n", " cache[n] = node_weights[n] + max_weight\n", " return cache[first_node]\n", "\n", "\n", "for f in [\"18.txt\", \"67.txt\"]:\n", " triangle = read_triangle(f)\n", " g = build_graph(triangle)\n", " print(longest_path(g))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "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.7.4" }, "title": "Maximum path sum I" }, "nbformat": 4, "nbformat_minor": 2 }