From 30158749c9a4fe8a078db13049c423db906b8f0b Mon Sep 17 00:00:00 2001 From: = Date: Wed, 5 Aug 2015 20:53:24 +0530 Subject: [PATCH] Added n-pairs parentheses challenge --- .../n_pairs_parentheses_challenge.ipynb | 162 ++++++++++++++++++ .../n_pairs_parentheses_solution.ipynb | 162 ++++++++++++++++++ .../test_n_pairs_parentheses.py | 17 ++ 3 files changed, 341 insertions(+) create mode 100644 recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_challenge.ipynb create mode 100644 recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_solution.ipynb create mode 100644 recursion_dynamic/n_pairs_parentheses/test_n_pairs_parentheses.py diff --git a/recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_challenge.ipynb b/recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_challenge.ipynb new file mode 100644 index 0000000..ec4abf3 --- /dev/null +++ b/recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_challenge.ipynb @@ -0,0 +1,162 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook was prepared by [Rishi Rajasekaran](https://github.com/rishihot55). Source and license info is available on [Github](https://github.com/donnemartin/interactive-coding-challenges)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Challenge Notebook" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Problem: Print all valid combinations of n-pairs of parentheses\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", + "* None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test Cases\n", + "\n", + "* 0 -> []\n", + "* 1 -> [()]\n", + "* 2 -> [(()), ()()]\n", + "* 3 -> [((())), (()()), (())(), ()(()), ()()()]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Code" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def parentheses_util(no_left, no_right, pair_string, result):\n", + " # TODO: implement parentheses pairing here\n", + " pass\n", + "\n", + "\n", + "def pair_parentheses(n):\n", + " result_set = set()\n", + " if n == 0:\n", + " return result_set\n", + " parentheses_util(n, n, '', result_set)\n", + " return result_set\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Unit Test" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "ename": "AssertionError", + "evalue": "Items in the second set but not the first:\n'()'", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mAssertionError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 16\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 17\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0m__name__\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m'__main__'\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 18\u001b[1;33m \u001b[0mmain\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[1;32m\u001b[0m in \u001b[0;36mmain\u001b[1;34m()\u001b[0m\n\u001b[0;32m 13\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mmain\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 14\u001b[0m \u001b[0mtest\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mTestPairParentheses\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 15\u001b[1;33m \u001b[0mtest\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtest_pair_parentheses\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpair_parentheses\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 16\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 17\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0m__name__\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m'__main__'\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m\u001b[0m in \u001b[0;36mtest_pair_parentheses\u001b[1;34m(self, solution)\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mtest_pair_parentheses\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msolution\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[0massert_equal\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msolution\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mset\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 8\u001b[1;33m \u001b[0massert_equal\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msolution\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mset\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'()'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 9\u001b[0m \u001b[0massert_equal\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msolution\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mset\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'(())'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'()()'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 10\u001b[0m \u001b[0massert_equal\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0msolution\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mset\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;34m'((()))'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;34m'(()())'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'(())()'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'()(())'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'()()()'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m/usr/lib/python2.7/unittest/case.py\u001b[0m in \u001b[0;36massertEqual\u001b[1;34m(self, first, second, msg)\u001b[0m\n\u001b[0;32m 511\u001b[0m \"\"\"\n\u001b[0;32m 512\u001b[0m \u001b[0massertion_func\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_getAssertEqualityFunc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfirst\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msecond\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 513\u001b[1;33m \u001b[0massertion_func\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfirst\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msecond\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmsg\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mmsg\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 514\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 515\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0massertNotEqual\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfirst\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msecond\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmsg\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m/usr/lib/python2.7/unittest/case.py\u001b[0m in \u001b[0;36massertSetEqual\u001b[1;34m(self, set1, set2, msg)\u001b[0m\n\u001b[0;32m 794\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 795\u001b[0m \u001b[0mstandardMsg\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;34m'\\n'\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mjoin\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlines\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 796\u001b[1;33m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfail\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_formatMessage\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mstandardMsg\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 797\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 798\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0massertIn\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmember\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcontainer\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmsg\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;32m/usr/lib/python2.7/unittest/case.py\u001b[0m in \u001b[0;36mfail\u001b[1;34m(self, msg)\u001b[0m\n\u001b[0;32m 408\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mfail\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmsg\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 409\u001b[0m \u001b[1;34m\"\"\"Fail immediately, with the given message.\"\"\"\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 410\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfailureException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmsg\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 411\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 412\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0massertFalse\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mexpr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mmsg\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mNone\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", + "\u001b[1;31mAssertionError\u001b[0m: Items in the second set but not the first:\n'()'" + ] + } + ], + "source": [ + "# %load test_n_pairs_parentheses.py\n", + "from nose.tools import assert_equal\n", + "\n", + "class TestPairParentheses(object):\n", + " \n", + " def test_pair_parentheses(self, solution):\n", + " assert_equal(solution(0), set([]))\n", + " assert_equal(solution(1), set(['()']))\n", + " assert_equal(solution(2), set(['(())', '()()']))\n", + " assert_equal(solution(3), set(['((()))','(()())', '(())()', '()(())', '()()()']))\n", + " print('Success: test_pair_parentheses')\n", + "\n", + "def main():\n", + " test = TestPairParentheses()\n", + " test.test_pair_parentheses(pair_parentheses)\n", + "\n", + "if __name__ == '__main__':\n", + " main()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Solution Notebook\n", + "\n", + "Review the [Solution Notebook](#) 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.9" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_solution.ipynb b/recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_solution.ipynb new file mode 100644 index 0000000..9cdb79e --- /dev/null +++ b/recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_solution.ipynb @@ -0,0 +1,162 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook was prepared by [Rishi Rajasekaran](https://github.com/rishihot55). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Solution Notebook" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Problem: Print all valid combinations of n-pairs of parentheses\n", + "\n", + "* [Constraints](#Constraints)\n", + "* [Test Cases](#Test-Cases)\n", + "* [Algorithm](#Algorithm)\n", + "* [Code](#Code)\n", + "* [Unit Test](#Unit-Test)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Constraints\n", + "* None" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test Cases\n", + "\n", + "* 0 -> ''\n", + "* 1 -> ()\n", + "* 2 -> (()), ()()\n", + "* 3 -> ((())), (()()), (())(), ()(()), ()()()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Algorithm\n", + "* If no_of_left == 0 and no_of right == 0, add pair_string to result\n", + "* Else \n", + " * If (no_left > 0), parentheses_util(no_left - 1, no_right, pair_string + '(', result)\n", + " * If (no_right > no_left), parentheses_util(no_left, no_right - 1, pair_string + ')', result)\n", + "\n", + "Complexity:\n", + "* Time: O(4^n/n^(3/2)) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Code" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def parentheses_util(no_left, no_right, pair_string, result):\n", + " if no_left == 0 and no_right == 0:\n", + " result.add(pair_string)\n", + " else:\n", + " if no_left > 0:\n", + " parentheses_util(no_left - 1, no_right, pair_string + '(', result)\n", + " if no_right > no_left:\n", + " parentheses_util(no_left, no_right - 1, pair_string + ')', result)\n", + "\n", + "\n", + "def pair_parentheses(n):\n", + " result_set = set()\n", + " if n == 0:\n", + " return result_set\n", + " parentheses_util(n, n, '', result_set)\n", + " return result_set\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Unit Test" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Success: test_pair_parentheses\n" + ] + } + ], + "source": [ + "# %load test_n_pairs_parentheses.py\n", + "from nose.tools import assert_equal\n", + "\n", + "class TestPairParentheses(object):\n", + " \n", + " def test_pair_parentheses(self, solution):\n", + " assert_equal(solution(0), set([]))\n", + " assert_equal(solution(1), set(['()']))\n", + " assert_equal(solution(2), set(['(())', '()()']))\n", + " assert_equal(solution(3), set(['((()))','(()())', '(())()', '()(())', '()()()']))\n", + " print('Success: test_pair_parentheses')\n", + "\n", + "def main():\n", + " test = TestPairParentheses()\n", + " test.test_pair_parentheses(pair_parentheses)\n", + "\n", + "if __name__ == '__main__':\n", + " main()" + ] + } + ], + "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 +} diff --git a/recursion_dynamic/n_pairs_parentheses/test_n_pairs_parentheses.py b/recursion_dynamic/n_pairs_parentheses/test_n_pairs_parentheses.py new file mode 100644 index 0000000..52d19d7 --- /dev/null +++ b/recursion_dynamic/n_pairs_parentheses/test_n_pairs_parentheses.py @@ -0,0 +1,17 @@ +from nose.tools import assert_equal + +class TestPairParentheses(object): + + def test_pair_parentheses(self, solution): + assert_equal(solution(0), set([])) + assert_equal(solution(1), set(['()'])) + assert_equal(solution(2), set(['(())', '()()'])) + assert_equal(solution(3), set(['((()))','(()())', '(())()', '()(())', '()()()'])) + print('Success: test_pair_parentheses') + +def main(): + test = TestPairParentheses() + test.test_pair_parentheses(pair_parentheses) + +if __name__ == '__main__': + main() \ No newline at end of file