From 1444f7cc7e3ec31111bf0071dd59356b6d3d6215 Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Wed, 17 Oct 2018 23:20:33 -0400 Subject: [PATCH] Added additional solutions to problem 31. --- ipython/EulerProblem031.ipynb | 194 ++++++++++++++++++++++------- ipython/html/EulerProblem031.html | 197 +++++++++++++++++++++++++----- 2 files changed, 320 insertions(+), 71 deletions(-) diff --git a/ipython/EulerProblem031.ipynb b/ipython/EulerProblem031.ipynb index a91e551..a759063 100644 --- a/ipython/EulerProblem031.ipynb +++ b/ipython/EulerProblem031.ipynb @@ -29,9 +29,7 @@ { "cell_type": "code", "execution_count": 1, - "metadata": { - "collapsed": false - }, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -51,59 +49,58 @@ }, { "cell_type": "code", - "execution_count": 2, - "metadata": { - "collapsed": false - }, + "execution_count": 8, + "metadata": {}, "outputs": [], "source": [ "from math import ceil\n", "\n", - "r = 200\n", - "c = 0\n", + "def calculate():\n", + " r = 200\n", + " c = 0\n", "\n", - "if r % 200 == 0:\n", - " c += 1\n", - "for p200 in range(ceil(r / 200)):\n", - " r200 = r - p200 * 200\n", - " if r200 % 100 == 0:\n", + " if r % 200 == 0:\n", " c += 1\n", - " for p100 in range(ceil(r200 / 100)):\n", - " r100 = r200 - p100 * 100\n", - " if r100 % 50 == 0:\n", + " for p200 in range(ceil(r / 200)):\n", + " r200 = r - p200 * 200\n", + " if r200 % 100 == 0:\n", " c += 1\n", - " for p50 in range(ceil(r100 / 50)):\n", - " r50 = r100 - p50 * 50\n", - " if r50 % 20 == 0:\n", + " for p100 in range(ceil(r200 / 100)):\n", + " r100 = r200 - p100 * 100\n", + " if r100 % 50 == 0:\n", " c += 1\n", - " for p20 in range(ceil(r50 / 20)):\n", - " r20 = r50 - p20 * 20\n", - " if r20 <= 0:\n", - " break\n", - " if r20 % 10 == 0:\n", + " for p50 in range(ceil(r100 / 50)):\n", + " r50 = r100 - p50 * 50\n", + " if r50 % 20 == 0:\n", " c += 1\n", - " for p10 in range(ceil(r20 / 10)):\n", - " r10 = r20 - p10 * 10\n", - " if r10 % 5 == 0:\n", + " for p20 in range(ceil(r50 / 20)):\n", + " r20 = r50 - p20 * 20\n", + " if r20 <= 0:\n", + " break\n", + " if r20 % 10 == 0:\n", " c += 1\n", - " for p5 in range(ceil(r10 / 5)):\n", - " r5 = r10 - p5 * 5\n", - " if r5 % 2 == 0:\n", + " for p10 in range(ceil(r20 / 10)):\n", + " r10 = r20 - p10 * 10\n", + " if r10 % 5 == 0:\n", " c += 1\n", - " for p2 in range(ceil(r5 / 2)):\n", - " r2 = r5 - p2 * 2\n", - " if r2 % 1 == 0:\n", + " for p5 in range(ceil(r10 / 5)):\n", + " r5 = r10 - p5 * 5\n", + " if r5 % 2 == 0:\n", " c += 1\n", + " for p2 in range(ceil(r5 / 2)):\n", + " r2 = r5 - p2 * 2\n", + " if r2 % 1 == 0:\n", + " c += 1\n", "\n", - "s = c" + " return c\n", + "\n", + "s = calculate()" ] }, { "cell_type": "code", - "execution_count": 3, - "metadata": { - "collapsed": false - }, + "execution_count": 9, + "metadata": {}, "outputs": [ { "name": "stdout", @@ -117,13 +114,128 @@ "print(s)\n", "assert(s == 73682)" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "I came up with a more concise solution that can be implemented in Scheme. I would like to compare the performance of the solutions." + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "73682\n" + ] + } + ], + "source": [ + "def count_change(change, coins):\n", + " if not coins:\n", + " return 0\n", + " count = 0\n", + " coin, coins = coins[0], coins[1:]\n", + " for i in range(change // coin + 1):\n", + " if change - i * coin == 0:\n", + " count += 1\n", + " continue\n", + " if change - i * coin < 0:\n", + " break\n", + " count += count_change(change - i * coin, coins)\n", + " return count\n", + "\n", + "def calculate_iterative():\n", + " return count_change(200, [200, 100, 50, 20, 10, 5, 2, 1])\n", + "\n", + "s = calculate_iterative()\n", + "print(s)" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.16300111500095227\n", + "11.429953110000497\n" + ] + } + ], + "source": [ + "import timeit\n", + "print(timeit.timeit(calculate, number=10))\n", + "print(timeit.timeit(calculate_iterative, number=10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Turns out I was way smarter than I thought when I have developped calculate. It checks the remainder and by doing that saves a ton of iterations." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "73682\n", + "0.34602016500139143\n" + ] + } + ], + "source": [ + "def count_change(change, coins):\n", + " count = 0\n", + " coin, coins = coins[0], coins[1:]\n", + "\n", + " if change % coin == 0:\n", + " count += 1\n", + " \n", + " if not coins:\n", + " return count\n", + " \n", + " for i in range(ceil(change / coin)):\n", + " count += count_change(change - i * coin, coins)\n", + " return count\n", + "\n", + "def calculate_iterative():\n", + " return count_change(200, [200, 100, 50, 20, 10, 5, 2, 1])\n", + "\n", + "s = calculate_iterative()\n", + "print(s)\n", + "print(timeit.timeit(calculate_iterative, number=10))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] } ], "metadata": { "completion_date": "Fri, 25 Aug 2017, 13:02", "kernelspec": { "display_name": "Python 3", - "language": "python", + "language": "python3.6", "name": "python3" }, "language_info": { @@ -136,7 +248,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.4" + "version": "3.6.5" }, "tags": [ "recursion", diff --git a/ipython/html/EulerProblem031.html b/ipython/html/EulerProblem031.html index bb26a9c..d7f9fcd 100644 --- a/ipython/html/EulerProblem031.html +++ b/ipython/html/EulerProblem031.html @@ -11814,48 +11814,51 @@ div#notebook {
-
In [2]:
+
In [8]:
from math import ceil
 
-r = 200
-c = 0
+def calculate():
+    r = 200
+    c = 0
 
-if r % 200 == 0:
-    c += 1
-for p200 in range(ceil(r / 200)):
-    r200 = r - p200 * 200
-    if r200 % 100 == 0:
+    if r % 200 == 0:
         c += 1
-    for p100 in range(ceil(r200 / 100)):
-        r100 = r200 - p100 * 100
-        if r100 % 50 == 0:
+    for p200 in range(ceil(r / 200)):
+        r200 = r - p200 * 200
+        if r200 % 100 == 0:
             c += 1
-        for p50 in range(ceil(r100 / 50)):
-            r50 = r100 - p50 * 50
-            if r50 % 20 == 0:
+        for p100 in range(ceil(r200 / 100)):
+            r100 = r200 - p100 * 100
+            if r100 % 50 == 0:
                 c += 1
-            for p20 in range(ceil(r50 / 20)):
-                r20 = r50 - p20 * 20
-                if r20 <= 0:
-                    break
-                if r20 % 10 == 0:
+            for p50 in range(ceil(r100 / 50)):
+                r50 = r100 - p50 * 50
+                if r50 % 20 == 0:
                     c += 1
-                for p10 in range(ceil(r20 / 10)):
-                    r10 = r20 - p10 * 10
-                    if r10 % 5 == 0:
+                for p20 in range(ceil(r50 / 20)):
+                    r20 = r50 - p20 * 20
+                    if r20 <= 0:
+                        break
+                    if r20 % 10 == 0:
                         c += 1
-                    for p5 in range(ceil(r10 / 5)):
-                        r5 = r10 - p5 * 5
-                        if r5 % 2 == 0:
+                    for p10 in range(ceil(r20 / 10)):
+                        r10 = r20 - p10 * 10
+                        if r10 % 5 == 0:
                             c += 1
-                        for p2 in range(ceil(r5 / 2)):
-                            r2 = r5 - p2 * 2
-                            if r2 % 1 == 0:
+                        for p5 in range(ceil(r10 / 5)):
+                            r5 = r10 - p5 * 5
+                            if r5 % 2 == 0:
                                 c += 1
+                            for p2 in range(ceil(r5 / 2)):
+                                r2 = r5 - p2 * 2
+                                if r2 % 1 == 0:
+                                    c += 1
 
-s = c
+    return c
+
+s = calculate()
 
@@ -11863,7 +11866,7 @@ div#notebook {
-
In [3]:
+
In [9]:
print(s)
@@ -11884,6 +11887,140 @@ div#notebook {
 
+
+
+
+
+

I came up with a more concise solution that can be implemented in Scheme. I would like to compare the performance of the solutions.

+
+
+
+
+
+
In [34]:
+
+
+
def count_change(change, coins):
+    if not coins:
+        return 0
+    count = 0
+    coin, coins = coins[0], coins[1:]
+    for i in range(change // coin + 1):
+        if change - i * coin == 0:
+            count += 1
+            continue
+        if change - i * coin < 0:
+            break
+        count += count_change(change - i * coin, coins)
+    return count
+
+def calculate_iterative():
+    return count_change(200, [200, 100, 50, 20, 10, 5, 2, 1])
+
+s = calculate_iterative()
+print(s)
+
+
+
+
+
+
+
+
+
+
73682
+
+
+
+
+
+
+
+
+
In [35]:
+
+
+
import timeit
+print(timeit.timeit(calculate, number=10))
+print(timeit.timeit(calculate_iterative, number=10))
+
+
+
+
+
+
+
+
+
+
0.16300111500095227
+11.429953110000497
+
+
+
+
+
+
+
+
+
+
+

Turns out I was way smarter than I thought when I have developped calculate. It checks the remainder and by doing that saves a ton of iterations.

+
+
+
+
+
+
In [36]:
+
+
+
def count_change(change, coins):
+    count = 0
+    coin, coins = coins[0], coins[1:]
+
+    if change % coin == 0:
+        count += 1
+        
+    if not coins:
+        return count
+    
+    for i in range(ceil(change / coin)):
+        count += count_change(change - i * coin, coins)
+    return count
+
+def calculate_iterative():
+    return count_change(200, [200, 100, 50, 20, 10, 5, 2, 1])
+
+s = calculate_iterative()
+print(s)
+print(timeit.timeit(calculate_iterative, number=10))
+
+
+
+
+
+
+
+
+
+
73682
+0.34602016500139143
+
+
+
+
+
+
+
+
+
In [ ]:
+
+
+
 
+
+
+
+
+