From eba98452e313920a272977ff5ea413e53051bb7b Mon Sep 17 00:00:00 2001 From: Donne Martin Date: Tue, 14 Feb 2017 06:19:21 -0500 Subject: [PATCH] Add fizz buzz challenge (#149) --- README.md | 1 + arrays_strings/fizz_buzz/__init__.py | 0 .../fizz_buzz/fizz_buzz_challenge.ipynb | 202 +++++++++++++++ .../fizz_buzz/fizz_buzz_solution.ipynb | 237 ++++++++++++++++++ arrays_strings/fizz_buzz/test_fizz_buzz.py | 37 +++ 5 files changed, 477 insertions(+) create mode 100644 arrays_strings/fizz_buzz/__init__.py create mode 100644 arrays_strings/fizz_buzz/fizz_buzz_challenge.ipynb create mode 100644 arrays_strings/fizz_buzz/fizz_buzz_solution.ipynb create mode 100644 arrays_strings/fizz_buzz/test_fizz_buzz.py diff --git a/README.md b/README.md index 70d5c21..1b9fe49 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,7 @@ Challenges, solutions, and unit tests are presented in the form of **IPython/Jup | Compress a string | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/compress/compress_challenge.ipynb)│[Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/compress/compress_solution.ipynb) | | Reverse characters in a string | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/reverse_string/reverse_string_challenge.ipynb)│[Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/reverse_string/reverse_string_solution.ipynb) | | Implement a hash table | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/hash_map/hash_map_challenge.ipynb)│[Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/hash_map/hash_map_solution.ipynb) | +| Implement fizz buzz | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/fizz_buzz/fizz_buzz_challenge.ipynb)│[Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/fizz_buzz/fizz_buzz_solution.ipynb) | | Find the first non-repeated character in a string | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)│[Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) | | Remove specified characters in a string | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)│[Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) | | Reverse words in a string | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)│[Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) | diff --git a/arrays_strings/fizz_buzz/__init__.py b/arrays_strings/fizz_buzz/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/arrays_strings/fizz_buzz/fizz_buzz_challenge.ipynb b/arrays_strings/fizz_buzz/fizz_buzz_challenge.ipynb new file mode 100644 index 0000000..5fb68d1 --- /dev/null +++ b/arrays_strings/fizz_buzz/fizz_buzz_challenge.ipynb @@ -0,0 +1,202 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook was prepared by [Donne Martin](https://github.com/donnemartin). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Challenge Notebook" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Problem: Implement Fizz Buzz.\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", + "* What is fizz buzz?\n", + " * Return the string representation of numbers from 1 to n\n", + " * Multiples of 3 -> 'Fizz'\n", + " * Multiples of 5 -> 'Buzz'\n", + " * Multiples of 3 and 5 -> 'FizzBuzz'\n", + "* Can we assume the inputs are valid?\n", + " * No\n", + "* Can we assume this fits memory?\n", + " * Yes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test Cases\n", + "\n", + "
\n",
+    "* None -> Exception\n",
+    "* < 1 -> Exception\n",
+    "* 15 ->\n",
+    "[\n",
+    "    '1',\n",
+    "    '2',\n",
+    "    'Fizz',\n",
+    "    '4',\n",
+    "    'Buzz',\n",
+    "    'Fizz',\n",
+    "    '7',\n",
+    "    '8',\n",
+    "    'Fizz',\n",
+    "    'Buzz',\n",
+    "    '11',\n",
+    "    'Fizz',\n",
+    "    '13',\n",
+    "    '14',\n",
+    "    'FizzBuzz'\n",
+    "]\n",
+    "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Algorithm\n", + "\n", + "Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/fizz_buzz/fizz_buzz_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": [ + "class Solution(object):\n", + "\n", + " def fizz_buzz(self, num):\n", + " # TODO: Implement me\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Unit Test" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**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_fizz_buzz.py\n", + "from nose.tools import assert_equal, assert_raises\n", + "\n", + "\n", + "class TestFizzBuzz(object):\n", + "\n", + " def test_fizz_buzz(self):\n", + " solution = Solution()\n", + " assert_raises(TypeError, solution.fizz_buzz, None)\n", + " assert_raises(ValueError, solution.fizz_buzz, 0)\n", + " expected = [\n", + " '1',\n", + " '2',\n", + " 'Fizz',\n", + " '4',\n", + " 'Buzz',\n", + " 'Fizz',\n", + " '7',\n", + " '8',\n", + " 'Fizz',\n", + " 'Buzz',\n", + " '11',\n", + " 'Fizz',\n", + " '13',\n", + " '14',\n", + " 'FizzBuzz'\n", + " ]\n", + " assert_equal(solution.fizz_buzz(15), expected)\n", + " print('Success: test_fizz_buzz')\n", + "\n", + "\n", + "def main():\n", + " test = TestFizzBuzz()\n", + " test.test_fizz_buzz()\n", + "\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/interactive-coding-challenges/blob/master/arrays_strings/fizz_buzz/fizz_buzz_solution.ipynb) for a discussion on algorithms and code solutions." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "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.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/arrays_strings/fizz_buzz/fizz_buzz_solution.ipynb b/arrays_strings/fizz_buzz/fizz_buzz_solution.ipynb new file mode 100644 index 0000000..0e3d90d --- /dev/null +++ b/arrays_strings/fizz_buzz/fizz_buzz_solution.ipynb @@ -0,0 +1,237 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook was prepared by [Donne Martin](https://github.com/donnemartin). 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: Implement Fizz Buzz.\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", + "\n", + "* What is fizz buzz?\n", + " * Return the string representation of numbers from 1 to n\n", + " * Multiples of 3 -> 'Fizz'\n", + " * Multiples of 5 -> 'Buzz'\n", + " * Multiples of 3 and 5 -> 'FizzBuzz'\n", + "* Can we assume the inputs are valid?\n", + " * No\n", + "* Can we assume this fits memory?\n", + " * Yes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Test Cases\n", + "\n", + "
\n",
+    "* None -> Exception\n",
+    "* < 1 -> Exception\n",
+    "* 15 ->\n",
+    "[\n",
+    "    '1',\n",
+    "    '2',\n",
+    "    'Fizz',\n",
+    "    '4',\n",
+    "    'Buzz',\n",
+    "    'Fizz',\n",
+    "    '7',\n",
+    "    '8',\n",
+    "    'Fizz',\n",
+    "    'Buzz',\n",
+    "    '11',\n",
+    "    'Fizz',\n",
+    "    '13',\n",
+    "    '14',\n",
+    "    'FizzBuzz'\n",
+    "]\n",
+    "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Algorithm\n", + "\n", + "There is no fancy algorithm to solve fizz buzz.\n", + "\n", + "* Iterate from 1 through n\n", + "* Use the mod operator to determine if the current iteration is divisible by:\n", + " * 3 and 5 -> 'FizzBuzz'\n", + " * 3 -> 'Fizz'\n", + " * 5 -> 'Buzz'\n", + " * else -> string of current iteration\n", + "* return the results\n", + "\n", + "Complexity:\n", + "* Time: O(n)\n", + "* Space: O(n)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Code" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "class Solution(object):\n", + "\n", + " def fizz_buzz(self, num):\n", + " if num is None:\n", + " raise TypeError('num cannot be None')\n", + " if num < 1:\n", + " raise ValueError('num cannot be less than one')\n", + " results = []\n", + " for i in range(1, num + 1):\n", + " if i % 3 == 0 and i % 5 == 0:\n", + " results.append('FizzBuzz')\n", + " elif i % 3 == 0:\n", + " results.append('Fizz')\n", + " elif i % 5 == 0:\n", + " results.append('Buzz')\n", + " else:\n", + " results.append(str(i))\n", + " return results" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Unit Test" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting test_fizz_buzz.py\n" + ] + } + ], + "source": [ + "%%writefile test_fizz_buzz.py\n", + "from nose.tools import assert_equal, assert_raises\n", + "\n", + "\n", + "class TestFizzBuzz(object):\n", + "\n", + " def test_fizz_buzz(self):\n", + " solution = Solution()\n", + " assert_raises(TypeError, solution.fizz_buzz, None)\n", + " assert_raises(ValueError, solution.fizz_buzz, 0)\n", + " expected = [\n", + " '1',\n", + " '2',\n", + " 'Fizz',\n", + " '4',\n", + " 'Buzz',\n", + " 'Fizz',\n", + " '7',\n", + " '8',\n", + " 'Fizz',\n", + " 'Buzz',\n", + " '11',\n", + " 'Fizz',\n", + " '13',\n", + " '14',\n", + " 'FizzBuzz'\n", + " ]\n", + " assert_equal(solution.fizz_buzz(15), expected)\n", + " print('Success: test_fizz_buzz')\n", + "\n", + "\n", + "def main():\n", + " test = TestFizzBuzz()\n", + " test.test_fizz_buzz()\n", + "\n", + "\n", + "if __name__ == '__main__':\n", + " main()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Success: test_fizz_buzz\n" + ] + } + ], + "source": [ + "%run -i test_fizz_buzz.py" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "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.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/arrays_strings/fizz_buzz/test_fizz_buzz.py b/arrays_strings/fizz_buzz/test_fizz_buzz.py new file mode 100644 index 0000000..3b475d5 --- /dev/null +++ b/arrays_strings/fizz_buzz/test_fizz_buzz.py @@ -0,0 +1,37 @@ +from nose.tools import assert_equal, assert_raises + + +class TestFizzBuzz(object): + + def test_fizz_buzz(self): + solution = Solution() + assert_raises(TypeError, solution.fizz_buzz, None) + assert_raises(ValueError, solution.fizz_buzz, 0) + expected = [ + '1', + '2', + 'Fizz', + '4', + 'Buzz', + 'Fizz', + '7', + '8', + 'Fizz', + 'Buzz', + '11', + 'Fizz', + '13', + '14', + 'FizzBuzz' + ] + assert_equal(solution.fizz_buzz(15), expected) + print('Success: test_fizz_buzz') + + +def main(): + test = TestFizzBuzz() + test.test_fizz_buzz() + + +if __name__ == '__main__': + main() \ No newline at end of file