{
 "cells": [
  {
   "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",
    "* [Clarifying Questions](#Clarifying-Questions)\n",
    "* [Test Cases](#Test-Cases)\n",
    "* [Algorithm](#Algorithm)\n",
    "* [Code](#Code)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Clarifying Questions\n",
    "\n",
    "* None"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test Cases\n",
    "\n",
    "* NULL towers\n",
    "* 0 disks\n",
    "* 1 disk\n",
    "* 2 or more disks"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Algorithm\n",
    "\n",
    "* Create three stacks to represent each tower\n",
    "* def hanoi(n, src, dest, buffer):\n",
    "    * If 0 disks return\n",
    "    * hanoi(n-1, src, buffer)\n",
    "    * Move remaining element from src to dest\n",
    "    * hanoi(n-1, buffer, dest)    \n",
    "\n",
    "Complexity:\n",
    "* Time: O(2^n - 1)\n",
    "* Space: O(m) where m is the number of recursion levels"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Code"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "%run stack.py"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def hanoi(num_disks, src, dest, buff):\n",
    "    if src is None or dest is None or buff is None:\n",
    "        return\n",
    "    if num_disks > 0:\n",
    "        hanoi(num_disks-1, src, buff, dest)\n",
    "        data = src.pop()\n",
    "        dest.push(data)\n",
    "        hanoi(num_disks-1, buff, dest, src)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "print('NULL towers')\n",
    "hanoi(num_disks, None, None, None)\n",
    "first = Stack()\n",
    "second = Stack()\n",
    "third = Stack()\n",
    "print('0 disks')\n",
    "hanoi(num_disks, first, third, second)\n",
    "print('1 disk')\n",
    "first.push(5)\n",
    "hanoi(num_disks, first, third, second)\n",
    "print(third.pop())\n",
    "print('2 or more disks')\n",
    "num_disks = 3\n",
    "for i in xrange(num_disks, -1, -1):\n",
    "    first.push(i)\n",
    "hanoi(num_disks, first, third, second)\n",
    "for i in xrange(0, num_disks):\n",
    "    print(third.pop())"
   ]
  }
 ],
 "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.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
