diff --git a/stacks_queues/hanoi/__init__.py b/stacks_queues/hanoi/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/stacks_queues/hanoi/hanoi_challenge.ipynb b/stacks_queues/hanoi/hanoi_challenge.ipynb new file mode 100644 index 0000000..dcec850 --- /dev/null +++ b/stacks_queues/hanoi/hanoi_challenge.ipynb @@ -0,0 +1,187 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/coding-challenges)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Challenge Notebook" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Problem: Implement the [Towers of Hanoi](http://en.wikipedia.org/wiki/Tower_of_Hanoi) with 3 towers and N disks.\n", + "\n", + "* [Constraints](#Constraints)\n", + "* [Test Cases](#Test-Cases)\n", + "* [Algorithm](#Algorithm)\n", + "* [Code](#Code)\n", + "* [Unit Test](#Unit-Test)\n", + "* [Solution Notebook](#Solution-Notebook)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Constraints\n", + "\n", + "*Problem statements are sometimes ambiguous. Identifying constraints and stating assumptions can help to ensure you code the intended solution.*\n", + "\n", + "* Can we assume we already have a stack class that can be used for this problem?\n", + " * Yes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test Cases\n", + "\n", + "* NULL tower(s)\n", + "* 0 disks\n", + "* 1 disk\n", + "* 2 or more disks" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Algorithm\n", + "\n", + "Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/coding-challenges/blob/master/stacks_queues/hanoi/hanoi_solution.ipynb). If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Code" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "%run ../stack/stack.py\n", + "%load ../stack/stack.py" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def hanoi(num_disks, src, dest, buff):\n", + " # TODO: Implement me\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Unit Test\n", + "\n", + "\n", + "\n", + "**The following unit test is expected to fail until you solve the challenge.**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "# %load test_hanoi.py\n", + "from nose.tools import assert_equal\n", + "\n", + "\n", + "class TestHanoi(object):\n", + " \n", + " def test_hanoi(self):\n", + " num_disks = 3\n", + " src = Stack()\n", + " buff = Stack()\n", + " dest = Stack()\n", + "\n", + " print('Test: NULL towers')\n", + " hanoi(num_disks, None, None, None)\n", + "\n", + " print('Test: 0 disks')\n", + " hanoi(num_disks, src, dest, buff)\n", + " assert_equal(dest.pop(), None)\n", + "\n", + " print('Test: 1 disk')\n", + " src.push(5)\n", + " hanoi(num_disks, src, dest, buff)\n", + " assert_equal(dest.pop(), 5)\n", + "\n", + " print('Test: 2 or more disks')\n", + " for i in xrange(num_disks, -1, -1):\n", + " src.push(i)\n", + " hanoi(num_disks, src, dest, buff)\n", + " for i in xrange(0, num_disks):\n", + " assert_equal(dest.pop(), i)\n", + "\n", + " print('Success: test_hanoi')\n", + "\n", + "def main():\n", + " test = TestHanoi()\n", + " test.test_hanoi()\n", + " \n", + "if __name__ == '__main__':\n", + " main()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solution Notebook\n", + "\n", + "Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/coding-challenges/blob/master/stacks_queues/hanoi/hanoi_solution.ipynb) for a discussion on algorithms and code solutions." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.10" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/stacks_queues/hanoi/hanoi_solution.ipynb b/stacks_queues/hanoi/hanoi_solution.ipynb index 68ada38..b419ccd 100644 --- a/stacks_queues/hanoi/hanoi_solution.ipynb +++ b/stacks_queues/hanoi/hanoi_solution.ipynb @@ -4,7 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://bit.ly/code-notes)." + "This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/coding-challenges)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Solution Notebook" ] }, { @@ -26,7 +33,7 @@ "source": [ "## Constraints\n", "\n", - "*Problem statements are often intentionally ambiguous. Identifying constraints and stating assumptions can help to ensure you code the intended solution.*\n", + "*Problem statements are sometimes ambiguous. Identifying constraints and stating assumptions can help to ensure you code the intended solution.*\n", "\n", "* Can we assume we already have a stack class that can be used for this problem?\n", " * Yes" @@ -38,7 +45,7 @@ "source": [ "## Test Cases\n", "\n", - "* NULL towers\n", + "* NULL tower(s)\n", "* 0 disks\n", "* 1 disk\n", "* 2 or more disks" @@ -73,11 +80,11 @@ "cell_type": "code", "execution_count": 1, "metadata": { - "collapsed": true + "collapsed": false }, "outputs": [], "source": [ - "%run stack.py" + "%run ../stack/stack.py" ] }, { @@ -103,8 +110,7 @@ "metadata": {}, "source": [ "## Unit Test\n", - "\n", - "*It is important to identify and run through general and edge cases from the [Test Cases](#Test-Cases) section by hand. You generally will not be asked to write a unit test like what is shown below.*" + "\n" ] }, { @@ -118,18 +124,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "Test: NULL towers\n", - "Test: 0 disks\n", - "Test: 1 disk\n", - "Test: 2 or more disks\n", - "Success: test_hanoi\n" + "Overwriting test_hanoi.py\n" ] } ], "source": [ + "%%writefile test_hanoi.py\n", "from nose.tools import assert_equal\n", "\n", - "class Test(object):\n", + "\n", + "class TestHanoi(object):\n", + " \n", " def test_hanoi(self):\n", " num_disks = 3\n", " src = Stack()\n", @@ -157,9 +162,35 @@ "\n", " print('Success: test_hanoi')\n", "\n", + "def main():\n", + " test = TestHanoi()\n", + " test.test_hanoi()\n", + " \n", "if __name__ == '__main__':\n", - " test = Test()\n", - " test.test_hanoi()" + " main()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test: NULL towers\n", + "Test: 0 disks\n", + "Test: 1 disk\n", + "Test: 2 or more disks\n", + "Success: test_hanoi\n" + ] + } + ], + "source": [ + "%run -i test_hanoi.py" ] } ], diff --git a/stacks_queues/hanoi/test_hanoi.py b/stacks_queues/hanoi/test_hanoi.py new file mode 100644 index 0000000..9e230a6 --- /dev/null +++ b/stacks_queues/hanoi/test_hanoi.py @@ -0,0 +1,38 @@ +from nose.tools import assert_equal + + +class TestHanoi(object): + + def test_hanoi(self): + num_disks = 3 + src = Stack() + buff = Stack() + dest = Stack() + + print('Test: NULL towers') + hanoi(num_disks, None, None, None) + + print('Test: 0 disks') + hanoi(num_disks, src, dest, buff) + assert_equal(dest.pop(), None) + + print('Test: 1 disk') + src.push(5) + hanoi(num_disks, src, dest, buff) + assert_equal(dest.pop(), 5) + + print('Test: 2 or more disks') + for i in xrange(num_disks, -1, -1): + src.push(i) + hanoi(num_disks, src, dest, buff) + for i in xrange(0, num_disks): + assert_equal(dest.pop(), i) + + print('Success: test_hanoi') + +def main(): + test = TestHanoi() + test.test_hanoi() + +if __name__ == '__main__': + main() \ No newline at end of file