{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Euler Problem 39\n",
    "\n",
    "If p is the perimeter of a right angle triangle with integral length sides, {a,b,c}, there are exactly three solutions for p = 120.\n",
    "\n",
    "$\\{20,48,52\\}, \\{24,45,51\\}, \\{30,40,50\\}$\n",
    "\n",
    "For which value of p ≤ 1000, is the number of solutions maximised?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "We are looking for right angle triangles so Pythagoras' theorem $a^2 + b^2 = c^2$ can be used. Also it must be true that $a <= b <= c$ is true for every solution. Let's start with a function that tests the given examples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def is_right_angle_triangle(a, b, c, p):\n",
    "    if a + b + c != p:\n",
    "        return False\n",
    "    if a**2 + b**2 != c**2:\n",
    "        return False\n",
    "    return True\n",
    "\n",
    "given = [(20, 48, 52, 120), (24, 45, 51, 120), (30, 40, 50, 120)]\n",
    "for g in given:\n",
    "    assert(is_right_angle_triangle(*g))\n",
    "assert(is_right_angle_triangle(29, 41, 50, 120) == False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This seems bruteforceable. Let's try to find the solutions for p = 120."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[(30, 40, 50), (24, 45, 51), (20, 48, 52)]\n"
     ]
    }
   ],
   "source": [
    "def brute_force(p):\n",
    "    solutions = [(a,b, p - a - b)\n",
    "        for b in range(1, p // 2 + 1)\n",
    "        for a in range(1, b)\n",
    "        if a*a + b*b == (p - a - b) * (p - a - b)\n",
    "    ]\n",
    "    return solutions\n",
    "\n",
    "print(brute_force(120))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Looks good. Let's try for all $p <= 1000$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "solutions = [(len(brute_force(p)), p) for p in range(1, 1001)]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Well, not too fast, but also not too slow. Let's get the max and we have our solution."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "840\n"
     ]
    }
   ],
   "source": [
    "s, p = max(solutions)\n",
    "print(p)\n",
    "assert(p == 840)"
   ]
  }
 ],
 "metadata": {
  "completion_date": "Sun, 20 May 2018, 21:16",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python3.6",
   "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.6.5"
  },
  "tags": [
   "triangle",
   "right",
   "integer"
  ]
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
