[
  {
    "path": ".gitattributes",
    "content": "*.ipynb linguist-language=Python\n"
  },
  {
    "path": ".gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nenv/\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\n*.egg-info/\n.installed.cfg\n*.egg\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.coverage\n.cache\nnosetests.xml\ncoverage.xml\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n\n# IPython notebook\n.ipynb_checkpoints\n\n# Repo scratch directory\nscratch/\n\n# IPython Notebook templates\ntemplate.ipynb"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "Contributing\n============\n\nContributions are welcome!\n\n**Please carefully read this page to make the code review process go as smoothly as possible and to maximize the likelihood of your contribution being merged.**\n\n## Bug Reports\n\nFor bug reports or requests [submit an issue](https://github.com/donnemartin/interactive-coding-challenges/issues).\n\n## Pull Requests\n\n**Please follow the general [Repo Structure](https://github.com/donnemartin/interactive-coding-challenges#repo-structure) and [Notebook Structure](https://github.com/donnemartin/interactive-coding-challenges#notebook-structure) before submitting your pull request.**\n\nThe preferred way to contribute is to fork the\n[main repository](https://github.com/donnemartin/interactive-coding-challenges) on GitHub.\n\n1. Fork the [main repository](https://github.com/donnemartin/interactive-coding-challenges).  Click on the 'Fork' button near the top of the page.  This creates a copy of the code under your account on the GitHub server.\n\n2. Clone this copy to your local disk:\n\n        $ git clone git@github.com:YourLogin/interactive-coding-challenges.git\n        $ cd interactive-coding-challenges\n\n3. Create a branch to hold your changes and start making changes. Don't work in the ``master`` branch!\n\n        $ git checkout -b my-feature\n\n4. Work on this copy on your computer using Git to do the version control. When you're done editing, run the following to record your changes in Git:\n\n        $ git add modified_files\n        $ git commit\n\n5. Push your changes to GitHub with:\n\n        $ git push -u origin my-feature\n\n6. Finally, go to the web page of your fork of the interactive-coding-challenges repo and click 'Pull request' to send your changes for review.\n\n**Please submit one pull request per challenge.**\n\n### GitHub Pull Requests Docs\n\nIf you are not familiar with pull requests, review the [pull request docs](https://help.github.com/articles/using-pull-requests/).\n\n### Notebook Installation\n\nRefer to [Accessing the Challenges](https://github.com/donnemartin/interactive-coding-challenges#accessing-the-challenges), [Notebook Installation](https://github.com/donnemartin/interactive-coding-challenges#notebook-installation), and [Nose Installation](https://github.com/donnemartin/interactive-coding-challenges#nose-installation) to set up your local environment.\n\n### Adding New Solutions to Existing Challenges\n\nChallenges have multiple solutions.  If adding new solutions to existing challenges:\n* Add your algorithm discussion and code solution to the existing notebook\n* Update the unit test to include your solution\n* Verify your code passes the unit tests\n\n### Adding New Challenges\n\nThe README contains several sample challenges that are not yet implemented.\n* The sample challenges are only suggestions, please do not limit yourself to only these topics\n* Feel free to send pull requests on different challenges or categories of challenges\n* Try to keep the \"Challenge\" title relatively short and expand on the details within the notebook\n* Review the [Repo Structure](https://github.com/donnemartin/interactive-coding-challenges#repo-structure) and [Notebook Structure](https://github.com/donnemartin/interactive-coding-challenges#notebook-structure) sections\n* Check out the [template challenge and solution notebooks](https://github.com/donnemartin/interactive-coding-challenges/tree/master/templates) to help you get started\n\n| Challenge | Static Notebooks |\n|--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|\n| Check if a number is prime | [Contribute](https://github.com/donnemartin/interactive-coding-challenges#contributing)│[Contribute](https://github.com/donnemartin/interactive-coding-challenges#contributing) |\n| Generate a list of primes | [Contribute](https://github.com/donnemartin/interactive-coding-challenges#contributing)│[Contribute](https://github.com/donnemartin/interactive-coding-challenges#contributing) |\n\nUpdate the list of challenges in the README so we can enjoy your challenge!\n\n### Update Notebook Author(s)\n\nWhen contributing to a notebook, update the notebook author(s):\n\n<small><i>This notebook was prepared by [Joe](https://github.com/) and [Jane](https://github.com/). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).</i></small>\n\n### Maintain Consistent Style\n\nPlease refer to the style of existing notebooks to help maintain consistency.  A consistently themed collection of notebooks will help users more seamlessly transition from challenge to challenge.\n\nReview the following [style guide](https://google.github.io/styleguide/pyguide.html).\n\nReview [PEP8](https://www.python.org/dev/peps/pep-0008/) and use a [validator](http://pep8online.com/).\n\n*Note: IPython Notebook doesn't seem to properly handle a blank line at the end of a code cell when writing the cell's contents to a file, as referenced in this [issue](https://github.com/ipython/ipython/issues/8626).  Notebook cells currently do not have a blank line at the end of each code cell.*\n\n### Contributions in Languages Other than Python\n\nFeel free to share your thoughts on how we could best approach adding challenges in other [supported languages](https://github.com/ipython/ipython/wiki/IPython-kernels-for-other-languages):\n* Repo structure\n* README challenge list\n* Installation instructions\n* Etc\n\nShare your thoughts in this [issue](https://github.com/donnemartin/interactive-coding-challenges/issues/3)."
  },
  {
    "path": "LICENSE",
    "content": "I am providing code and resources in this repository to you under an open source\nlicense.  Because this is my personal repository, the license you receive to my\ncode and resources is from me and not my employer (Facebook).\n\nCopyright 2015 Donne Martin\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License."
  },
  {
    "path": "README.md",
    "content": "<br/>\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/donnemartin/interactive-coding-challenges/master/images/cover_challenge.gif\">\n</p>\n\ninteractive-coding-challenges\n============\n\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/donnemartin/interactive-coding-challenges/master)\n\n**120+ continually updated, interactive, and test-driven coding challenges**, with [Anki flashcards](#anki-flashcards-coding-and-design).\n\nChallenges focus on **algorithms** and **data structures** found in **coding interviews**.\n\nEach challenge has one or more reference solutions that are:\n\n* Fully functional\n* Unit tested\n* Easy-to-understand\n\nChallenges will soon provide on-demand [incremental hints](https://github.com/donnemartin/interactive-coding-challenges/issues/22) to help you arrive at the optimal solution.\n\nNotebooks also detail:\n\n* Constraints\n* Test cases\n* Algorithms\n* Big-O time and space complexities\n\nAlso included are **unit tested reference implementations** of various [data structures](#reference-implementations-data-structures) and [algorithms](#reference-implementations-algorithms).\n\n## Challenge Solutions\n\n<br/>\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/donnemartin/interactive-coding-challenges/master/images/cover_solution.gif\">\n</p>\n<br/>\n\n## Anki Flashcards: Coding and Design\n\n<p align=\"center\">\n  <img src=\"http://i.imgur.com/b4YtAEN.png\">\n  <br/>\n</p>\n\nThe provided [Anki flashcard deck](https://apps.ankiweb.net/) uses spaced repetition to help you retain key concepts.\n\n* [Coding deck](anki_cards/Coding.apkg)\n\nGreat for use while on-the-go.\n\n### Design Resource: The System Design Primer\n\nLooking for resources to help you prep for the **System Design** and **Object-Oriented Design interviews**?\n\n<p align=\"center\">\n  <img src=\"http://i.imgur.com/zdCAkB3.png\">\n  <br/>\n</p>\n\nCheck out the sister repo [The System Design Primer](https://github.com/donnemartin/system-design-primer), which contains additional Anki decks:\n\n* [System design deck](https://github.com/donnemartin/system-design-primer/blob/master/resources/flash_cards/System%20Design.apkg)\n* [System design exercises deck](https://github.com/donnemartin/system-design-primer/blob/master/resources/flash_cards/System%20Design%20Exercises.apkg)\n* [Object oriented design exercises deck](https://github.com/donnemartin/system-design-primer/blob/master/resources/flash_cards/OO%20Design.apkg)\n\n![](https://camo.githubusercontent.com/e45e39c36eebcc4c66e1aecd4e4145112d8e88e3/687474703a2f2f692e696d6775722e636f6d2f6a6a3341354e382e706e67)\n\n## Notebook Structure\n\nEach challenge has two notebooks, a **challenge notebook** with unit tests for you to solve and a **solution notebook** for reference.\n\n### Problem Statement\n\n* States the problem to solve.\n\n### Constraints\n\n* Describes any constraints or assumptions.\n\n### Test Cases\n\n* Describes the general and edge test cases that will be evaluated in the unit test.\n\n### Algorithm\n\n* [Challenge Notebook] Empty, refer to the solution notebook algorithm section if you need a hint.\n* [Solution Notebook] One or more algorithm solution discussions, with Big-O time and space complexities.\n\n### Hints\n\n* [Challenge Notebook] Provides on-demand [incremental hints](https://github.com/donnemartin/interactive-coding-challenges/issues/22) to help you arrive at the optimal solution.  Coming soon!\n\n### Code (Challenge: Implement Me!)\n\n* [Challenge Notebook] Skeleton code for you to implement.\n* [Solution Notebook] One or more reference solutions.\n\n### Unit Test\n\n* [Challenge Notebook] Unit test for your code.  Expected to fail until you solve the challenge.\n* [Solution Notebook] Unit test for the reference solution(s).\n\n## Index\n\n### Challenges Categories\n\n**Format**: Challenge Category - Number of Challenges\n\n* [Arrays and Strings](#arrays-and-strings) - 10\n* [Linked Lists](#linked-lists) - 8\n* [Stacks and Queues](#stacks-and-queues) - 8\n* [Graphs and Trees](#graphs-and-trees) - 21\n* [Sorting](#sorting) - 10\n* [Recursion and Dynamic Programming](#recursion-and-dynamic-programming) - 17\n* [Mathematics and Probability](#mathematics-and-probability) - 6\n* [Bit Manipulation](#bit-manipulation) - 8\n* [Online Judges](#online-judges) - 16\n* [System Design](https://github.com/donnemartin/system-design-primer#system-design-interview-questions-with-solutions) - 8\n* [Object Oriented Design](https://github.com/donnemartin/system-design-primer#object-oriented-design-interview-questions-with-solutions) - 8\n\n**Total number of challenges: 120**\n\n### Reference Implementations: Data Structures\n\nUnit tested, fully functional implementations of the following data structures:\n\n* [Linked List](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/linked_list/linked_list_solution.ipynb)\n* [Stack](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/stack/stack_solution.ipynb)\n* [Queue](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/queue_list/queue_list_solution.ipynb)\n* [Binary Search Tree](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst/bst_solution.ipynb)\n* [Graph](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph/graph_solution.ipynb)\n* [Min Heap](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/min_heap/min_heap_solution.ipynb)\n* [Trie](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/trie/trie_solution.ipynb)\n* [Priority Queue](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/priority_queue/priority_queue_solution.ipynb)\n* [Hash Map](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/hash_map/hash_map_solution.ipynb)\n\n### Reference Implementations: Algorithms\n\nUnit tested, fully functional implementations of the following algorithms:\n\n* [Selection Sort](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/selection_sort/selection_sort_solution.ipynb)\n* [Insertion Sort](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/insertion_sort/insertion_sort_solution.ipynb)\n* [Quick Sort](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/quick_sort/quick_sort_solution.ipynb)\n* [Merge Sort](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/merge_sort/merge_sort_solution.ipynb)\n* [Radix Sort](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/radix_sort/radix_sort_solution.ipynb)\n* [Topological Sort](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_build_order/build_order_solution.ipynb)\n* [Tree Depth-First Search (Pre-, In-, Post-Order)](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_dfs/dfs_solution.ipynb)\n* [Tree Breadth-First Search](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_bfs/bfs_solution.ipynb)\n* [Graph Depth-First Search](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_dfs/dfs_solution.ipynb)\n* [Graph Breadth-First Search](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_bfs/bfs_solution.ipynb)\n* [Dijkstra's Shortest Path](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_shortest_path/graph_shortest_path_solution.ipynb)\n* [Unweighted Graph Shortest Path](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_shortest_path_unweighted/shortest_path_solution.ipynb)\n* [Knapsack 0/1](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/knapsack_01/knapsack_solution.ipynb)\n* [Knapsack Unbounded](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/knapsack_unbounded/knapsack_unbounded_solution.ipynb)\n* [Sieve of Eratosthenes](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/math_probability/generate_primes/check_prime_solution.ipynb)\n\n### Reference Implementations: TODO\n\n* [A*](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)\n* [Bellman-Ford](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)\n* [Bloom Filter](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)\n* [Convex Hull](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)\n* [Fisher-Yates Shuffle](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)\n* [Kruskal's](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)\n* [Max Flow](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)\n* [Prim's](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)\n* [Rabin-Karp](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)\n* [Traveling Salesman](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)\n* [Union Find](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)\n* [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)\n\n### Installing and Running Challenges\n\n* [Repo Structure](#repo-structure)\n* [Notebook Installation](#notebook-installation)\n* [Running Challenges](#running-challenges)\n\n### Misc\n\n* [Contributing](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md)\n* [Credits](#credits)\n* [Contact Info](#contact-info)\n* [License](#license)\n\n## Challenges\n\n[Image Credits](#credits)\n\n<br/>\n<p>\n  <img src=\"https://raw.githubusercontent.com/donnemartin/interactive-coding-challenges/master/images/arrays_nltk.png\">\n</p>\n<br/>\n\n### Arrays and Strings\n\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/donnemartin/interactive-coding-challenges/master)\n\n| Challenge | Static Notebook |\n|--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|\n| Determine if a string contains unique characters | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/unique_chars/unique_chars_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/unique_chars/unique_chars_solution.ipynb) |\n| Determine if a string is a permutation of another | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/permutation/permutation_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/permutation/permutation_solution.ipynb) |\n| Determine if a string is a rotation of another | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/rotation/rotation_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/rotation/rotation_solution.ipynb) |\n| 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) |\n| 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) |\n| Given two strings, find the single different char | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/str_diff/str_diff_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/str_diff/str_diff_solution.ipynb) |\n| Find two indices that sum to a specific value | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/two_sum/two_sum_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/two_sum/two_sum_solution.ipynb) |\n| 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) |\n| 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) |\n| 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) |\n| 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) |\n| 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) |\n| Convert a string to an integer | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Convert an integer to 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) |\n| Add a challenge | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n\n<br/>\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/donnemartin/interactive-coding-challenges/master/images/linked_lists_wikipedia.png\">\n</p>\n<br/>\n\n### Linked Lists\n\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/donnemartin/interactive-coding-challenges/master)\n\n| Challenge | Static Notebook |\n|--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|\n| Remove duplicates from a linked list | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/remove_duplicates/remove_duplicates_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/remove_duplicates/remove_duplicates_solution.ipynb) |\n| Find the kth to last element of a linked list | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/kth_to_last_elem/kth_to_last_elem_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/kth_to_last_elem/kth_to_last_elem_solution.ipynb) |\n| Delete a node in the middle of a linked list | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/delete_mid/delete_mid_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/delete_mid/delete_mid_solution.ipynb) |\n| Partition a linked list around a given value | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/partition/partition_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/partition/partition_solution.ipynb) |\n| Add two numbers whose digits are stored in a linked list | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/add_reverse/add_reverse_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/add_reverse/add_reverse_solution.ipynb) |\n| Find the start of a linked list loop | [Challenge](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/find_loop_start/find_loop_start_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/find_loop_start/find_loop_start_solution.ipynb) |\n| Determine if a linked list is a palindrome | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/palindrome/palindrome_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/palindrome/palindrome_solution.ipynb) |\n| Implement a linked list | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/linked_list/linked_list_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/linked_list/linked_list_solution.ipynb) |\n| Determine if a list is cyclic or acyclic | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Add a challenge | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n\n<br/>\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/donnemartin/interactive-coding-challenges/master/images/stack_queue_wikipedia.png\">\n</p>\n<br/>\n\n### Stacks and Queues\n\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/donnemartin/interactive-coding-challenges/master)\n\n| Challenge | Static Notebook |\n|--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|\n| Implement n stacks using a single array | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/n_stacks/n_stacks_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/n_stacks/n_stacks_solution.ipynb) |\n| Implement a stack that keeps track of its minimum element | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/stack_min/stack_min_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/stack_min/stack_min_solution.ipynb) |\n| Implement a set of stacks class that wraps a list of capacity-bounded stacks | [Challenge](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/set_of_stacks/set_of_stacks_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/set_of_stacks/set_of_stacks_solution.ipynb) |\n| Implement a queue using two stacks | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/queue_from_stacks/queue_from_stacks_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/queue_from_stacks/queue_from_stacks_solution.ipynb) |\n| Sort a stack using another stack as a buffer | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/sort_stack/sort_stack_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/sort_stack/sort_stack_solution.ipynb) |\n| Implement a stack | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/stack/stack_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/stack/stack_solution.ipynb) |\n| Implement a queue | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/queue_list/queue_list_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/queue_list/queue_list_solution.ipynb) |\n| Implement a priority queue backed by an array | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/priority_queue/priority_queue_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/priority_queue/priority_queue_solution.ipynb) |\n| Add a challenge | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n\n<br/>\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/donnemartin/interactive-coding-challenges/master/images/binary_tree_wikipedia.png\">\n</p>\n<br/>\n\n### Graphs and Trees\n\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/donnemartin/interactive-coding-challenges/master)\n\n| Challenge | Static Notebooks |\n|--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|\n| Implement depth-first search (pre-, in-, post-order) on a tree |  [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_dfs/dfs_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_dfs/dfs_solution.ipynb) |\n| Implement breadth-first search on a tree | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_bfs/bfs_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_bfs/bfs_solution.ipynb) |\n| Determine the height of a tree | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_height/height_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_height/height_solution.ipynb) |\n| Create a binary search tree with minimal height from a sorted array | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_min/bst_min_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_min/bst_min_solution.ipynb) |\n| Create a linked list for each level of a binary tree | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_level_lists/tree_level_lists_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_level_lists/tree_level_lists_solution.ipynb) |\n| Check if a binary tree is balanced | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/check_balance/check_balance_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/check_balance/check_balance_solution.ipynb) |\n| Determine if a tree is a valid binary search tree | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_validate/bst_validate_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_validate/bst_validate_solution.ipynb) |\n| Find the in-order successor of a given node in a binary search tree | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_successor/bst_successor_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_successor/bst_successor_solution.ipynb) |\n| Find the second largest node in a binary search tree | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_second_largest/bst_second_largest_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_second_largest/bst_second_largest_solution.ipynb) |\n| Find the lowest common ancestor | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_lca/tree_lca_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_lca/tree_lca_solution.ipynb) |\n| Invert a binary tree | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/invert_tree/invert_tree_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/invert_tree/invert_tree_solution.ipynb) |\n| Implement a binary search tree | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst/bst_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst/bst_solution.ipynb) |\n| Implement a min heap | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/min_heap/min_heap_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/min_heap/min_heap_solution.ipynb) |\n| Implement a trie | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/trie/trie_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/trie/trie_solution.ipynb) |\n| Implement depth-first search on a graph |  [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_dfs/dfs_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_dfs/dfs_solution.ipynb) |\n| Implement breadth-first search on a graph | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_bfs/bfs_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_bfs/bfs_solution.ipynb) |\n| Determine if there is a path between two nodes in a graph | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_path_exists/path_exists_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_path_exists/path_exists_solution.ipynb) |\n| Implement a graph | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph/graph_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph/graph_solution.ipynb) |\n| Find a build order given a list of projects and dependencies. |  [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_build_order/build_order_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_build_order/build_order_solution.ipynb) |\n| Find the shortest path in a weighted graph. |  [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_shortest_path/graph_shortest_path_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_shortest_path/graph_shortest_path_solution.ipynb) |\n| Find the shortest path in an unweighted graph. |  [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_shortest_path_unweighted/shortest_path_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_shortest_path_unweighted/shortest_path_solution.ipynb) |\n| Add a challenge | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n\n<br/>\n<p align=\"center\">\n  <img src=\"https://upload.wikimedia.org/wikipedia/commons/6/6a/Sorting_quicksort_anim.gif\">\n</p>\n<br/>\n\n### Sorting\n\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/donnemartin/interactive-coding-challenges/master)\n\n| Challenge | Static Notebooks |\n|--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|\n| Implement selection sort | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/selection_sort/selection_sort_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/selection_sort/selection_sort_solution.ipynb) |\n| Implement insertion sort | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/insertion_sort/insertion_sort_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/insertion_sort/insertion_sort_solution.ipynb) |\n| Implement quick sort | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/quick_sort/quick_sort_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/quick_sort/quick_sort_solution.ipynb) |\n| Implement merge sort | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/merge_sort/merge_sort_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/merge_sort/merge_sort_solution.ipynb) |\n| Implement radix sort | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/radix_sort/radix_sort_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/radix_sort/radix_sort_solution.ipynb) |\n| Sort an array of strings so all anagrams are next to each other | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/anagrams/anagrams_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/anagrams/anagrams_solution.ipynb) |\n| Find an item in a sorted, rotated array | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/rotated_array_search/rotated_array_search_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/rotated_array_search/rotated_array_search_solution.ipynb) |\n| Search a sorted matrix for an item | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/search_sorted_matrix/search_sorted_matrix_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/search_sorted_matrix/search_sorted_matrix_solution.ipynb) |\n| Find an int not in an input of n integers | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/new_int/new_int_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/new_int/new_int_solution.ipynb) |\n|  Given sorted arrays A, B, merge B into A in sorted order | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/merge_into/merge_into_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/merge_into/merge_into_solution.ipynb) |\n| Implement a stable selection sort | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Make an unstable sort stable | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Implement an efficient, in-place version of quicksort | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Given two sorted arrays, merge one into the other in sorted order | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Find an element in a rotated and sorted array of integers | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Add a challenge | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n\n<br/>\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/donnemartin/interactive-coding-challenges/master/images/fibonacci_wikipedia.png\">\n</p>\n<br/>\n\n### Recursion and Dynamic Programming\n\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/donnemartin/interactive-coding-challenges/master)\n\n| Challenge | Static Notebooks |\n|--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|\n| Implement fibonacci recursively, dynamically, and iteratively | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/fibonacci/fibonacci_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/fibonacci/fibonacci_solution.ipynb) |\n| Maximize items placed in a knapsack | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/knapsack_01/knapsack_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/knapsack_01/knapsack_solution.ipynb) |\n| Maximize unbounded items placed in a knapsack | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/knapsack_unbounded/knapsack_unbounded_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/knapsack_unbounded/knapsack_unbounded_solution.ipynb) |\n| Find the longest common subsequence | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/longest_common_subsequence/longest_common_subseq_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/longest_common_subsequence/longest_common_subseq_solution.ipynb) |\n| Find the longest increasing subsequence | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/longest_inc_subseq/longest_inc_subseq_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/longest_inc_subseq/longest_inc_subseq_solution.ipynb) |\n| Minimize the cost of matrix multiplication | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/matrix_mult/find_min_cost_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/matrix_mult/find_min_cost_solution.ipynb) |\n| Maximize stock prices given k transactions | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/max_profit_k/max_profit_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/max_profit_k/max_profit_solution.ipynb) |\n| Find the minimum number of ways to represent n cents given an array of coins | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/coin_change_min/coin_change_min_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/coin_change_min/coin_change_min_solution.ipynb) |\n| Find the unique number of ways to represent n cents given an array of coins | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/coin_change/coin_change_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/coin_change/coin_change_solution.ipynb) |\n| Print all valid combinations of n-pairs of parentheses | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_solution.ipynb) |\n| Navigate a maze | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/grid_path/grid_path_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/grid_path/grid_path_solution.ipynb) |\n| Print all subsets of a set | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/power_set/power_set_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/power_set/power_set_solution.ipynb) |\n| Print all permutations of a string | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/permutations/permutations_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/permutations/permutations_solution.ipynb) |\n| Find the magic index in an array | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/magic_index/magic_index_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/magic_index/magic_index_solution.ipynb) |\n| Find the number of ways to run up n steps | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/steps/steps_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/steps/steps_solution.ipynb) |\n| Implement the Towers of Hanoi with 3 towers and N disks | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/hanoi/hanoi_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/hanoi/hanoi_solution.ipynb) |\n| Implement factorial recursively, dynamically, and iteratively | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Perform a binary search on a sorted array of integers | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Print all combinations of 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) |\n| Implement a paint fill function | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Find all permutations to represent n cents, given 1, 5, 10, 25 cent coins | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Add a challenge | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n\n<br/>\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/donnemartin/interactive-coding-challenges/master/images/probability_distribution_wikipedia.png\">\n</p>\n<br/>\n\n### Mathematics and Probability\n\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/donnemartin/interactive-coding-challenges/master)\n\n| Challenge | Static Notebooks |\n|--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|\n| Generate a list of primes | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/math_probability/generate_primes/check_prime_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/math_probability/generate_primes/check_prime_solution.ipynb) |\n| Find the digital root | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/math_probability/add_digits/add_digits_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/math_probability/add_digits/add_digits_solution.ipynb) |\n| Create a class supporting insert, max, min, mean, mode in O(1) | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/math_probability/math_ops/math_ops_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/math_probability/math_ops/math_ops_solution.ipynb) |\n| Determine if a number is a power of two | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/math_probability/power_two/power_two_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/math_probability/power_two/power_two_solution.ipynb) |\n| Add two numbers without the + or - sign | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/math_probability/sum_two/sum_two_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/math_probability/sum_two/sum_two_solution.ipynb) |\n| Subtract two numbers without the + or - sign | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/math_probability/sub_two/sub_two_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/math_probability/sub_two/sub_two_solution.ipynb) |\n| Check if a number is prime | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Determine if two lines on a Cartesian plane intersect | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Using only add, implement multiply, subtract, and divide for ints | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Find the kth number such that the only prime factors are 3, 5, and 7 | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Add a challenge | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n\n<br/>\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/donnemartin/interactive-coding-challenges/master/images/bit_manipulation_wikipedia.png\">\n</p>\n<br/>\n\n### Bit Manipulation\n\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/donnemartin/interactive-coding-challenges/master)\n\n| Challenge | Static Notebooks |\n|--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|\n| Implement common bit manipulation operations | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/bit/bit_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/bit/bit_solution.ipynb) |\n| Determine number of bits to flip to convert a into b | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/bits_to_flip/bits_to_flip_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/bits_to_flip/bits_to_flip_solution.ipynb) |\n| Draw a line on a screen | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/draw_line/draw_line_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/draw_line/draw_line_solution.ipynb) |\n| Flip a bit to maximize the longest sequence of 1s | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/flip_bit/flip_bit_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/flip_bit/flip_bit_solution.ipynb) |\n| Get the next largest and next smallest numbers | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/get_next/get_next_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/get_next/get_next_solution.ipynb) |\n| Merge two binary numbers | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/insert_m_into_n/insert_m_into_n_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/insert_m_into_n/insert_m_into_n_solution.ipynb) |\n| Swap odd and even bits in an integer | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/pairwise_swap/pairwise_swap_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/pairwise_swap/pairwise_swap_solution.ipynb) |\n| Print the binary representation of a number between 0 and 1 | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/print_binary/print_binary_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/bit_manipulation/print_binary/print_binary_solution.ipynb) |\n| Determine the number of 1s in the binary representation of a given integer | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n| Add a challenge | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n\n<br/>\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/donnemartin/interactive-coding-challenges/master/images/logo_topcoder.png\">\n</p>\n<br/>\n\n### Online Judges\n\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/donnemartin/interactive-coding-challenges/master)\n\n| Challenge | Static Notebooks |\n|--------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|\n| Find the longest substring with at most k distinct chars | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/longest_substr_k_distinct/longest_substr_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/longest_substr_k_distinct/longest_substr_solution.ipynb) |\n| Find the highest product of three numbers | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/prod_three/prod_three_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/prod_three/prod_three_solution.ipynb) |\n| Maximize stocks profit from 1 buy and 1 sell | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/max_profit/max_profit_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/max_profit/max_profit_solution.ipynb) |\n| Move all zeroes in a list to the end | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/move_zeroes/move_zeroes_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/move_zeroes/move_zeroes_solution.ipynb) |\n| Find the products of every other int | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/mult_other_numbers/mult_other_numbers_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/mult_other_numbers/mult_other_numbers_solution.ipynb) |\n| Given a list of entries and exits, find the busiest period | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/busiest_period/busiest_period_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/busiest_period/busiest_period_solution.ipynb) |\n| Determine an island's perimeter | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/island_perimeter/island_perimeter_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/island_perimeter/island_perimeter_solution.ipynb) |\n| Format license keys | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/license_key/format_license_key_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/license_key/format_license_key_solution.ipynb) |\n| Find the longest absolute file path | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/longest_abs_file_path/longest_path_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/longest_abs_file_path/longest_path_solution.ipynb) |\n| Merge tuple ranges | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/merge_ranges/merge_ranges_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/merge_ranges/merge_ranges_solution.ipynb) |\n| Assign cookies | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/assign_cookies/assign_cookies_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/assign_cookies/assign_cookies_solution.ipynb) |\n| Determine if you can win in Nim | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/nim/nim_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/nim/nim_solution.ipynb) |\n| Check if a magazine could have been used to create a ransom note | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/ransom_note/ransom_note_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/ransom_note/ransom_note_solution.ipynb) |\n| Find the number of times a sentence can fit on a screen | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/sentence_screen_fit/sentence_screen_fit_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/sentence_screen_fit/sentence_screen_fit_solution.ipynb) |\n| Utopian tree | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/utopian_tree/utopian_tree_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/utopian_tree/utopian_tree_solution.ipynb) |\n| Maximizing xor | [Challenge](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/maximizing_xor/maximizing_xor_challenge.ipynb) │ [Solution](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/online_judges/maximizing_xor/maximizing_xor_solution.ipynb) |\n| Add a challenge | [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) │ [Contribute](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) |\n\n## Repo Structure\n\n```\ninteractive-coding-challenges        # Repo\n├─ arrays_strings                    # Category of challenges\n│  ├─ rotation                       # Challenge folder\n│  │  ├─ rotation_challenge.ipynb    # Challenge notebook\n│  │  ├─ rotation_solution.ipynb     # Solution notebook\n│  │  ├─ test_rotation.py            # Unit test*\n│  ├─ compress\n│  │  ├─ compress_challenge.ipynb\n│  │  ├─ compress_solution.ipynb\n│  │  ├─ test_compress.py\n│  ├─ ...\n├─ linked_lists\n│  ├─ palindrome\n│  │  └─ ...\n│  ├─ ...\n├─ ...\n```\n\n<i>\\*The notebooks (.ipynb) read/write the associated unit test (.py) file.</i>\n\n\n## Notebook Installation\n\n### Zero Install\n\n[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/donnemartin/interactive-coding-challenges/master)\n\nThis README contains links to [Binder](https://mybinder.org/v2/gh/donnemartin/interactive-coding-challenges/master) , which hosts **dynamic notebooks** of the repo's contents online with no installation needed.\n\n### Jupyter Notebook\n\nRun:\n\n```\npip install jupyter\n```\n\nFor detailed instructions, scripts, and tools to more optimally set up your development environment, check out the [dev-setup](https://github.com/donnemartin/dev-setup) repo.\n\nFor more details on notebook installation, follow the directions [here](http://ipython.org/install.html).\n\nMore information on IPython/Jupyter Notebooks can be found [here](http://ipython.org/notebook.html).\n\n## Running Challenges\n\n### Notebooks\n\nChallenges are provided in the form of **IPython/Jupyter Notebooks** and have been **tested with Python 2.7 and Python 3.x**.\n\n*If you need to install IPython/Jupyter Notebook, see the [Notebook Installation](#notebook-installation) section.*\n\n* This README contains links to [nbviewer](http://nbviewer.ipython.org), which hosts **static notebooks** of the repo's contents\n* To interact with or to modify elements within the **dynamic notebooks**, refer to the instructions below\n\nRun the notebook of challenges:\n\n```\n$ git clone https://github.com/donnemartin/interactive-coding-challenges.git\n$ cd interactive-coding-challenges\n$ jupyter notebook\n```\n\nThis will launch your web browser with the list of challenge categories:\n\n* Navigate to the **Challenge Notebook** you wish to solve\n* Run the cells within the challenge notebook (Cell->Run All)\n    * This will result in an expected unit test error\n* Solve the challenge and verify it passes the unit test\n* Check out the accompanying **Solution Notebook** for further discussion\n\nTo **debug** your solution with pdb, refer to the following [ticket](https://github.com/donnemartin/interactive-coding-challenges/issues/11).\n\nNote: If your solution is different from those listed in the Solution Notebook, consider submitting a pull request so others can benefit from your work.  Review the [Contributing Guidelines](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) for details.\n\n## Future Development\n\nChallenges, solutions, and unit tests are presented in the form of **IPython/Jupyter Notebooks**.\n\n* Notebooks currently contain mostly Python solutions (tested on both Python 2.7 and Python 3.x), but can be extended to include [40+ supported languages](https://github.com/ipython/ipython/wiki/IPython-kernels-for-other-languages)\n* Repo will be **continually updated** with new solutions and challenges\n* [Contributions](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) are welcome!\n\n## Contributing\n\nContributions are welcome!\n\nReview the [Contributing Guidelines](https://github.com/donnemartin/interactive-coding-challenges/blob/master/CONTRIBUTING.md) for details on how to:\n\n* Submit issues\n* Add solutions to existing challenges\n* Add new challenges\n\n## Credits\n\n### Resources\n\n* [Cracking the Coding Interview](http://www.amazon.com/Cracking-Coding-Interview-Programming-Questions/dp/098478280X) | [GitHub Solutions](https://github.com/gaylemcd/ctci)\n* [Programming Interviews Exposed](http://www.amazon.com/gp/product/1118261364/)\n* [The Algorithm Design Manual](http://www.amazon.com/Algorithm-Design-Manual-Steve-Skiena/dp/0387948600) | [Solutions](http://www.algorithm.cs.sunysb.edu/algowiki/index.php/The_Algorithms_Design_Manual_(Second_Edition))\n* [CareerCup](http://www.careercup.com/)\n* [Quora](http://www.quora.com/)\n* [HackerRank](https://www.hackerrank.com)\n* [LeetCode](https://leetcode.com/)\n\n### Images\n\n* [Arrays and Strings: nltk.org](http://www.nltk.org/images/string-slicing.png)\n* [Linked Lists: wikipedia.org](https://upload.wikimedia.org/wikipedia/commons/6/6d/Singly-linked-list.svg)\n* [Stacks: wikipedia.org](https://upload.wikimedia.org/wikipedia/commons/2/29/Data_stack.svg)\n* [Queues: wikipedia.org](https://upload.wikimedia.org/wikipedia/commons/5/52/Data_Queue.svg)\n* [Sorting: wikipedia.org](https://upload.wikimedia.org/wikipedia/commons/6/6a/Sorting_quicksort_anim.gif)\n* [Recursion and Dynamic Programming: wikipedia.org](https://upload.wikimedia.org/wikipedia/commons/b/bf/PascalTriangleFibanacci.svg)\n* [Graphs and Trees: wikipedia.org](https://upload.wikimedia.org/wikipedia/commons/f/f7/Binary_tree.svg)\n* [Mathematics and Probability: wikipedia.org](https://upload.wikimedia.org/wikipedia/commons/d/d2/Gaussian_distribution_2.jpg)\n* [Bit Manipulation: wikipedia.org](https://upload.wikimedia.org/wikipedia/commons/5/5c/Rotate_left_logically.svg)\n* [Online Judges: topcoder.com](https://www.topcoder.com/wp-content/uploads/2014/05/topcoder_logo_home_sm.png)\n\n## Contact Info\n\nFeel free to contact me to discuss any issues, questions, or comments.\n\nMy contact info can be found on my [GitHub page](https://github.com/donnemartin).\n\n## License\n\n*I am providing code and resources in this repository to you under an open source license.  Because this is my personal repository, the license you receive to my code and resources is from me and not my employer (Facebook).*\n\n    Copyright 2015 Donne Martin\n\n    Licensed under the Apache License, Version 2.0 (the \"License\");\n    you may not use this file except in compliance with the License.\n    You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing, software\n    distributed under the License is distributed on an \"AS IS\" BASIS,\n    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n    See the License for the specific language governing permissions and\n    limitations under the License.\n"
  },
  {
    "path": "__init__.py",
    "content": ""
  },
  {
    "path": "arrays_strings/__init__.py",
    "content": ""
  },
  {
    "path": "arrays_strings/compress/__init__.py",
    "content": ""
  },
  {
    "path": "arrays_strings/compress/compress_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Compress a string such that 'AAABCCDDDD' becomes 'A3BC2D4'.  Only compress the string if it saves space.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the string is ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: Unicode strings could require special handling depending on your language\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we use additional data structures?  \\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> None\\n\",\n    \"* '' -> ''\\n\",\n    \"* 'AABBCC' -> 'AABBCC'\\n\",\n    \"* 'AAABCCDDDD' -> 'A3BC2D4'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/compress/compress_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class CompressString(object):\\n\",\n    \"\\n\",\n    \"    def compress(self, string):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_compress.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestCompress(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_compress(self, func):\\n\",\n    \"        self.assertEqual(func(None), None)\\n\",\n    \"        self.assertEqual(func(''), '')\\n\",\n    \"        self.assertEqual(func('AABBCC'), 'AABBCC')\\n\",\n    \"        self.assertEqual(func('AAABCCDDDDE'), 'A3BC2D4E')\\n\",\n    \"        self.assertEqual(func('BAAACCDDDD'), 'BA3C2D4')\\n\",\n    \"        self.assertEqual(func('AAABAACCDDDD'), 'A3BA2C2D4')\\n\",\n    \"        print('Success: test_compress')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestCompress()\\n\",\n    \"    compress_string = CompressString()\\n\",\n    \"    test.test_compress(compress_string.compress)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/compress/compress_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/compress/compress_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Compress a string such that 'AAABCCDDDD' becomes 'A3BC2D4'.  Only compress the string if it saves space.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the string is ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: Unicode strings could require special handling depending on your language\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we use additional data structures?  \\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> None\\n\",\n    \"* '' -> ''\\n\",\n    \"* 'AABBCC' -> 'AABBCC'\\n\",\n    \"* 'AAABCCDDDD' -> 'A3BC2D4'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* For each char in string\\n\",\n    \"    * If char is the same as last_char, increment count\\n\",\n    \"    * Else\\n\",\n    \"        * Append last_char and count to compressed_string\\n\",\n    \"        * last_char = char\\n\",\n    \"        * count = 1\\n\",\n    \"* Append last_char and count to compressed_string\\n\",\n    \"* If the compressed string size is < string size\\n\",\n    \"    * Return compressed string\\n\",\n    \"* Else\\n\",\n    \"    * Return string\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\\n\",\n    \"\\n\",\n    \"Complexity Note:\\n\",\n    \"* Although strings are immutable in Python, appending to strings is optimized in CPython so that it now runs in O(n) and extends the string in-place.  Refer to this [Stack Overflow post](http://stackoverflow.com/a/4435752).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class CompressString(object):\\n\",\n    \"\\n\",\n    \"    def compress(self, string):\\n\",\n    \"        if string is None or not string:\\n\",\n    \"            return string\\n\",\n    \"        result = ''\\n\",\n    \"        prev_char = string[0]\\n\",\n    \"        count = 0\\n\",\n    \"        for char in string:\\n\",\n    \"            if char == prev_char:\\n\",\n    \"                count += 1\\n\",\n    \"            else:\\n\",\n    \"                result += self._calc_partial_result(prev_char, count)\\n\",\n    \"                prev_char = char\\n\",\n    \"                count = 1\\n\",\n    \"        result += self._calc_partial_result(prev_char, count)\\n\",\n    \"        return result if len(result) < len(string) else string\\n\",\n    \"\\n\",\n    \"    def _calc_partial_result(self, prev_char, count):\\n\",\n    \"        return prev_char + (str(count) if count > 1 else '')\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_compress.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_compress.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestCompress(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_compress(self, func):\\n\",\n    \"        self.assertEqual(func(None), None)\\n\",\n    \"        self.assertEqual(func(''), '')\\n\",\n    \"        self.assertEqual(func('AABBCC'), 'AABBCC')\\n\",\n    \"        self.assertEqual(func('AAABCCDDDDE'), 'A3BC2D4E')\\n\",\n    \"        self.assertEqual(func('BAAACCDDDD'), 'BA3C2D4')\\n\",\n    \"        self.assertEqual(func('AAABAACCDDDD'), 'A3BA2C2D4')\\n\",\n    \"        print('Success: test_compress')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestCompress()\\n\",\n    \"    compress_string = CompressString()\\n\",\n    \"    test.test_compress(compress_string.compress)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_compress\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_compress.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/compress/test_compress.py",
    "content": "import unittest\n\n\nclass TestCompress(unittest.TestCase):\n\n    def test_compress(self, func):\n        self.assertEqual(func(None), None)\n        self.assertEqual(func(''), '')\n        self.assertEqual(func('AABBCC'), 'AABBCC')\n        self.assertEqual(func('AAABCCDDDDE'), 'A3BC2D4E')\n        self.assertEqual(func('BAAACCDDDD'), 'BA3C2D4')\n        self.assertEqual(func('AAABAACCDDDD'), 'A3BA2C2D4')\n        print('Success: test_compress')\n\n\ndef main():\n    test = TestCompress()\n    compress_string = CompressString()\n    test.test_compress(compress_string.compress)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "arrays_strings/compress_alt/__init__.py",
    "content": ""
  },
  {
    "path": "arrays_strings/compress_alt/better_compress_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [hashhar](https://github.com/hashhar). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Compress a string such that 'AAABCCDDDD' becomes 'A3BCCD4'.  Only compress the string if it saves space.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the string is ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: Unicode strings could require special handling depending on your language\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we use additional data structures?  \\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> None\\n\",\n    \"* '' -> ''\\n\",\n    \"* 'AABBCC' -> 'AABBCC'\\n\",\n    \"* 'AAABCCDDDD' -> 'A3BCCD4'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/compress_alt/better_compress_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def compress_string(string):\\n\",\n    \"    # TODO: Implement me\\n\",\n    \"    pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_compress.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestCompress(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_compress(self, func):\\n\",\n    \"        self.assertEqual(func(None), None)\\n\",\n    \"        self.assertEqual(func(''), '')\\n\",\n    \"        self.assertEqual(func('AABBCC'), 'AABBCC')\\n\",\n    \"        self.assertEqual(func('AAABCCDDDD'), 'A3BCCD4')\\n\",\n    \"        self.assertEqual(\\n\",\n    \"            func('aaBCCEFFFFKKMMMMMMP taaammanlaarrrr seeeeeeeeek tooo'),\\n\",\n    \"            'aaBCCEF4KKM6P ta3mmanlaar4 se9k to3',\\n\",\n    \"        )\\n\",\n    \"        print('Success: test_compress')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestCompress()\\n\",\n    \"    test.test_compress(compress_string)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/compress_alt/better_compress_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/compress_alt/better_compress_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [hashhar](https://github.com/hashhar), second solution added by [janhak](https://github.com/janhak). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Compress a string such that 'AAABCCDDDD' becomes 'A3BCCD4'.  Only compress the string if it saves space.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the string is ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: Unicode strings could require special handling depending on your language\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we use additional data structures?  \\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> None\\n\",\n    \"* '' -> ''\\n\",\n    \"* 'AABBCC' -> 'AABBCC'\\n\",\n    \"* 'AAABCCDDDD' -> 'A3BCCD4'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Since Python strings are immutable, we'll use a list of characters to build the compressed string representation.  We'll then convert the list to a string.\\n\",\n    \"\\n\",\n    \"* Calculate the size of the compressed string\\n\",\n    \"    * Note the constraint about compressing only if it saves space\\n\",\n    \"* If the compressed string size is >= string size, return string\\n\",\n    \"* Create compressed_string\\n\",\n    \"    * For each char in string\\n\",\n    \"        * If char is the same as last_char, increment count\\n\",\n    \"        * Else\\n\",\n    \"            * If the count is more than 2\\n\",\n    \"                * Append last_char to compressed_string\\n\",\n    \"                * append count to compressed_string\\n\",\n    \"                * count = 1\\n\",\n    \"                * last_char = char\\n\",\n    \"            * If count is 1\\n\",\n    \"                * Append last_char to compressed_string\\n\",\n    \"                * count = 1\\n\",\n    \"                * last_char = char\\n\",\n    \"            * If count is 2\\n\",\n    \"                * Append last_char to compressed_string\\n\",\n    \"                * Append last_char to compressed_string once more\\n\",\n    \"                * count = 1\\n\",\n    \"                * last_char = char\\n\",\n    \"        * Append last_char to compressed_string\\n\",\n    \"        * Append count to compressed_string\\n\",\n    \"    * Return compressed_string\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def compress_string(string):\\n\",\n    \"    if string is None or len(string) == 0:\\n\",\n    \"        return string\\n\",\n    \"\\n\",\n    \"    # Calculate the size of the compressed string\\n\",\n    \"    size = 0\\n\",\n    \"    last_char = string[0]\\n\",\n    \"    for char in string:\\n\",\n    \"        if char != last_char:\\n\",\n    \"            size += 2\\n\",\n    \"            last_char = char\\n\",\n    \"    size += 2\\n\",\n    \"\\n\",\n    \"    # If the compressed string size is greater than\\n\",\n    \"    # or equal to string size, return original string\\n\",\n    \"    if size >= len(string):\\n\",\n    \"        return string\\n\",\n    \"\\n\",\n    \"    # Create compressed_string\\n\",\n    \"    # New objective:\\n\",\n    \"    # Single characters are to be left as is\\n\",\n    \"    # Double characters are to be left as are\\n\",\n    \"    compressed_string = list()\\n\",\n    \"    count = 0\\n\",\n    \"    last_char = string[0]\\n\",\n    \"    for char in string:\\n\",\n    \"        if char == last_char:\\n\",\n    \"            count += 1\\n\",\n    \"        else:\\n\",\n    \"            # Do the old compression tricks only if count exceeds two\\n\",\n    \"            if count > 2:\\n\",\n    \"                compressed_string.append(last_char)\\n\",\n    \"                compressed_string.append(str(count))\\n\",\n    \"                count = 1\\n\",\n    \"                last_char = char\\n\",\n    \"            # If count is either 1 or 2\\n\",\n    \"            else:\\n\",\n    \"                # If count is 1, leave the char as is\\n\",\n    \"                if count == 1:\\n\",\n    \"                    compressed_string.append(last_char)\\n\",\n    \"                    count = 1\\n\",\n    \"                    last_char = char\\n\",\n    \"                # If count is 2, append the character twice\\n\",\n    \"                else:\\n\",\n    \"                    compressed_string.append(last_char)\\n\",\n    \"                    compressed_string.append(last_char)\\n\",\n    \"                    count = 1\\n\",\n    \"                    last_char = char\\n\",\n    \"    compressed_string.append(last_char)\\n\",\n    \"    compressed_string.append(str(count))\\n\",\n    \"\\n\",\n    \"    # Convert the characters in the list to a string\\n\",\n    \"    return \\\"\\\".join(compressed_string)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm: Split to blocks and compress\\n\",\n    \"\\n\",\n    \"Let us split the string first into blocks of identical characters and then compress it block by block.\\n\",\n    \"\\n\",\n    \"* Split the string to blocks\\n\",\n    \"    * For each character in string\\n\",\n    \"        * Add this character to block\\n\",\n    \"        * If the next character is different\\n\",\n    \"            * Return block\\n\",\n    \"            * Erase the content of block\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"* Compress block\\n\",\n    \"    *  If block consists of two or fewer characters\\n\",\n    \"        * Return block\\n\",\n    \"    * Else\\n\",\n    \"        * Append length of the block to the first character and return\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"* Compress string\\n\",\n    \"    * Split the string to blocks\\n\",\n    \"    * Compress blocks\\n\",\n    \"    * Join compressed blocks\\n\",\n    \"    * Return result if it is shorter than original string\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def split_to_blocks(string):\\n\",\n    \"    block = ''\\n\",\n    \"    for char, next_char in zip(string, string[1:] + ' '):\\n\",\n    \"        block += char\\n\",\n    \"        if char is not next_char:\\n\",\n    \"            yield block\\n\",\n    \"            block = ''\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def compress_block(block):\\n\",\n    \"    if len(block) <= 2:\\n\",\n    \"        return block\\n\",\n    \"    else:\\n\",\n    \"        return block[0] + str(len(block))\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def compress_string(string):\\n\",\n    \"    if string is None or not string:\\n\",\n    \"        return string\\n\",\n    \"    compressed = (compress_block(block) for block in split_to_blocks(string))\\n\",\n    \"    result = ''.join(compressed)\\n\",\n    \"    return result if len(result) < len(string) else string\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_compress.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_compress.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestCompress(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_compress(self, func):\\n\",\n    \"        self.assertEqual(func(None), None)\\n\",\n    \"        self.assertEqual(func(''), '')\\n\",\n    \"        self.assertEqual(func('AABBCC'), 'AABBCC')\\n\",\n    \"        self.assertEqual(func('AAABCCDDDD'), 'A3BCCD4')\\n\",\n    \"        self.assertEqual(\\n\",\n    \"            func('aaBCCEFFFFKKMMMMMMP taaammanlaarrrr seeeeeeeeek tooo'),\\n\",\n    \"            'aaBCCEF4KKM6P ta3mmanlaar4 se9k to3',\\n\",\n    \"        )\\n\",\n    \"        print('Success: test_compress')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestCompress()\\n\",\n    \"    test.test_compress(compress_string)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_compress\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_compress.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/compress_alt/test_compress.py",
    "content": "import unittest\n\n\nclass TestCompress(unittest.TestCase):\n\n    def test_compress(self, func):\n        self.assertEqual(func(None), None)\n        self.assertEqual(func(''), '')\n        self.assertEqual(func('AABBCC'), 'AABBCC')\n        self.assertEqual(func('AAABCCDDDD'), 'A3BCCD4')\n        self.assertEqual(\n            func('aaBCCEFFFFKKMMMMMMP taaammanlaarrrr seeeeeeeeek tooo'),\n            'aaBCCEF4KKM6P ta3mmanlaar4 se9k to3',\n        )\n        print('Success: test_compress')\n\n\ndef main():\n    test = TestCompress()\n    test.test_compress(compress_string)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "arrays_strings/fizz_buzz/__init__.py",
    "content": ""
  },
  {
    "path": "arrays_strings/fizz_buzz/fizz_buzz_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement Fizz Buzz.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* What is fizz buzz?\\n\",\n    \"    * Return the string representation of numbers from 1 to n\\n\",\n    \"        * Multiples of 3 -> 'Fizz'\\n\",\n    \"        * Multiples of 5 -> 'Buzz'\\n\",\n    \"        * Multiples of 3 and 5 -> 'FizzBuzz'\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None -> Exception\\n\",\n    \"* < 1 -> Exception\\n\",\n    \"* 15 ->\\n\",\n    \"[\\n\",\n    \"    '1',\\n\",\n    \"    '2',\\n\",\n    \"    'Fizz',\\n\",\n    \"    '4',\\n\",\n    \"    'Buzz',\\n\",\n    \"    'Fizz',\\n\",\n    \"    '7',\\n\",\n    \"    '8',\\n\",\n    \"    'Fizz',\\n\",\n    \"    'Buzz',\\n\",\n    \"    '11',\\n\",\n    \"    'Fizz',\\n\",\n    \"    '13',\\n\",\n    \"    '14',\\n\",\n    \"    'FizzBuzz'\\n\",\n    \"]\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\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.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def fizz_buzz(self, num):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_fizz_buzz.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestFizzBuzz(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_fizz_buzz(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.fizz_buzz, None)\\n\",\n    \"        self.assertRaises(ValueError, solution.fizz_buzz, 0)\\n\",\n    \"        expected = [\\n\",\n    \"            '1',\\n\",\n    \"            '2',\\n\",\n    \"            'Fizz',\\n\",\n    \"            '4',\\n\",\n    \"            'Buzz',\\n\",\n    \"            'Fizz',\\n\",\n    \"            '7',\\n\",\n    \"            '8',\\n\",\n    \"            'Fizz',\\n\",\n    \"            'Buzz',\\n\",\n    \"            '11',\\n\",\n    \"            'Fizz',\\n\",\n    \"            '13',\\n\",\n    \"            '14',\\n\",\n    \"            'FizzBuzz'\\n\",\n    \"        ]\\n\",\n    \"        self.assertEqual(solution.fizz_buzz(15), expected)\\n\",\n    \"        print('Success: test_fizz_buzz')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestFizzBuzz()\\n\",\n    \"    test.test_fizz_buzz()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\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.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/fizz_buzz/fizz_buzz_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement Fizz Buzz.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* What is fizz buzz?\\n\",\n    \"    * Return the string representation of numbers from 1 to n\\n\",\n    \"        * Multiples of 3 -> 'Fizz'\\n\",\n    \"        * Multiples of 5 -> 'Buzz'\\n\",\n    \"        * Multiples of 3 and 5 -> 'FizzBuzz'\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None -> Exception\\n\",\n    \"* < 1 -> Exception\\n\",\n    \"* 15 ->\\n\",\n    \"[\\n\",\n    \"    '1',\\n\",\n    \"    '2',\\n\",\n    \"    'Fizz',\\n\",\n    \"    '4',\\n\",\n    \"    'Buzz',\\n\",\n    \"    'Fizz',\\n\",\n    \"    '7',\\n\",\n    \"    '8',\\n\",\n    \"    'Fizz',\\n\",\n    \"    'Buzz',\\n\",\n    \"    '11',\\n\",\n    \"    'Fizz',\\n\",\n    \"    '13',\\n\",\n    \"    '14',\\n\",\n    \"    'FizzBuzz'\\n\",\n    \"]\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"There is no fancy algorithm to solve fizz buzz.\\n\",\n    \"\\n\",\n    \"* Iterate from 1 through n\\n\",\n    \"* Use the mod operator to determine if the current iteration is divisible by:\\n\",\n    \"    * 3 and 5 -> 'FizzBuzz'\\n\",\n    \"    * 3 -> 'Fizz'\\n\",\n    \"    * 5 -> 'Buzz'\\n\",\n    \"    * else -> string of current iteration\\n\",\n    \"* return the results\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def fizz_buzz(self, num):\\n\",\n    \"        if num is None:\\n\",\n    \"            raise TypeError('num cannot be None')\\n\",\n    \"        if num < 1:\\n\",\n    \"            raise ValueError('num cannot be less than one')\\n\",\n    \"        results = []\\n\",\n    \"        for i in range(1, num + 1):\\n\",\n    \"            if i % 3 == 0 and i % 5 == 0:\\n\",\n    \"                results.append('FizzBuzz')\\n\",\n    \"            elif i % 3 == 0:\\n\",\n    \"                results.append('Fizz')\\n\",\n    \"            elif i % 5 == 0:\\n\",\n    \"                results.append('Buzz')\\n\",\n    \"            else:\\n\",\n    \"                results.append(str(i))\\n\",\n    \"        return results\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_fizz_buzz.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_fizz_buzz.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestFizzBuzz(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_fizz_buzz(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.fizz_buzz, None)\\n\",\n    \"        self.assertRaises(ValueError, solution.fizz_buzz, 0)\\n\",\n    \"        expected = [\\n\",\n    \"            '1',\\n\",\n    \"            '2',\\n\",\n    \"            'Fizz',\\n\",\n    \"            '4',\\n\",\n    \"            'Buzz',\\n\",\n    \"            'Fizz',\\n\",\n    \"            '7',\\n\",\n    \"            '8',\\n\",\n    \"            'Fizz',\\n\",\n    \"            'Buzz',\\n\",\n    \"            '11',\\n\",\n    \"            'Fizz',\\n\",\n    \"            '13',\\n\",\n    \"            '14',\\n\",\n    \"            'FizzBuzz'\\n\",\n    \"        ]\\n\",\n    \"        self.assertEqual(solution.fizz_buzz(15), expected)\\n\",\n    \"        print('Success: test_fizz_buzz')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestFizzBuzz()\\n\",\n    \"    test.test_fizz_buzz()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_fizz_buzz\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_fizz_buzz.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": []\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/fizz_buzz/test_fizz_buzz.py",
    "content": "import unittest\n\n\nclass TestFizzBuzz(unittest.TestCase):\n\n    def test_fizz_buzz(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.fizz_buzz, None)\n        self.assertRaises(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        self.assertEqual(solution.fizz_buzz(15), expected)\n        print('Success: test_fizz_buzz')\n\n\ndef main():\n    test = TestFizzBuzz()\n    test.test_fizz_buzz()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "arrays_strings/hash_map/__init__.py",
    "content": ""
  },
  {
    "path": "arrays_strings/hash_map/hash_map_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a hash table with set, get, and remove methods.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* For simplicity, are the keys integers only?\\n\",\n    \"    * Yes\\n\",\n    \"* For collision resolution, can we use chaining?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we have to worry about load factors?\\n\",\n    \"    * No\\n\",\n    \"* Do we have to validate inputs?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* `get` no matching key -> KeyError exception\\n\",\n    \"* `get` matching key -> value\\n\",\n    \"* `set` no matching key -> new key, value\\n\",\n    \"* `set` matching key -> update value\\n\",\n    \"* `remove` no matching key -> KeyError exception\\n\",\n    \"* `remove` matching key -> remove key, value\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/hash_map/hash_map_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Item(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, key, value):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class HashTable(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, size):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def _hash_function(self, key):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def set(self, key, value):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def get(self, key):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def remove(self, key):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_hash_map.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestHashMap(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    # TODO: It would be better if we had unit tests for each\\n\",\n    \"    # method in addition to the following end-to-end test\\n\",\n    \"    def test_end_to_end(self):\\n\",\n    \"        hash_table = HashTable(10)\\n\",\n    \"\\n\",\n    \"        print(\\\"Test: get on an empty hash table index\\\")\\n\",\n    \"        self.assertRaises(KeyError, hash_table.get, 0)\\n\",\n    \"\\n\",\n    \"        print(\\\"Test: set on an empty hash table index\\\")\\n\",\n    \"        hash_table.set(0, 'foo')\\n\",\n    \"        self.assertEqual(hash_table.get(0), 'foo')\\n\",\n    \"        hash_table.set(1, 'bar')\\n\",\n    \"        self.assertEqual(hash_table.get(1), 'bar')\\n\",\n    \"\\n\",\n    \"        print(\\\"Test: set on a non empty hash table index\\\")\\n\",\n    \"        hash_table.set(10, 'foo2')\\n\",\n    \"        self.assertEqual(hash_table.get(0), 'foo')\\n\",\n    \"        self.assertEqual(hash_table.get(10), 'foo2')\\n\",\n    \"\\n\",\n    \"        print(\\\"Test: set on a key that already exists\\\")\\n\",\n    \"        hash_table.set(10, 'foo3')\\n\",\n    \"        self.assertEqual(hash_table.get(0), 'foo')\\n\",\n    \"        self.assertEqual(hash_table.get(10), 'foo3')\\n\",\n    \"\\n\",\n    \"        print(\\\"Test: remove on a key that already exists\\\")\\n\",\n    \"        hash_table.remove(10)\\n\",\n    \"        self.assertEqual(hash_table.get(0), 'foo')\\n\",\n    \"        self.assertRaises(KeyError, hash_table.get, 10)\\n\",\n    \"\\n\",\n    \"        print(\\\"Test: remove on a key that doesn't exist\\\")\\n\",\n    \"        self.assertRaises(KeyError, hash_table.remove, -1)\\n\",\n    \"\\n\",\n    \"        print('Success: test_end_to_end')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestHashMap()\\n\",\n    \"    test.test_end_to_end()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/hash_map/hash_map_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/hash_map/hash_map_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a hash table with set, get, and remove methods.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* For simplicity, are the keys integers only?\\n\",\n    \"    * Yes\\n\",\n    \"* For collision resolution, can we use chaining?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we have to worry about load factors?\\n\",\n    \"    * No\\n\",\n    \"* Do we have to validate inputs?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* `get` no matching key -> KeyError exception\\n\",\n    \"* `get` matching key -> value\\n\",\n    \"* `set` no matching key -> new key, value\\n\",\n    \"* `set` matching key -> update value\\n\",\n    \"* `remove` no matching key -> KeyError exception\\n\",\n    \"* `remove` matching key -> remove key, value\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### Hash Function\\n\",\n    \"\\n\",\n    \"* Return key % table size\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Set\\n\",\n    \"\\n\",\n    \"* Get hash index for lookup\\n\",\n    \"* If key exists, replace\\n\",\n    \"* Else, add\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1) average and best, O(n) worst\\n\",\n    \"* Space: O(1) space for newly added element\\n\",\n    \"\\n\",\n    \"### Get\\n\",\n    \"\\n\",\n    \"* Get hash index for lookup\\n\",\n    \"* If key exists, return value\\n\",\n    \"* Else, raise KeyError\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1) average and best, O(n) worst\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Remove\\n\",\n    \"\\n\",\n    \"* Get hash index for lookup\\n\",\n    \"* If key exists, delete the item\\n\",\n    \"* Else, raise KeyError\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1) average and best, O(n) worst\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Item(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, key, value):\\n\",\n    \"        self.key = key\\n\",\n    \"        self.value = value\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class HashTable(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, size):\\n\",\n    \"        self.size = size\\n\",\n    \"        self.table = [[] for _ in range(self.size)]\\n\",\n    \"\\n\",\n    \"    def _hash_function(self, key):\\n\",\n    \"        return key % self.size\\n\",\n    \"\\n\",\n    \"    def set(self, key, value):\\n\",\n    \"        hash_index = self._hash_function(key)\\n\",\n    \"        for item in self.table[hash_index]:\\n\",\n    \"            if item.key == key:\\n\",\n    \"                item.value = value\\n\",\n    \"                return\\n\",\n    \"        self.table[hash_index].append(Item(key, value))\\n\",\n    \"\\n\",\n    \"    def get(self, key):\\n\",\n    \"        hash_index = self._hash_function(key)\\n\",\n    \"        for item in self.table[hash_index]:\\n\",\n    \"            if item.key == key:\\n\",\n    \"                return item.value\\n\",\n    \"        raise KeyError('Key not found')\\n\",\n    \"\\n\",\n    \"    def remove(self, key):\\n\",\n    \"        hash_index = self._hash_function(key)\\n\",\n    \"        for index, item in enumerate(self.table[hash_index]):\\n\",\n    \"            if item.key == key:\\n\",\n    \"                del self.table[hash_index][index]\\n\",\n    \"                return\\n\",\n    \"        raise KeyError('Key not found')\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_hash_map.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_hash_map.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestHashMap(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    # TODO: It would be better if we had unit tests for each\\n\",\n    \"    # method in addition to the following end-to-end test\\n\",\n    \"    def test_end_to_end(self):\\n\",\n    \"        hash_table = HashTable(10)\\n\",\n    \"\\n\",\n    \"        print(\\\"Test: get on an empty hash table index\\\")\\n\",\n    \"        self.assertRaises(KeyError, hash_table.get, 0)\\n\",\n    \"\\n\",\n    \"        print(\\\"Test: set on an empty hash table index\\\")\\n\",\n    \"        hash_table.set(0, 'foo')\\n\",\n    \"        self.assertEqual(hash_table.get(0), 'foo')\\n\",\n    \"        hash_table.set(1, 'bar')\\n\",\n    \"        self.assertEqual(hash_table.get(1), 'bar')\\n\",\n    \"\\n\",\n    \"        print(\\\"Test: set on a non empty hash table index\\\")\\n\",\n    \"        hash_table.set(10, 'foo2')\\n\",\n    \"        self.assertEqual(hash_table.get(0), 'foo')\\n\",\n    \"        self.assertEqual(hash_table.get(10), 'foo2')\\n\",\n    \"\\n\",\n    \"        print(\\\"Test: set on a key that already exists\\\")\\n\",\n    \"        hash_table.set(10, 'foo3')\\n\",\n    \"        self.assertEqual(hash_table.get(0), 'foo')\\n\",\n    \"        self.assertEqual(hash_table.get(10), 'foo3')\\n\",\n    \"\\n\",\n    \"        print(\\\"Test: remove on a key that already exists\\\")\\n\",\n    \"        hash_table.remove(10)\\n\",\n    \"        self.assertEqual(hash_table.get(0), 'foo')\\n\",\n    \"        self.assertRaises(KeyError, hash_table.get, 10)\\n\",\n    \"\\n\",\n    \"        print(\\\"Test: remove on a key that doesn't exist\\\")\\n\",\n    \"        self.assertRaises(KeyError, hash_table.remove, -1)\\n\",\n    \"\\n\",\n    \"        print('Success: test_end_to_end')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestHashMap()\\n\",\n    \"    test.test_end_to_end()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: get on an empty hash table index\\n\",\n      \"Test: set on an empty hash table index\\n\",\n      \"Test: set on a non empty hash table index\\n\",\n      \"Test: set on a key that already exists\\n\",\n      \"Test: remove on a key that already exists\\n\",\n      \"Test: remove on a key that doesn't exist\\n\",\n      \"Success: test_end_to_end\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"run -i test_hash_map.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": []\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/hash_map/test_hash_map.py",
    "content": "import unittest\n\n\nclass TestHashMap(unittest.TestCase):\n\n    # TODO: It would be better if we had unit tests for each\n    # method in addition to the following end-to-end test\n    def test_end_to_end(self):\n        hash_table = HashTable(10)\n\n        print(\"Test: get on an empty hash table index\")\n        self.assertRaises(KeyError, hash_table.get, 0)\n\n        print(\"Test: set on an empty hash table index\")\n        hash_table.set(0, 'foo')\n        self.assertEqual(hash_table.get(0), 'foo')\n        hash_table.set(1, 'bar')\n        self.assertEqual(hash_table.get(1), 'bar')\n\n        print(\"Test: set on a non empty hash table index\")\n        hash_table.set(10, 'foo2')\n        self.assertEqual(hash_table.get(0), 'foo')\n        self.assertEqual(hash_table.get(10), 'foo2')\n\n        print(\"Test: set on a key that already exists\")\n        hash_table.set(10, 'foo3')\n        self.assertEqual(hash_table.get(0), 'foo')\n        self.assertEqual(hash_table.get(10), 'foo3')\n\n        print(\"Test: remove on a key that already exists\")\n        hash_table.remove(10)\n        self.assertEqual(hash_table.get(0), 'foo')\n        self.assertRaises(KeyError, hash_table.get, 10)\n\n        print(\"Test: remove on a key that doesn't exist\")\n        self.assertRaises(KeyError, hash_table.remove, -1)\n\n        print('Success: test_end_to_end')\n\n\ndef main():\n    test = TestHashMap()\n    test.test_end_to_end()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "arrays_strings/permutation/__init__.py",
    "content": ""
  },
  {
    "path": "arrays_strings/permutation/permutation_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine if a string is a permutation of another string.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the string is ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: Unicode strings could require special handling depending on your language\\n\",\n    \"* Is whitespace important?\\n\",\n    \"    * Yes\\n\",\n    \"* Is this case sensitive?  'Nib', 'bin' is not a match?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we use additional data structures?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* One or more None inputs -> False\\n\",\n    \"* One or more empty strings -> False\\n\",\n    \"* 'Nib', 'bin' -> False\\n\",\n    \"* 'act', 'cat' -> True\\n\",\n    \"* 'a ct', 'ca t' -> True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/permutation/permutation_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Permutations(object):\\n\",\n    \"\\n\",\n    \"    def is_permutation(self, str1, str2):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_permutation_solution.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPermutation(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_permutation(self, func):\\n\",\n    \"        self.assertEqual(func(None, 'foo'), False)\\n\",\n    \"        self.assertEqual(func('', 'foo'), False)\\n\",\n    \"        self.assertEqual(func('Nib', 'bin'), False)\\n\",\n    \"        self.assertEqual(func('act', 'cat'), True)\\n\",\n    \"        self.assertEqual(func('a ct', 'ca t'), True)\\n\",\n    \"        self.assertEqual(func('dog', 'doggo'), False)\\n\",\n    \"        print('Success: test_permutation')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPermutation()\\n\",\n    \"    permutations = Permutations()\\n\",\n    \"    test.test_permutation(permutations.is_permutation)\\n\",\n    \"    try:\\n\",\n    \"        permutations_alt = PermutationsAlt()\\n\",\n    \"        test.test_permutation(permutations_alt.is_permutation)\\n\",\n    \"    except NameError:\\n\",\n    \"        # Alternate solutions are only defined\\n\",\n    \"        # in the solutions file\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/permutation/permutation_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/permutation/permutation_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine if a string is a permutation of another string.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm: Compare Sorted Strings](#Algorithm:-Compare-Sorted-Strings)\\n\",\n    \"* [Code: Compare Sorted Strings](#Code:-Compare-Sorted-Strings)\\n\",\n    \"* [Algorithm: Hashmap Lookup](#Algorithm:-Hash-Map-Lookup)\\n\",\n    \"* [Code: Hashmap Lookup](#Code:-Hash-Map-Lookup)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the string is ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: Unicode strings could require special handling depending on your language\\n\",\n    \"* Is whitespace important?\\n\",\n    \"    * Yes\\n\",\n    \"* Is this case sensitive?  'Nib', 'bin' is not a match?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we use additional data structures?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* One or more None inputs -> False\\n\",\n    \"* One or more empty strings -> False\\n\",\n    \"* 'Nib', 'bin' -> False\\n\",\n    \"* 'act', 'cat' -> True\\n\",\n    \"* 'a ct', 'ca t' -> True\\n\",\n    \"* 'dog', 'doggo' -> False\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm: Compare Sorted Strings\\n\",\n    \"\\n\",\n    \"Permutations contain the same strings but in different orders.  This approach could be slow for large strings due to sorting.\\n\",\n    \"\\n\",\n    \"* Sort both strings\\n\",\n    \"* If both sorted strings are equal\\n\",\n    \"    * return True\\n\",\n    \"* Else\\n\",\n    \"    * return False\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n log n) from the sort, in general\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code: Compare Sorted Strings\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Permutations(object):\\n\",\n    \"\\n\",\n    \"    def is_permutation(self, str1, str2):\\n\",\n    \"        if str1 is None or str2 is None:\\n\",\n    \"            return False\\n\",\n    \"        return sorted(str1) == sorted(str2)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm: Hash Map Lookup\\n\",\n    \"\\n\",\n    \"We'll keep a hash map (dict) to keep track of characters we encounter.  \\n\",\n    \"\\n\",\n    \"Steps:\\n\",\n    \"* Scan each character\\n\",\n    \"* For each character in each string:\\n\",\n    \"    * If the character does not exist in a hash map, add the character to a hash map\\n\",\n    \"    * Else, increment the character's count\\n\",\n    \"* If the hash maps for each string are equal\\n\",\n    \"    * Return True\\n\",\n    \"* Else\\n\",\n    \"    * Return False\\n\",\n    \"\\n\",\n    \"Notes:\\n\",\n    \"* Since the characters are in ASCII, we could potentially use an array of size 128 (or 256 for extended ASCII), where each array index is equivalent to an ASCII value\\n\",\n    \"* Instead of using two hash maps, you could use one hash map and increment character values based on the first string and decrement based on the second string\\n\",\n    \"* You can short circuit if the lengths of each string are not equal, although len() in Python is generally O(1) unlike other languages like C where getting the length of a string is O(n)\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code: Hash Map Lookup\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from collections import defaultdict\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class PermutationsAlt(object):\\n\",\n    \"\\n\",\n    \"    def is_permutation(self, str1, str2):\\n\",\n    \"        if str1 is None or str2 is None:\\n\",\n    \"            return False\\n\",\n    \"        if len(str1) != len(str2):\\n\",\n    \"            return False\\n\",\n    \"        unique_counts1 = defaultdict(int)\\n\",\n    \"        unique_counts2 = defaultdict(int)\\n\",\n    \"        for char in str1:\\n\",\n    \"            unique_counts1[char] += 1\\n\",\n    \"        for char in str2:\\n\",\n    \"            unique_counts2[char] += 1\\n\",\n    \"        return unique_counts1 == unique_counts2\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_permutation_solution.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_permutation_solution.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPermutation(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_permutation(self, func):\\n\",\n    \"        self.assertEqual(func(None, 'foo'), False)\\n\",\n    \"        self.assertEqual(func('', 'foo'), False)\\n\",\n    \"        self.assertEqual(func('Nib', 'bin'), False)\\n\",\n    \"        self.assertEqual(func('act', 'cat'), True)\\n\",\n    \"        self.assertEqual(func('a ct', 'ca t'), True)\\n\",\n    \"        self.assertEqual(func('dog', 'doggo'), False)\\n\",\n    \"        print('Success: test_permutation')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPermutation()\\n\",\n    \"    permutations = Permutations()\\n\",\n    \"    test.test_permutation(permutations.is_permutation)\\n\",\n    \"    try:\\n\",\n    \"        permutations_alt = PermutationsAlt()\\n\",\n    \"        test.test_permutation(permutations_alt.is_permutation)\\n\",\n    \"    except NameError:\\n\",\n    \"        # Alternate solutions are only defined\\n\",\n    \"        # in the solutions file\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_permutation\\n\",\n      \"Success: test_permutation\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"run -i test_permutation_solution.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/permutation/test_permutation_solution.py",
    "content": "import unittest\n\n\nclass TestPermutation(unittest.TestCase):\n\n    def test_permutation(self, func):\n        self.assertEqual(func(None, 'foo'), False)\n        self.assertEqual(func('', 'foo'), False)\n        self.assertEqual(func('Nib', 'bin'), False)\n        self.assertEqual(func('act', 'cat'), True)\n        self.assertEqual(func('a ct', 'ca t'), True)\n        self.assertEqual(func('dog', 'doggo'), False)\n        print('Success: test_permutation')\n\n\ndef main():\n    test = TestPermutation()\n    permutations = Permutations()\n    test.test_permutation(permutations.is_permutation)\n    try:\n        permutations_alt = PermutationsAlt()\n        test.test_permutation(permutations_alt.is_permutation)\n    except NameError:\n        # Alternate solutions are only defined\n        # in the solutions file\n        pass\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "arrays_strings/priority_queue/__init__.py",
    "content": ""
  },
  {
    "path": "arrays_strings/priority_queue/priority_queue.py",
    "content": "import sys\n\n\nclass PriorityQueueNode(object):\n\n    def __init__(self, obj, key):\n        self.obj = obj\n        self.key = key\n\n    def __repr__(self):\n        return str(self.obj) + ': ' + str(self.key)\n\n\nclass PriorityQueue(object):\n\n    def __init__(self):\n        self.array = []\n\n    def __len__(self):\n        return len(self.array)\n\n    def insert(self, node):\n        self.array.append(node)\n        return self.array[-1]\n\n    def extract_min(self):\n        if not self.array:\n            return None\n        minimum = sys.maxsize\n        for index, node in enumerate(self.array):\n            if node.key < minimum:\n                minimum = node.key\n                minimum_index = index\n        return self.array.pop(minimum_index)\n\n    def decrease_key(self, obj, new_key):\n        for node in self.array:\n            if node.obj is obj:\n                node.key = new_key\n                return node\n        return None\n"
  },
  {
    "path": "arrays_strings/priority_queue/priority_queue_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a priority queue backed by an array.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Do we expect the methods to be insert, extract_min, and decrease_key?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume there aren't any duplicate keys?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we need to validate inputs?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### insert\\n\",\n    \"\\n\",\n    \"* `insert` general case -> inserted node\\n\",\n    \"\\n\",\n    \"### extract_min\\n\",\n    \"\\n\",\n    \"* `extract_min` from an empty list -> None\\n\",\n    \"* `extract_min` general case -> min node\\n\",\n    \"\\n\",\n    \"### decrease_key\\n\",\n    \"\\n\",\n    \"* `decrease_key` an invalid key -> None\\n\",\n    \"* `decrease_key` general case -> updated node\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](priority_queue_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"class PriorityQueueNode(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, obj, key):\\n\",\n    \"        self.obj = obj\\n\",\n    \"        self.key = key\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return str(self.obj) + ': ' + str(self.key)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class PriorityQueue(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self):\\n\",\n    \"        self.array = []\\n\",\n    \"\\n\",\n    \"    def __len__(self):\\n\",\n    \"        return len(self.array)\\n\",\n    \"\\n\",\n    \"    def insert(self, node):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def extract_min(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def decrease_key(self, obj, new_key):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_priority_queue.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPriorityQueue(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_priority_queue(self):\\n\",\n    \"        priority_queue = PriorityQueue()\\n\",\n    \"        self.assertEqual(priority_queue.extract_min(), None)\\n\",\n    \"        priority_queue.insert(PriorityQueueNode('a', 20))\\n\",\n    \"        priority_queue.insert(PriorityQueueNode('b', 5))\\n\",\n    \"        priority_queue.insert(PriorityQueueNode('c', 15))\\n\",\n    \"        priority_queue.insert(PriorityQueueNode('d', 22))\\n\",\n    \"        priority_queue.insert(PriorityQueueNode('e', 40))\\n\",\n    \"        priority_queue.insert(PriorityQueueNode('f', 3))\\n\",\n    \"        priority_queue.decrease_key('f', 2)\\n\",\n    \"        priority_queue.decrease_key('a', 19)\\n\",\n    \"        mins = []\\n\",\n    \"        while priority_queue.array:\\n\",\n    \"            mins.append(priority_queue.extract_min().key)\\n\",\n    \"        self.assertEqual(mins, [2, 5, 15, 19, 22, 40])\\n\",\n    \"        print('Success: test_min_heap')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPriorityQueue()\\n\",\n    \"    test.test_priority_queue()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](priority_queue_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/priority_queue/priority_queue_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a priority queue backed by an array.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Do we expect the methods to be insert, extract_min, and decrease_key?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume there aren't any duplicate keys?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we need to validate inputs?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### insert\\n\",\n    \"\\n\",\n    \"* `insert` general case -> inserted node\\n\",\n    \"\\n\",\n    \"### extract_min\\n\",\n    \"\\n\",\n    \"* `extract_min` from an empty list -> None\\n\",\n    \"* `extract_min` general case -> min node\\n\",\n    \"\\n\",\n    \"### decrease_key\\n\",\n    \"\\n\",\n    \"* `decrease_key` an invalid key -> None\\n\",\n    \"* `decrease_key` general case -> updated node\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### insert\\n\",\n    \"\\n\",\n    \"* Append to the internal array.\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### extract_min\\n\",\n    \"\\n\",\n    \"* Loop through each item in the internal array\\n\",\n    \"    * Update the min value as needed\\n\",\n    \"* Remove the min element from the array and return it\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### decrease_key\\n\",\n    \"\\n\",\n    \"* Loop through each item in the internal array to find the matching input\\n\",\n    \"    * Update the matching element's key\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting priority_queue.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile priority_queue.py\\n\",\n    \"import sys\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class PriorityQueueNode(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, obj, key):\\n\",\n    \"        self.obj = obj\\n\",\n    \"        self.key = key\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return str(self.obj) + ': ' + str(self.key)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class PriorityQueue(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self):\\n\",\n    \"        self.array = []\\n\",\n    \"\\n\",\n    \"    def __len__(self):\\n\",\n    \"        return len(self.array)\\n\",\n    \"\\n\",\n    \"    def insert(self, node):\\n\",\n    \"        self.array.append(node)\\n\",\n    \"        return self.array[-1]\\n\",\n    \"\\n\",\n    \"    def extract_min(self):\\n\",\n    \"        if not self.array:\\n\",\n    \"            return None\\n\",\n    \"        minimum = sys.maxsize\\n\",\n    \"        for index, node in enumerate(self.array):\\n\",\n    \"            if node.key < minimum:\\n\",\n    \"                minimum = node.key\\n\",\n    \"                minimum_index = index\\n\",\n    \"        return self.array.pop(minimum_index)\\n\",\n    \"\\n\",\n    \"    def decrease_key(self, obj, new_key):\\n\",\n    \"        for node in self.array:\\n\",\n    \"            if node.obj is obj:\\n\",\n    \"                node.key = new_key\\n\",\n    \"                return node\\n\",\n    \"        return None\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run priority_queue.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_priority_queue.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_priority_queue.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPriorityQueue(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_priority_queue(self):\\n\",\n    \"        priority_queue = PriorityQueue()\\n\",\n    \"        self.assertEqual(priority_queue.extract_min(), None)\\n\",\n    \"        priority_queue.insert(PriorityQueueNode('a', 20))\\n\",\n    \"        priority_queue.insert(PriorityQueueNode('b', 5))\\n\",\n    \"        priority_queue.insert(PriorityQueueNode('c', 15))\\n\",\n    \"        priority_queue.insert(PriorityQueueNode('d', 22))\\n\",\n    \"        priority_queue.insert(PriorityQueueNode('e', 40))\\n\",\n    \"        priority_queue.insert(PriorityQueueNode('f', 3))\\n\",\n    \"        priority_queue.decrease_key('f', 2)\\n\",\n    \"        priority_queue.decrease_key('a', 19)\\n\",\n    \"        mins = []\\n\",\n    \"        while priority_queue.array:\\n\",\n    \"            mins.append(priority_queue.extract_min().key)\\n\",\n    \"        self.assertEqual(mins, [2, 5, 15, 19, 22, 40])\\n\",\n    \"        print('Success: test_min_heap')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPriorityQueue()\\n\",\n    \"    test.test_priority_queue()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_min_heap\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_priority_queue.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/priority_queue/test_priority_queue.py",
    "content": "import unittest\n\n\nclass TestPriorityQueue(unittest.TestCase):\n\n    def test_priority_queue(self):\n        priority_queue = PriorityQueue()\n        self.assertEqual(priority_queue.extract_min(), None)\n        priority_queue.insert(PriorityQueueNode('a', 20))\n        priority_queue.insert(PriorityQueueNode('b', 5))\n        priority_queue.insert(PriorityQueueNode('c', 15))\n        priority_queue.insert(PriorityQueueNode('d', 22))\n        priority_queue.insert(PriorityQueueNode('e', 40))\n        priority_queue.insert(PriorityQueueNode('f', 3))\n        priority_queue.decrease_key('f', 2)\n        priority_queue.decrease_key('a', 19)\n        mins = []\n        while priority_queue.array:\n            mins.append(priority_queue.extract_min().key)\n        self.assertEqual(mins, [2, 5, 15, 19, 22, 40])\n        print('Success: test_min_heap')\n\n\ndef main():\n    test = TestPriorityQueue()\n    test.test_priority_queue()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "arrays_strings/reverse_string/__init__.py",
    "content": ""
  },
  {
    "path": "arrays_strings/reverse_string/reverse_string.cpp",
    "content": "#include <stdio.h>\n\nvoid Reverse(char* str) {\n    if (str) {\n        char* i = str;\t// first letter\n        char* j = str;\t// last letter\n\n        // find the end of the string\n        while (*j) {\n            j++;\n        }\n\n        // don't point to the null terminator\n        j--;\n\n        char tmp;\n\n        // swap chars to reverse the string\n        while (i < j) {\n            tmp = *i;\n            *i++ = *j;\n            *j-- = tmp;\n        }\n    }\n}\n\nint main() {\n    char test0[] = \"\";\n    char test1[] = \"foo\";\n    Reverse(NULL);\n    Reverse(test0);\n    Reverse(test1);\n    printf(\"%s \\n\", test0);\n    printf(\"%s \\n\", test1);\n    return 0;\n}\n"
  },
  {
    "path": "arrays_strings/reverse_string/reverse_string_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a function to reverse a string (a list of characters), in-place.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the string is ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: Unicode strings could require special handling depending on your language\\n\",\n    \"* Since we need to do this in-place, it seems we cannot use the slice operator or the reversed function?\\n\",\n    \"    * Correct\\n\",\n    \"* Since Python string are immutable, can we use a list of characters instead?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> None\\n\",\n    \"* [''] -> ['']\\n\",\n    \"* ['f', 'o', 'o', ' ', 'b', 'a', 'r'] -> ['r', 'a', 'b', ' ', 'o', 'o', 'f']\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/reverse_string/reverse_string_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class ReverseString(object):\\n\",\n    \"\\n\",\n    \"    def reverse(self, chars):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_reverse_string.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestReverse(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_reverse(self, func):\\n\",\n    \"        self.assertEqual(func(None), None)\\n\",\n    \"        self.assertEqual(func(['']), [''])\\n\",\n    \"        self.assertEqual(func(\\n\",\n    \"            ['f', 'o', 'o', ' ', 'b', 'a', 'r']),\\n\",\n    \"            ['r', 'a', 'b', ' ', 'o', 'o', 'f'])\\n\",\n    \"        print('Success: test_reverse')\\n\",\n    \"\\n\",\n    \"    def test_reverse_inplace(self, func):\\n\",\n    \"        target_list = ['f', 'o', 'o', ' ', 'b', 'a', 'r']\\n\",\n    \"        func(target_list)\\n\",\n    \"        self.assertEqual(target_list, ['r', 'a', 'b', ' ', 'o', 'o', 'f'])\\n\",\n    \"        print('Success: test_reverse_inplace')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestReverse()\\n\",\n    \"    reverse_string = ReverseString()\\n\",\n    \"    test.test_reverse(reverse_string.reverse)\\n\",\n    \"    test.test_reverse_inplace(reverse_string.reverse)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/reverse_string/reverse_string_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/reverse_string/reverse_string_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a function to reverse a string (a list of characters), in-place.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Pythonic-Code](#Pythonic-Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Bonus C Algorithm](#Bonus-C-Algorithm)\\n\",\n    \"* [Bonus C Code](#Bonus-C-Code)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the string is ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: Unicode strings could require special handling depending on your language\\n\",\n    \"* Since we need to do this in-place, it seems we cannot use the slice operator or the reversed function?\\n\",\n    \"    * Correct\\n\",\n    \"* Since Python string are immutable, can we use a list of characters instead?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> None\\n\",\n    \"* [''] -> ['']\\n\",\n    \"* ['f', 'o', 'o', ' ', 'b', 'a', 'r'] -> ['r', 'a', 'b', ' ', 'o', 'o', 'f']\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Since Python strings are immutable, we'll use a list of chars instead to exercise in-place string manipulation as you would get with a C string.\\n\",\n    \"\\n\",\n    \"* Iterate len(string)/2 times, starting with i = 0:\\n\",\n    \"    * Swap char with index (i) and char with index (len(string) - 1 - i)\\n\",\n    \"    * Increment i\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"Note:\\n\",\n    \"* You could use a byte array instead of a list to do in-place string operations\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from __future__ import division\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class ReverseString(object):\\n\",\n    \"\\n\",\n    \"    def reverse(self, chars):\\n\",\n    \"        if chars:\\n\",\n    \"            size = len(chars)\\n\",\n    \"            for i in range(size // 2):\\n\",\n    \"                chars[i], chars[size - 1 - i] = \\\\\\n\",\n    \"                    chars[size - 1 - i], chars[i]\\n\",\n    \"        return chars\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Pythonic-Code\\n\",\n    \"\\n\",\n    \"This question has an artificial constraint that prevented the use of the slice operator and the reversed method.  For completeness, the solutions for these are provided below.  Note these solutions are not in-place.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class ReverseStringAlt(object):\\n\",\n    \"\\n\",\n    \"    def reverse_string_alt(string):\\n\",\n    \"        if string:\\n\",\n    \"            return string[::-1]\\n\",\n    \"        return string\\n\",\n    \"\\n\",\n    \"    def reverse_string_alt2(string):\\n\",\n    \"        if string:\\n\",\n    \"            return ''.join(reversed(string))\\n\",\n    \"        return string\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_reverse_string.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_reverse_string.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestReverse(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_reverse(self, func):\\n\",\n    \"        self.assertEqual(func(None), None)\\n\",\n    \"        self.assertEqual(func(['']), [''])\\n\",\n    \"        self.assertEqual(func(\\n\",\n    \"            ['f', 'o', 'o', ' ', 'b', 'a', 'r']),\\n\",\n    \"            ['r', 'a', 'b', ' ', 'o', 'o', 'f'])\\n\",\n    \"        print('Success: test_reverse')\\n\",\n    \"\\n\",\n    \"    def test_reverse_inplace(self, func):\\n\",\n    \"        target_list = ['f', 'o', 'o', ' ', 'b', 'a', 'r']\\n\",\n    \"        func(target_list)\\n\",\n    \"        self.assertEqual(target_list, ['r', 'a', 'b', ' ', 'o', 'o', 'f'])\\n\",\n    \"        print('Success: test_reverse_inplace')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestReverse()\\n\",\n    \"    reverse_string = ReverseString()\\n\",\n    \"    test.test_reverse(reverse_string.reverse)\\n\",\n    \"    test.test_reverse_inplace(reverse_string.reverse)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_reverse\\n\",\n      \"Success: test_reverse_inplace\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_reverse_string.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## C Algorithm\\n\",\n    \"\\n\",\n    \"This is a classic problem in C/C++\\n\",\n    \"\\n\",\n    \"We'll want to keep two pointers:\\n\",\n    \"* i is a pointer to the first char\\n\",\n    \"* j is a pointer to the last char\\n\",\n    \"\\n\",\n    \"To get a pointer to the last char, we need to loop through all characters, take note of null terminator.\\n\",\n    \"\\n\",\n    \"* while i < j\\n\",\n    \"    * swap i and j\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: In-place\\n\",\n    \"\\n\",\n    \"Note:\\n\",\n    \"* Instead of using i, you can use str instead, although this might not be as intuitive.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## C Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load reverse_string.cpp\\n\",\n    \"#include <stdio.h>\\n\",\n    \"\\n\",\n    \"void Reverse(char* str) {\\n\",\n    \"    if (str) {\\n\",\n    \"        char* i = str;\\t// first letter\\n\",\n    \"        char* j = str;\\t// last letter\\n\",\n    \"        \\n\",\n    \"        // find the end of the string\\n\",\n    \"        while (*j) {\\n\",\n    \"            j++;\\n\",\n    \"        }\\n\",\n    \"        \\n\",\n    \"        // don't point to the null terminator\\n\",\n    \"        j--;\\n\",\n    \"        \\n\",\n    \"        char tmp;\\n\",\n    \"        \\n\",\n    \"        // swap chars to reverse the string\\n\",\n    \"        while (i < j) {\\n\",\n    \"            tmp = *i;\\n\",\n    \"            *i++ = *j;\\n\",\n    \"            *j-- = tmp;\\n\",\n    \"        }\\n\",\n    \"    }\\n\",\n    \"}\\n\",\n    \"\\n\",\n    \"int main() {\\n\",\n    \"    char test0[] = \\\"\\\";\\n\",\n    \"    char test1[] = \\\"foo\\\";\\n\",\n    \"    Reverse(NULL);\\n\",\n    \"    Reverse(test0);\\n\",\n    \"    Reverse(test1);\\n\",\n    \"    printf(\\\"%s \\\\n\\\", test0);\\n\",\n    \"    printf(\\\"%s \\\\n\\\", test1);\\n\",\n    \"    return 0;\\n\",\n    \"}\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/reverse_string/test_reverse_string.py",
    "content": "import unittest\n\n\nclass TestReverse(unittest.TestCase):\n\n    def test_reverse(self, func):\n        self.assertEqual(func(None), None)\n        self.assertEqual(func(['']), [''])\n        self.assertEqual(func(\n            ['f', 'o', 'o', ' ', 'b', 'a', 'r']),\n            ['r', 'a', 'b', ' ', 'o', 'o', 'f'])\n        print('Success: test_reverse')\n\n    def test_reverse_inplace(self, func):\n        target_list = ['f', 'o', 'o', ' ', 'b', 'a', 'r']\n        func(target_list)\n        self.assertEqual(target_list, ['r', 'a', 'b', ' ', 'o', 'o', 'f'])\n        print('Success: test_reverse_inplace')\n\n\ndef main():\n    test = TestReverse()\n    reverse_string = ReverseString()\n    test.test_reverse(reverse_string.reverse)\n    test.test_reverse_inplace(reverse_string.reverse)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "arrays_strings/rotation/__init__.py",
    "content": ""
  },
  {
    "path": "arrays_strings/rotation/rotation_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine if a string s1 is a rotation of another string s2, by calling (only once) a function is_substring.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the string is ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: Unicode strings could require special handling depending on your language\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we use additional data structures?  \\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Any strings that differ in size -> False\\n\",\n    \"* None, 'foo' -> False (any None results in False)\\n\",\n    \"* ' ', 'foo' -> False\\n\",\n    \"* ' ', ' ' -> True\\n\",\n    \"* 'foobarbaz', 'barbazfoo' -> True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/rotation/rotation_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Rotation(object):\\n\",\n    \"\\n\",\n    \"    def is_substring(self, s1, s2):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def is_rotation(self, s1, s2):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        # Call is_substring only once\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_rotation.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestRotation(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_rotation(self):\\n\",\n    \"        rotation = Rotation()\\n\",\n    \"        self.assertEqual(rotation.is_rotation('o', 'oo'), False)\\n\",\n    \"        self.assertEqual(rotation.is_rotation(None, 'foo'), False)\\n\",\n    \"        self.assertEqual(rotation.is_rotation('', 'foo'), False)\\n\",\n    \"        self.assertEqual(rotation.is_rotation('', ''), True)\\n\",\n    \"        self.assertEqual(rotation.is_rotation('foobarbaz', 'barbazfoo'), True)\\n\",\n    \"        print('Success: test_rotation')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestRotation()\\n\",\n    \"    test.test_rotation()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/rotation/rotation_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/rotation/rotation_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine if a string s1 is a rotation of another string s2, by calling (only once) a function is_substring.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the string is ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: Unicode strings could require special handling depending on your language\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we use additional data structures?  \\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Any strings that differ in size -> False\\n\",\n    \"* None, 'foo' -> False (any None results in False)\\n\",\n    \"* ' ', 'foo' -> False\\n\",\n    \"* ' ', ' ' -> True\\n\",\n    \"* 'foobarbaz', 'barbazfoo' -> True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Examine the following test case:\\n\",\n    \"* s1 = 'barbazfoo'\\n\",\n    \"* s2 = 'foobarbaz'\\n\",\n    \"\\n\",\n    \"We see that if we can use the given is_substring method if we take compare s2 with s1 + s1:\\n\",\n    \"* s2 = 'foobarbaz'\\n\",\n    \"* s3 = 'barbaz*foobarbaz*foo'\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Rotation(object):\\n\",\n    \"\\n\",\n    \"    def is_substring(self, s1, s2):\\n\",\n    \"        return s1 in s2\\n\",\n    \"\\n\",\n    \"    def is_rotation(self, s1, s2):\\n\",\n    \"        if s1 is None or s2 is None:\\n\",\n    \"            return False\\n\",\n    \"        if len(s1) != len(s2):\\n\",\n    \"            return False\\n\",\n    \"        return self.is_substring(s1, s2 + s2)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_rotation.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_rotation.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestRotation(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_rotation(self):\\n\",\n    \"        rotation = Rotation()\\n\",\n    \"        self.assertEqual(rotation.is_rotation('o', 'oo'), False)\\n\",\n    \"        self.assertEqual(rotation.is_rotation(None, 'foo'), False)\\n\",\n    \"        self.assertEqual(rotation.is_rotation('', 'foo'), False)\\n\",\n    \"        self.assertEqual(rotation.is_rotation('', ''), True)\\n\",\n    \"        self.assertEqual(rotation.is_rotation('foobarbaz', 'barbazfoo'), True)\\n\",\n    \"        print('Success: test_rotation')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestRotation()\\n\",\n    \"    test.test_rotation()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_rotation\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_rotation.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/rotation/test_rotation.py",
    "content": "import unittest\n\n\nclass TestRotation(unittest.TestCase):\n\n    def test_rotation(self):\n        rotation = Rotation()\n        self.assertEqual(rotation.is_rotation('o', 'oo'), False)\n        self.assertEqual(rotation.is_rotation(None, 'foo'), False)\n        self.assertEqual(rotation.is_rotation('', 'foo'), False)\n        self.assertEqual(rotation.is_rotation('', ''), True)\n        self.assertEqual(rotation.is_rotation('foobarbaz', 'barbazfoo'), True)\n        print('Success: test_rotation')\n\n\ndef main():\n    test = TestRotation()\n    test.test_rotation()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "arrays_strings/str_diff/__init__.py",
    "content": ""
  },
  {
    "path": "arrays_strings/str_diff/str_diff_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the single different char between two strings.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the strings are ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Is case important?\\n\",\n    \"    * The strings are lower case\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"    * Otherwise, assume there is only a single different char between the two strings\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* 'ab', 'aab' -> 'a'\\n\",\n    \"* 'aab', 'ab' -> 'a'\\n\",\n    \"* 'abcd', 'abcde' -> 'e'\\n\",\n    \"* 'aaabbcdd', 'abdbacade' -> 'e'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](str_diff_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def find_diff(self, str1, str2):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_str_diff.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestFindDiff(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_find_diff(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.find_diff, None)\\n\",\n    \"        self.assertEqual(solution.find_diff('ab', 'aab'), 'a')\\n\",\n    \"        self.assertEqual(solution.find_diff('aab', 'ab'), 'a')\\n\",\n    \"        self.assertEqual(solution.find_diff('abcd', 'abcde'), 'e')\\n\",\n    \"        self.assertEqual(solution.find_diff('aaabbcdd', 'abdbacade'), 'e')\\n\",\n    \"        self.assertEqual(solution.find_diff_xor('ab', 'aab'), 'a')\\n\",\n    \"        self.assertEqual(solution.find_diff_xor('aab', 'ab'), 'a')\\n\",\n    \"        self.assertEqual(solution.find_diff_xor('abcd', 'abcde'), 'e')\\n\",\n    \"        self.assertEqual(solution.find_diff_xor('aaabbcdd', 'abdbacade'), 'e')\\n\",\n    \"        print('Success: test_find_diff')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestFindDiff()\\n\",\n    \"    test.test_find_diff()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/str_diff/str_diff_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/str_diff/str_diff_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the single different char between two strings.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the strings are ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Is case important?\\n\",\n    \"    * The strings are lower case\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"    * Otherwise, assume there is only a single different char between the two strings\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* 'ab', 'aab' -> 'a'\\n\",\n    \"* 'aab', 'ab' -> 'a'\\n\",\n    \"* 'abcd', 'abcde' -> 'e'\\n\",\n    \"* 'aaabbcdd', 'abdbacade' -> 'e'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### Dictionary\\n\",\n    \"\\n\",\n    \"* Keep a dictionary of seen values in s\\n\",\n    \"* Loop through t, decrementing the seen values\\n\",\n    \"    * If the char is not there or if the decrement results in a negative value, return the char\\n\",\n    \"* Return the differing char from the dictionary\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(m+n), where m and n are the lengths of s, t\\n\",\n    \"* Space: O(h), for the dict, where h is the unique chars in s\\n\",\n    \"\\n\",\n    \"### XOR\\n\",\n    \"\\n\",\n    \"* XOR the two strings, which will isolate the differing char\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(m+n), where m and n are the lengths of s, t\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def find_diff(self, str1, str2):\\n\",\n    \"        if str1 is None or str2 is None:\\n\",\n    \"            raise TypeError('str1 or str2 cannot be None')\\n\",\n    \"        seen = {}\\n\",\n    \"        for char in str1:\\n\",\n    \"            if char in seen:\\n\",\n    \"                seen[char] += 1\\n\",\n    \"            else:\\n\",\n    \"                seen[char] = 1\\n\",\n    \"        for char in str2:\\n\",\n    \"            try:\\n\",\n    \"                seen[char] -= 1\\n\",\n    \"            except KeyError:\\n\",\n    \"                return char\\n\",\n    \"            if seen[char] < 0:\\n\",\n    \"                return char\\n\",\n    \"        for char, count in seen.items():\\n\",\n    \"            return char\\n\",\n    \"\\n\",\n    \"    def find_diff_xor(self, str1, str2):\\n\",\n    \"        if str1 is None or str2 is None:\\n\",\n    \"            raise TypeError('str1 or str2 cannot be None')\\n\",\n    \"        result = 0\\n\",\n    \"        for char in str1:\\n\",\n    \"            result ^= ord(char)\\n\",\n    \"        for char in str2:\\n\",\n    \"            result ^= ord(char)\\n\",\n    \"        return chr(result)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_str_diff.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_str_diff.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestFindDiff(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_find_diff(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.find_diff, None)\\n\",\n    \"        self.assertEqual(solution.find_diff('ab', 'aab'), 'a')\\n\",\n    \"        self.assertEqual(solution.find_diff('aab', 'ab'), 'a')\\n\",\n    \"        self.assertEqual(solution.find_diff('abcd', 'abcde'), 'e')\\n\",\n    \"        self.assertEqual(solution.find_diff('aaabbcdd', 'abdbacade'), 'e')\\n\",\n    \"        self.assertEqual(solution.find_diff_xor('ab', 'aab'), 'a')\\n\",\n    \"        self.assertEqual(solution.find_diff_xor('aab', 'ab'), 'a')\\n\",\n    \"        self.assertEqual(solution.find_diff_xor('abcd', 'abcde'), 'e')\\n\",\n    \"        self.assertEqual(solution.find_diff_xor('aaabbcdd', 'abdbacade'), 'e')\\n\",\n    \"        print('Success: test_find_diff')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestFindDiff()\\n\",\n    \"    test.test_find_diff()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_find_diff\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_str_diff.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/str_diff/test_str_diff.py",
    "content": "import unittest\n\n\nclass TestFindDiff(unittest.TestCase):\n\n    def test_find_diff(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.find_diff, None)\n        self.assertEqual(solution.find_diff('ab', 'aab'), 'a')\n        self.assertEqual(solution.find_diff('aab', 'ab'), 'a')\n        self.assertEqual(solution.find_diff('abcd', 'abcde'), 'e')\n        self.assertEqual(solution.find_diff('aaabbcdd', 'abdbacade'), 'e')\n        self.assertEqual(solution.find_diff_xor('ab', 'aab'), 'a')\n        self.assertEqual(solution.find_diff_xor('aab', 'ab'), 'a')\n        self.assertEqual(solution.find_diff_xor('abcd', 'abcde'), 'e')\n        self.assertEqual(solution.find_diff_xor('aaabbcdd', 'abdbacade'), 'e')\n        print('Success: test_find_diff')\n\n\ndef main():\n    test = TestFindDiff()\n    test.test_find_diff()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "arrays_strings/two_sum/__init__.py",
    "content": ""
  },
  {
    "path": "arrays_strings/two_sum/test_two_sum.py",
    "content": "import unittest\n\n\nclass TestTwoSum(unittest.TestCase):\n\n    def test_two_sum(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.two_sum, None, None)\n        self.assertRaises(ValueError, solution.two_sum, [], 0)\n        target = 7\n        nums = [1, 3, 2, -7, 5]\n        expected = [2, 4]\n        self.assertEqual(solution.two_sum(nums, target), expected)\n        print('Success: test_two_sum')\n\n\ndef main():\n    test = TestTwoSum()\n    test.test_two_sum()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "arrays_strings/two_sum/two_sum_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given an array, find the two indices that sum to a specific value.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is there exactly one solution?\\n\",\n    \"    * Yes\\n\",\n    \"* Is there always a solution?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the array an array of ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the array sorted?\\n\",\n    \"    No\\n\",\n    \"* Are negative values possible?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* [] -> ValueError\\n\",\n    \"* [1, 3, 2, -7, 5], 7 -> [2, 4]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def two_sum(self, nums, val):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_two_sum.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestTwoSum(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_two_sum(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.two_sum, None, None)\\n\",\n    \"        self.assertRaises(ValueError, solution.two_sum, [], 0)\\n\",\n    \"        target = 7\\n\",\n    \"        nums = [1, 3, 2, -7, 5]\\n\",\n    \"        expected = [2, 4]\\n\",\n    \"        self.assertEqual(solution.two_sum(nums, target), expected)\\n\",\n    \"        print('Success: test_two_sum')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestTwoSum()\\n\",\n    \"    test.test_two_sum()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/two_sum/two_sum_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given an array, find the two indices that sum to a specific value.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is there exactly one solution?\\n\",\n    \"    * Yes\\n\",\n    \"* Is there always a solution?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the array an array of ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the array sorted?\\n\",\n    \"    No\\n\",\n    \"* Are negative values possible?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* [] -> ValueError\\n\",\n    \"* [1, 3, 2, -7, 5], 7 -> [2, 4]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### Brute force\\n\",\n    \"\\n\",\n    \"* For i in range(len(input)):\\n\",\n    \"    * For j in range(i+1, len(input)):\\n\",\n    \"        * if i + j == target return True\\n\",\n    \"* return False\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n^2)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Optimized\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* Loop through each num in nums\\n\",\n    \"    * Calculate the cache_target = target - num\\n\",\n    \"\\n\",\n    \"target = 7\\n\",\n    \"index  =  0  1  2   3  4\\n\",\n    \"nums   = [1, 3, 2, -7, 5]\\n\",\n    \"          ^\\n\",\n    \"cache_target = 7 - 1 = 6\\n\",\n    \"cache\\n\",\n    \"6 -> 0\\n\",\n    \"\\n\",\n    \"1 not in cache\\n\",\n    \"\\n\",\n    \"index  =  0  1  2   3  4\\n\",\n    \"nums   = [1, 3, 2, -7, 5]\\n\",\n    \"             ^\\n\",\n    \"cache_target = 7 - 3 = 4\\n\",\n    \"cache\\n\",\n    \"6 -> 0\\n\",\n    \"4 -> 1\\n\",\n    \"\\n\",\n    \"3 not in cache\\n\",\n    \"\\n\",\n    \"index  =  0  1  2   3  4\\n\",\n    \"nums   = [1, 3, 2, -7, 5]\\n\",\n    \"                ^\\n\",\n    \"cache_target = 7 - 2 = 5\\n\",\n    \"cache\\n\",\n    \"6 -> 0\\n\",\n    \"4 -> 1\\n\",\n    \"5 -> 2\\n\",\n    \"\\n\",\n    \"2 not in cache\\n\",\n    \"\\n\",\n    \"index  =  0  1  2   3  4\\n\",\n    \"nums   = [1, 3, 2, -7, 5]\\n\",\n    \"                    ^\\n\",\n    \"cache_target = 7 + 7 = 14\\n\",\n    \"cache\\n\",\n    \"6  -> 0\\n\",\n    \"4  -> 1\\n\",\n    \"5  -> 2\\n\",\n    \"14 -> 3\\n\",\n    \"\\n\",\n    \"-7 not in cache\\n\",\n    \"\\n\",\n    \"index  =  0  1  2   3  4\\n\",\n    \"nums   = [1, 3, 2, -7, 5]\\n\",\n    \"                       ^\\n\",\n    \"cache_target = 7 - 5 = 2\\n\",\n    \"cache\\n\",\n    \"6  -> 0\\n\",\n    \"4  -> 1\\n\",\n    \"5  -> 2\\n\",\n    \"14 -> 3\\n\",\n    \"\\n\",\n    \"5 in cache, success, output matching indices: cache[num] and current iteration index\\n\",\n    \"\\n\",\n    \"output = [2, 4]\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def two_sum(self, nums, target):\\n\",\n    \"        if nums is None or target is None:\\n\",\n    \"            raise TypeError('nums or target cannot be None')\\n\",\n    \"        if not nums:\\n\",\n    \"            raise ValueError('nums cannot be empty')\\n\",\n    \"        cache = {}\\n\",\n    \"        for index, num in enumerate(nums):\\n\",\n    \"            cache_target = target - num\\n\",\n    \"            if num in cache:\\n\",\n    \"                return [cache[num], index]\\n\",\n    \"            else:\\n\",\n    \"                cache[cache_target] = index\\n\",\n    \"        return None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_two_sum.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_two_sum.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestTwoSum(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_two_sum(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.two_sum, None, None)\\n\",\n    \"        self.assertRaises(ValueError, solution.two_sum, [], 0)\\n\",\n    \"        target = 7\\n\",\n    \"        nums = [1, 3, 2, -7, 5]\\n\",\n    \"        expected = [2, 4]\\n\",\n    \"        self.assertEqual(solution.two_sum(nums, target), expected)\\n\",\n    \"        print('Success: test_two_sum')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestTwoSum()\\n\",\n    \"    test.test_two_sum()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_two_sum\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_two_sum.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/unique_chars/__init__.py",
    "content": ""
  },
  {
    "path": "arrays_strings/unique_chars/test_unique_chars.py",
    "content": "import unittest\n\n\nclass TestUniqueChars(unittest.TestCase):\n\n    def test_unique_chars(self, func):\n        self.assertEqual(func(None), False)\n        self.assertEqual(func(''), True)\n        self.assertEqual(func('foo'), False)\n        self.assertEqual(func('bar'), True)\n        print('Success: test_unique_chars')\n\n\ndef main():\n    test = TestUniqueChars()\n    unique_chars = UniqueChars()\n    test.test_unique_chars(unique_chars.has_unique_chars)\n    try:\n        unique_chars_set = UniqueCharsSet()\n        test.test_unique_chars(unique_chars_set.has_unique_chars)\n        unique_chars_in_place = UniqueCharsInPlace()\n        test.test_unique_chars(unique_chars_in_place.has_unique_chars)\n    except NameError:\n        # Alternate solutions are only defined\n        # in the solutions file\n        pass\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "arrays_strings/unique_chars/unique_chars_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement an algorithm to determine if a string has all unique characters.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the string is ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: Unicode strings could require special handling depending on your language\\n\",\n    \"* Can we assume this is case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we use additional data structures?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> False\\n\",\n    \"* '' -> True\\n\",\n    \"* 'foo' -> False\\n\",\n    \"* 'bar' -> True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/unique_chars/unique_chars_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class UniqueChars(object):\\n\",\n    \"\\n\",\n    \"    def has_unique_chars(self, string):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_unique_chars.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestUniqueChars(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_unique_chars(self, func):\\n\",\n    \"        self.assertEqual(func(None), False)\\n\",\n    \"        self.assertEqual(func(''), True)\\n\",\n    \"        self.assertEqual(func('foo'), False)\\n\",\n    \"        self.assertEqual(func('bar'), True)\\n\",\n    \"        print('Success: test_unique_chars')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestUniqueChars()\\n\",\n    \"    unique_chars = UniqueChars()\\n\",\n    \"    test.test_unique_chars(unique_chars.has_unique_chars)\\n\",\n    \"    try:\\n\",\n    \"        unique_chars_set = UniqueCharsSet()\\n\",\n    \"        test.test_unique_chars(unique_chars_set.has_unique_chars)\\n\",\n    \"        unique_chars_in_place = UniqueCharsInPlace()\\n\",\n    \"        test.test_unique_chars(unique_chars_in_place.has_unique_chars)\\n\",\n    \"    except NameError:\\n\",\n    \"        # Alternate solutions are only defined\\n\",\n    \"        # in the solutions file\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/unique_chars/unique_chars_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "arrays_strings/unique_chars/unique_chars_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement an algorithm to determine if a string has all unique characters.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm 1: Sets and Length Comparison](#Algorithm-1:-Sets-and-Length-Comparison)\\n\",\n    \"* [Code: Sets and Length Comparison](#Code:-Sets-and-Length-Comparison)\\n\",\n    \"* [Algorithm 2: Hash Map Lookup](#Algorithm-2:-Hash-Map-Lookup)\\n\",\n    \"* [Code: Hash Map Lookup](#Code:-Hash-Map-Lookup)\\n\",\n    \"* [Algorithm 3: In-Place](#Algorithm-3:-In-Place)\\n\",\n    \"* [Code: In-Place](#Code:-In-Place)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the string is ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: Unicode strings could require special handling depending on your language\\n\",\n    \"* Can we assume this is case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we use additional data structures?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> False\\n\",\n    \"* '' -> True\\n\",\n    \"* 'foo' -> False\\n\",\n    \"* 'bar' -> True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm 1: Sets and Length Comparison\\n\",\n    \"\\n\",\n    \"A set is an unordered collection of unique elements.  \\n\",\n    \"\\n\",\n    \"* If the length of the set(string) equals the length of the string\\n\",\n    \"    * Return True\\n\",\n    \"* Else\\n\",\n    \"    * Return False\\n\",\n    \"    \\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: Additional O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code: Sets and Length Comparison\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class UniqueCharsSet(object):\\n\",\n    \"\\n\",\n    \"    def has_unique_chars(self, string):\\n\",\n    \"        if string is None:\\n\",\n    \"            return False\\n\",\n    \"        return len(set(string)) == len(string)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm 2: Hash Map Lookup\\n\",\n    \"\\n\",\n    \"We'll keep a hash map (set) to keep track of unique characters we encounter.  \\n\",\n    \"\\n\",\n    \"Steps:\\n\",\n    \"* Scan each character\\n\",\n    \"* For each character:\\n\",\n    \"    * If the character does not exist in a hash map, add the character to a hash map\\n\",\n    \"    * Else, return False\\n\",\n    \"* Return True\\n\",\n    \"\\n\",\n    \"Notes:\\n\",\n    \"* We could also use a dictionary, but it seems more logical to use a set as it does not contain duplicate elements\\n\",\n    \"* Since the characters are in ASCII, we could potentially use an array of size 128 (or 256 for extended ASCII)\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: Additional O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code: Hash Map Lookup\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class UniqueChars(object):\\n\",\n    \"\\n\",\n    \"    def has_unique_chars(self, string):\\n\",\n    \"        if string is None:\\n\",\n    \"            return False\\n\",\n    \"        chars_set = set()\\n\",\n    \"        for char in string:\\n\",\n    \"            if char in chars_set:\\n\",\n    \"                return False\\n\",\n    \"            else:\\n\",\n    \"                chars_set.add(char)\\n\",\n    \"        return True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm 3: In-Place\\n\",\n    \"\\n\",\n    \"Assume we cannot use additional data structures, which will eliminate the fast lookup O(1) time provided by our hash map.  \\n\",\n    \"* Scan each character\\n\",\n    \"* For each character:\\n\",\n    \"    * Scan all [other] characters in the array\\n\",\n    \"        * Excluding the current character from the scan is rather tricky in Python and results in a non-Pythonic solution\\n\",\n    \"        * If there is a match, return False\\n\",\n    \"* Return True\\n\",\n    \"\\n\",\n    \"Algorithm Complexity:\\n\",\n    \"* Time: O(n^2)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code: In-Place\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class UniqueCharsInPlace(object):\\n\",\n    \"\\n\",\n    \"    def has_unique_chars(self, string):\\n\",\n    \"        if string is None:\\n\",\n    \"            return False\\n\",\n    \"        for char in string:\\n\",\n    \"            if string.count(char) > 1:\\n\",\n    \"                return False\\n\",\n    \"        return True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_unique_chars.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_unique_chars.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestUniqueChars(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_unique_chars(self, func):\\n\",\n    \"        self.assertEqual(func(None), False)\\n\",\n    \"        self.assertEqual(func(''), True)\\n\",\n    \"        self.assertEqual(func('foo'), False)\\n\",\n    \"        self.assertEqual(func('bar'), True)\\n\",\n    \"        print('Success: test_unique_chars')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestUniqueChars()\\n\",\n    \"    unique_chars = UniqueChars()\\n\",\n    \"    test.test_unique_chars(unique_chars.has_unique_chars)\\n\",\n    \"    try:\\n\",\n    \"        unique_chars_set = UniqueCharsSet()\\n\",\n    \"        test.test_unique_chars(unique_chars_set.has_unique_chars)\\n\",\n    \"        unique_chars_in_place = UniqueCharsInPlace()\\n\",\n    \"        test.test_unique_chars(unique_chars_in_place.has_unique_chars)\\n\",\n    \"    except NameError:\\n\",\n    \"        # Alternate solutions are only defined\\n\",\n    \"        # in the solutions file\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_unique_chars\\n\",\n      \"Success: test_unique_chars\\n\",\n      \"Success: test_unique_chars\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_unique_chars.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/__init__.py",
    "content": ""
  },
  {
    "path": "bit_manipulation/bit/__init__.py",
    "content": ""
  },
  {
    "path": "bit_manipulation/bit/bit_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement common bit manipulation operations: get_bit, set_bit, clear_bit, clear_bits_msb_to_index, clear_bits_msb_to_lsb, update_bit.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None as a number input -> Exception\\n\",\n    \"* Negative index -> Exception\\n\",\n    \"\\n\",\n    \"### get_bit\\n\",\n    \"    number   = 0b10001110, index = 3\\n\",\n    \"    expected = True\\n\",\n    \"### set_bit\\n\",\n    \"    number   = 0b10001110, index = 4\\n\",\n    \"    expected = 0b10011110\\n\",\n    \"### clear_bit\\n\",\n    \"    number   = 0b10001110, index = 3\\n\",\n    \"    expected = 0b10000110\\n\",\n    \"### clear_bits_msb_to_index\\n\",\n    \"    number   = 0b10001110, index = 3\\n\",\n    \"    expected = 0b00000110\\n\",\n    \"### clear_bits_index_to_lsb\\n\",\n    \"    number   = 0b10001110, index = 3\\n\",\n    \"    expected = 0b10000000\\n\",\n    \"### update_bit\\n\",\n    \"    number   = 0b10001110, index = 3, value = 1\\n\",\n    \"    expected = 0b10001110\\n\",\n    \"    number   = 0b10001110, index = 3, value = 0\\n\",\n    \"    expected = 0b10000110\\n\",\n    \"    number   = 0b10001110, index = 0, value = 1\\n\",\n    \"    expected = 0b10001111\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Bit(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, number):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def get_bit(self, index):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def set_bit(self, index):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def clear_bit(self, index):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def clear_bits_msb_to_index(self, index):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def clear_bits_index_to_lsb(self, index):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def update_bit(self, index, value):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_bit.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBit(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_bit(self):\\n\",\n    \"        number = int('10001110', base=2)\\n\",\n    \"        bit = Bit(number)\\n\",\n    \"        self.assertEqual(bit.get_bit(index=3), True)\\n\",\n    \"        expected = int('10011110', base=2)\\n\",\n    \"        self.assertEqual(bit.set_bit(index=4), expected)\\n\",\n    \"        bit = Bit(number)\\n\",\n    \"        expected = int('10000110', base=2)\\n\",\n    \"        self.assertEqual(bit.clear_bit(index=3), expected)\\n\",\n    \"        bit = Bit(number)\\n\",\n    \"        expected = int('00000110', base=2)\\n\",\n    \"        self.assertEqual(bit.clear_bits_msb_to_index(index=3), expected)\\n\",\n    \"        bit = Bit(number)\\n\",\n    \"        expected = int('10000000', base=2)\\n\",\n    \"        self.assertEqual(bit.clear_bits_index_to_lsb(index=3), expected)\\n\",\n    \"        bit = Bit(number)\\n\",\n    \"        self.assertEqual(bit.update_bit(index=3, value=1), number)\\n\",\n    \"        bit = Bit(number)\\n\",\n    \"        expected = int('10000110', base=2)\\n\",\n    \"        self.assertEqual(bit.update_bit(index=3, value=0), expected)\\n\",\n    \"        bit = Bit(number)\\n\",\n    \"        expected = int('10001111', base=2)\\n\",\n    \"        self.assertEqual(bit.update_bit(index=0, value=1), expected)\\n\",\n    \"        print('Success: test_bit')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBit()\\n\",\n    \"    test.test_bit()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/bit/bit_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement common bit manipulation operations: get_bit, set_bit, clear_bit, clear_bits_msb_to_index, clear_bits_msb_to_lsb, update_bit.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None as a number input -> Exception\\n\",\n    \"* Negative index -> Exception\\n\",\n    \"\\n\",\n    \"### get_bit\\n\",\n    \"    number   = 0b10001110, index = 3\\n\",\n    \"    expected = True\\n\",\n    \"### set_bit\\n\",\n    \"    number   = 0b10001110, index = 4\\n\",\n    \"    expected = 0b10011110\\n\",\n    \"### clear_bit\\n\",\n    \"    number   = 0b10001110, index = 3\\n\",\n    \"    expected = 0b10000110\\n\",\n    \"### clear_bits_msb_to_index\\n\",\n    \"    number   = 0b10001110, index = 3\\n\",\n    \"    expected = 0b00000110\\n\",\n    \"### clear_bits_index_to_lsb\\n\",\n    \"    number   = 0b10001110, index = 3\\n\",\n    \"    expected = 0b10000000\\n\",\n    \"### update_bit\\n\",\n    \"    number   = 0b10001110, index = 3, value = 1\\n\",\n    \"    expected = 0b10001110\\n\",\n    \"    number   = 0b10001110, index = 3, value = 0\\n\",\n    \"    expected = 0b10000110\\n\",\n    \"    number   = 0b10001110, index = 0, value = 1\\n\",\n    \"    expected = 0b10001111\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### get_bit\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"indices  7 6 5 4  3 2 1 0  index = 3\\n\",\n    \"--------------------------------------------------\\n\",\n    \"input    1 0 0 0  1 1 1 0  0b10001110\\n\",\n    \"mask     0 0 0 0  1 0 0 0  1 << index\\n\",\n    \"--------------------------------------------------\\n\",\n    \"result   0 0 0 0  1 0 0 0  number & mask != 0\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\\n\",\n    \"\\n\",\n    \"### set_bit\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"indices  7 6 5 4  3 2 1 0  index = 4\\n\",\n    \"--------------------------------------------------\\n\",\n    \"input    1 0 0 0  1 1 1 0  0b10001110\\n\",\n    \"mask     0 0 0 1  0 0 0 0  1 << index\\n\",\n    \"--------------------------------------------------\\n\",\n    \"result   1 0 0 1  1 1 1 0  number | mask\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\\n\",\n    \"\\n\",\n    \"### clear_bit\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"indices  7 6 5 4  3 2 1 0  index = 3\\n\",\n    \"--------------------------------------------------\\n\",\n    \"input    1 0 0 0  1 1 1 0  0b10001110\\n\",\n    \"mask     0 0 0 0  1 0 0 0  1 << index\\n\",\n    \"mask     1 1 1 1  0 1 1 1  ~(1 << index)\\n\",\n    \"--------------------------------------------------\\n\",\n    \"result   1 0 0 0  0 1 1 0  number & mask\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\\n\",\n    \"\\n\",\n    \"### clear_bits_msb_to_index\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"indices  7 6 5 4  3 2 1 0  index = 3\\n\",\n    \"--------------------------------------------------\\n\",\n    \"input    1 0 0 0  1 1 1 0  0b10001110\\n\",\n    \"mask     0 0 0 0  1 0 0 0  1 << index\\n\",\n    \"mask     0 0 0 0  0 1 1 1  (1 << index) - 1\\n\",\n    \"--------------------------------------------------\\n\",\n    \"result   0 0 0 0  0 1 1 1  number & mask\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\\n\",\n    \"\\n\",\n    \"### clear_bits_index_to_lsb\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"indices  7 6 5 4  3 2 1 0  index = 3\\n\",\n    \"--------------------------------------------------\\n\",\n    \"input    1 0 0 0  1 1 1 0  0b10001110\\n\",\n    \"mask     0 0 0 1  0 0 0 0  1 << index + 1\\n\",\n    \"mask     0 0 0 0  1 1 1 1  (1 << index + 1) - 1\\n\",\n    \"mask     1 1 1 1  0 0 0 0  ~((1 << index + 1) - 1)\\n\",\n    \"--------------------------------------------------\\n\",\n    \"result   1 0 0 0  0 0 0 0  number & mask\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\\n\",\n    \"\\n\",\n    \"### update_bit\\n\",\n    \"\\n\",\n    \"* Use `get_bit` to see if the value is already set or cleared\\n\",\n    \"* If not, use `set_bit` if setting the value or `clear_bit` if clearing the value\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\\n\",\n    \"\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def validate_index(func):\\n\",\n    \"    def validate_index_wrapper(self, *args, **kwargs):\\n\",\n    \"        for arg in args:\\n\",\n    \"            if arg < 0:\\n\",\n    \"                raise IndexError('Invalid index')\\n\",\n    \"        return func(self, *args, **kwargs)\\n\",\n    \"    return validate_index_wrapper\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Bit(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, number):\\n\",\n    \"        if number is None:\\n\",\n    \"            raise TypeError('number cannot be None')\\n\",\n    \"        self.number = number\\n\",\n    \"\\n\",\n    \"    @validate_index\\n\",\n    \"    def get_bit(self, index):\\n\",\n    \"        mask = 1 << index\\n\",\n    \"        return self.number & mask != 0\\n\",\n    \"\\n\",\n    \"    @validate_index\\n\",\n    \"    def set_bit(self, index):\\n\",\n    \"        mask = 1 << index\\n\",\n    \"        self.number |= mask\\n\",\n    \"        return self.number\\n\",\n    \"\\n\",\n    \"    @validate_index\\n\",\n    \"    def clear_bit(self, index):\\n\",\n    \"        mask = ~(1 << index)\\n\",\n    \"        self.number &= mask\\n\",\n    \"        return self.number\\n\",\n    \"\\n\",\n    \"    @validate_index\\n\",\n    \"    def clear_bits_msb_to_index(self, index):\\n\",\n    \"        mask = (1 << index) - 1\\n\",\n    \"        self.number &= mask\\n\",\n    \"        return self.number\\n\",\n    \"\\n\",\n    \"    @validate_index\\n\",\n    \"    def clear_bits_index_to_lsb(self, index):\\n\",\n    \"        mask = ~((1 << index + 1) - 1)\\n\",\n    \"        self.number &= mask\\n\",\n    \"        return self.number\\n\",\n    \"\\n\",\n    \"    @validate_index\\n\",\n    \"    def update_bit(self, index, value):\\n\",\n    \"        if value is None or value not in (0, 1):\\n\",\n    \"            raise Exception('Invalid value')\\n\",\n    \"        if self.get_bit(index) == value:\\n\",\n    \"            return self.number\\n\",\n    \"        if value:\\n\",\n    \"            self.set_bit(index)\\n\",\n    \"        else:\\n\",\n    \"            self.clear_bit(index)\\n\",\n    \"        return self.number\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_bit.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_bit.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBit(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_bit(self):\\n\",\n    \"        number = int('10001110', base=2)\\n\",\n    \"        bit = Bit(number)\\n\",\n    \"        self.assertEqual(bit.get_bit(index=3), True)\\n\",\n    \"        expected = int('10011110', base=2)\\n\",\n    \"        self.assertEqual(bit.set_bit(index=4), expected)\\n\",\n    \"        bit = Bit(number)\\n\",\n    \"        expected = int('10000110', base=2)\\n\",\n    \"        self.assertEqual(bit.clear_bit(index=3), expected)\\n\",\n    \"        bit = Bit(number)\\n\",\n    \"        expected = int('00000110', base=2)\\n\",\n    \"        self.assertEqual(bit.clear_bits_msb_to_index(index=3), expected)\\n\",\n    \"        bit = Bit(number)\\n\",\n    \"        expected = int('10000000', base=2)\\n\",\n    \"        self.assertEqual(bit.clear_bits_index_to_lsb(index=3), expected)\\n\",\n    \"        bit = Bit(number)\\n\",\n    \"        self.assertEqual(bit.update_bit(index=3, value=1), number)\\n\",\n    \"        bit = Bit(number)\\n\",\n    \"        expected = int('10000110', base=2)\\n\",\n    \"        self.assertEqual(bit.update_bit(index=3, value=0), expected)\\n\",\n    \"        bit = Bit(number)\\n\",\n    \"        expected = int('10001111', base=2)\\n\",\n    \"        self.assertEqual(bit.update_bit(index=0, value=1), expected)\\n\",\n    \"        print('Success: test_bit')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBit()\\n\",\n    \"    test.test_bit()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_bit\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_bit.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/bit/test_bit.py",
    "content": "import unittest\n\n\nclass TestBit(unittest.TestCase):\n\n    def test_bit(self):\n        number = int('10001110', base=2)\n        bit = Bit(number)\n        self.assertEqual(bit.get_bit(index=3), True)\n        expected = int('10011110', base=2)\n        self.assertEqual(bit.set_bit(index=4), expected)\n        bit = Bit(number)\n        expected = int('10000110', base=2)\n        self.assertEqual(bit.clear_bit(index=3), expected)\n        bit = Bit(number)\n        expected = int('00000110', base=2)\n        self.assertEqual(bit.clear_bits_msb_to_index(index=3), expected)\n        bit = Bit(number)\n        expected = int('10000000', base=2)\n        self.assertEqual(bit.clear_bits_index_to_lsb(index=3), expected)\n        bit = Bit(number)\n        self.assertEqual(bit.update_bit(index=3, value=1), number)\n        bit = Bit(number)\n        expected = int('10000110', base=2)\n        self.assertEqual(bit.update_bit(index=3, value=0), expected)\n        bit = Bit(number)\n        expected = int('10001111', base=2)\n        self.assertEqual(bit.update_bit(index=0, value=1), expected)\n        print('Success: test_bit')\n\n\ndef main():\n    test = TestBit()\n    test.test_bit()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "bit_manipulation/bits_to_flip/__init__.py",
    "content": ""
  },
  {
    "path": "bit_manipulation/bits_to_flip/bits_to_flip_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine the number of bits to flip to convert int a to int b'.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume A and B are always ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output an int?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume A and B are always the same number of bits?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid (not None)?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* A or B is None -> Exception\\n\",\n    \"* General case\\n\",\n    \"<pre>\\n\",\n    \"    A = 11101\\n\",\n    \"    B = 01111\\n\",\n    \"    Result: 2\\n\",\n    \"<pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Bits(object):\\n\",\n    \"\\n\",\n    \"    def bits_to_flip(self, a, b):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_bits_to_flip.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBits(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_bits_to_flip(self):\\n\",\n    \"        bits = Bits()\\n\",\n    \"        a = int('11101', base=2)\\n\",\n    \"        b = int('01111', base=2)\\n\",\n    \"        expected = 2\\n\",\n    \"        self.assertEqual(bits.bits_to_flip(a, b), expected)\\n\",\n    \"        print('Success: test_bits_to_flip')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBits()\\n\",\n    \"    test.test_bits_to_flip()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/bits_to_flip/bits_to_flip_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine the number of bits to flip to convert int a to int b.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume A and B are always ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output an int?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume A and B are always the same number of bits?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid (not None)?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* A or B is None -> Exception\\n\",\n    \"* General case\\n\",\n    \"<pre>\\n\",\n    \"    A = 11101\\n\",\n    \"    B = 01111\\n\",\n    \"    Result: 2\\n\",\n    \"<pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We can use the xor operator to determine the bit differences between a and b\\n\",\n    \"\\n\",\n    \"* Set count to 0\\n\",\n    \"* Set c to a xor b\\n\",\n    \"* Loop while c != 0:\\n\",\n    \"    * Increment count if the LSB in c is a 1\\n\",\n    \"        * We can check this by using a mask of 1\\n\",\n    \"    * Right shift c by 1\\n\",\n    \"* Return the count\\n\",\n    \"    \\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(b), where b is the number of bits\\n\",\n    \"* Space: O(b), where b is the number of bits\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Bits(object):\\n\",\n    \"\\n\",\n    \"    def bits_to_flip(self, a, b):\\n\",\n    \"        if a is None or b is None:\\n\",\n    \"            raise TypeError('a or b cannot be None')\\n\",\n    \"        count = 0\\n\",\n    \"        c = a ^ b\\n\",\n    \"        while c:\\n\",\n    \"            count += c & 1\\n\",\n    \"            c >>= 1\\n\",\n    \"        return count\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_bits_to_flip.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_bits_to_flip.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBits(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_bits_to_flip(self):\\n\",\n    \"        bits = Bits()\\n\",\n    \"        a = int('11101', base=2)\\n\",\n    \"        b = int('01111', base=2)\\n\",\n    \"        expected = 2\\n\",\n    \"        self.assertEqual(bits.bits_to_flip(a, b), expected)\\n\",\n    \"        print('Success: test_bits_to_flip')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBits()\\n\",\n    \"    test.test_bits_to_flip()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_bits_to_flip\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_bits_to_flip.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/bits_to_flip/test_bits_to_flip.py",
    "content": "import unittest\n\n\nclass TestBits(unittest.TestCase):\n\n    def test_bits_to_flip(self):\n        bits = Bits()\n        a = int('11101', base=2)\n        b = int('01111', base=2)\n        expected = 2\n        self.assertEqual(bits.bits_to_flip(a, b), expected)\n        print('Success: test_bits_to_flip')\n\n\ndef main():\n    test = TestBits()\n    test.test_bits_to_flip()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "bit_manipulation/draw_line/__init__.py",
    "content": ""
  },
  {
    "path": "bit_manipulation/draw_line/draw_line_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement the method draw_line(screen, width, x1, x2) where screen is a list of bytes, width is divisible by 8, and x1, x2 are absolute pixel positions.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* For the output, do we set corresponding bits in screen?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Invalid inputs -> Exception\\n\",\n    \"    * screen is empty\\n\",\n    \"    * width = 0\\n\",\n    \"    * any input param is None\\n\",\n    \"    * x1 or x2 is out of bounds\\n\",\n    \"* General case for len(screen) = 20, width = 32:\\n\",\n    \"    * x1 = 2, x2 = 6\\n\",\n    \"        * screen[0] = int('00111110', base=2)\\n\",\n    \"    * x1 = 68, x2 = 80\\n\",\n    \"        * screen[8], int('00001111', base=2)\\n\",\n    \"        * screen[9], int('11111111', base=2)\\n\",\n    \"        * screen[10], int('10000000', base=2)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BitsScreen(object):\\n\",\n    \"\\n\",\n    \"    def draw_line(self, screen, width, x1, x2):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_draw_line.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBitsScreen(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_draw_line(self):\\n\",\n    \"        bits_screen = BitsScreen()\\n\",\n    \"        screen = []\\n\",\n    \"        for _ in range(20):\\n\",\n    \"            screen.append(int('00000000', base=2))\\n\",\n    \"        bits_screen.draw_line(screen, width=32, x1=68, x2=80)\\n\",\n    \"        self.assertEqual(screen[8], int('00001111', base=2))\\n\",\n    \"        self.assertEqual(screen[9], int('11111111', base=2))\\n\",\n    \"        self.assertEqual(screen[10], int('10000000', base=2))\\n\",\n    \"        bits_screen.draw_line(screen, width=32, x1=2, x2=6)\\n\",\n    \"        self.assertEqual(screen[0], int('00111110', base=2))\\n\",\n    \"        bits_screen.draw_line(screen, width=32, x1=10, x2=13)\\n\",\n    \"        self.assertEqual(screen[1], int('00111100', base=2))\\n\",\n    \"        print('Success: test_draw_line')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBitsScreen()\\n\",\n    \"    test.test_draw_line()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/draw_line/draw_line_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement the method draw_line(screen, width, x1, x2) where screen is a list of bytes, width is divisible by 8, and x1, x2 are absolute pixel positions.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* For the output, do we set corresponding bits in screen?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Invalid inputs -> Exception\\n\",\n    \"    * screen is empty\\n\",\n    \"    * width = 0\\n\",\n    \"    * any input param is None\\n\",\n    \"    * x1 or x2 is out of bounds\\n\",\n    \"* General case for len(screen) = 20, width = 32:\\n\",\n    \"    * x1 = 2, x2 = 6\\n\",\n    \"        * screen[0] = int('00111110', base=2)\\n\",\n    \"    * x1 = 68, x2 = 80\\n\",\n    \"        * screen[8], int('00001111', base=2)\\n\",\n    \"        * screen[9], int('11111111', base=2)\\n\",\n    \"        * screen[10], int('10000000', base=2)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Set start offset to x1 % 8\\n\",\n    \"* Set end offset to x2 % 8\\n\",\n    \"* Determine where the first and last full bytes are\\n\",\n    \"    * First full byte = x1 // 8\\n\",\n    \"        * Increment by 1 if start offset != 0\\n\",\n    \"    * Last full byte = x2 // 8\\n\",\n    \"        * Decrement by 1 if end offset != 7\\n\",\n    \"    * Fill the bytes with 1111 1111\\n\",\n    \"* If x1 and x2 are in the same byte\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"    x1 = 2\\n\",\n    \"    x2 = 6\\n\",\n    \"\\n\",\n    \"    index  0123 4567\\n\",\n    \"    byte   0011 1110\\n\",\n    \"\\n\",\n    \"    We want to build left and right masks such that:\\n\",\n    \"\\n\",\n    \"    left   0011 1111\\n\",\n    \"    right  1111 1110\\n\",\n    \"    ----------------\\n\",\n    \"           0011 1110  left & right\\n\",\n    \"\\n\",\n    \"    Build the left mask:\\n\",\n    \"\\n\",\n    \"    left   0000 0001  1\\n\",\n    \"           0100 0000  1 << (8 - x1)\\n\",\n    \"           0011 1111  (1 << (8 - x1)) - 1\\n\",\n    \"\\n\",\n    \"    Build the right mask:\\n\",\n    \"\\n\",\n    \"    right  0000 0000  1\\n\",\n    \"           0000 0010  1 << (8 - x2 - 1)\\n\",\n    \"           0000 0001  (1 << (8 - x2 - 1) - 1\\n\",\n    \"           1111 1110  ~((1 << (8 - x2 - 1) - 1)\\n\",\n    \"\\n\",\n    \"    Combine the left and right masks:\\n\",\n    \"\\n\",\n    \"    left   0011 1111\\n\",\n    \"    right  1111 1110\\n\",\n    \"    ----------------\\n\",\n    \"           0011 1110  left & right\\n\",\n    \"\\n\",\n    \"    Set screen[x1//8] or screen[x2//8] |= mask\\n\",\n    \"</pre>\\n\",\n    \"* Else\\n\",\n    \"<pre>\\n\",\n    \"    If our starting partial byte is:\\n\",\n    \"           0000 1111\\n\",\n    \"\\n\",\n    \"    Build start mask:\\n\",\n    \"    \\n\",\n    \"    start  0000 0001  1\\n\",\n    \"           0001 0000  1 << 1 << start offset\\n\",\n    \"           0000 1111  (1 << 1 << start offset) - 1\\n\",\n    \"\\n\",\n    \"    If our ending partial byte is:\\n\",\n    \"           1111 1100\\n\",\n    \"\\n\",\n    \"    Build end mask:\\n\",\n    \"    \\n\",\n    \"    end    1000 0000  0x10000000\\n\",\n    \"           1111 1100  0x10000000 >> end offset\\n\",\n    \"\\n\",\n    \"    Set screen[x1//8] |= start mask\\n\",\n    \"    Set screen[x2//8] |= end mask\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(length of screen)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BitsScreen(object):\\n\",\n    \"\\n\",\n    \"    def draw_line(self, screen, width, x1, x2):\\n\",\n    \"        if None in (screen, width, x1, x2):\\n\",\n    \"            raise TypeError('Invalid argument: None')\\n\",\n    \"        if not screen or not width:\\n\",\n    \"            raise ValueError('Invalid arg: Empty screen or width')\\n\",\n    \"        MAX_BIT_VALUE = len(screen) * 8\\n\",\n    \"        if x1 < 0 or x2 < 0 or x1 >= MAX_BIT_VALUE or x2 >= MAX_BIT_VALUE:\\n\",\n    \"            raise ValueError('Invalid arg: x1 or x2 out of bounds')\\n\",\n    \"        start_bit = x1 % 8\\n\",\n    \"        end_bit = x2 % 8\\n\",\n    \"        first_full_byte = x1 // 8\\n\",\n    \"        if start_bit != 0:\\n\",\n    \"            first_full_byte += 1\\n\",\n    \"        last_full_byte = x2 // 8\\n\",\n    \"        if end_bit != (8 - 1):\\n\",\n    \"            last_full_byte -= 1\\n\",\n    \"        for byte in range(first_full_byte, last_full_byte + 1):\\n\",\n    \"            screen[byte] = int('11111111', base=2)\\n\",\n    \"        start_byte = x1 // 8\\n\",\n    \"        end_byte = x2 // 8\\n\",\n    \"        if start_byte == end_byte:\\n\",\n    \"            left_mask = (1 << (8 - start_bit)) - 1\\n\",\n    \"            right_mask = ~((1 << (8 - end_bit - 1)) - 1)\\n\",\n    \"            mask = left_mask & right_mask\\n\",\n    \"            screen[start_byte] |= mask\\n\",\n    \"        else:\\n\",\n    \"            start_mask = (1 << (8 - start_bit)) - 1\\n\",\n    \"            end_mask = 1 << (8 - end_bit - 1)\\n\",\n    \"            screen[start_byte] |= start_mask\\n\",\n    \"            screen[end_byte] |= end_mask\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_draw_line.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_draw_line.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBitsScreen(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_draw_line(self):\\n\",\n    \"        bits_screen = BitsScreen()\\n\",\n    \"        screen = []\\n\",\n    \"        for _ in range(20):\\n\",\n    \"            screen.append(int('00000000', base=2))\\n\",\n    \"        bits_screen.draw_line(screen, width=32, x1=68, x2=80)\\n\",\n    \"        self.assertEqual(screen[8], int('00001111', base=2))\\n\",\n    \"        self.assertEqual(screen[9], int('11111111', base=2))\\n\",\n    \"        self.assertEqual(screen[10], int('10000000', base=2))\\n\",\n    \"        bits_screen.draw_line(screen, width=32, x1=2, x2=6)\\n\",\n    \"        self.assertEqual(screen[0], int('00111110', base=2))\\n\",\n    \"        bits_screen.draw_line(screen, width=32, x1=10, x2=13)\\n\",\n    \"        self.assertEqual(screen[1], int('00111100', base=2))\\n\",\n    \"        print('Success: test_draw_line')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBitsScreen()\\n\",\n    \"    test.test_draw_line()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_draw_line\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_draw_line.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/draw_line/test_draw_line.py",
    "content": "import unittest\n\n\nclass TestBitsScreen(unittest.TestCase):\n\n    def test_draw_line(self):\n        bits_screen = BitsScreen()\n        screen = []\n        for _ in range(20):\n            screen.append(int('00000000', base=2))\n        bits_screen.draw_line(screen, width=32, x1=68, x2=80)\n        self.assertEqual(screen[8], int('00001111', base=2))\n        self.assertEqual(screen[9], int('11111111', base=2))\n        self.assertEqual(screen[10], int('10000000', base=2))\n        bits_screen.draw_line(screen, width=32, x1=2, x2=6)\n        self.assertEqual(screen[0], int('00111110', base=2))\n        bits_screen.draw_line(screen, width=32, x1=10, x2=13)\n        self.assertEqual(screen[1], int('00111100', base=2))\n        print('Success: test_draw_line')\n\n\ndef main():\n    test = TestBitsScreen()\n    test.test_draw_line()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "bit_manipulation/flip_bit/__init__.py",
    "content": ""
  },
  {
    "path": "bit_manipulation/flip_bit/flip_bit_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Flip one bit from 0 to 1 to maximize the longest sequence of 1s.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input an int, base 2?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input is a 32 bit number?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we have to validate the length of the input?\\n\",\n    \"    * No\\n\",\n    \"* Is the output an int?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume we are using a positive number since Python doesn't have an >>> operator?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* All 1's -> Count of 1s\\n\",\n    \"* All 0's -> 1\\n\",\n    \"* General case\\n\",\n    \"    * 0000 1111 1101 1101 1111 0011 1111 0000 -> 10 (ten)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Bits(object):\\n\",\n    \"\\n\",\n    \"    def flip_bit(self, num):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_flip_bit.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBits(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_flip_bit(self):\\n\",\n    \"        bits = Bits()\\n\",\n    \"        self.assertRaises(TypeError, bits.flip_bit, None)\\n\",\n    \"        self.assertEqual(bits.flip_bit(0), 1)\\n\",\n    \"        self.assertEqual(bits.flip_bit(-1), bits.MAX_BITS)\\n\",\n    \"        num = int('00001111110111011110001111110000', base=2)\\n\",\n    \"        expected = 10\\n\",\n    \"        self.assertEqual(bits.flip_bit(num), expected)\\n\",\n    \"        num = int('00000100111011101111100011111011', base=2)\\n\",\n    \"        expected = 9\\n\",\n    \"        self.assertEqual(bits.flip_bit(num), expected)\\n\",\n    \"        num = int('00010011101110111110001111101111', base=2)\\n\",\n    \"        expected = 10\\n\",\n    \"        self.assertEqual(bits.flip_bit(num), expected)\\n\",\n    \"        print('Success: test_print_binary')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBits()\\n\",\n    \"    test.test_flip_bit()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/flip_bit/flip_bit_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Flip one bit from 0 to 1 to maximize the longest sequence of 1s.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input an int, base 2?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input is a 32 bit number?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we have to validate the length of the input?\\n\",\n    \"    * No\\n\",\n    \"* Is the output an int?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume we are using a positive number since Python doesn't have an >>> operator?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* All 1's -> Count of 1s\\n\",\n    \"* All 0's -> 1\\n\",\n    \"* General case\\n\",\n    \"    * Trailing zeroes\\n\",\n    \"        * 0000 1111 1101 1101 1111 0011 1111 0000 -> 10 (ten)\\n\",\n    \"    * Trailing ones\\n\",\n    \"        * 0000 1001 1101 1101 1111 0001 1111 0111 -> 9\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* seen = []\\n\",\n    \"* Build a list of sequence counts\\n\",\n    \"    * Look for 0's\\n\",\n    \"        * This will be 0 length if the input has trailing ones\\n\",\n    \"        * Add sequence length to seen\\n\",\n    \"    * Look for 1's\\n\",\n    \"        * Add sequence length to seen\\n\",\n    \"* Find the largest sequence of ones looking at seen\\n\",\n    \"    * Loop through seen\\n\",\n    \"        * On each iteration of the loop, flip what we are looking for from 0 to 1 and vice versa\\n\",\n    \"        * If seen[i] represents 1's, continue, we only want to process 0's\\n\",\n    \"        * If this is our first iteration:\\n\",\n    \"            * max_result = seen[i+1] + 1 if seen[i] > 0\\n\",\n    \"            * continue\\n\",\n    \"        * If we are looking at leading zeroes (i == len(seen)-1):\\n\",\n    \"            * result = seen[i-1] + 1\\n\",\n    \"        * If we are looking at one zero:\\n\",\n    \"            * result = seen[i+1] + seen[i-1] + 1\\n\",\n    \"        * If we are looking at multiple zeroes:\\n\",\n    \"            * result = max(seen[i+1], seen[i-1]) + 1\\n\",\n    \"        * Update max_result based on result\\n\",\n    \"\\n\",\n    \"We should make a note that Python does not have a logical right shift operator built in.  We can either use a positive number or implement one for a 32 bit number:\\n\",\n    \"\\n\",\n    \"    num % 0x100000000 >> n\\n\",\n    \"    \\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(b)\\n\",\n    \"* Space: O(b)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Bits(object):\\n\",\n    \"\\n\",\n    \"    MAX_BITS = 32\\n\",\n    \"    \\n\",\n    \"    def _build_seen_list(self, num):\\n\",\n    \"        seen = []\\n\",\n    \"        looking_for = 0\\n\",\n    \"        count = 0\\n\",\n    \"        for _ in range(self.MAX_BITS):\\n\",\n    \"            if num & 1 != looking_for:\\n\",\n    \"                seen.append(count)\\n\",\n    \"                looking_for = not looking_for\\n\",\n    \"                count = 0\\n\",\n    \"            count += 1\\n\",\n    \"            num >>= 1\\n\",\n    \"        seen.append(count)\\n\",\n    \"        return seen\\n\",\n    \"    \\n\",\n    \"    def flip_bit(self, num):\\n\",\n    \"        if num is None:\\n\",\n    \"            raise TypeError('num cannot be None')\\n\",\n    \"        if num == -1:\\n\",\n    \"            return self.MAX_BITS\\n\",\n    \"        if num == 0:\\n\",\n    \"            return 1\\n\",\n    \"        seen = self._build_seen_list(num)\\n\",\n    \"        max_result = 0\\n\",\n    \"        looking_for = 0\\n\",\n    \"        for index, count in enumerate(seen):\\n\",\n    \"            result = 0\\n\",\n    \"            # Only look for zeroes\\n\",\n    \"            if looking_for == 1:\\n\",\n    \"                looking_for = not looking_for\\n\",\n    \"                continue\\n\",\n    \"            # First iteration, take trailing zeroes\\n\",\n    \"            # or trailing ones into account\\n\",\n    \"            if index == 0:\\n\",\n    \"                if count != 0:\\n\",\n    \"                    # Trailing zeroes\\n\",\n    \"                    try:\\n\",\n    \"                        result = seen[index + 1] + 1\\n\",\n    \"                    except IndexError:\\n\",\n    \"                        result = 1\\n\",\n    \"            # Last iteration\\n\",\n    \"            elif index == len(seen) - 1:\\n\",\n    \"                result = 1 + seen[index - 1]\\n\",\n    \"            else:\\n\",\n    \"                # One zero\\n\",\n    \"                if count == 1:\\n\",\n    \"                    result = seen[index + 1] + seen[index - 1] + 1\\n\",\n    \"                # Multiple zeroes\\n\",\n    \"                else:\\n\",\n    \"                    result = max(seen[index + 1], seen[index - 1]) + 1\\n\",\n    \"            if result > max_result:\\n\",\n    \"                max_result = result\\n\",\n    \"            looking_for = not looking_for\\n\",\n    \"        return max_result\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_flip_bit.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_flip_bit.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBits(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_flip_bit(self):\\n\",\n    \"        bits = Bits()\\n\",\n    \"        self.assertRaises(TypeError, bits.flip_bit, None)\\n\",\n    \"        self.assertEqual(bits.flip_bit(0), 1)\\n\",\n    \"        self.assertEqual(bits.flip_bit(-1), bits.MAX_BITS)\\n\",\n    \"        num = int('00001111110111011110001111110000', base=2)\\n\",\n    \"        expected = 10\\n\",\n    \"        self.assertEqual(bits.flip_bit(num), expected)\\n\",\n    \"        num = int('00000100111011101111100011111011', base=2)\\n\",\n    \"        expected = 9\\n\",\n    \"        self.assertEqual(bits.flip_bit(num), expected)\\n\",\n    \"        num = int('00010011101110111110001111101111', base=2)\\n\",\n    \"        expected = 10\\n\",\n    \"        self.assertEqual(bits.flip_bit(num), expected)\\n\",\n    \"        print('Success: test_print_binary')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBits()\\n\",\n    \"    test.test_flip_bit()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_print_binary\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_flip_bit.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/flip_bit/test_flip_bit.py",
    "content": "import unittest\n\n\nclass TestBits(unittest.TestCase):\n\n    def test_flip_bit(self):\n        bits = Bits()\n        self.assertRaises(TypeError, bits.flip_bit, None)\n        self.assertEqual(bits.flip_bit(0), 1)\n        self.assertEqual(bits.flip_bit(-1), bits.MAX_BITS)\n        num = int('00001111110111011110001111110000', base=2)\n        expected = 10\n        self.assertEqual(bits.flip_bit(num), expected)\n        num = int('00000100111011101111100011111011', base=2)\n        expected = 9\n        self.assertEqual(bits.flip_bit(num), expected)\n        num = int('00010011101110111110001111101111', base=2)\n        expected = 10\n        self.assertEqual(bits.flip_bit(num), expected)\n        print('Success: test_print_binary')\n\n\ndef main():\n    test = TestBits()\n    test.test_flip_bit()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "bit_manipulation/get_next/__init__.py",
    "content": ""
  },
  {
    "path": "bit_manipulation/get_next/get_next_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a positive integer, get the next largest number and the next smallest number with the same number of 1's as the given number.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the output a positive int?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* 0 -> Exception\\n\",\n    \"* negative int -> Exception\\n\",\n    \"* General case:\\n\",\n    \"<pre>\\n\",\n    \"    * Input:         0000 0000 1101 0111\\n\",\n    \"    * Next largest:  0000 0000 1101 1011\\n\",\n    \"    * Next smallest: 0000 0000 1100 1111\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Bits(object):\\n\",\n    \"\\n\",\n    \"    def get_next_largest(self, num):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def get_next_smallest(self, num):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_get_next_largest.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBits(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_get_next_largest(self):\\n\",\n    \"        bits = Bits()\\n\",\n    \"        self.assertRaises(Exception, bits.get_next_largest, None)\\n\",\n    \"        self.assertRaises(Exception, bits.get_next_largest, 0)\\n\",\n    \"        self.assertRaises(Exception, bits.get_next_largest, -1)\\n\",\n    \"        num = int('011010111', base=2)\\n\",\n    \"        expected = int('011011011', base=2)\\n\",\n    \"        self.assertEqual(bits.get_next_largest(num), expected)\\n\",\n    \"        print('Success: test_get_next_largest')\\n\",\n    \"\\n\",\n    \"    def test_get_next_smallest(self):\\n\",\n    \"        bits = Bits()\\n\",\n    \"        self.assertRaises(Exception, bits.get_next_smallest, None)\\n\",\n    \"        self.assertRaises(Exception, bits.get_next_smallest, 0)\\n\",\n    \"        self.assertRaises(Exception, bits.get_next_smallest, -1)\\n\",\n    \"        num = int('011010111', base=2)\\n\",\n    \"        expected = int('011001111', base=2)\\n\",\n    \"        self.assertEqual(bits.get_next_smallest(num), expected)\\n\",\n    \"        print('Success: test_get_next_smallest')\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBits()\\n\",\n    \"    test.test_get_next_largest()\\n\",\n    \"    test.test_get_next_smallest()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/get_next/get_next_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a positive integer, get the next largest number and the next smallest number with the same number of 1's as the given number.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the output a positive int?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* 0 -> Exception\\n\",\n    \"* negative int -> Exception\\n\",\n    \"* General case:\\n\",\n    \"<pre>\\n\",\n    \"    * Input:         0000 0000 1101 0111\\n\",\n    \"    * Next largest:  0000 0000 1101 1011\\n\",\n    \"    * Next smallest: 0000 0000 1100 1111\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### get_next_largest\\n\",\n    \"\\n\",\n    \"* Find the right-most non trailing zero, call this index\\n\",\n    \"    * We'll use a mask of 1 and do a logical right shift on a copy of num to examine each bit starting from the right\\n\",\n    \"    * Count the number of zeroes to the right of index\\n\",\n    \"        * While num & 1 == 0 and num_copy != 0:\\n\",\n    \"            * Increment number of zeroes\\n\",\n    \"            * Logical shift right num_copy\\n\",\n    \"    * Count the number of ones to the right of index\\n\",\n    \"        * While num & 1 == 1 and num_copy != 0:\\n\",\n    \"            * Increment number of ones\\n\",\n    \"            * Logical shift right num_copy\\n\",\n    \"    * The index will be the sum of number of ones and number of zeroes\\n\",\n    \"    * Set the index bit\\n\",\n    \"    * Clear all bits to the right of index\\n\",\n    \"    * Set bits starting from 0\\n\",\n    \"        * Only set (number of ones - 1) bits because we set index to 1\\n\",\n    \"\\n\",\n    \"We should make a note that Python does not have a logical right shift operator built in.  We can either use a positive number of implement one for a 32 bit number:\\n\",\n    \"\\n\",\n    \"    num % 0x100000000 >> n\\n\",\n    \"\\n\",\n    \"### get_next_smallest\\n\",\n    \"\\n\",\n    \"* The algorithm for finding the next smallest number is very similar to finding the next largest number\\n\",\n    \"    * Instead of finding the right-most non-trailing zero, we'll find the right most non-trailing one and clear it\\n\",\n    \"    * Clear all bits to the right of index\\n\",\n    \"    * Set bits starting at 0 to the number of ones to the right of index, plus one\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(b), where b is the number of bits in num\\n\",\n    \"* Space: O(b), where b is the number of bits in num\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Bits(object):\\n\",\n    \"\\n\",\n    \"    def get_next_largest(self, num):\\n\",\n    \"        if num is None:\\n\",\n    \"            raise TypeError('num cannot be None')\\n\",\n    \"        if num <= 0:\\n\",\n    \"            raise ValueError('num cannot be 0 or negative')\\n\",\n    \"        num_ones = 0\\n\",\n    \"        num_zeroes = 0\\n\",\n    \"        num_copy = num\\n\",\n    \"        # We'll look for index, which is the right-most non-trailing zero\\n\",\n    \"        # Count number of zeroes to the right of index\\n\",\n    \"        while num_copy != 0 and num_copy & 1 == 0:\\n\",\n    \"            num_zeroes += 1\\n\",\n    \"            num_copy >>= 1\\n\",\n    \"        # Count number of ones to the right of index\\n\",\n    \"        while num_copy != 0 and num_copy & 1 == 1:\\n\",\n    \"            num_ones += 1\\n\",\n    \"            num_copy >>= 1\\n\",\n    \"        # Determine index and set the bit\\n\",\n    \"        index = num_zeroes + num_ones\\n\",\n    \"        num |= 1 << index\\n\",\n    \"        # Clear all bits to the right of index\\n\",\n    \"        num &= ~((1 << index) - 1)\\n\",\n    \"        # Set bits starting from 0\\n\",\n    \"        num |= ((1 << num_ones - 1) - 1)\\n\",\n    \"        return num\\n\",\n    \"\\n\",\n    \"    def get_next_smallest(self, num):\\n\",\n    \"        if num is None:\\n\",\n    \"            raise TypeError('num cannot be None')\\n\",\n    \"        if num <= 0:\\n\",\n    \"            raise ValueError('num cannot be 0 or negative')\\n\",\n    \"        num_ones = 0\\n\",\n    \"        num_zeroes = 0\\n\",\n    \"        num_copy = num\\n\",\n    \"        # We'll look for index, which is the right-most non-trailing one\\n\",\n    \"        # Count number of zeroes to the right of index\\n\",\n    \"        while num_copy != 0 and num_copy & 1 == 1:\\n\",\n    \"            num_ones += 1\\n\",\n    \"            num_copy >>= 1\\n\",\n    \"        # Count number of zeroes to the right of index\\n\",\n    \"        while num_copy != 0 and num_copy & 1 == 0:\\n\",\n    \"            num_zeroes += 1\\n\",\n    \"            num_copy >>= 1\\n\",\n    \"        # Determine index and clear the bit\\n\",\n    \"        index = num_zeroes + num_ones\\n\",\n    \"        num &= ~(1 << index)\\n\",\n    \"        # Clear all bits to the right of index\\n\",\n    \"        num &= ~((1 << index) - 1)\\n\",\n    \"        # Set bits starting from 0\\n\",\n    \"        num |= (1 << num_ones + 1) - 1\\n\",\n    \"        return num\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_get_next_largest.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_get_next_largest.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBits(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_get_next_largest(self):\\n\",\n    \"        bits = Bits()\\n\",\n    \"        self.assertRaises(Exception, bits.get_next_largest, None)\\n\",\n    \"        self.assertRaises(Exception, bits.get_next_largest, 0)\\n\",\n    \"        self.assertRaises(Exception, bits.get_next_largest, -1)\\n\",\n    \"        num = int('011010111', base=2)\\n\",\n    \"        expected = int('011011011', base=2)\\n\",\n    \"        self.assertEqual(bits.get_next_largest(num), expected)\\n\",\n    \"        print('Success: test_get_next_largest')\\n\",\n    \"\\n\",\n    \"    def test_get_next_smallest(self):\\n\",\n    \"        bits = Bits()\\n\",\n    \"        self.assertRaises(Exception, bits.get_next_smallest, None)\\n\",\n    \"        self.assertRaises(Exception, bits.get_next_smallest, 0)\\n\",\n    \"        self.assertRaises(Exception, bits.get_next_smallest, -1)\\n\",\n    \"        num = int('011010111', base=2)\\n\",\n    \"        expected = int('011001111', base=2)\\n\",\n    \"        self.assertEqual(bits.get_next_smallest(num), expected)\\n\",\n    \"        print('Success: test_get_next_smallest')\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBits()\\n\",\n    \"    test.test_get_next_largest()\\n\",\n    \"    test.test_get_next_smallest()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_get_next_largest\\n\",\n      \"Success: test_get_next_smallest\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_get_next_largest.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/get_next/test_get_next_largest.py",
    "content": "import unittest\n\n\nclass TestBits(unittest.TestCase):\n\n    def test_get_next_largest(self):\n        bits = Bits()\n        self.assertRaises(Exception, bits.get_next_largest, None)\n        self.assertRaises(Exception, bits.get_next_largest, 0)\n        self.assertRaises(Exception, bits.get_next_largest, -1)\n        num = int('011010111', base=2)\n        expected = int('011011011', base=2)\n        self.assertEqual(bits.get_next_largest(num), expected)\n        print('Success: test_get_next_largest')\n\n    def test_get_next_smallest(self):\n        bits = Bits()\n        self.assertRaises(Exception, bits.get_next_smallest, None)\n        self.assertRaises(Exception, bits.get_next_smallest, 0)\n        self.assertRaises(Exception, bits.get_next_smallest, -1)\n        num = int('011010111', base=2)\n        expected = int('011001111', base=2)\n        self.assertEqual(bits.get_next_smallest(num), expected)\n        print('Success: test_get_next_smallest')\n\ndef main():\n    test = TestBits()\n    test.test_get_next_largest()\n    test.test_get_next_smallest()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "bit_manipulation/insert_m_into_n/__init__.py",
    "content": ""
  },
  {
    "path": "bit_manipulation/insert_m_into_n/insert_m_into_n_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given two 16 bit numbers, n and m, and two indices i, j, insert m into n such that m starts at bit j and ends at bit i.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume j > i?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume i through j have enough space for m?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None as an input -> Exception\\n\",\n    \"* Negative index for i or j -> Exception\\n\",\n    \"* General case\\n\",\n    \"<pre>\\n\",\n    \"i      = 2\\n\",\n    \"j      = 6\\n\",\n    \"n      = 0000 0100 0000 0000\\n\",\n    \"m      = 0000 0000 0001 0011\\n\",\n    \"result = 0000 0100 0100 1100\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Bits(object):\\n\",\n    \"\\n\",\n    \"    def insert_m_into_n(self, m, n, i, j):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_insert_m_into_n.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBit(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_insert_m_into_n(self):\\n\",\n    \"        n = int('0000010000111101', base=2)\\n\",\n    \"        m = int('0000000000010011', base=2)\\n\",\n    \"        expected = int('0000010001001101', base=2)\\n\",\n    \"        bits = Bits()\\n\",\n    \"        self.assertEqual(bits.insert_m_into_n(m, n, i=2, j=6), expected)\\n\",\n    \"        print('Success: test_insert_m_into_n')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBit()\\n\",\n    \"    test.test_insert_m_into_n()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/insert_m_into_n/insert_m_into_n_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given two 16 bit numbers, n and m, and two indices i, j, insert m into n such that m starts at bit j and ends at bit i.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume j > i?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume i through j have enough space for m?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None as an input -> Exception\\n\",\n    \"* Negative index for i or j -> Exception\\n\",\n    \"* General case\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"i = 2, j = 6\\n\",\n    \"                    j    i\\n\",\n    \"n      = 0000 0100 0011 1101\\n\",\n    \"m      = 0000 0000 0001 0011\\n\",\n    \"result = 0000 0100 0100 1101\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"                    j    i\\n\",\n    \"n      = 0000 0100 0011 1101\\n\",\n    \"m      = 0000 0000 0001 0011\\n\",\n    \"\\n\",\n    \"lmask  = 1111 1111 1111 1111  -1\\n\",\n    \"lmask  = 1111 1111 1000 0000  -1 << (j + 1)\\n\",\n    \"\\n\",\n    \"rmask  = 0000 0000 0000 0001   1\\n\",\n    \"rmask  = 0000 0000 0000 0100   1 << i\\n\",\n    \"rmask  = 0000 0000 0000 0011   (1 << i) -1\\n\",\n    \"\\n\",\n    \"mask   = 1111 1111 1000 0011   lmask | rmask\\n\",\n    \"\\n\",\n    \"n      = 0000 0100 0011 1101\\n\",\n    \"mask   = 1111 1111 1000 0011   n & mask \\n\",\n    \"--------------------------------------------------\\n\",\n    \"n2     = 0000 0100 0000 0001\\n\",\n    \"\\n\",\n    \"n2     = 0000 0100 0000 0001\\n\",\n    \"mask2  = 0000 0000 0100 1100   m << i\\n\",\n    \"--------------------------------------------------\\n\",\n    \"result = 0000 0100 0100 1101   n2 | mask2\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(b), where b is the number of bits\\n\",\n    \"* Space: O(b), where b is the number of bits\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Bits(object):\\n\",\n    \"\\n\",\n    \"    def insert_m_into_n(self, m, n, i, j):\\n\",\n    \"        if None in (m, n, i, j):\\n\",\n    \"            raise TypeError('Argument cannot be None')\\n\",\n    \"        if i < 0 or j < 0:\\n\",\n    \"            raise ValueError('Index cannot be negative')\\n\",\n    \"        left_mask = -1 << (j + 1)\\n\",\n    \"        right_mask = (1 << i) - 1\\n\",\n    \"        n_mask = left_mask | right_mask\\n\",\n    \"        # Clear bits from j to i, inclusive\\n\",\n    \"        n_cleared = n & n_mask\\n\",\n    \"        # Shift m into place before inserting it into n\\n\",\n    \"        m_mask = m << i\\n\",\n    \"        return n_cleared | m_mask\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_insert_m_into_n.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_insert_m_into_n.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBit(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_insert_m_into_n(self):\\n\",\n    \"        n = int('0000010000111101', base=2)\\n\",\n    \"        m = int('0000000000010011', base=2)\\n\",\n    \"        expected = int('0000010001001101', base=2)\\n\",\n    \"        bits = Bits()\\n\",\n    \"        self.assertEqual(bits.insert_m_into_n(m, n, i=2, j=6), expected)\\n\",\n    \"        print('Success: test_insert_m_into_n')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBit()\\n\",\n    \"    test.test_insert_m_into_n()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_insert_m_into_n\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_insert_m_into_n.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/insert_m_into_n/test_insert_m_into_n.py",
    "content": "import unittest\n\n\nclass TestBit(unittest.TestCase):\n\n    def test_insert_m_into_n(self):\n        n = int('0000010000111101', base=2)\n        m = int('0000000000010011', base=2)\n        expected = int('0000010001001101', base=2)\n        bits = Bits()\n        self.assertEqual(bits.insert_m_into_n(m, n, i=2, j=6), expected)\n        print('Success: test_insert_m_into_n')\n\n\ndef main():\n    test = TestBit()\n    test.test_insert_m_into_n()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "bit_manipulation/pairwise_swap/__init__.py",
    "content": ""
  },
  {
    "path": "bit_manipulation/pairwise_swap/pairwise_swap_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Swap the odd and even bits of a positive integer with as few operations as possible.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the input is always a positive int?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we're working with 32 bits?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output an int?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid (not None)?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* 0 -> 0\\n\",\n    \"* -1 -> -1\\n\",\n    \"* General case\\n\",\n    \"<pre>\\n\",\n    \"    input  = 1001 1111 0110\\n\",\n    \"    result = 0110 1111 1001\\n\",\n    \"<pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Bits(object):\\n\",\n    \"\\n\",\n    \"    def pairwise_swap(self, num):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_pairwise_swap.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBits(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_pairwise_swap(self):\\n\",\n    \"        bits = Bits()\\n\",\n    \"        self.assertEqual(bits.pairwise_swap(0), 0)\\n\",\n    \"        self.assertEqual(bits.pairwise_swap(1), 1)\\n\",\n    \"        num = int('0000100111110110', base=2)\\n\",\n    \"        expected = int('0000011011111001', base=2)\\n\",\n    \"        self.assertEqual(bits.pairwise_swap(num), expected)\\n\",\n    \"        print('Success: test_pairwise_swap')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBits()\\n\",\n    \"    test.test_pairwise_swap()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/pairwise_swap/pairwise_swap_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Swap the odd and even bits of a positive integer with as few operations as possible.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the input is always a positive int?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we're working with 32 bits?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output an int?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid (not None)?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* 0 -> 0\\n\",\n    \"* -1 -> -1\\n\",\n    \"* General case\\n\",\n    \"<pre>\\n\",\n    \"    input  = 0000 1001 1111 0110\\n\",\n    \"    result = 0000 0110 1111 1001\\n\",\n    \"<pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* Isolate the odd bits with a mask:\\n\",\n    \"    0000 1001 1111 0110  num\\n\",\n    \"    1010 1010 1010 1010  mask\\n\",\n    \"    --------------------------------\\n\",\n    \"    0000 1000 1010 0010  num & mask\\n\",\n    \"\\n\",\n    \"* Shift the odd bits right:\\n\",\n    \"    0000 0100 0101 0001  odd\\n\",\n    \"\\n\",\n    \"* Isolate the even bits with a mask:\\n\",\n    \"    0000 1001 1111 0110  num\\n\",\n    \"    0101 0101 0101 0101  mask\\n\",\n    \"    --------------------------------\\n\",\n    \"    0000 0001 0101 0100  num & mask\\n\",\n    \"\\n\",\n    \"* Shift the even bits left:\\n\",\n    \"    0000 0010 1010 1000  even\\n\",\n    \"\\n\",\n    \"* Return even | odd\\n\",\n    \"    0000 0100 0101 0001  odd\\n\",\n    \"    0000 0010 1010 1000  even\\n\",\n    \"    --------------------------------\\n\",\n    \"    0000 0110 1111 1001  odd | even\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(b), where b is the number of bits\\n\",\n    \"* Space: O(b), where b is the number of bits\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Bits(object):\\n\",\n    \"\\n\",\n    \"    def pairwise_swap(self, num):\\n\",\n    \"        if num is None:\\n\",\n    \"            raise TypeError('num cannot be None')\\n\",\n    \"        if num == 0 or num == 1:\\n\",\n    \"            return num\\n\",\n    \"        odd = (num & int('1010101010101010', base=2)) >> 1\\n\",\n    \"        even = (num & int('0101010101010101', base=2)) << 1\\n\",\n    \"        return odd | even\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_pairwise_swap.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_pairwise_swap.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBits(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_pairwise_swap(self):\\n\",\n    \"        bits = Bits()\\n\",\n    \"        self.assertEqual(bits.pairwise_swap(0), 0)\\n\",\n    \"        self.assertEqual(bits.pairwise_swap(1), 1)\\n\",\n    \"        num = int('0000100111110110', base=2)\\n\",\n    \"        expected = int('0000011011111001', base=2)\\n\",\n    \"        self.assertEqual(bits.pairwise_swap(num), expected)\\n\",\n    \"        self.assertRaises(TypeError, bits.pairwise_swap, None)\\n\",\n    \"        \\n\",\n    \"        print('Success: test_pairwise_swap')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBits()\\n\",\n    \"    test.test_pairwise_swap()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_pairwise_swap\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_pairwise_swap.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/pairwise_swap/test_pairwise_swap.py",
    "content": "import unittest\n\n\nclass TestBits(unittest.TestCase):\n\n    def test_pairwise_swap(self):\n        bits = Bits()\n        self.assertEqual(bits.pairwise_swap(0), 0)\n        self.assertEqual(bits.pairwise_swap(1), 1)\n        num = int('0000100111110110', base=2)\n        expected = int('0000011011111001', base=2)\n        self.assertEqual(bits.pairwise_swap(num), expected)\n        self.assertRaises(TypeError, bits.pairwise_swap, None)\n        \n        print('Success: test_pairwise_swap')\n\n\ndef main():\n    test = TestBits()\n    test.test_pairwise_swap()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "bit_manipulation/print_binary/__init__.py",
    "content": ""
  },
  {
    "path": "bit_manipulation/print_binary/print_binary_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a real number between 0 and 1, print the binary representation.  If the length of the representation is > 32, return 'ERROR'.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input a float?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output a string?\\n\",\n    \"    * Yes\\n\",\n    \"* Is 0 and 1 inclusive?\\n\",\n    \"    * No\\n\",\n    \"* Does the result include a trailing zero and decimal point?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the leading zero and decimal point counted in the 32 char limit?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> 'ERROR'\\n\",\n    \"* Out of bounds (0, 1) -> 'ERROR'\\n\",\n    \"* General case\\n\",\n    \"    * 0.625 -> 0.101\\n\",\n    \"    * 0.987654321 -> 'ERROR'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Bits(object):\\n\",\n    \"\\n\",\n    \"    def print_binary(self, num):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_print_binary.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBits(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_print_binary(self):\\n\",\n    \"        bit = Bits()\\n\",\n    \"        self.assertEqual(bit.print_binary(None), 'ERROR')\\n\",\n    \"        self.assertEqual(bit.print_binary(0), 'ERROR')\\n\",\n    \"        self.assertEqual(bit.print_binary(1), 'ERROR')\\n\",\n    \"        num = 0.625\\n\",\n    \"        expected = '0.101'\\n\",\n    \"        self.assertEqual(bit.print_binary(num), expected)\\n\",\n    \"        num = 0.987654321\\n\",\n    \"        self.assertEqual(bit.print_binary(num), 'ERROR')\\n\",\n    \"        print('Success: test_print_binary')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBits()\\n\",\n    \"    test.test_print_binary()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/print_binary/print_binary_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a real number between 0 and 1, print the binary representation.  If the length of the representation is > 32, return 'ERROR'.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input a float?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output a string?\\n\",\n    \"    * Yes\\n\",\n    \"* Is 0 and 1 inclusive?\\n\",\n    \"    * No\\n\",\n    \"* Does the result include a trailing zero and decimal point?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the leading zero and decimal point counted in the 32 char limit?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> 'ERROR'\\n\",\n    \"* Out of bounds (0, 1) -> 'ERROR'\\n\",\n    \"* General case\\n\",\n    \"    * 0.625 -> 0.101\\n\",\n    \"    * 0.987654321 -> 'ERROR'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Set the result to '0.'\\n\",\n    \"* Start with a fraction of 0.5, which is 0.1 in base 2\\n\",\n    \"* Loop while num > 0\\n\",\n    \"    * Check num versus fraction\\n\",\n    \"        * If num > fraction, add a 1 to the result, num -= fraction\\n\",\n    \"        * Else, add a 0 to the result\\n\",\n    \"        * If the len(result) > 32, return 'ERROR'\\n\",\n    \"    \\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from __future__ import division\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Bits(object):\\n\",\n    \"\\n\",\n    \"    MAX_BITS = 32\\n\",\n    \"\\n\",\n    \"    def print_binary(self, num):\\n\",\n    \"        if num is None or num >= 1 or num <= 0:\\n\",\n    \"            return 'ERROR'\\n\",\n    \"        result = ['0', '.']\\n\",\n    \"        fraction = 0.5\\n\",\n    \"        while num:\\n\",\n    \"            if num >= fraction:\\n\",\n    \"                result.append('1')\\n\",\n    \"                num -= fraction\\n\",\n    \"            else:\\n\",\n    \"                result.append('0')\\n\",\n    \"            if len(result) > self.MAX_BITS:\\n\",\n    \"                return 'ERROR'\\n\",\n    \"            fraction /= 2\\n\",\n    \"        return ''.join(result)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_print_binary.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_print_binary.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBits(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_print_binary(self):\\n\",\n    \"        bit = Bits()\\n\",\n    \"        self.assertEqual(bit.print_binary(None), 'ERROR')\\n\",\n    \"        self.assertEqual(bit.print_binary(0), 'ERROR')\\n\",\n    \"        self.assertEqual(bit.print_binary(1), 'ERROR')\\n\",\n    \"        num = 0.625\\n\",\n    \"        expected = '0.101'\\n\",\n    \"        self.assertEqual(bit.print_binary(num), expected)\\n\",\n    \"        num = 0.987654321\\n\",\n    \"        self.assertEqual(bit.print_binary(num), 'ERROR')\\n\",\n    \"        print('Success: test_print_binary')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBits()\\n\",\n    \"    test.test_print_binary()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_print_binary\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_print_binary.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "bit_manipulation/print_binary/test_print_binary.py",
    "content": "import unittest\n\n\nclass TestBits(unittest.TestCase):\n\n    def test_print_binary(self):\n        bit = Bits()\n        self.assertEqual(bit.print_binary(None), 'ERROR')\n        self.assertEqual(bit.print_binary(0), 'ERROR')\n        self.assertEqual(bit.print_binary(1), 'ERROR')\n        num = 0.625\n        expected = '0.101'\n        self.assertEqual(bit.print_binary(num), expected)\n        num = 0.987654321\n        self.assertEqual(bit.print_binary(num), 'ERROR')\n        print('Success: test_print_binary')\n\n\ndef main():\n    test = TestBits()\n    test.test_print_binary()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/bst/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/bst/bst.py",
    "content": "class Node(object):\n\n    def __init__(self, data):\n        self.data = data\n        self.left = None\n        self.right = None\n        self.parent = None\n\n    def __repr__(self):\n        return str(self.data)\n\n\nclass Bst(object):\n\n    def __init__(self, root=None):\n        self.root = root\n\n    def insert(self, data):\n        if data is None:\n            raise TypeError('data cannot be None')\n        if self.root is None:\n            self.root = Node(data)\n            return self.root\n        else:\n            return self._insert(self.root, data)\n\n    def _insert(self, node, data):\n        if node is None:\n            return Node(data)\n        if data <= node.data:\n            if node.left is None:\n                node.left = self._insert(node.left, data)\n                node.left.parent = node\n                return node.left\n            else:\n                return self._insert(node.left, data)\n        else:\n            if node.right is None:\n                node.right = self._insert(node.right, data)\n                node.right.parent = node\n                return node.right\n            else:\n                return self._insert(node.right, data)\n"
  },
  {
    "path": "graphs_trees/bst/bst_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a binary search tree with an insert method.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we insert None values?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume we are working with valid integers?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume all left descendents <= n < all right descendents?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we have to keep track of the parent nodes?\\n\",\n    \"    * This is optional\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### Insert\\n\",\n    \"\\n\",\n    \"Insert will be tested through the following traversal:\\n\",\n    \"\\n\",\n    \"### In-Order Traversal\\n\",\n    \"\\n\",\n    \"* 5, 2, 8, 1, 3 -> 1, 2, 3, 5, 8\\n\",\n    \"* 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\\n\",\n    \"\\n\",\n    \"If the `root` input is `None`, return a tree with the only element being the new root node.\\n\",\n    \"\\n\",\n    \"You do not have to code the in-order traversal, it is part of the unit test.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst/bst_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Node(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Bst(object):\\n\",\n    \"\\n\",\n    \"    def insert(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run dfs.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../utils/results.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_bst.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestTree(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def __init__(self, *args, **kwargs):\\n\",\n    \"        super(TestTree, self).__init__()\\n\",\n    \"        self.results = Results()\\n\",\n    \"\\n\",\n    \"    def test_tree_one(self):\\n\",\n    \"        bst = Bst()\\n\",\n    \"        bst.insert(5)\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        in_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), '[1, 2, 3, 5, 8]')\\n\",\n    \"        self.results.clear_results()\\n\",\n    \"\\n\",\n    \"    def test_tree_two(self):\\n\",\n    \"        bst = Bst()\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        bst.insert(4)\\n\",\n    \"        bst.insert(5)\\n\",\n    \"        in_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), '[1, 2, 3, 4, 5]')\\n\",\n    \"\\n\",\n    \"        print('Success: test_tree')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestTree()\\n\",\n    \"    test.test_tree_one()\\n\",\n    \"    test.test_tree_two()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst/bst_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/bst/bst_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a binary search tree with an insert method.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we insert None values?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume we are working with valid integers?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume all left descendents <= n < all right descendents?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we have to keep track of the parent nodes?\\n\",\n    \"    * This is optional\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### Insert\\n\",\n    \"\\n\",\n    \"Insert will be tested through the following traversal:\\n\",\n    \"\\n\",\n    \"### In-Order Traversal\\n\",\n    \"\\n\",\n    \"* 5, 2, 8, 1, 3 -> 1, 2, 3, 5, 8\\n\",\n    \"* 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\\n\",\n    \"\\n\",\n    \"If the `root` input is `None`, return a tree with the only element being the new root node.\\n\",\n    \"\\n\",\n    \"You do not have to code the in-order traversal, it is part of the unit test.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### Insert\\n\",\n    \"\\n\",\n    \"* If the root is None, return Node(data)\\n\",\n    \"* If the data is <= the current node's data\\n\",\n    \"    * If the current node's left child is None, set it to Node(data)\\n\",\n    \"    * Else, recursively call insert on the left child\\n\",\n    \"* Else\\n\",\n    \"    * If the current node's right child is None, set it to Node(data)\\n\",\n    \"    * Else, recursively call insert on the right child\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"\\n\",\n    \"* Time: O(h), where h is the height of the tree\\n\",\n    \"    * In a balanced tree, the height is O(log(n))\\n\",\n    \"    * In the worst case we have a linked list structure with O(n)\\n\",\n    \"* Space: O(m), where m is the recursion depth, or O(1) if using an iterative approach\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting bst.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile bst.py\\n\",\n    \"class Node(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, data):\\n\",\n    \"        self.data = data\\n\",\n    \"        self.left = None\\n\",\n    \"        self.right = None\\n\",\n    \"        self.parent = None\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return str(self.data)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Bst(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, root=None):\\n\",\n    \"        self.root = root\\n\",\n    \"\\n\",\n    \"    def insert(self, data):\\n\",\n    \"        if data is None:\\n\",\n    \"            raise TypeError('data cannot be None')\\n\",\n    \"        if self.root is None:\\n\",\n    \"            self.root = Node(data)\\n\",\n    \"            return self.root\\n\",\n    \"        else:\\n\",\n    \"            return self._insert(self.root, data)\\n\",\n    \"\\n\",\n    \"    def _insert(self, node, data):\\n\",\n    \"        if node is None:\\n\",\n    \"            return Node(data)\\n\",\n    \"        if data <= node.data:\\n\",\n    \"            if node.left is None:\\n\",\n    \"                node.left = self._insert(node.left, data)\\n\",\n    \"                node.left.parent = node\\n\",\n    \"                return node.left\\n\",\n    \"            else:\\n\",\n    \"                return self._insert(node.left, data)\\n\",\n    \"        else:\\n\",\n    \"            if node.right is None:\\n\",\n    \"                node.right = self._insert(node.right, data)\\n\",\n    \"                node.right.parent = node\\n\",\n    \"                return node.right\\n\",\n    \"            else:\\n\",\n    \"                return self._insert(node.right, data)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run dfs.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../utils/results.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_bst.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_bst.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestTree(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def __init__(self, *args, **kwargs):\\n\",\n    \"        super(TestTree, self).__init__()\\n\",\n    \"        self.results = Results()\\n\",\n    \"\\n\",\n    \"    def test_tree_one(self):\\n\",\n    \"        bst = Bst()\\n\",\n    \"        bst.insert(5)\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        in_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), '[1, 2, 3, 5, 8]')\\n\",\n    \"        self.results.clear_results()\\n\",\n    \"\\n\",\n    \"    def test_tree_two(self):\\n\",\n    \"        bst = Bst()\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        bst.insert(4)\\n\",\n    \"        bst.insert(5)\\n\",\n    \"        in_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), '[1, 2, 3, 4, 5]')\\n\",\n    \"\\n\",\n    \"        print('Success: test_tree')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestTree()\\n\",\n    \"    test.test_tree_one()\\n\",\n    \"    test.test_tree_two()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 6,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_tree\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_bst.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/bst/dfs.py",
    "content": "def in_order_traversal(node, visit_func):\n    if node is not None:\n        in_order_traversal(node.left, visit_func)\n        visit_func(node.data)\n        in_order_traversal(node.right, visit_func)\n\ndef pre_order_traversal(node, visit_func):\n    if node is not None:\n        visit_func(node.data)\n        pre_order_traversal(node.left, visit_func)\n        pre_order_traversal(node.right, visit_func)\n\ndef post_order_traversal(node, visit_func):\n    if node is not None:\n        post_order_traversal(node.left, visit_func)\n        post_order_traversal(node.right, visit_func)\n        visit_func(node.data)"
  },
  {
    "path": "graphs_trees/bst/test_bst.py",
    "content": "import unittest\n\n\nclass TestTree(unittest.TestCase):\n\n    def __init__(self, *args, **kwargs):\n        super(TestTree, self).__init__()\n        self.results = Results()\n\n    def test_tree_one(self):\n        bst = Bst()\n        bst.insert(5)\n        bst.insert(2)\n        bst.insert(8)\n        bst.insert(1)\n        bst.insert(3)\n        in_order_traversal(bst.root, self.results.add_result)\n        self.assertEqual(str(self.results), '[1, 2, 3, 5, 8]')\n        self.results.clear_results()\n\n    def test_tree_two(self):\n        bst = Bst()\n        bst.insert(1)\n        bst.insert(2)\n        bst.insert(3)\n        bst.insert(4)\n        bst.insert(5)\n        in_order_traversal(bst.root, self.results.add_result)\n        self.assertEqual(str(self.results), '[1, 2, 3, 4, 5]')\n\n        print('Success: test_tree')\n\n\ndef main():\n    test = TestTree()\n    test.test_tree_one()\n    test.test_tree_two()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/bst_min/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/bst_min/bst_min_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Create a binary search tree with minimal height from a sorted array.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the array in increasing order?\\n\",\n    \"    * Yes\\n\",\n    \"* Are the array elements unique?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a Node class with an insert method?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* 0, 1, 2, 3, 4, 5, 6 -> height 3\\n\",\n    \"* 0, 1, 2, 3, 4, 5, 6, 7 -> height 4\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_min/bst_min_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\\n\",\n    \"%load ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MinBst(object):\\n\",\n    \"\\n\",\n    \"    def create_min_bst(self, array):\\n\",\n    \"    # TODO: Implement me\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_bst_min.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def height(node):\\n\",\n    \"    if node is None:\\n\",\n    \"        return 0\\n\",\n    \"    return 1 + max(height(node.left),\\n\",\n    \"                   height(node.right))\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBstMin(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_bst_min(self):\\n\",\n    \"        min_bst = MinBst()\\n\",\n    \"        array = [0, 1, 2, 3, 4, 5, 6]\\n\",\n    \"        root = min_bst.create_min_bst(array)\\n\",\n    \"        self.assertEqual(height(root), 3)\\n\",\n    \"\\n\",\n    \"        min_bst = MinBst()\\n\",\n    \"        array = [0, 1, 2, 3, 4, 5, 6, 7]\\n\",\n    \"        root = min_bst.create_min_bst(array)\\n\",\n    \"        self.assertEqual(height(root), 4)\\n\",\n    \"\\n\",\n    \"        print('Success: test_bst_min')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBstMin()\\n\",\n    \"    test.test_bst_min()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_min/bst_min_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/bst_min/bst_min_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Create a binary search tree with minimal height from a sorted array.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the array in increasing order?\\n\",\n    \"    * Yes\\n\",\n    \"* Are the array elements unique?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a Node class with an insert method?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* 0, 1, 2, 3, 4, 5, 6 -> height 3\\n\",\n    \"* 0, 1, 2, 3, 4, 5, 6, 7 -> height 4\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"To create a bst with minimum height, we need to use the middle element as the root.  We'll use recursion to divide the array in half and continue to pick the middle element from the left and right halves as the nodes to insert in the tree.\\n\",\n    \"\\n\",\n    \"* create_min_bst(array, start, end)\\n\",\n    \"* Base case: Stop when end < start\\n\",\n    \"* Create a node with the mid element\\n\",\n    \"* Recursively build node.left by calling create_min_bst using the left sub array\\n\",\n    \"* Recursively build node.right by calling create_min_bst using the right sub array\\n\",\n    \"* Return the node\\n\",\n    \"    \\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(h), where h is the tree's height (since this is a tree with minimum height, h = log n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from __future__ import division\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class MinBst(object):\\n\",\n    \"\\n\",\n    \"    def create_min_bst(self, array):\\n\",\n    \"        if array is None:\\n\",\n    \"            return\\n\",\n    \"        return self._create_min_bst(array, 0, len(array) - 1)\\n\",\n    \"\\n\",\n    \"    def _create_min_bst(self, array, start, end):\\n\",\n    \"        if end < start:\\n\",\n    \"            return None\\n\",\n    \"        mid = (start + end) // 2\\n\",\n    \"        node = Node(array[mid])\\n\",\n    \"        node.left = self._create_min_bst(array, start, mid - 1)\\n\",\n    \"        node.right = self._create_min_bst(array, mid + 1, end)\\n\",\n    \"        return node\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_bst_min.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_bst_min.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def height(node):\\n\",\n    \"    if node is None:\\n\",\n    \"        return 0\\n\",\n    \"    return 1 + max(height(node.left),\\n\",\n    \"                   height(node.right))\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBstMin(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_bst_min(self):\\n\",\n    \"        min_bst = MinBst()\\n\",\n    \"        array = [0, 1, 2, 3, 4, 5, 6]\\n\",\n    \"        root = min_bst.create_min_bst(array)\\n\",\n    \"        self.assertEqual(height(root), 3)\\n\",\n    \"\\n\",\n    \"        min_bst = MinBst()\\n\",\n    \"        array = [0, 1, 2, 3, 4, 5, 6, 7]\\n\",\n    \"        root = min_bst.create_min_bst(array)\\n\",\n    \"        self.assertEqual(height(root), 4)\\n\",\n    \"\\n\",\n    \"        print('Success: test_bst_min')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBstMin()\\n\",\n    \"    test.test_bst_min()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_bst_min\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_bst_min.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/bst_min/test_bst_min.py",
    "content": "import unittest\n\n\ndef height(node):\n    if node is None:\n        return 0\n    return 1 + max(height(node.left),\n                   height(node.right))\n\n\nclass TestBstMin(unittest.TestCase):\n\n    def test_bst_min(self):\n        min_bst = MinBst()\n        array = [0, 1, 2, 3, 4, 5, 6]\n        root = min_bst.create_min_bst(array)\n        self.assertEqual(height(root), 3)\n\n        min_bst = MinBst()\n        array = [0, 1, 2, 3, 4, 5, 6, 7]\n        root = min_bst.create_min_bst(array)\n        self.assertEqual(height(root), 4)\n\n        print('Success: test_bst_min')\n\n\ndef main():\n    test = TestBstMin()\n    test.test_bst_min()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/bst_second_largest/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/bst_second_largest/bst_second_largest_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the second largest node in a binary search tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* If this is called on a None input or a single node, should we raise an exception?\\n\",\n    \"    * Yes\\n\",\n    \"        * None -> TypeError\\n\",\n    \"        * Single node -> ValueError\\n\",\n    \"* Can we assume we already have a Node class with an insert method?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None or single node -> Exception\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Input:\\n\",\n    \"                _10_\\n\",\n    \"              _/    \\\\_          \\n\",\n    \"             5        15\\n\",\n    \"            / \\\\       / \\\\\\n\",\n    \"           3   8     12  20\\n\",\n    \"          /     \\\\         \\\\\\n\",\n    \"         2       4        30\\n\",\n    \"\\n\",\n    \"Output: 20\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"                 10\\n\",\n    \"                 /  \\n\",\n    \"                5\\n\",\n    \"               / \\\\\\n\",\n    \"              3   7\\n\",\n    \"Output: 7\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_second_largest/bst_second_largest_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\\n\",\n    \"%load ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(Bst):\\n\",\n    \"\\n\",\n    \"    def find_second_largest(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_bst_second_largest.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBstSecondLargest(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_bst_second_largest(self):\\n\",\n    \"        bst = Solution(None)\\n\",\n    \"        self.assertRaises(TypeError, bst.find_second_largest)\\n\",\n    \"        root = Node(10)\\n\",\n    \"        bst = Solution(root)\\n\",\n    \"        node5 = bst.insert(5)\\n\",\n    \"        node15 = bst.insert(15)\\n\",\n    \"        node3 = bst.insert(3)\\n\",\n    \"        node8 = bst.insert(8)\\n\",\n    \"        node12 = bst.insert(12)\\n\",\n    \"        node20 = bst.insert(20)\\n\",\n    \"        node2 = bst.insert(2)\\n\",\n    \"        node4 = bst.insert(4)\\n\",\n    \"        node30 = bst.insert(30)\\n\",\n    \"        self.assertEqual(bst.find_second_largest(), node20)\\n\",\n    \"        root = Node(10)\\n\",\n    \"        bst = Solution(root)\\n\",\n    \"        node5 = bst.insert(5)\\n\",\n    \"        node3 = bst.insert(3)\\n\",\n    \"        node7 = bst.insert(7)\\n\",\n    \"        self.assertEqual(bst.find_second_largest(), node7)\\n\",\n    \"        print('Success: test_bst_second_largest')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBstSecondLargest()\\n\",\n    \"    test.test_bst_second_largest()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/check_balance/check_balance_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/bst_second_largest/bst_second_largest_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the second largest node in a binary search tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* If this is called on a None input or a single node, should we raise an exception?\\n\",\n    \"    * Yes\\n\",\n    \"        * None -> TypeError\\n\",\n    \"        * Single node -> ValueError\\n\",\n    \"* Can we assume we already have a Node class with an insert method?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None or single node -> Exception\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Input:\\n\",\n    \"                _10_\\n\",\n    \"              _/    \\\\_          \\n\",\n    \"             5        15\\n\",\n    \"            / \\\\       / \\\\\\n\",\n    \"           3   8     12  20\\n\",\n    \"          /     \\\\         \\\\\\n\",\n    \"         2       4        30\\n\",\n    \"\\n\",\n    \"Output: 20\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"                 10\\n\",\n    \"                 /  \\n\",\n    \"                5\\n\",\n    \"               / \\\\\\n\",\n    \"              3   7\\n\",\n    \"Output: 7\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"\\n\",\n    \"If there is no right node, the second largest is the right most left subtree:\\n\",\n    \"\\n\",\n    \"                 10\\n\",\n    \"                 /  \\n\",\n    \"                5\\n\",\n    \"               / \\\\\\n\",\n    \"              3   7\\n\",\n    \"\\n\",\n    \"If there is a right node and the right node has children, recurse to that right child:\\n\",\n    \"\\n\",\n    \"                _10_\\n\",\n    \"              _/    \\\\_          \\n\",\n    \"             5        15\\n\",\n    \"            / \\\\       / \\\\\\n\",\n    \"           3   8     12  20\\n\",\n    \"          /     \\\\         \\\\\\n\",\n    \"         2       4        30\\n\",\n    \"\\n\",\n    \"Eventually we'll get to the following scenario:\\n\",\n    \"\\n\",\n    \"                 20\\n\",\n    \"                  \\\\\\n\",\n    \"                   30\\n\",\n    \"\\n\",\n    \"If the right node has no children, the second largest is the current node.\\n\",\n    \"\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(h)\\n\",\n    \"* Space: O(h), where h is the height of the tree\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(Bst):\\n\",\n    \"\\n\",\n    \"    def _find_second_largest(self, node):\\n\",\n    \"        if node.right is not None:\\n\",\n    \"            if node.right.left is not None or node.right.right is not None:\\n\",\n    \"                return self._find_second_largest(node.right)\\n\",\n    \"            else:\\n\",\n    \"                return node\\n\",\n    \"        else:\\n\",\n    \"            return self._find_right_most_node(node.left)\\n\",\n    \"\\n\",\n    \"    def _find_right_most_node(self, node):\\n\",\n    \"        if node.right is not None:\\n\",\n    \"            return self._find_right_most_node(node.right)\\n\",\n    \"        else:\\n\",\n    \"            return node\\n\",\n    \"\\n\",\n    \"    def find_second_largest(self):\\n\",\n    \"        if self.root is None:\\n\",\n    \"            raise TypeError('root cannot be None')\\n\",\n    \"        if self.root.right is None and self.root.left is None:\\n\",\n    \"            raise ValueError('root must have at least one child')\\n\",\n    \"        return self._find_second_largest(self.root)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_bst_second_largest.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_bst_second_largest.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBstSecondLargest(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_bst_second_largest(self):\\n\",\n    \"        bst = Solution(None)\\n\",\n    \"        self.assertRaises(TypeError, bst.find_second_largest)\\n\",\n    \"        root = Node(10)\\n\",\n    \"        bst = Solution(root)\\n\",\n    \"        node5 = bst.insert(5)\\n\",\n    \"        node15 = bst.insert(15)\\n\",\n    \"        node3 = bst.insert(3)\\n\",\n    \"        node8 = bst.insert(8)\\n\",\n    \"        node12 = bst.insert(12)\\n\",\n    \"        node20 = bst.insert(20)\\n\",\n    \"        node2 = bst.insert(2)\\n\",\n    \"        node4 = bst.insert(4)\\n\",\n    \"        node30 = bst.insert(30)\\n\",\n    \"        self.assertEqual(bst.find_second_largest(), node20)\\n\",\n    \"        root = Node(10)\\n\",\n    \"        bst = Solution(root)\\n\",\n    \"        node5 = bst.insert(5)\\n\",\n    \"        node3 = bst.insert(3)\\n\",\n    \"        node7 = bst.insert(7)\\n\",\n    \"        self.assertEqual(bst.find_second_largest(), node7)\\n\",\n    \"        print('Success: test_bst_second_largest')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBstSecondLargest()\\n\",\n    \"    test.test_bst_second_largest()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_bst_second_largest\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_bst_second_largest.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/bst_second_largest/test_bst_second_largest.py",
    "content": "import unittest\n\n\nclass TestBstSecondLargest(unittest.TestCase):\n\n    def test_bst_second_largest(self):\n        bst = Solution(None)\n        self.assertRaises(TypeError, bst.find_second_largest)\n        root = Node(10)\n        bst = Solution(root)\n        node5 = bst.insert(5)\n        node15 = bst.insert(15)\n        node3 = bst.insert(3)\n        node8 = bst.insert(8)\n        node12 = bst.insert(12)\n        node20 = bst.insert(20)\n        node2 = bst.insert(2)\n        node4 = bst.insert(4)\n        node30 = bst.insert(30)\n        self.assertEqual(bst.find_second_largest(), node20)\n        root = Node(10)\n        bst = Solution(root)\n        node5 = bst.insert(5)\n        node3 = bst.insert(3)\n        node7 = bst.insert(7)\n        self.assertEqual(bst.find_second_largest(), node7)\n        print('Success: test_bst_second_largest')\n\n\ndef main():\n    test = TestBstSecondLargest()\n    test.test_bst_second_largest()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/bst_successor/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/bst_successor/bst_successor_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the in-order successor of a given node in a binary search tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* If there is no successor, do we return None?\\n\",\n    \"    * Yes\\n\",\n    \"* If the input is None, should we throw an exception?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a Node class that keeps track of parents?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"          _5_\\n\",\n    \"        /     \\\\\\n\",\n    \"       3       8\\n\",\n    \"      / \\\\    /   \\\\\\n\",\n    \"     2   4  6    12\\n\",\n    \"    /        \\\\   / \\\\\\n\",\n    \"   1          7 10  15\\n\",\n    \"               /\\n\",\n    \"              9\\n\",\n    \"\\n\",\n    \"In: None  Out: Exception\\n\",\n    \"In: 4     Out: 5\\n\",\n    \"In: 5     Out: 6\\n\",\n    \"In: 8     Out: 9\\n\",\n    \"In: 15    Out: None\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_successor/bst_successor_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\\n\",\n    \"%load ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BstSuccessor(object):\\n\",\n    \"\\n\",\n    \"    def get_next(self, node):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_bst_successor.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBstSuccessor(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_bst_successor_empty(self):\\n\",\n    \"        bst_successor = BstSuccessor()\\n\",\n    \"        bst_successor.get_next(None)\\n\",\n    \"\\n\",\n    \"    def test_bst_successor(self):\\n\",\n    \"        nodes = {}\\n\",\n    \"        node = Node(5)\\n\",\n    \"        nodes[5] = node\\n\",\n    \"        bst = Bst(nodes[5])\\n\",\n    \"        nodes[3] = bst.insert(3)\\n\",\n    \"        nodes[8] = bst.insert(8)\\n\",\n    \"        nodes[2] = bst.insert(2)\\n\",\n    \"        nodes[4] = bst.insert(4)\\n\",\n    \"        nodes[6] = bst.insert(6)\\n\",\n    \"        nodes[12] = bst.insert(12)\\n\",\n    \"        nodes[1] = bst.insert(1)\\n\",\n    \"        nodes[7] = bst.insert(7)\\n\",\n    \"        nodes[10] = bst.insert(10)\\n\",\n    \"        nodes[15] = bst.insert(15)\\n\",\n    \"        nodes[9] = bst.insert(9)\\n\",\n    \"\\n\",\n    \"        bst_successor = BstSuccessor()\\n\",\n    \"        self.assertEqual(bst_successor.get_next(nodes[4]), 5)\\n\",\n    \"        self.assertEqual(bst_successor.get_next(nodes[5]), 6)\\n\",\n    \"        self.assertEqual(bst_successor.get_next(nodes[8]), 9)\\n\",\n    \"        self.assertEqual(bst_successor.get_next(nodes[15]), None)\\n\",\n    \"\\n\",\n    \"        print('Success: test_bst_successor')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBstSuccessor()\\n\",\n    \"    test.test_bst_successor()\\n\",\n    \"    test.assertRaises(TypeError, test.test_bst_successor_empty)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_successor/bst_successor_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/bst_successor/bst_successor_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the in-order successor of a given node in a binary search tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* If there is no successor, do we return None?\\n\",\n    \"    * Yes\\n\",\n    \"* If the input is None, should we throw an exception?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a Node class that keeps track of parents?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"          _5_\\n\",\n    \"        /     \\\\\\n\",\n    \"       3       8\\n\",\n    \"      / \\\\    /   \\\\\\n\",\n    \"     2   4  6    12\\n\",\n    \"    /        \\\\   / \\\\\\n\",\n    \"   1          7 10  15\\n\",\n    \"               /\\n\",\n    \"              9\\n\",\n    \"\\n\",\n    \"In: None  Out: Exception\\n\",\n    \"In: 4     Out: 5\\n\",\n    \"In: 5     Out: 6\\n\",\n    \"In: 8     Out: 9\\n\",\n    \"In: 15    Out: None\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* If the node has a right subtree, return the left-most node in the right subtree\\n\",\n    \"* Else, go up until you find a node that is its parent's left node\\n\",\n    \"    * If you get to the root (ie node.parent is None), return None\\n\",\n    \"        * The original input node must be the largest in the tree\\n\",\n    \"    * Else, return the parent\\n\",\n    \"    \\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(h), where h is the height of the tree\\n\",\n    \"* Space: O(h), where h is the recursion depth (tree height), or O(1) if using an iterative approach\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BstSuccessor(object):\\n\",\n    \"\\n\",\n    \"    def get_next(self, node):\\n\",\n    \"        if node is None:\\n\",\n    \"            raise TypeError('node cannot be None')\\n\",\n    \"        if node.right is not None:\\n\",\n    \"            return self._left_most(node.right)\\n\",\n    \"        else:\\n\",\n    \"            return self._next_ancestor(node)\\n\",\n    \"\\n\",\n    \"    def _left_most(self, node):\\n\",\n    \"        if node.left is not None:\\n\",\n    \"            return self._left_most(node.left)\\n\",\n    \"        else:\\n\",\n    \"            return node.data\\n\",\n    \"\\n\",\n    \"    def _next_ancestor(self, node):\\n\",\n    \"        if node.parent is not None:\\n\",\n    \"            if node.parent.data > node.data:\\n\",\n    \"                return node.parent.data\\n\",\n    \"            else:\\n\",\n    \"                return self._next_ancestor(node.parent)\\n\",\n    \"        # We reached the root, the original input node\\n\",\n    \"        # must be the largest element in the tree.\\n\",\n    \"        return None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_bst_successor.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_bst_successor.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBstSuccessor(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_bst_successor_empty(self):\\n\",\n    \"        bst_successor = BstSuccessor()\\n\",\n    \"        bst_successor.get_next(None)\\n\",\n    \"\\n\",\n    \"    def test_bst_successor(self):\\n\",\n    \"        nodes = {}\\n\",\n    \"        node = Node(5)\\n\",\n    \"        nodes[5] = node\\n\",\n    \"        bst = Bst(nodes[5])\\n\",\n    \"        nodes[3] = bst.insert(3)\\n\",\n    \"        nodes[8] = bst.insert(8)\\n\",\n    \"        nodes[2] = bst.insert(2)\\n\",\n    \"        nodes[4] = bst.insert(4)\\n\",\n    \"        nodes[6] = bst.insert(6)\\n\",\n    \"        nodes[12] = bst.insert(12)\\n\",\n    \"        nodes[1] = bst.insert(1)\\n\",\n    \"        nodes[7] = bst.insert(7)\\n\",\n    \"        nodes[10] = bst.insert(10)\\n\",\n    \"        nodes[15] = bst.insert(15)\\n\",\n    \"        nodes[9] = bst.insert(9)\\n\",\n    \"\\n\",\n    \"        bst_successor = BstSuccessor()\\n\",\n    \"        self.assertEqual(bst_successor.get_next(nodes[4]), 5)\\n\",\n    \"        self.assertEqual(bst_successor.get_next(nodes[5]), 6)\\n\",\n    \"        self.assertEqual(bst_successor.get_next(nodes[8]), 9)\\n\",\n    \"        self.assertEqual(bst_successor.get_next(nodes[15]), None)\\n\",\n    \"\\n\",\n    \"        print('Success: test_bst_successor')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBstSuccessor()\\n\",\n    \"    test.test_bst_successor()\\n\",\n    \"    test.assertRaises(TypeError, test.test_bst_successor_empty)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_bst_successor\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_bst_successor.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/bst_successor/test_bst_successor.py",
    "content": "import unittest\n\n\nclass TestBstSuccessor(unittest.TestCase):\n\n    def test_bst_successor_empty(self):\n        bst_successor = BstSuccessor()\n        bst_successor.get_next(None)\n\n    def test_bst_successor(self):\n        nodes = {}\n        node = Node(5)\n        nodes[5] = node\n        bst = Bst(nodes[5])\n        nodes[3] = bst.insert(3)\n        nodes[8] = bst.insert(8)\n        nodes[2] = bst.insert(2)\n        nodes[4] = bst.insert(4)\n        nodes[6] = bst.insert(6)\n        nodes[12] = bst.insert(12)\n        nodes[1] = bst.insert(1)\n        nodes[7] = bst.insert(7)\n        nodes[10] = bst.insert(10)\n        nodes[15] = bst.insert(15)\n        nodes[9] = bst.insert(9)\n\n        bst_successor = BstSuccessor()\n        self.assertEqual(bst_successor.get_next(nodes[4]), 5)\n        self.assertEqual(bst_successor.get_next(nodes[5]), 6)\n        self.assertEqual(bst_successor.get_next(nodes[8]), 9)\n        self.assertEqual(bst_successor.get_next(nodes[15]), None)\n\n        print('Success: test_bst_successor')\n\n\ndef main():\n    test = TestBstSuccessor()\n    test.test_bst_successor()\n    test.assertRaises(TypeError, test.test_bst_successor_empty)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/bst_validate/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/bst_validate/bst_validate_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine if a tree is a valid binary search tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can the tree have duplicates?\\n\",\n    \"    * Yes\\n\",\n    \"* If this is called on a None input, should we raise an exception?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a Node class?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Valid:\\n\",\n    \"      5\\n\",\n    \"    /   \\\\\\n\",\n    \"   5     8\\n\",\n    \"  /     /\\n\",\n    \" 4     6\\n\",\n    \"        \\\\\\n\",\n    \"         7\\n\",\n    \"        \\n\",\n    \"Invalid:\\n\",\n    \"      5\\n\",\n    \"    /   \\\\\\n\",\n    \"   5     8\\n\",\n    \"  / \\\\   /\\n\",\n    \" 4   9 7\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_validate/bst_validate_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\\n\",\n    \"%load ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BstValidate(Bst):\\n\",\n    \"\\n\",\n    \"    def validate(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_bst_validate.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBstValidate(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_bst_validate_empty(self):\\n\",\n    \"        bst = BstValidate(None)\\n\",\n    \"        bst.validate()\\n\",\n    \"\\n\",\n    \"    def test_bst_validate(self):\\n\",\n    \"        bst = BstValidate(Node(5))\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(5)\\n\",\n    \"        bst.insert(6)\\n\",\n    \"        bst.insert(4)\\n\",\n    \"        bst.insert(7)\\n\",\n    \"        self.assertEqual(bst.validate(), True)\\n\",\n    \"\\n\",\n    \"        bst = BstValidate(Node(5))\\n\",\n    \"        left = Node(5)\\n\",\n    \"        right = Node(8)\\n\",\n    \"        invalid = Node(20)\\n\",\n    \"        bst.root.left = left\\n\",\n    \"        bst.root.right = right\\n\",\n    \"        bst.root.left.right = invalid\\n\",\n    \"        self.assertEqual(bst.validate(), False)\\n\",\n    \"\\n\",\n    \"        print('Success: test_bst_validate')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBstValidate()\\n\",\n    \"    test.assertRaises(TypeError, test.test_bst_validate_empty)\\n\",\n    \"    test.test_bst_validate()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/bst_validate/bst_validate_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/bst_validate/bst_validate_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine if a tree is a valid binary search tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can the tree have duplicates?\\n\",\n    \"    * Yes\\n\",\n    \"* If this is called on a None input, should we raise an exception?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a Node class?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"None -> exception\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Valid:\\n\",\n    \"      5\\n\",\n    \"    /   \\\\\\n\",\n    \"   5     8\\n\",\n    \"  /     /\\n\",\n    \" 4     6\\n\",\n    \"        \\\\\\n\",\n    \"         7\\n\",\n    \"        \\n\",\n    \"Invalid:\\n\",\n    \"      5\\n\",\n    \"    /   \\\\\\n\",\n    \"   5     8\\n\",\n    \"    \\\\   \\n\",\n    \"    20\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use a recursive solution that validates left <= current < right, passing down the min and max values as we do a depth-first traversal.\\n\",\n    \"\\n\",\n    \"* If the node is None, return True\\n\",\n    \"* If min is set and the node's value <= min, return False\\n\",\n    \"* if max is set and the node's value > max, return False\\n\",\n    \"* Recursively call the validate function on node.left, updating max\\n\",\n    \"* Recursively call the validate function on node.right, updating min\\n\",\n    \"    \\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(h), where h is the height of the tree\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import sys\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class BstValidate(Bst):\\n\",\n    \"\\n\",\n    \"    def validate(self):\\n\",\n    \"        if self.root is None:\\n\",\n    \"            raise TypeError('No root node')\\n\",\n    \"        return self._validate(self.root)\\n\",\n    \"\\n\",\n    \"    def _validate(self, node, minimum=-sys.maxsize, maximum=sys.maxsize):\\n\",\n    \"        if node is None:\\n\",\n    \"            return True\\n\",\n    \"        if node.data <= minimum or node.data > maximum:\\n\",\n    \"            return False\\n\",\n    \"        if not self._validate(node.left, minimum, node.data):\\n\",\n    \"            return False\\n\",\n    \"        if not self._validate(node.right, node.data, maximum):\\n\",\n    \"            return False\\n\",\n    \"        return True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_bst_validate.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_bst_validate.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBstValidate(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_bst_validate_empty(self):\\n\",\n    \"        bst = BstValidate(None)\\n\",\n    \"        bst.validate()\\n\",\n    \"\\n\",\n    \"    def test_bst_validate(self):\\n\",\n    \"        bst = BstValidate(Node(5))\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(5)\\n\",\n    \"        bst.insert(6)\\n\",\n    \"        bst.insert(4)\\n\",\n    \"        bst.insert(7)\\n\",\n    \"        self.assertEqual(bst.validate(), True)\\n\",\n    \"\\n\",\n    \"        bst = BstValidate(Node(5))\\n\",\n    \"        left = Node(5)\\n\",\n    \"        right = Node(8)\\n\",\n    \"        invalid = Node(20)\\n\",\n    \"        bst.root.left = left\\n\",\n    \"        bst.root.right = right\\n\",\n    \"        bst.root.left.right = invalid\\n\",\n    \"        self.assertEqual(bst.validate(), False)\\n\",\n    \"\\n\",\n    \"        print('Success: test_bst_validate')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBstValidate()\\n\",\n    \"    test.assertRaises(TypeError, test.test_bst_validate_empty)\\n\",\n    \"    test.test_bst_validate()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_bst_validate\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_bst_validate.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/bst_validate/test_bst_validate.py",
    "content": "import unittest\n\n\nclass TestBstValidate(unittest.TestCase):\n\n    def test_bst_validate_empty(self):\n        bst = BstValidate(None)\n        bst.validate()\n\n    def test_bst_validate(self):\n        bst = BstValidate(Node(5))\n        bst.insert(8)\n        bst.insert(5)\n        bst.insert(6)\n        bst.insert(4)\n        bst.insert(7)\n        self.assertEqual(bst.validate(), True)\n\n        bst = BstValidate(Node(5))\n        left = Node(5)\n        right = Node(8)\n        invalid = Node(20)\n        bst.root.left = left\n        bst.root.right = right\n        bst.root.left.right = invalid\n        self.assertEqual(bst.validate(), False)\n\n        print('Success: test_bst_validate')\n\n\ndef main():\n    test = TestBstValidate()\n    test.assertRaises(TypeError, test.test_bst_validate_empty)\n    test.test_bst_validate()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/check_balance/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/check_balance/check_balance_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Check if a binary tree is balanced.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is a balanced tree one where the heights of two sub trees of any node doesn't differ by more than 1?\\n\",\n    \"    * Yes\\n\",\n    \"* If this is called on a None input, should we raise an exception?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a Node class with an insert method?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> No\\n\",\n    \"* 1 -> Yes\\n\",\n    \"* 5, 3, 8, 1, 4 -> Yes\\n\",\n    \"* 5, 3, 8, 9, 10 -> No\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/check_balance/check_balance_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\\n\",\n    \"%load ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BstBalance(Bst):\\n\",\n    \"\\n\",\n    \"    def check_balance(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_check_balance.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestCheckBalance(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_check_balance_empty(self):\\n\",\n    \"        bst = BstBalance(None)\\n\",\n    \"        bst.check_balance()\\n\",\n    \"\\n\",\n    \"    def test_check_balance(self):\\n\",\n    \"        bst = BstBalance(Node(5))\\n\",\n    \"        self.assertEqual(bst.check_balance(), True)\\n\",\n    \"\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(4)\\n\",\n    \"        self.assertEqual(bst.check_balance(), True)\\n\",\n    \"\\n\",\n    \"        bst = BstBalance(Node(5))\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(9)\\n\",\n    \"        bst.insert(10)\\n\",\n    \"        self.assertEqual(bst.check_balance(), False)\\n\",\n    \"\\n\",\n    \"        bst = BstBalance(Node(3))\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(5)\\n\",\n    \"        bst.insert(4)\\n\",\n    \"        bst.insert(6)\\n\",\n    \"        bst.insert(7)\\n\",\n    \"        self.assertEqual(bst.check_balance(), True)\\n\",\n    \"\\n\",\n    \"        print('Success: test_check_balance')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestCheckBalance()\\n\",\n    \"    test.assertRaises(TypeError, test.test_check_balance_empty)\\n\",\n    \"    test.test_check_balance()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/check_balance/check_balance_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/check_balance/check_balance_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Check if a binary tree is balanced.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is a balanced tree one where the heights of two sub trees of any node doesn't differ by more than 1?\\n\",\n    \"    * Yes\\n\",\n    \"* If this is called on a None input, should we raise an exception?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a Node class with an insert method?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> No\\n\",\n    \"* 1 -> Yes\\n\",\n    \"* 5, 3, 8, 1, 4 -> Yes\\n\",\n    \"* 5, 3, 8, 9, 10 -> No\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"The algorithm will be similar to where we get the height of a tree as seen in [here](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_height/height_solution.ipynb).\\n\",\n    \"\\n\",\n    \"However, we could check whether the tree is balanced while also checking for the heights.\\n\",\n    \"\\n\",\n    \"* Base case: If the root is None, return 0\\n\",\n    \"* Recursively check whether the left sub tree is balanced, and get its height left_height\\n\",\n    \"* Recursively check whether the right sub tree is balanced, and get its height right_height\\n\",\n    \"* Compare left_height and right_height\\n\",\n    \"* Return 1 + max(left_height, right_height)\\n\",\n    \"    \\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(h), where h is the height of the tree\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BstBalance(Bst):\\n\",\n    \"\\n\",\n    \"    def _check_balance(self, node):\\n\",\n    \"        if node is None:\\n\",\n    \"            return 0\\n\",\n    \"        left_height = self._check_balance(node.left)\\n\",\n    \"        if left_height == -1:\\n\",\n    \"            return -1\\n\",\n    \"        right_height = self._check_balance(node.right)\\n\",\n    \"        if right_height == -1:\\n\",\n    \"            return -1\\n\",\n    \"        diff = abs(left_height - right_height)\\n\",\n    \"        if diff > 1:\\n\",\n    \"            return -1\\n\",\n    \"        return 1 + max(left_height, right_height)\\n\",\n    \"\\n\",\n    \"    def check_balance(self):\\n\",\n    \"        if self.root is None:\\n\",\n    \"            raise TypeError('root cannot be None')\\n\",\n    \"        height = self._check_balance(self.root)\\n\",\n    \"        return height != -1\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_check_balance.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_check_balance.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestCheckBalance(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_check_balance_empty(self):\\n\",\n    \"        bst = BstBalance(None)\\n\",\n    \"        bst.check_balance()\\n\",\n    \"\\n\",\n    \"    def test_check_balance(self):\\n\",\n    \"        bst = BstBalance(Node(5))\\n\",\n    \"        self.assertEqual(bst.check_balance(), True)\\n\",\n    \"\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(4)\\n\",\n    \"        self.assertEqual(bst.check_balance(), True)\\n\",\n    \"\\n\",\n    \"        bst = BstBalance(Node(5))\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(9)\\n\",\n    \"        bst.insert(10)\\n\",\n    \"        self.assertEqual(bst.check_balance(), False)\\n\",\n    \"\\n\",\n    \"        bst = BstBalance(Node(3))\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(5)\\n\",\n    \"        bst.insert(4)\\n\",\n    \"        bst.insert(6)\\n\",\n    \"        bst.insert(7)\\n\",\n    \"        self.assertEqual(bst.check_balance(), True)\\n\",\n    \"\\n\",\n    \"        print('Success: test_check_balance')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestCheckBalance()\\n\",\n    \"    test.assertRaises(TypeError, test.test_check_balance_empty)\\n\",\n    \"    test.test_check_balance()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_check_balance\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_check_balance.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/check_balance/test_check_balance.py",
    "content": "import unittest\n\n\nclass TestCheckBalance(unittest.TestCase):\n\n    def test_check_balance_empty(self):\n        bst = BstBalance(None)\n        bst.check_balance()\n\n    def test_check_balance(self):\n        bst = BstBalance(Node(5))\n        self.assertEqual(bst.check_balance(), True)\n\n        bst.insert(3)\n        bst.insert(8)\n        bst.insert(1)\n        bst.insert(4)\n        self.assertEqual(bst.check_balance(), True)\n\n        bst = BstBalance(Node(5))\n        bst.insert(3)\n        bst.insert(8)\n        bst.insert(9)\n        bst.insert(10)\n        self.assertEqual(bst.check_balance(), False)\n\n        bst = BstBalance(Node(3))\n        bst.insert(2)\n        bst.insert(1)\n        bst.insert(5)\n        bst.insert(4)\n        bst.insert(6)\n        bst.insert(7)\n        self.assertEqual(bst.check_balance(), True)\n\n        print('Success: test_check_balance')\n\n\ndef main():\n    test = TestCheckBalance()\n    test.assertRaises(TypeError, test.test_check_balance_empty)\n    test.test_check_balance()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/graph/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/graph/graph.py",
    "content": "from enum import Enum  # Python 2 users: Run pip install enum34\n\n\nclass State(Enum):\n\n    unvisited = 0\n    visiting = 1\n    visited = 2\n\n\nclass Node:\n\n    def __init__(self, key):\n        self.key = key\n        self.visit_state = State.unvisited\n        self.incoming_edges = 0\n        self.adj_nodes = {}  # Key = key, val = Node\n        self.adj_weights = {}  # Key = key, val = weight\n\n    def __repr__(self):\n        return str(self.key)\n\n    def __lt__(self, other):\n        return self.key < other.key\n\n    def add_neighbor(self, neighbor, weight=0):\n        if neighbor is None or weight is None:\n            raise TypeError('neighbor or weight cannot be None')\n        neighbor.incoming_edges += 1\n        self.adj_weights[neighbor.key] = weight\n        self.adj_nodes[neighbor.key] = neighbor\n\n    def remove_neighbor(self, neighbor):\n        if neighbor is None:\n            raise TypeError('neighbor cannot be None')\n        if neighbor.key not in self.adj_nodes:\n            raise KeyError('neighbor not found')\n        neighbor.incoming_edges -= 1\n        del self.adj_weights[neighbor.key]\n        del self.adj_nodes[neighbor.key]\n\n\nclass Graph:\n\n    def __init__(self):\n        self.nodes = {}  # Key = key, val = Node\n\n    def add_node(self, key):\n        if key is None:\n            raise TypeError('key cannot be None')\n        if key not in self.nodes:\n            self.nodes[key] = Node(key)\n        return self.nodes[key]\n\n    def add_edge(self, source_key, dest_key, weight=0):\n        if source_key is None or dest_key is None:\n            raise KeyError('Invalid key')\n        if source_key not in self.nodes:\n            self.add_node(source_key)\n        if dest_key not in self.nodes:\n            self.add_node(dest_key)\n        self.nodes[source_key].add_neighbor(self.nodes[dest_key], weight)\n\n    def add_undirected_edge(self, src_key, dst_key, weight=0):\n        if src_key is None or dst_key is None:\n            raise TypeError('key cannot be None')\n        self.add_edge(src_key, dst_key, weight)\n        self.add_edge(dst_key, src_key, weight)\n"
  },
  {
    "path": "graphs_trees/graph/graph_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a graph.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the graph directed?\\n\",\n    \"    * Implement both\\n\",\n    \"* Do the edges have weights?\\n\",\n    \"    * Yes\\n\",\n    \"* Can the graph have cycles?\\n\",\n    \"    * Yes\\n\",\n    \"* If we try to add a node that already exists, do we just do nothing?\\n\",\n    \"    * Yes\\n\",\n    \"* If we try to delete a node that doesn't exist, do we just do nothing?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this is a connected graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"* `add_edge(source, destination, weight)`\\n\",\n    \"\\n\",\n    \"```\\n\",\n    \"graph.add_edge(0, 1, 5)\\n\",\n    \"graph.add_edge(0, 5, 2)\\n\",\n    \"graph.add_edge(1, 2, 3)\\n\",\n    \"graph.add_edge(2, 3, 4)\\n\",\n    \"graph.add_edge(3, 4, 5)\\n\",\n    \"graph.add_edge(3, 5, 6)\\n\",\n    \"graph.add_edge(4, 0, 7)\\n\",\n    \"graph.add_edge(5, 4, 8)\\n\",\n    \"graph.add_edge(5, 2, 9)\\n\",\n    \"```\\n\",\n    \"\\n\",\n    \"Result:\\n\",\n    \"* `source` and `destination` nodes within `graph` are connected with specified `weight`.\\n\",\n    \"\\n\",\n    \"Note: \\n\",\n    \"* The Graph class will be used as a building block for more complex graph challenges.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph/graph_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from enum import Enum  # Python 2 users: Run pip install enum34\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class State(Enum):\\n\",\n    \"\\n\",\n    \"    unvisited = 0\\n\",\n    \"    visiting = 1\\n\",\n    \"    visited = 2\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Node:\\n\",\n    \"\\n\",\n    \"    def __init__(self, key):\\n\",\n    \"        self.key = key\\n\",\n    \"        self.visit_state = State.unvisited\\n\",\n    \"        self.incoming_edges = 0\\n\",\n    \"        self.adj_nodes = {}  # Key = key, val = Node\\n\",\n    \"        self.adj_weights = {}  # Key = key, val = weight\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return str(self.key)\\n\",\n    \"\\n\",\n    \"    def __lt__(self, other):\\n\",\n    \"        return self.key < other.key\\n\",\n    \"\\n\",\n    \"    def add_neighbor(self, neighbor, weight=0):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def remove_neighbor(self, neighbor):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Graph:\\n\",\n    \"\\n\",\n    \"    def __init__(self):\\n\",\n    \"        self.nodes = {}  # Key = key, val = Node\\n\",\n    \"\\n\",\n    \"    def add_node(self, id):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def add_edge(self, source, dest, weight=0):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def add_undirected_edge(self, source, dest, weight=0):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_graph.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestGraph(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def create_graph(self):\\n\",\n    \"        graph = Graph()\\n\",\n    \"        for key in range(0, 6):\\n\",\n    \"            graph.add_node(key)\\n\",\n    \"        return graph\\n\",\n    \"\\n\",\n    \"    def test_graph(self):\\n\",\n    \"        graph = self.create_graph()\\n\",\n    \"        graph.add_edge(0, 1, weight=5)\\n\",\n    \"        graph.add_edge(0, 5, weight=2)\\n\",\n    \"        graph.add_edge(1, 2, weight=3)\\n\",\n    \"        graph.add_edge(2, 3, weight=4)\\n\",\n    \"        graph.add_edge(3, 4, weight=5)\\n\",\n    \"        graph.add_edge(3, 5, weight=6)\\n\",\n    \"        graph.add_edge(4, 0, weight=7)\\n\",\n    \"        graph.add_edge(5, 4, weight=8)\\n\",\n    \"        graph.add_edge(5, 2, weight=9)\\n\",\n    \"\\n\",\n    \"        self.assertEqual(graph.nodes[0].adj_weights[graph.nodes[1].key], 5)\\n\",\n    \"        self.assertEqual(graph.nodes[0].adj_weights[graph.nodes[5].key], 2)\\n\",\n    \"        self.assertEqual(graph.nodes[1].adj_weights[graph.nodes[2].key], 3)\\n\",\n    \"        self.assertEqual(graph.nodes[2].adj_weights[graph.nodes[3].key], 4)\\n\",\n    \"        self.assertEqual(graph.nodes[3].adj_weights[graph.nodes[4].key], 5)\\n\",\n    \"        self.assertEqual(graph.nodes[3].adj_weights[graph.nodes[5].key], 6)\\n\",\n    \"        self.assertEqual(graph.nodes[4].adj_weights[graph.nodes[0].key], 7)\\n\",\n    \"        self.assertEqual(graph.nodes[5].adj_weights[graph.nodes[4].key], 8)\\n\",\n    \"        self.assertEqual(graph.nodes[5].adj_weights[graph.nodes[2].key], 9)\\n\",\n    \"\\n\",\n    \"        self.assertEqual(graph.nodes[0].incoming_edges, 1)\\n\",\n    \"        self.assertEqual(graph.nodes[1].incoming_edges, 1)\\n\",\n    \"        self.assertEqual(graph.nodes[2].incoming_edges, 2)\\n\",\n    \"        self.assertEqual(graph.nodes[3].incoming_edges, 1)\\n\",\n    \"        self.assertEqual(graph.nodes[4].incoming_edges, 2)\\n\",\n    \"        self.assertEqual(graph.nodes[5].incoming_edges, 2)\\n\",\n    \"\\n\",\n    \"        graph.nodes[0].remove_neighbor(graph.nodes[1])\\n\",\n    \"        self.assertEqual(graph.nodes[1].incoming_edges, 0)\\n\",\n    \"        graph.nodes[3].remove_neighbor(graph.nodes[4])\\n\",\n    \"        self.assertEqual(graph.nodes[4].incoming_edges, 1)\\n\",\n    \"\\n\",\n    \"        self.assertEqual(graph.nodes[0] < graph.nodes[1], True)\\n\",\n    \"\\n\",\n    \"        print('Success: test_graph')\\n\",\n    \"\\n\",\n    \"    def test_graph_undirected(self):\\n\",\n    \"        graph = self.create_graph()\\n\",\n    \"        graph.add_undirected_edge(0, 1, weight=5)\\n\",\n    \"        graph.add_undirected_edge(0, 5, weight=2)\\n\",\n    \"        graph.add_undirected_edge(1, 2, weight=3)\\n\",\n    \"\\n\",\n    \"        self.assertEqual(graph.nodes[0].adj_weights[graph.nodes[1].key], 5)\\n\",\n    \"        self.assertEqual(graph.nodes[1].adj_weights[graph.nodes[0].key], 5)\\n\",\n    \"        self.assertEqual(graph.nodes[0].adj_weights[graph.nodes[5].key], 2)\\n\",\n    \"        self.assertEqual(graph.nodes[5].adj_weights[graph.nodes[0].key], 2)\\n\",\n    \"        self.assertEqual(graph.nodes[1].adj_weights[graph.nodes[2].key], 3)\\n\",\n    \"        self.assertEqual(graph.nodes[2].adj_weights[graph.nodes[1].key], 3)\\n\",\n    \"\\n\",\n    \"        print('Success: test_graph_undirected')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestGraph()\\n\",\n    \"    test.test_graph()\\n\",\n    \"    test.test_graph_undirected()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](https://github.com/donnemartin/interactive-coding-challenges/graphs_trees/graphs/graph_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/graph/graph_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a graph.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the graph directed?\\n\",\n    \"    * Implement both\\n\",\n    \"* Do the edges have weights?\\n\",\n    \"    * Yes\\n\",\n    \"* Can the graph have cycles?\\n\",\n    \"    * Yes\\n\",\n    \"* If we try to add a node that already exists, do we just do nothing?\\n\",\n    \"    * Yes\\n\",\n    \"* If we try to delete a node that doesn't exist, do we just do nothing?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this is a connected graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"* `add_edge(source, destination, weight)`\\n\",\n    \"\\n\",\n    \"```\\n\",\n    \"graph.add_edge(0, 1, 5)\\n\",\n    \"graph.add_edge(0, 5, 2)\\n\",\n    \"graph.add_edge(1, 2, 3)\\n\",\n    \"graph.add_edge(2, 3, 4)\\n\",\n    \"graph.add_edge(3, 4, 5)\\n\",\n    \"graph.add_edge(3, 5, 6)\\n\",\n    \"graph.add_edge(4, 0, 7)\\n\",\n    \"graph.add_edge(5, 4, 8)\\n\",\n    \"graph.add_edge(5, 2, 9)\\n\",\n    \"```\\n\",\n    \"\\n\",\n    \"Result:\\n\",\n    \"* `source` and `destination` nodes within `graph` are connected with specified `weight`.\\n\",\n    \"\\n\",\n    \"Note: \\n\",\n    \"* The Graph class will be used as a building block for more complex graph challenges.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### Node\\n\",\n    \"\\n\",\n    \"Node will keep track of its:\\n\",\n    \"* id\\n\",\n    \"* visit state\\n\",\n    \"* incoming edge count (useful for algorithms such as topological sort)\\n\",\n    \"* adjacent nodes and edge weights\\n\",\n    \"\\n\",\n    \"#### add_neighbor\\n\",\n    \"\\n\",\n    \"* If the neighbor doesn't already exist as an adjacent node\\n\",\n    \"    * Update the adjacent nodes and edge weights\\n\",\n    \"    * Increment the neighbor's incoming edge count\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"#### remove_neighbor\\n\",\n    \"\\n\",\n    \"* If the neighbor exists as an adjacent node\\n\",\n    \"    * Decrement the neighbor's incoming edge count\\n\",\n    \"    * Remove the neighbor as an adjacent node\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Graph\\n\",\n    \"\\n\",\n    \"Graph will keep track of its:\\n\",\n    \"* nodes\\n\",\n    \"\\n\",\n    \"#### add_node\\n\",\n    \"\\n\",\n    \"* If node already exists, return it\\n\",\n    \"* Create a node with the given id\\n\",\n    \"* Add the newly created node to the collection of nodes\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"#### add_edge\\n\",\n    \"\\n\",\n    \"* If the source node is not in the collection of nodes, add it\\n\",\n    \"* If the dest node is not in the collection of nodes, add it\\n\",\n    \"* Add a connection from the source node to the dest node with the given edge weight\\n\",\n    \"\\n\",\n    \"#### add_undirected_edge\\n\",\n    \"\\n\",\n    \"* Call add_edge\\n\",\n    \"* Also add a connection from the dest node to the source node with the given edge weight\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting graph.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile graph.py\\n\",\n    \"from enum import Enum  # Python 2 users: Run pip install enum34\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class State(Enum):\\n\",\n    \"\\n\",\n    \"    unvisited = 0\\n\",\n    \"    visiting = 1\\n\",\n    \"    visited = 2\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Node:\\n\",\n    \"\\n\",\n    \"    def __init__(self, key):\\n\",\n    \"        self.key = key\\n\",\n    \"        self.visit_state = State.unvisited\\n\",\n    \"        self.incoming_edges = 0\\n\",\n    \"        self.adj_nodes = {}  # Key = key, val = Node\\n\",\n    \"        self.adj_weights = {}  # Key = key, val = weight\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return str(self.key)\\n\",\n    \"\\n\",\n    \"    def __lt__(self, other):\\n\",\n    \"        return self.key < other.key\\n\",\n    \"\\n\",\n    \"    def add_neighbor(self, neighbor, weight=0):\\n\",\n    \"        if neighbor is None or weight is None:\\n\",\n    \"            raise TypeError('neighbor or weight cannot be None')\\n\",\n    \"        neighbor.incoming_edges += 1\\n\",\n    \"        self.adj_weights[neighbor.key] = weight\\n\",\n    \"        self.adj_nodes[neighbor.key] = neighbor\\n\",\n    \"\\n\",\n    \"    def remove_neighbor(self, neighbor):\\n\",\n    \"        if neighbor is None:\\n\",\n    \"            raise TypeError('neighbor cannot be None')\\n\",\n    \"        if neighbor.key not in self.adj_nodes:\\n\",\n    \"            raise KeyError('neighbor not found')\\n\",\n    \"        neighbor.incoming_edges -= 1\\n\",\n    \"        del self.adj_weights[neighbor.key]\\n\",\n    \"        del self.adj_nodes[neighbor.key]\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Graph:\\n\",\n    \"\\n\",\n    \"    def __init__(self):\\n\",\n    \"        self.nodes = {}  # Key = key, val = Node\\n\",\n    \"\\n\",\n    \"    def add_node(self, key):\\n\",\n    \"        if key is None:\\n\",\n    \"            raise TypeError('key cannot be None')\\n\",\n    \"        if key not in self.nodes:\\n\",\n    \"            self.nodes[key] = Node(key)\\n\",\n    \"        return self.nodes[key]\\n\",\n    \"\\n\",\n    \"    def add_edge(self, source_key, dest_key, weight=0):\\n\",\n    \"        if source_key is None or dest_key is None:\\n\",\n    \"            raise KeyError('Invalid key')\\n\",\n    \"        if source_key not in self.nodes:\\n\",\n    \"            self.add_node(source_key)\\n\",\n    \"        if dest_key not in self.nodes:\\n\",\n    \"            self.add_node(dest_key)\\n\",\n    \"        self.nodes[source_key].add_neighbor(self.nodes[dest_key], weight)\\n\",\n    \"\\n\",\n    \"    def add_undirected_edge(self, src_key, dst_key, weight=0):\\n\",\n    \"        if src_key is None or dst_key is None:\\n\",\n    \"            raise TypeError('key cannot be None')\\n\",\n    \"        self.add_edge(src_key, dst_key, weight)\\n\",\n    \"        self.add_edge(dst_key, src_key, weight)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run graph.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_graph.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_graph.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestGraph(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def create_graph(self):\\n\",\n    \"        graph = Graph()\\n\",\n    \"        for key in range(0, 6):\\n\",\n    \"            graph.add_node(key)\\n\",\n    \"        return graph\\n\",\n    \"\\n\",\n    \"    def test_graph(self):\\n\",\n    \"        graph = self.create_graph()\\n\",\n    \"        graph.add_edge(0, 1, weight=5)\\n\",\n    \"        graph.add_edge(0, 5, weight=2)\\n\",\n    \"        graph.add_edge(1, 2, weight=3)\\n\",\n    \"        graph.add_edge(2, 3, weight=4)\\n\",\n    \"        graph.add_edge(3, 4, weight=5)\\n\",\n    \"        graph.add_edge(3, 5, weight=6)\\n\",\n    \"        graph.add_edge(4, 0, weight=7)\\n\",\n    \"        graph.add_edge(5, 4, weight=8)\\n\",\n    \"        graph.add_edge(5, 2, weight=9)\\n\",\n    \"\\n\",\n    \"        self.assertEqual(graph.nodes[0].adj_weights[graph.nodes[1].key], 5)\\n\",\n    \"        self.assertEqual(graph.nodes[0].adj_weights[graph.nodes[5].key], 2)\\n\",\n    \"        self.assertEqual(graph.nodes[1].adj_weights[graph.nodes[2].key], 3)\\n\",\n    \"        self.assertEqual(graph.nodes[2].adj_weights[graph.nodes[3].key], 4)\\n\",\n    \"        self.assertEqual(graph.nodes[3].adj_weights[graph.nodes[4].key], 5)\\n\",\n    \"        self.assertEqual(graph.nodes[3].adj_weights[graph.nodes[5].key], 6)\\n\",\n    \"        self.assertEqual(graph.nodes[4].adj_weights[graph.nodes[0].key], 7)\\n\",\n    \"        self.assertEqual(graph.nodes[5].adj_weights[graph.nodes[4].key], 8)\\n\",\n    \"        self.assertEqual(graph.nodes[5].adj_weights[graph.nodes[2].key], 9)\\n\",\n    \"\\n\",\n    \"        self.assertEqual(graph.nodes[0].incoming_edges, 1)\\n\",\n    \"        self.assertEqual(graph.nodes[1].incoming_edges, 1)\\n\",\n    \"        self.assertEqual(graph.nodes[2].incoming_edges, 2)\\n\",\n    \"        self.assertEqual(graph.nodes[3].incoming_edges, 1)\\n\",\n    \"        self.assertEqual(graph.nodes[4].incoming_edges, 2)\\n\",\n    \"        self.assertEqual(graph.nodes[5].incoming_edges, 2)\\n\",\n    \"\\n\",\n    \"        graph.nodes[0].remove_neighbor(graph.nodes[1])\\n\",\n    \"        self.assertEqual(graph.nodes[1].incoming_edges, 0)\\n\",\n    \"        graph.nodes[3].remove_neighbor(graph.nodes[4])\\n\",\n    \"        self.assertEqual(graph.nodes[4].incoming_edges, 1)\\n\",\n    \"\\n\",\n    \"        self.assertEqual(graph.nodes[0] < graph.nodes[1], True)\\n\",\n    \"\\n\",\n    \"        print('Success: test_graph')\\n\",\n    \"\\n\",\n    \"    def test_graph_undirected(self):\\n\",\n    \"        graph = self.create_graph()\\n\",\n    \"        graph.add_undirected_edge(0, 1, weight=5)\\n\",\n    \"        graph.add_undirected_edge(0, 5, weight=2)\\n\",\n    \"        graph.add_undirected_edge(1, 2, weight=3)\\n\",\n    \"\\n\",\n    \"        self.assertEqual(graph.nodes[0].adj_weights[graph.nodes[1].key], 5)\\n\",\n    \"        self.assertEqual(graph.nodes[1].adj_weights[graph.nodes[0].key], 5)\\n\",\n    \"        self.assertEqual(graph.nodes[0].adj_weights[graph.nodes[5].key], 2)\\n\",\n    \"        self.assertEqual(graph.nodes[5].adj_weights[graph.nodes[0].key], 2)\\n\",\n    \"        self.assertEqual(graph.nodes[1].adj_weights[graph.nodes[2].key], 3)\\n\",\n    \"        self.assertEqual(graph.nodes[2].adj_weights[graph.nodes[1].key], 3)\\n\",\n    \"\\n\",\n    \"        print('Success: test_graph_undirected')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestGraph()\\n\",\n    \"    test.test_graph()\\n\",\n    \"    test.test_graph_undirected()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_graph\\n\",\n      \"Success: test_graph_undirected\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_graph.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/graph/test_graph.py",
    "content": "import unittest\n\n\nclass TestGraph(unittest.TestCase):\n\n    def create_graph(self):\n        graph = Graph()\n        for key in range(0, 6):\n            graph.add_node(key)\n        return graph\n\n    def test_graph(self):\n        graph = self.create_graph()\n        graph.add_edge(0, 1, weight=5)\n        graph.add_edge(0, 5, weight=2)\n        graph.add_edge(1, 2, weight=3)\n        graph.add_edge(2, 3, weight=4)\n        graph.add_edge(3, 4, weight=5)\n        graph.add_edge(3, 5, weight=6)\n        graph.add_edge(4, 0, weight=7)\n        graph.add_edge(5, 4, weight=8)\n        graph.add_edge(5, 2, weight=9)\n\n        self.assertEqual(graph.nodes[0].adj_weights[graph.nodes[1].key], 5)\n        self.assertEqual(graph.nodes[0].adj_weights[graph.nodes[5].key], 2)\n        self.assertEqual(graph.nodes[1].adj_weights[graph.nodes[2].key], 3)\n        self.assertEqual(graph.nodes[2].adj_weights[graph.nodes[3].key], 4)\n        self.assertEqual(graph.nodes[3].adj_weights[graph.nodes[4].key], 5)\n        self.assertEqual(graph.nodes[3].adj_weights[graph.nodes[5].key], 6)\n        self.assertEqual(graph.nodes[4].adj_weights[graph.nodes[0].key], 7)\n        self.assertEqual(graph.nodes[5].adj_weights[graph.nodes[4].key], 8)\n        self.assertEqual(graph.nodes[5].adj_weights[graph.nodes[2].key], 9)\n\n        self.assertEqual(graph.nodes[0].incoming_edges, 1)\n        self.assertEqual(graph.nodes[1].incoming_edges, 1)\n        self.assertEqual(graph.nodes[2].incoming_edges, 2)\n        self.assertEqual(graph.nodes[3].incoming_edges, 1)\n        self.assertEqual(graph.nodes[4].incoming_edges, 2)\n        self.assertEqual(graph.nodes[5].incoming_edges, 2)\n\n        graph.nodes[0].remove_neighbor(graph.nodes[1])\n        self.assertEqual(graph.nodes[1].incoming_edges, 0)\n        graph.nodes[3].remove_neighbor(graph.nodes[4])\n        self.assertEqual(graph.nodes[4].incoming_edges, 1)\n\n        self.assertEqual(graph.nodes[0] < graph.nodes[1], True)\n\n        print('Success: test_graph')\n\n    def test_graph_undirected(self):\n        graph = self.create_graph()\n        graph.add_undirected_edge(0, 1, weight=5)\n        graph.add_undirected_edge(0, 5, weight=2)\n        graph.add_undirected_edge(1, 2, weight=3)\n\n        self.assertEqual(graph.nodes[0].adj_weights[graph.nodes[1].key], 5)\n        self.assertEqual(graph.nodes[1].adj_weights[graph.nodes[0].key], 5)\n        self.assertEqual(graph.nodes[0].adj_weights[graph.nodes[5].key], 2)\n        self.assertEqual(graph.nodes[5].adj_weights[graph.nodes[0].key], 2)\n        self.assertEqual(graph.nodes[1].adj_weights[graph.nodes[2].key], 3)\n        self.assertEqual(graph.nodes[2].adj_weights[graph.nodes[1].key], 3)\n\n        print('Success: test_graph_undirected')\n\n\ndef main():\n    test = TestGraph()\n    test.test_graph()\n    test.test_graph_undirected()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/graph_bfs/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/graph_bfs/bfs_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement breadth-first search on a graph.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the graph directed?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have Graph and Node classes?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this is a connected graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"* `add_edge(source, destination, weight)`\\n\",\n    \"\\n\",\n    \"```\\n\",\n    \"graph.add_edge(0, 1, 5)\\n\",\n    \"graph.add_edge(0, 4, 3)\\n\",\n    \"graph.add_edge(0, 5, 2)\\n\",\n    \"graph.add_edge(1, 3, 5)\\n\",\n    \"graph.add_edge(1, 4, 4)\\n\",\n    \"graph.add_edge(2, 1, 6)\\n\",\n    \"graph.add_edge(3, 2, 7)\\n\",\n    \"graph.add_edge(3, 4, 8)\\n\",\n    \"```\\n\",\n    \"\\n\",\n    \"Result:\\n\",\n    \"* Order of nodes visited: [0, 1, 4, 5, 3, 2]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_bfs/bfs_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../graph/graph.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class GraphBfs(Graph):\\n\",\n    \"\\n\",\n    \"    def bfs(self, root, visit_func):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../utils/results.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_bfs.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBfs(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def __init__(self, *args, **kwargs):\\n\",\n    \"        super(TestBfs, self).__init__()\\n\",\n    \"        self.results = Results()\\n\",\n    \"\\n\",\n    \"    def test_bfs(self):\\n\",\n    \"        nodes = []\\n\",\n    \"        graph = GraphBfs()\\n\",\n    \"        for id in range(0, 6):\\n\",\n    \"            nodes.append(graph.add_node(id))\\n\",\n    \"        graph.add_edge(0, 1, 5)\\n\",\n    \"        graph.add_edge(0, 4, 3)\\n\",\n    \"        graph.add_edge(0, 5, 2)\\n\",\n    \"        graph.add_edge(1, 3, 5)\\n\",\n    \"        graph.add_edge(1, 4, 4)\\n\",\n    \"        graph.add_edge(2, 1, 6)\\n\",\n    \"        graph.add_edge(3, 2, 7)\\n\",\n    \"        graph.add_edge(3, 4, 8)\\n\",\n    \"        graph.bfs(nodes[0], self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[0, 1, 4, 5, 3, 2]\\\")\\n\",\n    \"\\n\",\n    \"        print('Success: test_bfs')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBfs()\\n\",\n    \"    test.test_bfs()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/graph_bfs/bfs_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement breadth-first search on a graph.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the graph directed?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have Graph and Node classes?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this is a connected graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"* `add_edge(source, destination, weight)`\\n\",\n    \"\\n\",\n    \"```\\n\",\n    \"graph.add_edge(0, 1, 5)\\n\",\n    \"graph.add_edge(0, 4, 3)\\n\",\n    \"graph.add_edge(0, 5, 2)\\n\",\n    \"graph.add_edge(1, 3, 5)\\n\",\n    \"graph.add_edge(1, 4, 4)\\n\",\n    \"graph.add_edge(2, 1, 6)\\n\",\n    \"graph.add_edge(3, 2, 7)\\n\",\n    \"graph.add_edge(3, 4, 8)\\n\",\n    \"```\\n\",\n    \"\\n\",\n    \"Result:\\n\",\n    \"* Order of nodes visited: [0, 1, 4, 5, 3, 2]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We generally use breadth-first search to determine the shortest path.\\n\",\n    \"\\n\",\n    \"* Add the current node to the queue and mark it as visited\\n\",\n    \"* While the queue is not empty\\n\",\n    \"    * Dequeue a node and visit it\\n\",\n    \"    * Iterate through each adjacent node\\n\",\n    \"        * If the node has not been visited, add it to the queue and mark it as visited\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(V + E), where V = number of vertices and E = number of edges\\n\",\n    \"* Space: O(V)\\n\",\n    \"\\n\",\n    \"Note on space complexity from [Wikipedia](https://en.wikipedia.org/wiki/Breadth-first_search):\\n\",\n    \"* When the number of vertices in the graph is known ahead of time, and additional data structures are used to determine which vertices have already been added to the queue, the space complexity can be expressed as O(V) \\n\",\n    \"* If the graph is represented by an adjacency list it occupies O(V + E) space in memory\\n\",\n    \"* If the graph is represented by an adjacency matrix representation, it occupies O(V^2)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../graph/graph.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from collections import deque\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class GraphBfs(Graph):\\n\",\n    \"\\n\",\n    \"    def bfs(self, root, visit_func):\\n\",\n    \"        if root is None:\\n\",\n    \"            return\\n\",\n    \"        queue = deque()\\n\",\n    \"        queue.append(root)\\n\",\n    \"        root.visit_state = State.visited\\n\",\n    \"        while queue:\\n\",\n    \"            node = queue.popleft()\\n\",\n    \"            visit_func(node)\\n\",\n    \"            for adjacent_node in node.adj_nodes.values():\\n\",\n    \"                if adjacent_node.visit_state == State.unvisited:\\n\",\n    \"                    queue.append(adjacent_node)\\n\",\n    \"                    adjacent_node.visit_state = State.visited\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../utils/results.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_bfs.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_bfs.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBfs(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def __init__(self, *args, **kwargs):\\n\",\n    \"        super(TestBfs, self).__init__()\\n\",\n    \"        self.results = Results()\\n\",\n    \"\\n\",\n    \"    def test_bfs(self):\\n\",\n    \"        nodes = []\\n\",\n    \"        graph = GraphBfs()\\n\",\n    \"        for id in range(0, 6):\\n\",\n    \"            nodes.append(graph.add_node(id))\\n\",\n    \"        graph.add_edge(0, 1, 5)\\n\",\n    \"        graph.add_edge(0, 4, 3)\\n\",\n    \"        graph.add_edge(0, 5, 2)\\n\",\n    \"        graph.add_edge(1, 3, 5)\\n\",\n    \"        graph.add_edge(1, 4, 4)\\n\",\n    \"        graph.add_edge(2, 1, 6)\\n\",\n    \"        graph.add_edge(3, 2, 7)\\n\",\n    \"        graph.add_edge(3, 4, 8)\\n\",\n    \"        graph.bfs(nodes[0], self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[0, 1, 4, 5, 3, 2]\\\")\\n\",\n    \"\\n\",\n    \"        print('Success: test_bfs')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBfs()\\n\",\n    \"    test.test_bfs()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_bfs\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_bfs.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/graph_bfs/test_bfs.py",
    "content": "import unittest\n\n\nclass TestBfs(unittest.TestCase):\n\n    def __init__(self, *args, **kwargs):\n        super(TestBfs, self).__init__()\n        self.results = Results()\n\n    def test_bfs(self):\n        nodes = []\n        graph = GraphBfs()\n        for id in range(0, 6):\n            nodes.append(graph.add_node(id))\n        graph.add_edge(0, 1, 5)\n        graph.add_edge(0, 4, 3)\n        graph.add_edge(0, 5, 2)\n        graph.add_edge(1, 3, 5)\n        graph.add_edge(1, 4, 4)\n        graph.add_edge(2, 1, 6)\n        graph.add_edge(3, 2, 7)\n        graph.add_edge(3, 4, 8)\n        graph.bfs(nodes[0], self.results.add_result)\n        self.assertEqual(str(self.results), \"[0, 1, 4, 5, 3, 2]\")\n\n        print('Success: test_bfs')\n\n\ndef main():\n    test = TestBfs()\n    test.test_bfs()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/graph_build_order/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/graph_build_order/build_order_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find a build order given a list of projects and dependencies.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is it possible to have a cyclic graph as the input?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have Graph and Node classes?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this is a connected graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* projects: a, b, c, d, e, f, g\\n\",\n    \"* dependencies: (d, g), (f, c), (f, b), (f, a), (c, a), (b, a), (a, e), (b, e)\\n\",\n    \"* output: d, f, c, b, g, a, e\\n\",\n    \"\\n\",\n    \"Note: Edge direction is down\\n\",\n    \"<pre>\\n\",\n    \"    f     d\\n\",\n    \"   /|\\\\    |\\n\",\n    \"  c | b   g\\n\",\n    \"   \\\\|/|\\n\",\n    \"    a |\\n\",\n    \"    |/\\n\",\n    \"    e\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Test a graph with a cycle, output should be None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_build_order/build_order_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"class Dependency(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, node_key_before, node_key_after):\\n\",\n    \"        self.node_key_before = node_key_before\\n\",\n    \"        self.node_key_after = node_key_after\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../graph/graph.py\\n\",\n    \"%load ../graph/graph.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BuildOrder(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, dependencies):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def find_build_order(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_build_order.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBuildOrder(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def __init__(self, *args, **kwargs):\\n\",\n    \"        super(TestBuildOrder, self).__init__()\\n\",\n    \"        self.dependencies = [\\n\",\n    \"            Dependency('d', 'g'),\\n\",\n    \"            Dependency('f', 'c'),\\n\",\n    \"            Dependency('f', 'b'),\\n\",\n    \"            Dependency('f', 'a'),\\n\",\n    \"            Dependency('c', 'a'),\\n\",\n    \"            Dependency('b', 'a'),\\n\",\n    \"            Dependency('a', 'e'),\\n\",\n    \"            Dependency('b', 'e'),\\n\",\n    \"        ]\\n\",\n    \"\\n\",\n    \"    def test_build_order(self):\\n\",\n    \"        build_order = BuildOrder(self.dependencies)\\n\",\n    \"        processed_nodes = build_order.find_build_order()\\n\",\n    \"\\n\",\n    \"        expected_result0 = ('d', 'f')\\n\",\n    \"        expected_result1 = ('c', 'b', 'g')\\n\",\n    \"        self.assertTrue(processed_nodes[0].key in expected_result0)\\n\",\n    \"        self.assertTrue(processed_nodes[1].key in expected_result0)\\n\",\n    \"        self.assertTrue(processed_nodes[2].key in expected_result1)\\n\",\n    \"        self.assertTrue(processed_nodes[3].key in expected_result1)\\n\",\n    \"        self.assertTrue(processed_nodes[4].key in expected_result1)\\n\",\n    \"        self.assertTrue(processed_nodes[5].key is 'a')\\n\",\n    \"        self.assertTrue(processed_nodes[6].key is 'e')\\n\",\n    \"\\n\",\n    \"        print('Success: test_build_order')\\n\",\n    \"\\n\",\n    \"    def test_build_order_circular(self):\\n\",\n    \"        self.dependencies.append(Dependency('e', 'f'))\\n\",\n    \"        build_order = BuildOrder(self.dependencies)\\n\",\n    \"        processed_nodes = build_order.find_build_order()\\n\",\n    \"        self.assertTrue(processed_nodes is None)\\n\",\n    \"\\n\",\n    \"        print('Success: test_build_order_circular')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBuildOrder()\\n\",\n    \"    test.test_build_order()\\n\",\n    \"    test.test_build_order_circular()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](https://github.com/donnemartin/interactive-coding-challenges/graphs_trees/build_order/build_order_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/graph_build_order/build_order_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find a build order given a list of projects and dependencies.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is it possible to have a cyclic graph as the input?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have Graph and Node classes?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this is a connected graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* projects: a, b, c, d, e, f, g\\n\",\n    \"* dependencies: (d, g), (f, c), (f, b), (f, a), (c, a), (b, a), (a, e), (b, e)\\n\",\n    \"* output: d, f, c, b, g, a, e\\n\",\n    \"\\n\",\n    \"Note: Edge direction is down\\n\",\n    \"<pre>\\n\",\n    \"    f     d\\n\",\n    \"   /|\\\\    |\\n\",\n    \"  c | b   g\\n\",\n    \"   \\\\|/|\\n\",\n    \"    a |\\n\",\n    \"    |/\\n\",\n    \"    e\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Test a graph with a cycle, output should be None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We can determine the build order using a topological sort.\\n\",\n    \"\\n\",\n    \"* Build the graph with projects (nodes) and dependencies (directed edges)\\n\",\n    \"* Add initially non-dependent nodes to processed_nodes\\n\",\n    \"    * If none exist, we have a circular dependency, return None\\n\",\n    \"* While the length processed_nodes < the length of graph nodes\\n\",\n    \"    * Remove outgoing edges from newly added items in processed_nodes\\n\",\n    \"    * Add non-dependent nodes to processed_nodes\\n\",\n    \"        * If we didn't add any nodes, we have a circular dependency, return None\\n\",\n    \"* Return processed_nodes\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(V + E)\\n\",\n    \"* Space: O(V + E)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from collections import deque\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Dependency(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, node_key_before, node_key_after):\\n\",\n    \"        self.node_key_before = node_key_before\\n\",\n    \"        self.node_key_after = node_key_after\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../graph/graph.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BuildOrder(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, dependencies):\\n\",\n    \"        self.dependencies = dependencies\\n\",\n    \"        self.graph = Graph()\\n\",\n    \"        self._build_graph()\\n\",\n    \"\\n\",\n    \"    def _build_graph(self):\\n\",\n    \"        for dependency in self.dependencies:\\n\",\n    \"            self.graph.add_edge(dependency.node_key_before,\\n\",\n    \"                                dependency.node_key_after)\\n\",\n    \"\\n\",\n    \"    def _find_start_nodes(self, processed_nodes):\\n\",\n    \"        nodes_to_process = {}\\n\",\n    \"        for key, node in self.graph.nodes.items():\\n\",\n    \"            if node.incoming_edges == 0 and key not in processed_nodes:\\n\",\n    \"                nodes_to_process[key] = node\\n\",\n    \"        return nodes_to_process\\n\",\n    \"\\n\",\n    \"    def _process_nodes(self, nodes_to_process, processed_nodes):\\n\",\n    \"        for node in nodes_to_process.values():\\n\",\n    \"            # We'll need to iterate on copies since we'll need\\n\",\n    \"            # to change the dictionaries during iteration with\\n\",\n    \"            # the remove_neighbor call\\n\",\n    \"            for adj_node in list(node.adj_nodes.values()):\\n\",\n    \"                node.remove_neighbor(adj_node)\\n\",\n    \"            processed_nodes[node.key] = node\\n\",\n    \"        nodes_to_process = {}\\n\",\n    \"\\n\",\n    \"    def find_build_order(self):\\n\",\n    \"        result = []\\n\",\n    \"        nodes_to_process = {}\\n\",\n    \"        processed_nodes = {}\\n\",\n    \"        while len(result) != len(self.graph.nodes):\\n\",\n    \"            nodes_to_process = self._find_start_nodes(processed_nodes)\\n\",\n    \"            if not nodes_to_process:\\n\",\n    \"                return None\\n\",\n    \"            result.extend(nodes_to_process.values())\\n\",\n    \"            self._process_nodes(nodes_to_process, processed_nodes)\\n\",\n    \"        return result\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../utils/results.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_build_order.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_build_order.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBuildOrder(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def __init__(self, *args, **kwargs):\\n\",\n    \"        super(TestBuildOrder, self).__init__()\\n\",\n    \"        self.dependencies = [\\n\",\n    \"            Dependency('d', 'g'),\\n\",\n    \"            Dependency('f', 'c'),\\n\",\n    \"            Dependency('f', 'b'),\\n\",\n    \"            Dependency('f', 'a'),\\n\",\n    \"            Dependency('c', 'a'),\\n\",\n    \"            Dependency('b', 'a'),\\n\",\n    \"            Dependency('a', 'e'),\\n\",\n    \"            Dependency('b', 'e'),\\n\",\n    \"        ]\\n\",\n    \"\\n\",\n    \"    def test_build_order(self):\\n\",\n    \"        build_order = BuildOrder(self.dependencies)\\n\",\n    \"        processed_nodes = build_order.find_build_order()\\n\",\n    \"\\n\",\n    \"        expected_result0 = ('d', 'f')\\n\",\n    \"        expected_result1 = ('c', 'b', 'g')\\n\",\n    \"        self.assertTrue(processed_nodes[0].key in expected_result0)\\n\",\n    \"        self.assertTrue(processed_nodes[1].key in expected_result0)\\n\",\n    \"        self.assertTrue(processed_nodes[2].key in expected_result1)\\n\",\n    \"        self.assertTrue(processed_nodes[3].key in expected_result1)\\n\",\n    \"        self.assertTrue(processed_nodes[4].key in expected_result1)\\n\",\n    \"        self.assertTrue(processed_nodes[5].key is 'a')\\n\",\n    \"        self.assertTrue(processed_nodes[6].key is 'e')\\n\",\n    \"\\n\",\n    \"        print('Success: test_build_order')\\n\",\n    \"\\n\",\n    \"    def test_build_order_circular(self):\\n\",\n    \"        self.dependencies.append(Dependency('e', 'f'))\\n\",\n    \"        build_order = BuildOrder(self.dependencies)\\n\",\n    \"        processed_nodes = build_order.find_build_order()\\n\",\n    \"        self.assertTrue(processed_nodes is None)\\n\",\n    \"\\n\",\n    \"        print('Success: test_build_order_circular')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBuildOrder()\\n\",\n    \"    test.test_build_order()\\n\",\n    \"    test.test_build_order_circular()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 6,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_build_order\\n\",\n      \"Success: test_build_order_circular\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_build_order.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/graph_build_order/test_build_order.py",
    "content": "import unittest\n\n\nclass TestBuildOrder(unittest.TestCase):\n\n    def __init__(self, *args, **kwargs):\n        super(TestBuildOrder, self).__init__()\n        self.dependencies = [\n            Dependency('d', 'g'),\n            Dependency('f', 'c'),\n            Dependency('f', 'b'),\n            Dependency('f', 'a'),\n            Dependency('c', 'a'),\n            Dependency('b', 'a'),\n            Dependency('a', 'e'),\n            Dependency('b', 'e'),\n        ]\n\n    def test_build_order(self):\n        build_order = BuildOrder(self.dependencies)\n        processed_nodes = build_order.find_build_order()\n\n        expected_result0 = ('d', 'f')\n        expected_result1 = ('c', 'b', 'g')\n        self.assertTrue(processed_nodes[0].key in expected_result0)\n        self.assertTrue(processed_nodes[1].key in expected_result0)\n        self.assertTrue(processed_nodes[2].key in expected_result1)\n        self.assertTrue(processed_nodes[3].key in expected_result1)\n        self.assertTrue(processed_nodes[4].key in expected_result1)\n        self.assertTrue(processed_nodes[5].key is 'a')\n        self.assertTrue(processed_nodes[6].key is 'e')\n\n        print('Success: test_build_order')\n\n    def test_build_order_circular(self):\n        self.dependencies.append(Dependency('e', 'f'))\n        build_order = BuildOrder(self.dependencies)\n        processed_nodes = build_order.find_build_order()\n        self.assertTrue(processed_nodes is None)\n\n        print('Success: test_build_order_circular')\n\n\ndef main():\n    test = TestBuildOrder()\n    test.test_build_order()\n    test.test_build_order_circular()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/graph_dfs/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/graph_dfs/dfs_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement depth-first search on a graph.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the graph directed?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have Graph and Node classes?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this is a connected graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"* `add_edge(source, destination, weight)`\\n\",\n    \"\\n\",\n    \"```\\n\",\n    \"graph.add_edge(0, 1, 5)\\n\",\n    \"graph.add_edge(0, 4, 3)\\n\",\n    \"graph.add_edge(0, 5, 2)\\n\",\n    \"graph.add_edge(1, 3, 5)\\n\",\n    \"graph.add_edge(1, 4, 4)\\n\",\n    \"graph.add_edge(2, 1, 6)\\n\",\n    \"graph.add_edge(3, 2, 7)\\n\",\n    \"graph.add_edge(3, 4, 8)\\n\",\n    \"```\\n\",\n    \"\\n\",\n    \"Result:\\n\",\n    \"* Order of nodes visited: [0, 1, 3, 2, 4, 5]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_dfs/dfs_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../graph/graph.py\\n\",\n    \"%load ../graph/graph.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class GraphDfs(Graph):\\n\",\n    \"\\n\",\n    \"    def dfs(self, root, visit_func):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../utils/results.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_dfs.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestDfs(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def __init__(self, *args, **kwargs):\\n\",\n    \"        super(TestDfs, self).__init__()\\n\",\n    \"        self.results = Results()\\n\",\n    \"\\n\",\n    \"    def test_dfs(self):\\n\",\n    \"        nodes = []\\n\",\n    \"        graph = GraphDfs()\\n\",\n    \"        for id in range(0, 6):\\n\",\n    \"            nodes.append(graph.add_node(id))\\n\",\n    \"        graph.add_edge(0, 1, 5)\\n\",\n    \"        graph.add_edge(0, 4, 3)\\n\",\n    \"        graph.add_edge(0, 5, 2)\\n\",\n    \"        graph.add_edge(1, 3, 5)\\n\",\n    \"        graph.add_edge(1, 4, 4)\\n\",\n    \"        graph.add_edge(2, 1, 6)\\n\",\n    \"        graph.add_edge(3, 2, 7)\\n\",\n    \"        graph.add_edge(3, 4, 8)\\n\",\n    \"        graph.dfs(nodes[0], self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[0, 1, 3, 2, 4, 5]\\\")\\n\",\n    \"\\n\",\n    \"        print('Success: test_dfs')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestDfs()\\n\",\n    \"    test.test_dfs()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_dfs/dfs_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/graph_dfs/dfs_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement depth-first search on a graph.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the graph directed?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have Graph and Node classes?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this is a connected graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"* `add_edge(source, destination, weight)`\\n\",\n    \"\\n\",\n    \"```\\n\",\n    \"graph.add_edge(0, 1, 5)\\n\",\n    \"graph.add_edge(0, 4, 3)\\n\",\n    \"graph.add_edge(0, 5, 2)\\n\",\n    \"graph.add_edge(1, 3, 5)\\n\",\n    \"graph.add_edge(1, 4, 4)\\n\",\n    \"graph.add_edge(2, 1, 6)\\n\",\n    \"graph.add_edge(3, 2, 7)\\n\",\n    \"graph.add_edge(3, 4, 8)\\n\",\n    \"```\\n\",\n    \"\\n\",\n    \"Result:\\n\",\n    \"* Order of nodes visited: [0, 1, 3, 2, 4, 5]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"If we want to visit every node in a graph, we generally prefer depth-first search since it is simpler (no need to use a queue).  For shortest path, we generally use breadth-first search.\\n\",\n    \"\\n\",\n    \"* Visit the current node and mark it visited\\n\",\n    \"* Iterate through each adjacent node\\n\",\n    \"    * If the node has not been visited, call dfs on it\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(V + E), where V = number of vertices and E = number of edges\\n\",\n    \"* Space: O(V), for the recursion depth\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../graph/graph.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class GraphDfs(Graph):\\n\",\n    \"\\n\",\n    \"    def dfs(self, root, visit_func):\\n\",\n    \"        if root is None:\\n\",\n    \"            return\\n\",\n    \"        visit_func(root)\\n\",\n    \"        root.visit_state = State.visited\\n\",\n    \"        for node in root.adj_nodes.values():\\n\",\n    \"            if node.visit_state == State.unvisited:\\n\",\n    \"                self.dfs(node, visit_func)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../utils/results.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_dfs.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_dfs.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestDfs(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def __init__(self, *args, **kwargs):\\n\",\n    \"        super(TestDfs, self).__init__()\\n\",\n    \"        self.results = Results()\\n\",\n    \"\\n\",\n    \"    def test_dfs(self):\\n\",\n    \"        nodes = []\\n\",\n    \"        graph = GraphDfs()\\n\",\n    \"        for id in range(0, 6):\\n\",\n    \"            nodes.append(graph.add_node(id))\\n\",\n    \"        graph.add_edge(0, 1, 5)\\n\",\n    \"        graph.add_edge(0, 4, 3)\\n\",\n    \"        graph.add_edge(0, 5, 2)\\n\",\n    \"        graph.add_edge(1, 3, 5)\\n\",\n    \"        graph.add_edge(1, 4, 4)\\n\",\n    \"        graph.add_edge(2, 1, 6)\\n\",\n    \"        graph.add_edge(3, 2, 7)\\n\",\n    \"        graph.add_edge(3, 4, 8)\\n\",\n    \"        graph.dfs(nodes[0], self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[0, 1, 3, 2, 4, 5]\\\")\\n\",\n    \"\\n\",\n    \"        print('Success: test_dfs')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestDfs()\\n\",\n    \"    test.test_dfs()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_dfs\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_dfs.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/graph_dfs/test_dfs.py",
    "content": "import unittest\n\n\nclass TestDfs(unittest.TestCase):\n\n    def __init__(self, *args, **kwargs):\n        super(TestDfs, self).__init__()\n        self.results = Results()\n\n    def test_dfs(self):\n        nodes = []\n        graph = GraphDfs()\n        for id in range(0, 6):\n            nodes.append(graph.add_node(id))\n        graph.add_edge(0, 1, 5)\n        graph.add_edge(0, 4, 3)\n        graph.add_edge(0, 5, 2)\n        graph.add_edge(1, 3, 5)\n        graph.add_edge(1, 4, 4)\n        graph.add_edge(2, 1, 6)\n        graph.add_edge(3, 2, 7)\n        graph.add_edge(3, 4, 8)\n        graph.dfs(nodes[0], self.results.add_result)\n        self.assertEqual(str(self.results), \"[0, 1, 3, 2, 4, 5]\")\n\n        print('Success: test_dfs')\n\n\ndef main():\n    test = TestDfs()\n    test.test_dfs()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/graph_path_exists/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/graph_path_exists/path_exists_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine whether there is a path between two nodes in a graph.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the graph directed?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have Graph and Node classes?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this is a connected graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"* `add_edge(source, destination, weight)`\\n\",\n    \"\\n\",\n    \"```\\n\",\n    \"graph.add_edge(0, 1, 5)\\n\",\n    \"graph.add_edge(0, 4, 3)\\n\",\n    \"graph.add_edge(0, 5, 2)\\n\",\n    \"graph.add_edge(1, 3, 5)\\n\",\n    \"graph.add_edge(1, 4, 4)\\n\",\n    \"graph.add_edge(2, 1, 6)\\n\",\n    \"graph.add_edge(3, 2, 7)\\n\",\n    \"graph.add_edge(3, 4, 8)\\n\",\n    \"```\\n\",\n    \"\\n\",\n    \"Result:\\n\",\n    \"* search_path(start=0, end=2) -> True\\n\",\n    \"* search_path(start=0, end=0) -> True\\n\",\n    \"* search_path(start=4, end=5) -> False\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_path_exists/path_exists_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../graph/graph.py\\n\",\n    \"%load ../graph/graph.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class GraphPathExists(Graph):\\n\",\n    \"\\n\",\n    \"    def path_exists(self, start, end):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_path_exists.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPathExists(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_path_exists(self):\\n\",\n    \"        nodes = []\\n\",\n    \"        graph = GraphPathExists()\\n\",\n    \"        for id in range(0, 6):\\n\",\n    \"            nodes.append(graph.add_node(id))\\n\",\n    \"        graph.add_edge(0, 1, 5)\\n\",\n    \"        graph.add_edge(0, 4, 3)\\n\",\n    \"        graph.add_edge(0, 5, 2)\\n\",\n    \"        graph.add_edge(1, 3, 5)\\n\",\n    \"        graph.add_edge(1, 4, 4)\\n\",\n    \"        graph.add_edge(2, 1, 6)\\n\",\n    \"        graph.add_edge(3, 2, 7)\\n\",\n    \"        graph.add_edge(3, 4, 8)\\n\",\n    \"\\n\",\n    \"        self.assertEqual(graph.path_exists(nodes[0], nodes[2]), True)\\n\",\n    \"        self.assertEqual(graph.path_exists(nodes[0], nodes[0]), True)\\n\",\n    \"        self.assertEqual(graph.path_exists(nodes[4], nodes[5]), False)\\n\",\n    \"\\n\",\n    \"        print('Success: test_path_exists')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPathExists()\\n\",\n    \"    test.test_path_exists()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_path_exists/path_exists_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/graph_path_exists/path_exists_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine whether there is a path between two nodes in a graph.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the graph directed?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have Graph and Node classes?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this is a connected graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"* `add_edge(source, destination, weight)`\\n\",\n    \"\\n\",\n    \"```\\n\",\n    \"graph.add_edge(0, 1, 5)\\n\",\n    \"graph.add_edge(0, 4, 3)\\n\",\n    \"graph.add_edge(0, 5, 2)\\n\",\n    \"graph.add_edge(1, 3, 5)\\n\",\n    \"graph.add_edge(1, 4, 4)\\n\",\n    \"graph.add_edge(2, 1, 6)\\n\",\n    \"graph.add_edge(3, 2, 7)\\n\",\n    \"graph.add_edge(3, 4, 8)\\n\",\n    \"```\\n\",\n    \"\\n\",\n    \"Result:\\n\",\n    \"* search_path(start=0, end=2) -> True\\n\",\n    \"* search_path(start=0, end=0) -> True\\n\",\n    \"* search_path(start=4, end=5) -> False\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"To determine if there is a path, we can use either breadth-first or depth-first search.\\n\",\n    \"\\n\",\n    \"Breadth-first search can also be used to determine the shortest path.  Depth-first search is easier to implement with just straight recursion, but often results in a longer path.\\n\",\n    \"\\n\",\n    \"We'll use a breadth-first search approach:\\n\",\n    \"\\n\",\n    \"* Add the start node to the queue and mark it as visited\\n\",\n    \"* If the start node is the end node, return True\\n\",\n    \"* While the queue is not empty\\n\",\n    \"    * Dequeue a node and visit it\\n\",\n    \"    * If the node is the end node, return True\\n\",\n    \"    * Iterate through each adjacent node\\n\",\n    \"        * If the node has not been visited, add it to the queue and mark it as visited\\n\",\n    \"* Return False\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(V + E), where V = number of vertices and E = number of edges\\n\",\n    \"* Space: O(V + E)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../graph/graph.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from collections import deque\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class GraphPathExists(Graph):\\n\",\n    \"\\n\",\n    \"    def path_exists(self, start, end):\\n\",\n    \"        if start is None or end is None:\\n\",\n    \"            return False\\n\",\n    \"        if start is end:\\n\",\n    \"            return True\\n\",\n    \"        queue = deque()\\n\",\n    \"        queue.append(start)\\n\",\n    \"        start.visit_state = State.visited\\n\",\n    \"        while queue:\\n\",\n    \"            node = queue.popleft()\\n\",\n    \"            if node is end:\\n\",\n    \"                return True\\n\",\n    \"            for adj_node in node.adj_nodes.values():\\n\",\n    \"                if adj_node.visit_state == State.unvisited:\\n\",\n    \"                    queue.append(adj_node)\\n\",\n    \"                    adj_node.visit_state = State.visited\\n\",\n    \"        return False\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_path_exists.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_path_exists.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPathExists(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_path_exists(self):\\n\",\n    \"        nodes = []\\n\",\n    \"        graph = GraphPathExists()\\n\",\n    \"        for id in range(0, 6):\\n\",\n    \"            nodes.append(graph.add_node(id))\\n\",\n    \"        graph.add_edge(0, 1, 5)\\n\",\n    \"        graph.add_edge(0, 4, 3)\\n\",\n    \"        graph.add_edge(0, 5, 2)\\n\",\n    \"        graph.add_edge(1, 3, 5)\\n\",\n    \"        graph.add_edge(1, 4, 4)\\n\",\n    \"        graph.add_edge(2, 1, 6)\\n\",\n    \"        graph.add_edge(3, 2, 7)\\n\",\n    \"        graph.add_edge(3, 4, 8)\\n\",\n    \"\\n\",\n    \"        self.assertEqual(graph.path_exists(nodes[0], nodes[2]), True)\\n\",\n    \"        self.assertEqual(graph.path_exists(nodes[0], nodes[0]), True)\\n\",\n    \"        self.assertEqual(graph.path_exists(nodes[4], nodes[5]), False)\\n\",\n    \"\\n\",\n    \"        print('Success: test_path_exists')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPathExists()\\n\",\n    \"    test.test_path_exists()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_path_exists\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_path_exists.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/graph_path_exists/test_path_exists.py",
    "content": "import unittest\n\n\nclass TestPathExists(unittest.TestCase):\n\n    def test_path_exists(self):\n        nodes = []\n        graph = GraphPathExists()\n        for id in range(0, 6):\n            nodes.append(graph.add_node(id))\n        graph.add_edge(0, 1, 5)\n        graph.add_edge(0, 4, 3)\n        graph.add_edge(0, 5, 2)\n        graph.add_edge(1, 3, 5)\n        graph.add_edge(1, 4, 4)\n        graph.add_edge(2, 1, 6)\n        graph.add_edge(3, 2, 7)\n        graph.add_edge(3, 4, 8)\n\n        self.assertEqual(graph.path_exists(nodes[0], nodes[2]), True)\n        self.assertEqual(graph.path_exists(nodes[0], nodes[0]), True)\n        self.assertEqual(graph.path_exists(nodes[4], nodes[5]), False)\n\n        print('Success: test_path_exists')\n\n\ndef main():\n    test = TestPathExists()\n    test.test_path_exists()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/graph_shortest_path/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/graph_shortest_path/graph_shortest_path_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the shortest path between two nodes in a graph.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is this a directional graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Could the graph have cycles?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: If the answer were no, this would be a DAG.  \\n\",\n    \"        * DAGs can be solved with a [topological sort](http://www.geeksforgeeks.org/shortest-path-for-directed-acyclic-graphs/)\\n\",\n    \"* Are the edges weighted?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: If the edges were not weighted, we could do a BFS\\n\",\n    \"* Are the edges all non-negative numbers?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: Graphs with negative edges can be done with Bellman-Ford\\n\",\n    \"        * Graphs with negative cost cycles do not have a defined shortest path\\n\",\n    \"* Do we have to check for non-negative edges?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this is a connected graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume we already have a graph class?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a priority queue class?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"The constraints state we don't have to check for negative edges, so we test with the general case.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"graph.add_edge('a', 'b', weight=5)\\n\",\n    \"graph.add_edge('a', 'c', weight=3)\\n\",\n    \"graph.add_edge('a', 'e', weight=2)\\n\",\n    \"graph.add_edge('b', 'd', weight=2)\\n\",\n    \"graph.add_edge('c', 'b', weight=1)\\n\",\n    \"graph.add_edge('c', 'd', weight=1)\\n\",\n    \"graph.add_edge('d', 'a', weight=1)\\n\",\n    \"graph.add_edge('d', 'g', weight=2)\\n\",\n    \"graph.add_edge('d', 'h', weight=1)\\n\",\n    \"graph.add_edge('e', 'a', weight=1)\\n\",\n    \"graph.add_edge('e', 'h', weight=4)\\n\",\n    \"graph.add_edge('e', 'i', weight=7)\\n\",\n    \"graph.add_edge('f', 'b', weight=3)\\n\",\n    \"graph.add_edge('f', 'g', weight=1)\\n\",\n    \"graph.add_edge('g', 'c', weight=3)\\n\",\n    \"graph.add_edge('g', 'i', weight=2)\\n\",\n    \"graph.add_edge('h', 'c', weight=2)\\n\",\n    \"graph.add_edge('h', 'f', weight=2)\\n\",\n    \"graph.add_edge('h', 'g', weight=2)\\n\",\n    \"shortest_path = ShortestPath(graph)\\n\",\n    \"result = shortest_path.find_shortest_path('a', 'i')\\n\",\n    \"self.assertEqual(result, ['a', 'c', 'd', 'g', 'i'])\\n\",\n    \"self.assertEqual(shortest_path.path_weight['i'], 8)\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_shortest_path/graph_shortest_path_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../../arrays_strings/priority_queue/priority_queue.py\\n\",\n    \"%load ../../arrays_strings/priority_queue/priority_queue.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../graph/graph.py\\n\",\n    \"%load ../graph/graph.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class ShortestPath(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, graph):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def find_shortest_path(self, start_node_key, end_node_key):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_shortest_path.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestShortestPath(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_shortest_path(self):\\n\",\n    \"        graph = Graph()\\n\",\n    \"        graph.add_edge('a', 'b', weight=5)\\n\",\n    \"        graph.add_edge('a', 'c', weight=3)\\n\",\n    \"        graph.add_edge('a', 'e', weight=2)\\n\",\n    \"        graph.add_edge('b', 'd', weight=2)\\n\",\n    \"        graph.add_edge('c', 'b', weight=1)\\n\",\n    \"        graph.add_edge('c', 'd', weight=1)\\n\",\n    \"        graph.add_edge('d', 'a', weight=1)\\n\",\n    \"        graph.add_edge('d', 'g', weight=2)\\n\",\n    \"        graph.add_edge('d', 'h', weight=1)\\n\",\n    \"        graph.add_edge('e', 'a', weight=1)\\n\",\n    \"        graph.add_edge('e', 'h', weight=4)\\n\",\n    \"        graph.add_edge('e', 'i', weight=7)\\n\",\n    \"        graph.add_edge('f', 'b', weight=3)\\n\",\n    \"        graph.add_edge('f', 'g', weight=1)\\n\",\n    \"        graph.add_edge('g', 'c', weight=3)\\n\",\n    \"        graph.add_edge('g', 'i', weight=2)\\n\",\n    \"        graph.add_edge('h', 'c', weight=2)\\n\",\n    \"        graph.add_edge('h', 'f', weight=2)\\n\",\n    \"        graph.add_edge('h', 'g', weight=2)\\n\",\n    \"        shortest_path = ShortestPath(graph)\\n\",\n    \"        result = shortest_path.find_shortest_path('a', 'i')\\n\",\n    \"        self.assertEqual(result, ['a', 'c', 'd', 'g', 'i'])\\n\",\n    \"        self.assertEqual(shortest_path.path_weight['i'], 8)\\n\",\n    \"\\n\",\n    \"        print('Success: test_shortest_path')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestShortestPath()\\n\",\n    \"    test.test_shortest_path()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](https://github.com/donnemartin/interactive-coding-challenges/graphs_trees/graph_shortest_path/graph_shortest_path_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/graph_shortest_path/graph_shortest_path_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the shortest path between two nodes in a graph.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is this a directional graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Could the graph have cycles?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: If the answer were no, this would be a DAG.  \\n\",\n    \"        * DAGs can be solved with a [topological sort](http://www.geeksforgeeks.org/shortest-path-for-directed-acyclic-graphs/)\\n\",\n    \"* Are the edges weighted?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: If the edges were not weighted, we could do a BFS\\n\",\n    \"* Are the edges all non-negative numbers?\\n\",\n    \"    * Yes\\n\",\n    \"    * Note: Graphs with negative edges can be done with Bellman-Ford\\n\",\n    \"        * Graphs with negative cost cycles do not have a defined shortest path\\n\",\n    \"* Do we have to check for non-negative edges?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this is a connected graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume we already have a graph class?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a priority queue class?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"The constraints state we don't have to check for negative edges, so we test with the general case.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"graph.add_edge('a', 'b', weight=5)\\n\",\n    \"graph.add_edge('a', 'c', weight=3)\\n\",\n    \"graph.add_edge('a', 'e', weight=2)\\n\",\n    \"graph.add_edge('b', 'd', weight=2)\\n\",\n    \"graph.add_edge('c', 'b', weight=1)\\n\",\n    \"graph.add_edge('c', 'd', weight=1)\\n\",\n    \"graph.add_edge('d', 'a', weight=1)\\n\",\n    \"graph.add_edge('d', 'g', weight=2)\\n\",\n    \"graph.add_edge('d', 'h', weight=1)\\n\",\n    \"graph.add_edge('e', 'a', weight=1)\\n\",\n    \"graph.add_edge('e', 'h', weight=4)\\n\",\n    \"graph.add_edge('e', 'i', weight=7)\\n\",\n    \"graph.add_edge('f', 'b', weight=3)\\n\",\n    \"graph.add_edge('f', 'g', weight=1)\\n\",\n    \"graph.add_edge('g', 'c', weight=3)\\n\",\n    \"graph.add_edge('g', 'i', weight=2)\\n\",\n    \"graph.add_edge('h', 'c', weight=2)\\n\",\n    \"graph.add_edge('h', 'f', weight=2)\\n\",\n    \"graph.add_edge('h', 'g', weight=2)\\n\",\n    \"shortest_path = ShortestPath(graph)\\n\",\n    \"result = shortest_path.find_shortest_path('a', 'i')\\n\",\n    \"self.assertEqual(result, ['a', 'c', 'd', 'g', 'i'])\\n\",\n    \"self.assertEqual(shortest_path.path_weight['i'], 8)\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Wikipedia's animation:\\n\",\n    \"\\n\",\n    \"![](https://upload.wikimedia.org/wikipedia/commons/5/57/Dijkstra_Animation.gif)\\n\",\n    \"\\n\",\n    \"Initialize the following:\\n\",\n    \"\\n\",\n    \"* previous = {}  # Key: node key, val: prev node key, shortest path\\n\",\n    \"    * Set each node's previous node key to None\\n\",\n    \"* path_weight = {}  # Key: node key, val: weight, shortest path\\n\",\n    \"    * Set each node's shortest path weight to infinity\\n\",\n    \"* remaining = PriorityQueue()  # Queue of node key, path weight\\n\",\n    \"    * Add each node's shortest path weight to the priority queue\\n\",\n    \"\\n\",\n    \"* Set the start node's path_weight to 0 and update the value in remaining\\n\",\n    \"* Loop while remaining still has items\\n\",\n    \"    * Extract the min node (node with minimum path weight) from remaining\\n\",\n    \"    * Loop through each adjacent node in the min node\\n\",\n    \"        * Calculate the new weight:\\n\",\n    \"            * Adjacent node's edge weight + the min node's path_weight            \\n\",\n    \"        * If the newly calculated path is less than the adjacent node's current path_weight:\\n\",\n    \"            * Set the node's previous node key leading to the shortest path\\n\",\n    \"            * Update the adjacent node's shortest path and update the value in the priority queue\\n\",\n    \"* Walk backwards to determine the shortest path:\\n\",\n    \"    * Start at the end node, walk the previous dict to get to the start node\\n\",\n    \"* Reverse the list and return it\\n\",\n    \"\\n\",\n    \"### Complexity for array-based priority queue:\\n\",\n    \"\\n\",\n    \"* Time: O(v^2), where v is the number of vertices\\n\",\n    \"* Space: O(v^2)\\n\",\n    \"\\n\",\n    \"This might be better than the min-heap-based variant if the graph has a lot of edges.\\n\",\n    \"\\n\",\n    \"O(v^2) is better than O((v + v^2) log v).\\n\",\n    \"\\n\",\n    \"### Complexity for min-heap-based priority queue:\\n\",\n    \"\\n\",\n    \"* Time: O((v + e) log v), where v is the number of vertices, e is the number of edges\\n\",\n    \"* Space: O((v + e) log v)\\n\",\n    \"\\n\",\n    \"This might be better than the array-based variant if the graph is sparse.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../../arrays_strings/priority_queue/priority_queue.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../graph/graph.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import sys\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class ShortestPath(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, graph):\\n\",\n    \"        if graph is None:\\n\",\n    \"            raise TypeError('graph cannot be None')\\n\",\n    \"        self.graph = graph\\n\",\n    \"        self.previous = {}  # Key: node key, val: prev node key, shortest path\\n\",\n    \"        self.path_weight = {}  # Key: node key, val: weight, shortest path\\n\",\n    \"        self.remaining = PriorityQueue()  # Queue of node key, path weight\\n\",\n    \"        for key in self.graph.nodes.keys():\\n\",\n    \"            # Set each node's previous node key to None\\n\",\n    \"            # Set each node's shortest path weight to infinity\\n\",\n    \"            # Add each node's shortest path weight to the priority queue\\n\",\n    \"            self.previous[key] = None\\n\",\n    \"            self.path_weight[key] = sys.maxsize\\n\",\n    \"            self.remaining.insert(\\n\",\n    \"                PriorityQueueNode(key, self.path_weight[key]))\\n\",\n    \"\\n\",\n    \"    def find_shortest_path(self, start_node_key, end_node_key):\\n\",\n    \"        if start_node_key is None or end_node_key is None:\\n\",\n    \"            raise TypeError('Input node keys cannot be None')\\n\",\n    \"        if (start_node_key not in self.graph.nodes or\\n\",\n    \"                end_node_key not in self.graph.nodes):\\n\",\n    \"            raise ValueError('Invalid start or end node key')\\n\",\n    \"        # Set the start node's shortest path weight to 0\\n\",\n    \"        # and update the value in the priority queue\\n\",\n    \"        self.path_weight[start_node_key] = 0\\n\",\n    \"        self.remaining.decrease_key(start_node_key, 0)\\n\",\n    \"        while self.remaining:\\n\",\n    \"            # Extract the min node (node with minimum path weight)\\n\",\n    \"            # from the priority queue\\n\",\n    \"            min_node_key = self.remaining.extract_min().obj\\n\",\n    \"            min_node = self.graph.nodes[min_node_key]\\n\",\n    \"            # Loop through each adjacent node in the min node\\n\",\n    \"            for adj_key in min_node.adj_nodes.keys():\\n\",\n    \"                # Node's path:\\n\",\n    \"                # Adjacent node's edge weight + the min node's\\n\",\n    \"                # shortest path weight\\n\",\n    \"                new_weight = (min_node.adj_weights[adj_key] +\\n\",\n    \"                    self.path_weight[min_node_key])\\n\",\n    \"                # Only update if the newly calculated path is\\n\",\n    \"                # less than the existing node's shortest path\\n\",\n    \"                if self.path_weight[adj_key] > new_weight:\\n\",\n    \"                    # Set the node's previous node key leading to the shortest path\\n\",\n    \"                    # Update the adjacent node's shortest path and\\n\",\n    \"                    # update the value in the priority queue\\n\",\n    \"                    self.previous[adj_key] = min_node_key\\n\",\n    \"                    self.path_weight[adj_key] = new_weight\\n\",\n    \"                    self.remaining.decrease_key(adj_key, new_weight)\\n\",\n    \"        # Walk backwards to determine the shortest path:\\n\",\n    \"        # Start at the end node, walk the previous dict to get to the start node\\n\",\n    \"        result = []\\n\",\n    \"        current_node_key = end_node_key\\n\",\n    \"        while current_node_key is not None:\\n\",\n    \"            result.append(current_node_key)\\n\",\n    \"            current_node_key = self.previous[current_node_key]\\n\",\n    \"        # Reverse the list\\n\",\n    \"        return result[::-1]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_shortest_path.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_shortest_path.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestShortestPath(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_shortest_path(self):\\n\",\n    \"        graph = Graph()\\n\",\n    \"        graph.add_edge('a', 'b', weight=5)\\n\",\n    \"        graph.add_edge('a', 'c', weight=3)\\n\",\n    \"        graph.add_edge('a', 'e', weight=2)\\n\",\n    \"        graph.add_edge('b', 'd', weight=2)\\n\",\n    \"        graph.add_edge('c', 'b', weight=1)\\n\",\n    \"        graph.add_edge('c', 'd', weight=1)\\n\",\n    \"        graph.add_edge('d', 'a', weight=1)\\n\",\n    \"        graph.add_edge('d', 'g', weight=2)\\n\",\n    \"        graph.add_edge('d', 'h', weight=1)\\n\",\n    \"        graph.add_edge('e', 'a', weight=1)\\n\",\n    \"        graph.add_edge('e', 'h', weight=4)\\n\",\n    \"        graph.add_edge('e', 'i', weight=7)\\n\",\n    \"        graph.add_edge('f', 'b', weight=3)\\n\",\n    \"        graph.add_edge('f', 'g', weight=1)\\n\",\n    \"        graph.add_edge('g', 'c', weight=3)\\n\",\n    \"        graph.add_edge('g', 'i', weight=2)\\n\",\n    \"        graph.add_edge('h', 'c', weight=2)\\n\",\n    \"        graph.add_edge('h', 'f', weight=2)\\n\",\n    \"        graph.add_edge('h', 'g', weight=2)\\n\",\n    \"        shortest_path = ShortestPath(graph)\\n\",\n    \"        result = shortest_path.find_shortest_path('a', 'i')\\n\",\n    \"        self.assertEqual(result, ['a', 'c', 'd', 'g', 'i'])\\n\",\n    \"        self.assertEqual(shortest_path.path_weight['i'], 8)\\n\",\n    \"\\n\",\n    \"        print('Success: test_shortest_path')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestShortestPath()\\n\",\n    \"    test.test_shortest_path()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_shortest_path\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_shortest_path.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/graph_shortest_path/priority_queue.py",
    "content": "import sys\n\n\nclass PriorityQueueNode(object):\n\n    def __init__(self, obj, key):\n        self.obj = obj\n        self.key = key\n\n    def __repr__(self):\n        return str(self.obj) + ': ' + str(self.key)\n\n\nclass PriorityQueue(object):\n\n    def __init__(self):\n        self.queue = []\n\n    def insert(self, node):\n        if node is not None:\n            self.queue.append(node)\n            return self.queue[-1]\n        return None\n\n    def extract_min(self):\n        if not self.queue:\n            return None\n        minimum = sys.maxsize\n        for index, node in enumerate(self.queue):\n            if node.key < minimum:\n                minimum = node.key\n                minimum_index = index\n        node = self.queue.pop(minimum_index)\n        return node.obj\n\n    def decrease_key(self, obj, new_key):\n        for node in self.queue:\n            if node.obj is obj:\n                node.key = new_key\n                return node\n        return None"
  },
  {
    "path": "graphs_trees/graph_shortest_path/test_shortest_path.py",
    "content": "import unittest\n\n\nclass TestShortestPath(unittest.TestCase):\n\n    def test_shortest_path(self):\n        graph = Graph()\n        graph.add_edge('a', 'b', weight=5)\n        graph.add_edge('a', 'c', weight=3)\n        graph.add_edge('a', 'e', weight=2)\n        graph.add_edge('b', 'd', weight=2)\n        graph.add_edge('c', 'b', weight=1)\n        graph.add_edge('c', 'd', weight=1)\n        graph.add_edge('d', 'a', weight=1)\n        graph.add_edge('d', 'g', weight=2)\n        graph.add_edge('d', 'h', weight=1)\n        graph.add_edge('e', 'a', weight=1)\n        graph.add_edge('e', 'h', weight=4)\n        graph.add_edge('e', 'i', weight=7)\n        graph.add_edge('f', 'b', weight=3)\n        graph.add_edge('f', 'g', weight=1)\n        graph.add_edge('g', 'c', weight=3)\n        graph.add_edge('g', 'i', weight=2)\n        graph.add_edge('h', 'c', weight=2)\n        graph.add_edge('h', 'f', weight=2)\n        graph.add_edge('h', 'g', weight=2)\n        shortest_path = ShortestPath(graph)\n        result = shortest_path.find_shortest_path('a', 'i')\n        self.assertEqual(result, ['a', 'c', 'd', 'g', 'i'])\n        self.assertEqual(shortest_path.path_weight['i'], 8)\n\n        print('Success: test_shortest_path')\n\n\ndef main():\n    test = TestShortestPath()\n    test.test_shortest_path()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/graph_shortest_path_unweighted/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/graph_shortest_path_unweighted/shortest_path_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the shortest path between two nodes in a graph.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the graph directed?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the graph weighted?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume we already have Graph and Node classes?\\n\",\n    \"    * Yes\\n\",\n    \"* Are the inputs two Nodes?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output a list of Node keys that make up the shortest path?\\n\",\n    \"    * Yes\\n\",\n    \"* If there is no path, should we return None?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this is a connected graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"* `add_edge(source, destination, weight)`\\n\",\n    \"\\n\",\n    \"```\\n\",\n    \"graph.add_edge(0, 1)\\n\",\n    \"graph.add_edge(0, 4)\\n\",\n    \"graph.add_edge(0, 5)\\n\",\n    \"graph.add_edge(1, 3)\\n\",\n    \"graph.add_edge(1, 4)\\n\",\n    \"graph.add_edge(2, 1)\\n\",\n    \"graph.add_edge(3, 2)\\n\",\n    \"graph.add_edge(3, 4)\\n\",\n    \"```\\n\",\n    \"\\n\",\n    \"Result:\\n\",\n    \"* search_path(start=0, end=2) -> [0, 1, 3, 2]\\n\",\n    \"* search_path(start=0, end=0) -> [0]\\n\",\n    \"* search_path(start=4, end=5) -> None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_path_exists/path_exists_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../graph/graph.py\\n\",\n    \"%load ../graph/graph.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class GraphShortestPath(Graph):\\n\",\n    \"\\n\",\n    \"    def shortest_path(self, source_key, dest_key):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_shortest_path.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestShortestPath(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_shortest_path(self):\\n\",\n    \"        nodes = []\\n\",\n    \"        graph = GraphShortestPath()\\n\",\n    \"        for id in range(0, 6):\\n\",\n    \"            nodes.append(graph.add_node(id))\\n\",\n    \"        graph.add_edge(0, 1)\\n\",\n    \"        graph.add_edge(0, 4)\\n\",\n    \"        graph.add_edge(0, 5)\\n\",\n    \"        graph.add_edge(1, 3)\\n\",\n    \"        graph.add_edge(1, 4)\\n\",\n    \"        graph.add_edge(2, 1)\\n\",\n    \"        graph.add_edge(3, 2)\\n\",\n    \"        graph.add_edge(3, 4)\\n\",\n    \"\\n\",\n    \"        self.assertEqual(graph.shortest_path(nodes[0].key, nodes[2].key), [0, 1, 3, 2])\\n\",\n    \"        self.assertEqual(graph.shortest_path(nodes[0].key, nodes[0].key), [0])\\n\",\n    \"        self.assertEqual(graph.shortest_path(nodes[4].key, nodes[5].key), None)\\n\",\n    \"\\n\",\n    \"        print('Success: test_shortest_path')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestShortestPath()\\n\",\n    \"    test.test_shortest_path()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/graph_path_exists/path_exists_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/graph_shortest_path_unweighted/shortest_path_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the shortest path between two nodes in a graph.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the graph directed?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the graph weighted?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume we already have Graph and Node classes?\\n\",\n    \"    * Yes\\n\",\n    \"* Are the inputs two Nodes?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output a list of Node keys that make up the shortest path?\\n\",\n    \"    * Yes\\n\",\n    \"* If there is no path, should we return None?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this is a connected graph?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"* `add_edge(source, destination, weight)`\\n\",\n    \"\\n\",\n    \"```\\n\",\n    \"graph.add_edge(0, 1)\\n\",\n    \"graph.add_edge(0, 4)\\n\",\n    \"graph.add_edge(0, 5)\\n\",\n    \"graph.add_edge(1, 3)\\n\",\n    \"graph.add_edge(1, 4)\\n\",\n    \"graph.add_edge(2, 1)\\n\",\n    \"graph.add_edge(3, 2)\\n\",\n    \"graph.add_edge(3, 4)\\n\",\n    \"```\\n\",\n    \"\\n\",\n    \"Result:\\n\",\n    \"* search_path(start=0, end=2) -> [0, 1, 3, 2]\\n\",\n    \"* search_path(start=0, end=0) -> [0]\\n\",\n    \"* search_path(start=4, end=5) -> None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"To determine the shorted path in an unweighted graph, we can use breadth-first search keeping track of the previous nodes ids for each node.  Previous nodes ids can be a dictionary of key: current node id and value: previous node id.\\n\",\n    \"\\n\",\n    \"* If the start node is the end node, return True\\n\",\n    \"* Add the start node to the queue and mark it as visited\\n\",\n    \"    * Update the previous node ids, the previous node id of the start node is None\\n\",\n    \"* While the queue is not empty\\n\",\n    \"    * Dequeue a node and visit it\\n\",\n    \"    * If the node is the end node, return the previous nodes\\n\",\n    \"    * Set the previous node to the current node\\n\",\n    \"    * Iterate through each adjacent node\\n\",\n    \"        * If the node has not been visited, add it to the queue and mark it as visited\\n\",\n    \"            * Update the previous node ids\\n\",\n    \"* Return None\\n\",\n    \"\\n\",\n    \"Walk the previous node ids backwards to get the path.\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(V + E), where V = number of vertices and E = number of edges\\n\",\n    \"* Space: O(V + E)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../graph/graph.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from collections import deque\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class GraphShortestPath(Graph):\\n\",\n    \"\\n\",\n    \"    def shortest_path(self, source_key, dest_key):\\n\",\n    \"        if source_key is None or dest_key is None:\\n\",\n    \"            return None\\n\",\n    \"        if source_key is dest_key:\\n\",\n    \"            return [source_key]\\n\",\n    \"        prev_node_keys = self._shortest_path(source_key, dest_key)\\n\",\n    \"        if prev_node_keys is None:\\n\",\n    \"            return None\\n\",\n    \"        else:\\n\",\n    \"            path_ids = [dest_key]\\n\",\n    \"            prev_node_key = prev_node_keys[dest_key]\\n\",\n    \"            while prev_node_key is not None:\\n\",\n    \"                path_ids.append(prev_node_key)\\n\",\n    \"                prev_node_key = prev_node_keys[prev_node_key]\\n\",\n    \"            return path_ids[::-1]\\n\",\n    \"\\n\",\n    \"    def _shortest_path(self, source_key, dest_key):\\n\",\n    \"        queue = deque()\\n\",\n    \"        queue.append(self.nodes[source_key])\\n\",\n    \"        prev_node_keys = {source_key: None}\\n\",\n    \"        self.nodes[source_key].visit_state = State.visited\\n\",\n    \"        while queue:\\n\",\n    \"            node = queue.popleft()\\n\",\n    \"            if node.key is dest_key:\\n\",\n    \"                return prev_node_keys\\n\",\n    \"            prev_node = node\\n\",\n    \"            for adj_node in node.adj_nodes.values():\\n\",\n    \"                if adj_node.visit_state == State.unvisited:\\n\",\n    \"                    queue.append(adj_node)\\n\",\n    \"                    prev_node_keys[adj_node.key] = prev_node.key\\n\",\n    \"                    adj_node.visit_state = State.visited\\n\",\n    \"        return None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_shortest_path.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_shortest_path.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestShortestPath(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_shortest_path(self):\\n\",\n    \"        nodes = []\\n\",\n    \"        graph = GraphShortestPath()\\n\",\n    \"        for id in range(0, 6):\\n\",\n    \"            nodes.append(graph.add_node(id))\\n\",\n    \"        graph.add_edge(0, 1)\\n\",\n    \"        graph.add_edge(0, 4)\\n\",\n    \"        graph.add_edge(0, 5)\\n\",\n    \"        graph.add_edge(1, 3)\\n\",\n    \"        graph.add_edge(1, 4)\\n\",\n    \"        graph.add_edge(2, 1)\\n\",\n    \"        graph.add_edge(3, 2)\\n\",\n    \"        graph.add_edge(3, 4)\\n\",\n    \"\\n\",\n    \"        self.assertEqual(graph.shortest_path(nodes[0].key, nodes[2].key), [0, 1, 3, 2])\\n\",\n    \"        self.assertEqual(graph.shortest_path(nodes[0].key, nodes[0].key), [0])\\n\",\n    \"        self.assertEqual(graph.shortest_path(nodes[4].key, nodes[5].key), None)\\n\",\n    \"\\n\",\n    \"        print('Success: test_shortest_path')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestShortestPath()\\n\",\n    \"    test.test_shortest_path()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_shortest_path\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_shortest_path.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/graph_shortest_path_unweighted/test_shortest_path.py",
    "content": "import unittest\n\n\nclass TestShortestPath(unittest.TestCase):\n\n    def test_shortest_path(self):\n        nodes = []\n        graph = GraphShortestPath()\n        for id in range(0, 6):\n            nodes.append(graph.add_node(id))\n        graph.add_edge(0, 1)\n        graph.add_edge(0, 4)\n        graph.add_edge(0, 5)\n        graph.add_edge(1, 3)\n        graph.add_edge(1, 4)\n        graph.add_edge(2, 1)\n        graph.add_edge(3, 2)\n        graph.add_edge(3, 4)\n\n        self.assertEqual(graph.shortest_path(nodes[0].key, nodes[2].key), [0, 1, 3, 2])\n        self.assertEqual(graph.shortest_path(nodes[0].key, nodes[0].key), [0])\n        self.assertEqual(graph.shortest_path(nodes[4].key, nodes[5].key), None)\n\n        print('Success: test_shortest_path')\n\n\ndef main():\n    test = TestShortestPath()\n    test.test_shortest_path()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/invert_tree/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/invert_tree/invert_tree_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Invert a binary tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* What does it mean to invert a binary tree?\\n\",\n    \"    * Swap all left and right node pairs\\n\",\n    \"* Can we assume we already have a Node class?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Input:\\n\",\n    \"     5\\n\",\n    \"   /   \\\\\\n\",\n    \"  2     7\\n\",\n    \" / \\\\   / \\\\\\n\",\n    \"1   3 6   9\\n\",\n    \"\\n\",\n    \"Output:\\n\",\n    \"     5\\n\",\n    \"   /   \\\\\\n\",\n    \"  7     2\\n\",\n    \" / \\\\   / \\\\\\n\",\n    \"9   6 3   1\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/invert_tree/invert_tree_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class InverseBst(Bst):\\n\",\n    \"\\n\",\n    \"    def invert_tree(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_invert_tree.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestInvertTree(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_invert_tree(self):\\n\",\n    \"        root = Node(5)\\n\",\n    \"        bst = InverseBst(root)\\n\",\n    \"        node2 = bst.insert(2)\\n\",\n    \"        node3 = bst.insert(3)\\n\",\n    \"        node1 = bst.insert(1)\\n\",\n    \"        node7 = bst.insert(7)\\n\",\n    \"        node6 = bst.insert(6)\\n\",\n    \"        node9 = bst.insert(9)\\n\",\n    \"        result = bst.invert_tree()\\n\",\n    \"        self.assertEqual(result, root)\\n\",\n    \"        self.assertEqual(result.left, node7)\\n\",\n    \"        self.assertEqual(result.right, node2)\\n\",\n    \"        self.assertEqual(result.left.left, node9)\\n\",\n    \"        self.assertEqual(result.left.right, node6)\\n\",\n    \"        self.assertEqual(result.right.left, node3)\\n\",\n    \"        self.assertEqual(result.right.right, node1)\\n\",\n    \"        print('Success: test_invert_tree')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestInvertTree()\\n\",\n    \"    test.test_invert_tree()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/invert_tree/invert_tree_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Invert a binary tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* What does it mean to invert a binary tree?\\n\",\n    \"    * Swap all left and right node pairs\\n\",\n    \"* Can we assume we already have a Node class?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Input:\\n\",\n    \"     5\\n\",\n    \"   /   \\\\\\n\",\n    \"  2     7\\n\",\n    \" / \\\\   / \\\\\\n\",\n    \"1   3 6   9\\n\",\n    \"\\n\",\n    \"Output:\\n\",\n    \"     5\\n\",\n    \"   /   \\\\\\n\",\n    \"  7     2\\n\",\n    \" / \\\\   / \\\\\\n\",\n    \"9   6 3   1\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Base case\\n\",\n    \"    * If the root is None, return\\n\",\n    \"* Recursive case\\n\",\n    \"    * Recurse on the left node\\n\",\n    \"    * Recurse on the right node\\n\",\n    \"    * Swap left and right\\n\",\n    \"* Return the node\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(h), where h is the height, for the recursion depth\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class InverseBst(Bst):\\n\",\n    \"\\n\",\n    \"    def invert_tree(self):\\n\",\n    \"        if self.root is None:\\n\",\n    \"            raise TypeError('root cannot be None')\\n\",\n    \"        return self._invert_tree(self.root)\\n\",\n    \"\\n\",\n    \"    def _invert_tree(self, root):\\n\",\n    \"        if root is None:\\n\",\n    \"            return\\n\",\n    \"        self._invert_tree(root.left)\\n\",\n    \"        self._invert_tree(root.right)\\n\",\n    \"        root.left, root.right = root.right, root.left\\n\",\n    \"        return root\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_invert_tree.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_invert_tree.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestInvertTree(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_invert_tree(self):\\n\",\n    \"        root = Node(5)\\n\",\n    \"        bst = InverseBst(root)\\n\",\n    \"        node2 = bst.insert(2)\\n\",\n    \"        node3 = bst.insert(3)\\n\",\n    \"        node1 = bst.insert(1)\\n\",\n    \"        node7 = bst.insert(7)\\n\",\n    \"        node6 = bst.insert(6)\\n\",\n    \"        node9 = bst.insert(9)\\n\",\n    \"        result = bst.invert_tree()\\n\",\n    \"        self.assertEqual(result, root)\\n\",\n    \"        self.assertEqual(result.left, node7)\\n\",\n    \"        self.assertEqual(result.right, node2)\\n\",\n    \"        self.assertEqual(result.left.left, node9)\\n\",\n    \"        self.assertEqual(result.left.right, node6)\\n\",\n    \"        self.assertEqual(result.right.left, node3)\\n\",\n    \"        self.assertEqual(result.right.right, node1)\\n\",\n    \"        print('Success: test_invert_tree')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestInvertTree()\\n\",\n    \"    test.test_invert_tree()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_invert_tree\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_invert_tree.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/invert_tree/test_invert_tree.py",
    "content": "import unittest\n\n\nclass TestInvertTree(unittest.TestCase):\n\n    def test_invert_tree(self):\n        root = Node(5)\n        bst = InverseBst(root)\n        node2 = bst.insert(2)\n        node3 = bst.insert(3)\n        node1 = bst.insert(1)\n        node7 = bst.insert(7)\n        node6 = bst.insert(6)\n        node9 = bst.insert(9)\n        result = bst.invert_tree()\n        self.assertEqual(result, root)\n        self.assertEqual(result.left, node7)\n        self.assertEqual(result.right, node2)\n        self.assertEqual(result.left.left, node9)\n        self.assertEqual(result.left.right, node6)\n        self.assertEqual(result.right.left, node3)\n        self.assertEqual(result.right.right, node1)\n        print('Success: test_invert_tree')\n\n\ndef main():\n    test = TestInvertTree()\n    test.test_invert_tree()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/min_heap/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/min_heap/min_heap.py",
    "content": "from __future__ import division\n\nimport sys\n\n\nclass MinHeap(object):\n\n    def __init__(self):\n        self.array = []\n\n    def __len__(self):\n        return len(self.array)\n\n    def extract_min(self):\n        if not self.array:\n            return None\n        if len(self.array) == 1:\n            return self.array.pop(0)\n        minimum = self.array[0]\n        # Move the last element to the root\n        self.array[0] = self.array.pop(-1)\n        self._bubble_down(index=0)\n        return minimum\n\n    def peek_min(self):\n        return self.array[0] if self.array else None\n\n    def insert(self, key):\n        if key is None:\n            raise TypeError('key cannot be None')\n        self.array.append(key)\n        self._bubble_up(index=len(self.array) - 1)\n\n    def _bubble_up(self, index):\n        if index == 0:\n            return\n        index_parent = (index - 1) // 2\n        if self.array[index] < self.array[index_parent]:\n            # Swap the indices and recurse\n            self.array[index], self.array[index_parent] = \\\n                self.array[index_parent], self.array[index]\n            self._bubble_up(index_parent)\n\n    def _bubble_down(self, index):\n        min_child_index = self._find_smaller_child(index)\n        if min_child_index == -1:\n            return\n        if self.array[index] > self.array[min_child_index]:\n            # Swap the indices and recurse\n            self.array[index], self.array[min_child_index] = \\\n                self.array[min_child_index], self.array[index]\n            self._bubble_down(min_child_index)\n\n    def _find_smaller_child(self, index):\n        left_child_index = 2 * index + 1\n        right_child_index = 2 * index + 2\n        # No right child\n        if right_child_index >= len(self.array):\n            # No left child\n            if left_child_index >= len(self.array):\n                return -1\n            # Left child only\n            else:\n                return left_child_index\n        else:\n            # Compare left and right children\n            if self.array[left_child_index] < self.array[right_child_index]:\n                return left_child_index\n            else:\n                return right_child_index\n"
  },
  {
    "path": "graphs_trees/min_heap/min_heap_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a min heap with extract_min and insert methods.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Extract min of an empty tree\\n\",\n    \"* Extract min general case\\n\",\n    \"* Insert into an empty tree\\n\",\n    \"* Insert general case (left and right insert)\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"          _5_\\n\",\n    \"        /     \\\\\\n\",\n    \"       20     15\\n\",\n    \"      / \\\\    /  \\\\\\n\",\n    \"     22  40 25\\n\",\n    \"     \\n\",\n    \"extract_min(): 5\\n\",\n    \"\\n\",\n    \"          _15_\\n\",\n    \"        /      \\\\\\n\",\n    \"       20      25\\n\",\n    \"      / \\\\     /  \\\\\\n\",\n    \"     22  40 \\n\",\n    \"\\n\",\n    \"insert(2):\\n\",\n    \"\\n\",\n    \"          _2_\\n\",\n    \"        /     \\\\\\n\",\n    \"       20      5\\n\",\n    \"      / \\\\     / \\\\\\n\",\n    \"     22  40  25  15\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/min_heap/min_heap_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MinHeap(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def extract_min(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass    \\n\",\n    \"\\n\",\n    \"    def peek_min(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def insert(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def _bubble_up(self, index):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_min_heap.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMinHeap(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_min_heap(self):\\n\",\n    \"        heap = MinHeap()\\n\",\n    \"        self.assertEqual(heap.peek_min(), None)\\n\",\n    \"        self.assertEqual(heap.extract_min(), None)\\n\",\n    \"        heap.insert(20)\\n\",\n    \"        self.assertEqual(heap.peek_min(), 20)\\n\",\n    \"        heap.insert(5)\\n\",\n    \"        self.assertEqual(heap.peek_min(), 5)\\n\",\n    \"        heap.insert(15)\\n\",\n    \"        heap.insert(22)\\n\",\n    \"        heap.insert(40)\\n\",\n    \"        heap.insert(5)\\n\",\n    \"        self.assertEqual(heap.peek_min(), 5)\\n\",\n    \"        heap.insert(3)\\n\",\n    \"        self.assertEqual(heap.peek_min(), 3)\\n\",\n    \"        self.assertEqual(heap.extract_min(), 3)\\n\",\n    \"        self.assertEqual(heap.peek_min(), 5)\\n\",\n    \"        print('Success: test_min_heap')\\n\",\n    \"\\n\",\n    \"        \\n\",\n    \"def main():\\n\",\n    \"    test = TestMinHeap()\\n\",\n    \"    test.test_min_heap()\\n\",\n    \"\\n\",\n    \"    \\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/min_heap/min_heap_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/min_heap/min_heap_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a min heap with extract_min and insert methods.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Extract min of an empty tree\\n\",\n    \"* Extract min general case\\n\",\n    \"* Insert into an empty tree\\n\",\n    \"* Insert general case (left and right insert)\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"          _5_\\n\",\n    \"        /     \\\\\\n\",\n    \"       20     15\\n\",\n    \"      / \\\\    /  \\\\\\n\",\n    \"     22  40 25\\n\",\n    \"     \\n\",\n    \"extract_min(): 5\\n\",\n    \"\\n\",\n    \"          _15_\\n\",\n    \"        /      \\\\\\n\",\n    \"       20      25\\n\",\n    \"      / \\\\     /  \\\\\\n\",\n    \"     22  40 \\n\",\n    \"\\n\",\n    \"insert(2):\\n\",\n    \"\\n\",\n    \"          _2_\\n\",\n    \"        /     \\\\\\n\",\n    \"       20      5\\n\",\n    \"      / \\\\     / \\\\\\n\",\n    \"     22  40  25  15\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"A heap is a complete binary tree where each node is smaller than its children.\\n\",\n    \"\\n\",\n    \"### extract_min\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"          _5_\\n\",\n    \"        /     \\\\\\n\",\n    \"       20     15\\n\",\n    \"      / \\\\    /  \\\\\\n\",\n    \"     22  40 25\\n\",\n    \"\\n\",\n    \"Save the root as the value to be returned: 5\\n\",\n    \"Move the right most element to the root: 25\\n\",\n    \"\\n\",\n    \"          _25_\\n\",\n    \"        /      \\\\\\n\",\n    \"       20      15\\n\",\n    \"      / \\\\     /  \\\\\\n\",\n    \"     22  40 \\n\",\n    \"\\n\",\n    \"Bubble down 25: Swap 25 and 15 (the smaller child)\\n\",\n    \"\\n\",\n    \"          _15_\\n\",\n    \"        /      \\\\\\n\",\n    \"       20      25\\n\",\n    \"      / \\\\     /  \\\\\\n\",\n    \"     22  40 \\n\",\n    \"\\n\",\n    \"Return 5\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"We'll use an array to represent the tree, here are the indices:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"          _0_\\n\",\n    \"        /     \\\\\\n\",\n    \"       1       2\\n\",\n    \"      / \\\\     / \\\\\\n\",\n    \"     3   4   \\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"To get to a child, we take 2 * index + 1 (left child) or 2 * index + 2 (right child).\\n\",\n    \"\\n\",\n    \"For example, the right child of index 1 is 2 * 1 + 2 = 4.\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(lg(n))\\n\",\n    \"* Space: O(lg(n)) for the recursion depth (tree height), or O(1) if using an iterative approach\\n\",\n    \"\\n\",\n    \"### insert\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"          _5_\\n\",\n    \"        /     \\\\\\n\",\n    \"       20     15\\n\",\n    \"      / \\\\    /  \\\\\\n\",\n    \"     22  40 25\\n\",\n    \"\\n\",\n    \"insert(2):\\n\",\n    \"Insert at the right-most spot to maintain the heap property.\\n\",\n    \"\\n\",\n    \"          _5_\\n\",\n    \"        /     \\\\\\n\",\n    \"       20     15\\n\",\n    \"      / \\\\    /  \\\\\\n\",\n    \"     22  40 25   2\\n\",\n    \"\\n\",\n    \"Bubble up 2: Swap 2 and 15\\n\",\n    \"\\n\",\n    \"          _5_\\n\",\n    \"        /     \\\\\\n\",\n    \"       20     2\\n\",\n    \"      / \\\\    / \\\\\\n\",\n    \"     22  40 25  15\\n\",\n    \"\\n\",\n    \"Bubble up 2: Swap 2 and 5\\n\",\n    \"\\n\",\n    \"          _2_\\n\",\n    \"        /     \\\\\\n\",\n    \"       20     5\\n\",\n    \"      / \\\\    / \\\\\\n\",\n    \"     22  40 25  15\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"We'll use an array to represent the tree, here are the indices:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"          _0_\\n\",\n    \"        /     \\\\\\n\",\n    \"       1       2\\n\",\n    \"      / \\\\     / \\\\\\n\",\n    \"     3   4   5   6\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"To get to a parent, we take (index - 1) // 2.  \\n\",\n    \"\\n\",\n    \"For example, the parent of index 6 is (6 - 1) // 2 = 2.\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(lg(n))\\n\",\n    \"* Space: O(lg(n)) for the recursion depth (tree height), or O(1) if using an iterative approach\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting min_heap.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile min_heap.py\\n\",\n    \"from __future__ import division\\n\",\n    \"\\n\",\n    \"import sys\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class MinHeap(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self):\\n\",\n    \"        self.array = []\\n\",\n    \"\\n\",\n    \"    def __len__(self):\\n\",\n    \"        return len(self.array)\\n\",\n    \"\\n\",\n    \"    def extract_min(self):\\n\",\n    \"        if not self.array:\\n\",\n    \"            return None\\n\",\n    \"        if len(self.array) == 1:\\n\",\n    \"            return self.array.pop(0)\\n\",\n    \"        minimum = self.array[0]\\n\",\n    \"        # Move the last element to the root\\n\",\n    \"        self.array[0] = self.array.pop(-1)\\n\",\n    \"        self._bubble_down(index=0)\\n\",\n    \"        return minimum\\n\",\n    \"\\n\",\n    \"    def peek_min(self):\\n\",\n    \"        return self.array[0] if self.array else None\\n\",\n    \"\\n\",\n    \"    def insert(self, key):\\n\",\n    \"        if key is None:\\n\",\n    \"            raise TypeError('key cannot be None')\\n\",\n    \"        self.array.append(key)\\n\",\n    \"        self._bubble_up(index=len(self.array) - 1)\\n\",\n    \"\\n\",\n    \"    def _bubble_up(self, index):\\n\",\n    \"        if index == 0:\\n\",\n    \"            return\\n\",\n    \"        index_parent = (index - 1) // 2\\n\",\n    \"        if self.array[index] < self.array[index_parent]:\\n\",\n    \"            # Swap the indices and recurse\\n\",\n    \"            self.array[index], self.array[index_parent] = \\\\\\n\",\n    \"                self.array[index_parent], self.array[index]\\n\",\n    \"            self._bubble_up(index_parent)\\n\",\n    \"\\n\",\n    \"    def _bubble_down(self, index):\\n\",\n    \"        min_child_index = self._find_smaller_child(index)\\n\",\n    \"        if min_child_index == -1:\\n\",\n    \"            return\\n\",\n    \"        if self.array[index] > self.array[min_child_index]:\\n\",\n    \"            # Swap the indices and recurse\\n\",\n    \"            self.array[index], self.array[min_child_index] = \\\\\\n\",\n    \"                self.array[min_child_index], self.array[index]\\n\",\n    \"            self._bubble_down(min_child_index)\\n\",\n    \"\\n\",\n    \"    def _find_smaller_child(self, index):\\n\",\n    \"        left_child_index = 2 * index + 1\\n\",\n    \"        right_child_index = 2 * index + 2\\n\",\n    \"        # No right child\\n\",\n    \"        if right_child_index >= len(self.array):\\n\",\n    \"            # No left child\\n\",\n    \"            if left_child_index >= len(self.array):\\n\",\n    \"                return -1\\n\",\n    \"            # Left child only\\n\",\n    \"            else:\\n\",\n    \"                return left_child_index\\n\",\n    \"        else:\\n\",\n    \"            # Compare left and right children\\n\",\n    \"            if self.array[left_child_index] < self.array[right_child_index]:\\n\",\n    \"                return left_child_index\\n\",\n    \"            else:\\n\",\n    \"                return right_child_index\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run min_heap.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_min_heap.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_min_heap.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMinHeap(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_min_heap(self):\\n\",\n    \"        heap = MinHeap()\\n\",\n    \"        self.assertEqual(heap.peek_min(), None)\\n\",\n    \"        self.assertEqual(heap.extract_min(), None)\\n\",\n    \"        heap.insert(20)\\n\",\n    \"        self.assertEqual(heap.array[0], 20)\\n\",\n    \"        heap.insert(5)\\n\",\n    \"        self.assertEqual(heap.array[0], 5)\\n\",\n    \"        self.assertEqual(heap.array[1], 20)\\n\",\n    \"        heap.insert(15)\\n\",\n    \"        self.assertEqual(heap.array[0], 5)\\n\",\n    \"        self.assertEqual(heap.array[1], 20)\\n\",\n    \"        self.assertEqual(heap.array[2], 15)\\n\",\n    \"        heap.insert(22)\\n\",\n    \"        self.assertEqual(heap.array[0], 5)\\n\",\n    \"        self.assertEqual(heap.array[1], 20)\\n\",\n    \"        self.assertEqual(heap.array[2], 15)\\n\",\n    \"        self.assertEqual(heap.array[3], 22)\\n\",\n    \"        heap.insert(40)\\n\",\n    \"        self.assertEqual(heap.array[0], 5)\\n\",\n    \"        self.assertEqual(heap.array[1], 20)\\n\",\n    \"        self.assertEqual(heap.array[2], 15)\\n\",\n    \"        self.assertEqual(heap.array[3], 22)\\n\",\n    \"        self.assertEqual(heap.array[4], 40)\\n\",\n    \"        heap.insert(3)\\n\",\n    \"        self.assertEqual(heap.array[0], 3)\\n\",\n    \"        self.assertEqual(heap.array[1], 20)\\n\",\n    \"        self.assertEqual(heap.array[2], 5)\\n\",\n    \"        self.assertEqual(heap.array[3], 22)\\n\",\n    \"        self.assertEqual(heap.array[4], 40)\\n\",\n    \"        self.assertEqual(heap.array[5], 15)\\n\",\n    \"        mins = []\\n\",\n    \"        while heap:\\n\",\n    \"            mins.append(heap.extract_min())\\n\",\n    \"        self.assertEqual(mins, [3, 5, 15, 20, 22, 40])\\n\",\n    \"        print('Success: test_min_heap')\\n\",\n    \"\\n\",\n    \"        \\n\",\n    \"def main():\\n\",\n    \"    test = TestMinHeap()\\n\",\n    \"    test.test_min_heap()\\n\",\n    \"\\n\",\n    \"    \\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_min_heap\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_min_heap.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/min_heap/test_min_heap.py",
    "content": "import unittest\n\n\nclass TestMinHeap(unittest.TestCase):\n\n    def test_min_heap(self):\n        heap = MinHeap()\n        self.assertEqual(heap.peek_min(), None)\n        self.assertEqual(heap.extract_min(), None)\n        heap.insert(20)\n        self.assertEqual(heap.array[0], 20)\n        heap.insert(5)\n        self.assertEqual(heap.array[0], 5)\n        self.assertEqual(heap.array[1], 20)\n        heap.insert(15)\n        self.assertEqual(heap.array[0], 5)\n        self.assertEqual(heap.array[1], 20)\n        self.assertEqual(heap.array[2], 15)\n        heap.insert(22)\n        self.assertEqual(heap.array[0], 5)\n        self.assertEqual(heap.array[1], 20)\n        self.assertEqual(heap.array[2], 15)\n        self.assertEqual(heap.array[3], 22)\n        heap.insert(40)\n        self.assertEqual(heap.array[0], 5)\n        self.assertEqual(heap.array[1], 20)\n        self.assertEqual(heap.array[2], 15)\n        self.assertEqual(heap.array[3], 22)\n        self.assertEqual(heap.array[4], 40)\n        heap.insert(3)\n        self.assertEqual(heap.array[0], 3)\n        self.assertEqual(heap.array[1], 20)\n        self.assertEqual(heap.array[2], 5)\n        self.assertEqual(heap.array[3], 22)\n        self.assertEqual(heap.array[4], 40)\n        self.assertEqual(heap.array[5], 15)\n        mins = []\n        while heap:\n            mins.append(heap.extract_min())\n        self.assertEqual(mins, [3, 5, 15, 20, 22, 40])\n        print('Success: test_min_heap')\n\n        \ndef main():\n    test = TestMinHeap()\n    test.test_min_heap()\n\n    \nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/tree_bfs/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/tree_bfs/bfs_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement breadth-first traversal on a binary tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume we already have a Node class with an insert method?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\\n\",\n    \"* What should we do with each node when we process it?\\n\",\n    \"    * Call an input method `visit_func` on the node\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### Breadth-First Traversal\\n\",\n    \"* 5, 2, 8, 1, 3 -> 5, 2, 8, 1, 3\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_bfs/bfs_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\\n\",\n    \"%load ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BstBfs(Bst):\\n\",\n    \"\\n\",\n    \"    def bfs(self, visit_func):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../utils/results.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_bfs.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBfs(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def __init__(self, *args, **kwargs):\\n\",\n    \"        super(TestBfs, self).__init__()\\n\",\n    \"        self.results = Results()\\n\",\n    \"\\n\",\n    \"    def test_bfs(self):\\n\",\n    \"        bst = BstBfs(Node(5))\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        bst.bfs(self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), '[5, 2, 8, 1, 3]')\\n\",\n    \"\\n\",\n    \"        print('Success: test_bfs')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBfs()\\n\",\n    \"    test.test_bfs()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_bfs/bfs_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/tree_bfs/bfs_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement breadth-first traversal on a binary tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume we already have a Node class with an insert method?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\\n\",\n    \"* What should we do with each node when we process it?\\n\",\n    \"    * Call an input method `visit_func` on the node\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### Breadth-First Traversal\\n\",\n    \"* 5, 2, 8, 1, 3 -> 5, 2, 8, 1, 3\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Initialize queue with root\\n\",\n    \"* While queue is not empty\\n\",\n    \"    * Dequeue and print the node\\n\",\n    \"    * Queue the left child\\n\",\n    \"    * Queue the right child\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n), extra space for the queue\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from collections import deque\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class BstBfs(Bst):\\n\",\n    \"\\n\",\n    \"    def bfs(self, visit_func):\\n\",\n    \"        if self.root is None:\\n\",\n    \"            raise TypeError('root is None')\\n\",\n    \"        queue = deque()\\n\",\n    \"        queue.append(self.root)\\n\",\n    \"        while queue:\\n\",\n    \"            node = queue.popleft()\\n\",\n    \"            visit_func(node)\\n\",\n    \"            if node.left is not None:\\n\",\n    \"                queue.append(node.left)\\n\",\n    \"            if node.right is not None:\\n\",\n    \"                queue.append(node.right)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../utils/results.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_bfs.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_bfs.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBfs(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def __init__(self, *args, **kwargs):\\n\",\n    \"        super(TestBfs, self).__init__()\\n\",\n    \"        self.results = Results()\\n\",\n    \"\\n\",\n    \"    def test_bfs(self):\\n\",\n    \"        bst = BstBfs(Node(5))\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        bst.bfs(self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), '[5, 2, 8, 1, 3]')\\n\",\n    \"\\n\",\n    \"        print('Success: test_bfs')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBfs()\\n\",\n    \"    test.test_bfs()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_bfs\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_bfs.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/tree_bfs/test_bfs.py",
    "content": "import unittest\n\n\nclass TestBfs(unittest.TestCase):\n\n    def __init__(self, *args, **kwargs):\n        super(TestBfs, self).__init__()\n        self.results = Results()\n\n    def test_bfs(self):\n        bst = BstBfs(Node(5))\n        bst.insert(2)\n        bst.insert(8)\n        bst.insert(1)\n        bst.insert(3)\n        bst.bfs(self.results.add_result)\n        self.assertEqual(str(self.results), '[5, 2, 8, 1, 3]')\n\n        print('Success: test_bfs')\n\n\ndef main():\n    test = TestBfs()\n    test.test_bfs()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/tree_dfs/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/tree_dfs/dfs_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement depth-first traversals (in-order, pre-order, post-order) on a binary tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume we already have a Node class with an insert method?\\n\",\n    \"    * Yes\\n\",\n    \"* What should we do with each node when we process it?\\n\",\n    \"    * Call an input method `visit_func` on the node\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### In-Order Traversal\\n\",\n    \"\\n\",\n    \"* 5, 2, 8, 1, 3 -> 1, 2, 3, 5, 8\\n\",\n    \"* 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\\n\",\n    \"\\n\",\n    \"### Pre-Order Traversal\\n\",\n    \"\\n\",\n    \"* 5, 2, 8, 1, 3 -> 5, 2, 1, 3, 8\\n\",\n    \"* 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\\n\",\n    \"\\n\",\n    \"### Post-Order Traversal\\n\",\n    \"\\n\",\n    \"* 5, 2, 8, 1, 3 -> 1, 3, 2, 8, 5\\n\",\n    \"* 1, 2, 3, 4, 5 -> 5, 4, 3, 2, 1\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_dfs/dfs_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\\n\",\n    \"%load ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BstDfs(Bst):\\n\",\n    \"\\n\",\n    \"    def in_order_traversal(self, node, visit_func):\\n\",\n    \"    # TODO: Implement me\\n\",\n    \"    pass\\n\",\n    \"\\n\",\n    \"    def pre_order_traversal(self, node, visit_func):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def post_order_traversal(self,node, visit_func):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../utils/results.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_dfs.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestDfs(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def __init__(self, *args, **kwargs):\\n\",\n    \"        super(TestDfs, self).__init__()\\n\",\n    \"        self.results = Results()\\n\",\n    \"\\n\",\n    \"    def test_dfs(self):\\n\",\n    \"        bst = BstDfs(Node(5))\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(3)\\n\",\n    \"\\n\",\n    \"        bst.in_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[1, 2, 3, 5, 8]\\\")\\n\",\n    \"        self.results.clear_results()\\n\",\n    \"\\n\",\n    \"        bst.pre_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[5, 2, 1, 3, 8]\\\")\\n\",\n    \"        self.results.clear_results()\\n\",\n    \"\\n\",\n    \"        bst.post_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[1, 3, 2, 8, 5]\\\")\\n\",\n    \"        self.results.clear_results()\\n\",\n    \"\\n\",\n    \"        bst = BstDfs(Node(1))\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        bst.insert(4)\\n\",\n    \"        bst.insert(5)\\n\",\n    \"\\n\",\n    \"        bst.in_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[1, 2, 3, 4, 5]\\\")\\n\",\n    \"        self.results.clear_results()\\n\",\n    \"\\n\",\n    \"        bst.pre_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[1, 2, 3, 4, 5]\\\")\\n\",\n    \"        self.results.clear_results()\\n\",\n    \"\\n\",\n    \"        bst.post_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[5, 4, 3, 2, 1]\\\")\\n\",\n    \"\\n\",\n    \"        print('Success: test_dfs')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestDfs()\\n\",\n    \"    test.test_dfs()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_dfs/dfs_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/tree_dfs/dfs_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement depth-first traversals (in-order, pre-order, post-order) on a binary tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume we already have a Node class with an insert method?\\n\",\n    \"    * Yes\\n\",\n    \"* What should we do with each node when we process it?\\n\",\n    \"    * Call an input method `visit_func` on the node\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### In-Order Traversal\\n\",\n    \"\\n\",\n    \"* 5, 2, 8, 1, 3 -> 1, 2, 3, 5, 8\\n\",\n    \"* 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\\n\",\n    \"\\n\",\n    \"### Pre-Order Traversal\\n\",\n    \"\\n\",\n    \"* 5, 2, 8, 1, 3 -> 5, 2, 1, 3, 8\\n\",\n    \"* 1, 2, 3, 4, 5 -> 1, 2, 3, 4, 5\\n\",\n    \"\\n\",\n    \"### Post-Order Traversal\\n\",\n    \"\\n\",\n    \"* 5, 2, 8, 1, 3 -> 1, 3, 2, 8, 5\\n\",\n    \"* 1, 2, 3, 4, 5 -> 5, 4, 3, 2, 1\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"Note:\\n\",\n    \"\\n\",\n    \"* This following are all forms of depth-first traversals\\n\",\n    \"\\n\",\n    \"### In-Order Traversal\\n\",\n    \"\\n\",\n    \"* Recursively call in-order traversal on the left child\\n\",\n    \"* Visit the current node\\n\",\n    \"* Recursively call in-order traversal on the right child\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(m), where m is the recursion depth, or O(1) if using an iterative approach\\n\",\n    \"\\n\",\n    \"### Pre-Order Traversal\\n\",\n    \"\\n\",\n    \"* Visit the current node\\n\",\n    \"* Recursively call pre-order traversal on the left child\\n\",\n    \"* Recursively call pre-order traversal on the right child\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(m), where m is the recursion depth, or O(1) if using an iterative approach\\n\",\n    \"\\n\",\n    \"### Post-Order Traversal\\n\",\n    \"\\n\",\n    \"* Recursively call post-order traversal on the left child\\n\",\n    \"* Recursively call post-order traversal on the right child\\n\",\n    \"* Visit the current node\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(m), where m is the recursion depth, or O(1) if using an iterative approach\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BstDfs(Bst):\\n\",\n    \"\\n\",\n    \"    def in_order_traversal(self, node, visit_func):\\n\",\n    \"        if node is not None:\\n\",\n    \"            self.in_order_traversal(node.left, visit_func)\\n\",\n    \"            visit_func(node)\\n\",\n    \"            self.in_order_traversal(node.right, visit_func)\\n\",\n    \"\\n\",\n    \"    def pre_order_traversal(self, node, visit_func):\\n\",\n    \"        if node is not None:\\n\",\n    \"            visit_func(node)\\n\",\n    \"            self.pre_order_traversal(node.left, visit_func)\\n\",\n    \"            self.pre_order_traversal(node.right, visit_func)\\n\",\n    \"\\n\",\n    \"    def post_order_traversal(self, node, visit_func):\\n\",\n    \"        if node is not None:\\n\",\n    \"            self.post_order_traversal(node.left, visit_func)\\n\",\n    \"            self.post_order_traversal(node.right, visit_func)\\n\",\n    \"            visit_func(node)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../utils/results.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_dfs.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_dfs.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestDfs(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def __init__(self, *args, **kwargs):\\n\",\n    \"        super(TestDfs, self).__init__()\\n\",\n    \"        self.results = Results()\\n\",\n    \"\\n\",\n    \"    def test_dfs(self):\\n\",\n    \"        bst = BstDfs(Node(5))\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(3)\\n\",\n    \"\\n\",\n    \"        bst.in_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[1, 2, 3, 5, 8]\\\")\\n\",\n    \"        self.results.clear_results()\\n\",\n    \"\\n\",\n    \"        bst.pre_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[5, 2, 1, 3, 8]\\\")\\n\",\n    \"        self.results.clear_results()\\n\",\n    \"\\n\",\n    \"        bst.post_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[1, 3, 2, 8, 5]\\\")\\n\",\n    \"        self.results.clear_results()\\n\",\n    \"\\n\",\n    \"        bst = BstDfs(Node(1))\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        bst.insert(4)\\n\",\n    \"        bst.insert(5)\\n\",\n    \"\\n\",\n    \"        bst.in_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[1, 2, 3, 4, 5]\\\")\\n\",\n    \"        self.results.clear_results()\\n\",\n    \"\\n\",\n    \"        bst.pre_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[1, 2, 3, 4, 5]\\\")\\n\",\n    \"        self.results.clear_results()\\n\",\n    \"\\n\",\n    \"        bst.post_order_traversal(bst.root, self.results.add_result)\\n\",\n    \"        self.assertEqual(str(self.results), \\\"[5, 4, 3, 2, 1]\\\")\\n\",\n    \"\\n\",\n    \"        print('Success: test_dfs')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestDfs()\\n\",\n    \"    test.test_dfs()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_dfs\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_dfs.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/tree_dfs/test_dfs.py",
    "content": "import unittest\n\n\nclass TestDfs(unittest.TestCase):\n\n    def __init__(self, *args, **kwargs):\n        super(TestDfs, self).__init__()\n        self.results = Results()\n\n    def test_dfs(self):\n        bst = BstDfs(Node(5))\n        bst.insert(2)\n        bst.insert(8)\n        bst.insert(1)\n        bst.insert(3)\n\n        bst.in_order_traversal(bst.root, self.results.add_result)\n        self.assertEqual(str(self.results), \"[1, 2, 3, 5, 8]\")\n        self.results.clear_results()\n\n        bst.pre_order_traversal(bst.root, self.results.add_result)\n        self.assertEqual(str(self.results), \"[5, 2, 1, 3, 8]\")\n        self.results.clear_results()\n\n        bst.post_order_traversal(bst.root, self.results.add_result)\n        self.assertEqual(str(self.results), \"[1, 3, 2, 8, 5]\")\n        self.results.clear_results()\n\n        bst = BstDfs(Node(1))\n        bst.insert(2)\n        bst.insert(3)\n        bst.insert(4)\n        bst.insert(5)\n\n        bst.in_order_traversal(bst.root, self.results.add_result)\n        self.assertEqual(str(self.results), \"[1, 2, 3, 4, 5]\")\n        self.results.clear_results()\n\n        bst.pre_order_traversal(bst.root, self.results.add_result)\n        self.assertEqual(str(self.results), \"[1, 2, 3, 4, 5]\")\n        self.results.clear_results()\n\n        bst.post_order_traversal(bst.root, self.results.add_result)\n        self.assertEqual(str(self.results), \"[5, 4, 3, 2, 1]\")\n\n        print('Success: test_dfs')\n\n\ndef main():\n    test = TestDfs()\n    test.test_dfs()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/tree_height/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/tree_height/height.py",
    "content": "class BstHeight(Bst):\n\n    def height(self, node):\n        if node is None:\n            return 0\n        return 1 + max(self.height(node.left),\n                       self.height(node.right))"
  },
  {
    "path": "graphs_trees/tree_height/height_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine the height of a tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is this a binary tree?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a Node class with an insert method?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* 5 -> 1\\n\",\n    \"* 5, 2, 8, 1, 3 -> 3\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_height/height_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\\n\",\n    \"%load ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BstHeight(Bst):\\n\",\n    \"\\n\",\n    \"    def height(self, node):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_height.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestHeight(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_height(self):\\n\",\n    \"        bst = BstHeight(Node(5))\\n\",\n    \"        self.assertEqual(bst.height(bst.root), 1)\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        self.assertEqual(bst.height(bst.root), 3)\\n\",\n    \"\\n\",\n    \"        print('Success: test_height')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestHeight()\\n\",\n    \"    test.test_height()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_height/height_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/tree_height/height_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine the height of a tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is this a binary tree?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a Node class with an insert method?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* 5 -> 1\\n\",\n    \"* 5, 2, 8, 1, 3 -> 3\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use a recursive algorithm.\\n\",\n    \"\\n\",\n    \"* If the current node is None, return 0\\n\",\n    \"* Else, return 1 + the maximum height of the left or right children\\n\",\n    \"    \\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(h), where h is the height of the tree\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BstHeight(Bst):\\n\",\n    \"\\n\",\n    \"    def height(self, node):\\n\",\n    \"        if node is None:\\n\",\n    \"            return 0\\n\",\n    \"        return 1 + max(self.height(node.left),\\n\",\n    \"                       self.height(node.right))\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_height.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_height.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestHeight(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_height(self):\\n\",\n    \"        bst = BstHeight(Node(5))\\n\",\n    \"        self.assertEqual(bst.height(bst.root), 1)\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        self.assertEqual(bst.height(bst.root), 3)\\n\",\n    \"\\n\",\n    \"        print('Success: test_height')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestHeight()\\n\",\n    \"    test.test_height()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_height\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_height.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/tree_height/test_height.py",
    "content": "import unittest\n\n\nclass TestHeight(unittest.TestCase):\n\n    def test_height(self):\n        bst = BstHeight(Node(5))\n        self.assertEqual(bst.height(bst.root), 1)\n        bst.insert(2)\n        bst.insert(8)\n        bst.insert(1)\n        bst.insert(3)\n        self.assertEqual(bst.height(bst.root), 3)\n\n        print('Success: test_height')\n\n\ndef main():\n    test = TestHeight()\n    test.test_height()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/tree_lca/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/tree_lca/test_lca.py",
    "content": "import unittest\n\n\nclass TestLowestCommonAncestor(unittest.TestCase):\n\n    def test_lca(self):\n        node10 = Node(10)\n        node5 = Node(5)\n        node12 = Node(12)\n        node3 = Node(3)\n        node1 = Node(1)\n        node8 = Node(8)\n        node9 = Node(9)\n        node18 = Node(18)\n        node20 = Node(20)\n        node40 = Node(40)\n        node3.left = node1\n        node3.right = node8\n        node5.left = node12\n        node5.right = node3\n        node20.left = node40\n        node9.left = node18\n        node9.right = node20\n        node10.left = node5\n        node10.right = node9\n        root = node10\n        node0 = Node(0)\n        binary_tree = BinaryTree()\n        self.assertEqual(binary_tree.lca(root, node0, node5), None)\n        self.assertEqual(binary_tree.lca(root, node5, node0), None)\n        self.assertEqual(binary_tree.lca(root, node1, node8), node3)\n        self.assertEqual(binary_tree.lca(root, node12, node8), node5)\n        self.assertEqual(binary_tree.lca(root, node12, node40), node10)\n        self.assertEqual(binary_tree.lca(root, node9, node20), node9)\n        self.assertEqual(binary_tree.lca(root, node3, node5), node5)\n        print('Success: test_lca')\n\n\ndef main():\n    test = TestLowestCommonAncestor()\n    test.test_lca()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/tree_lca/tree_lca_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the lowest common ancestor in a binary tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is this a binary search tree?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the two nodes are in the tree?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"          _10_\\n\",\n    \"        /      \\\\\\n\",\n    \"       5        9\\n\",\n    \"      / \\\\      / \\\\\\n\",\n    \"     12  3    18  20\\n\",\n    \"        / \\\\       /\\n\",\n    \"       1   8     40\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"* 0, 5 -> None\\n\",\n    \"* 5, 0 -> None\\n\",\n    \"* 1, 8 -> 3\\n\",\n    \"* 12, 8 -> 5\\n\",\n    \"* 12, 40 -> 10\\n\",\n    \"* 9, 20 -> 9\\n\",\n    \"* 3, 5 -> 5\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_lca/tree_lca_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"class Node(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, key, left=None, right=None):\\n\",\n    \"        self.key = key\\n\",\n    \"        self.left = left\\n\",\n    \"        self.right = right\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return str(self.key)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BinaryTree(object):\\n\",\n    \"\\n\",\n    \"    def lca(self, root, node1, node2):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_lca.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestLowestCommonAncestor(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_lca(self):\\n\",\n    \"        node10 = Node(10)\\n\",\n    \"        node5 = Node(5)\\n\",\n    \"        node12 = Node(12)\\n\",\n    \"        node3 = Node(3)\\n\",\n    \"        node1 = Node(1)\\n\",\n    \"        node8 = Node(8)\\n\",\n    \"        node9 = Node(9)\\n\",\n    \"        node18 = Node(18)\\n\",\n    \"        node20 = Node(20)\\n\",\n    \"        node40 = Node(40)\\n\",\n    \"        node3.left = node1\\n\",\n    \"        node3.right = node8\\n\",\n    \"        node5.left = node12\\n\",\n    \"        node5.right = node3\\n\",\n    \"        node20.left = node40\\n\",\n    \"        node9.left = node18\\n\",\n    \"        node9.right = node20\\n\",\n    \"        node10.left = node5\\n\",\n    \"        node10.right = node9\\n\",\n    \"        root = node10\\n\",\n    \"        node0 = Node(0)\\n\",\n    \"        binary_tree = BinaryTree()\\n\",\n    \"        self.assertEqual(binary_tree.lca(root, node0, node5), None)\\n\",\n    \"        self.assertEqual(binary_tree.lca(root, node5, node0), None)\\n\",\n    \"        self.assertEqual(binary_tree.lca(root, node1, node8), node3)\\n\",\n    \"        self.assertEqual(binary_tree.lca(root, node12, node8), node5)\\n\",\n    \"        self.assertEqual(binary_tree.lca(root, node12, node40), node10)\\n\",\n    \"        self.assertEqual(binary_tree.lca(root, node9, node20), node9)\\n\",\n    \"        self.assertEqual(binary_tree.lca(root, node3, node5), node5)\\n\",\n    \"        print('Success: test_lca')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestLowestCommonAncestor()\\n\",\n    \"    test.test_lca()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/tree_lca/tree_lca_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the lowest common ancestor of two nodes in a binary tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is this a binary search tree?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the two nodes are in the tree?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"          _10_\\n\",\n    \"        /      \\\\\\n\",\n    \"       5        9\\n\",\n    \"      / \\\\      / \\\\\\n\",\n    \"     12  3    18  20\\n\",\n    \"        / \\\\       /\\n\",\n    \"       1   8     40\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"* 0, 5 -> None\\n\",\n    \"* 5, 0 -> None\\n\",\n    \"* 1, 8 -> 3\\n\",\n    \"* 12, 8 -> 5\\n\",\n    \"* 12, 40 -> 10\\n\",\n    \"* 9, 20 -> 9\\n\",\n    \"* 3, 5 -> 5\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Verify both nodes are in the tree\\n\",\n    \"* Base cases\\n\",\n    \"    * If the root is None, return None\\n\",\n    \"    * If the root is either node, return the root\\n\",\n    \"* Recursively search left and right\\n\",\n    \"* If the left and right are both nodes\\n\",\n    \"    * The return the root\\n\",\n    \"* Else, left or right, whichever is valid\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(h), where h is the height of the tree\\n\",\n    \"* Space: O(h), where h is the recursion depth\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Node(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, key, left=None, right=None):\\n\",\n    \"        self.key = key\\n\",\n    \"        self.left = left\\n\",\n    \"        self.right = right\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return str(self.key)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BinaryTree(object):\\n\",\n    \"\\n\",\n    \"    def lca(self, root, node1, node2):\\n\",\n    \"        if None in (root, node1, node2):\\n\",\n    \"            return None\\n\",\n    \"        if (not self._node_in_tree(root, node1) or\\n\",\n    \"                not self._node_in_tree(root, node2)):\\n\",\n    \"            return None\\n\",\n    \"        return self._lca(root, node1, node2)\\n\",\n    \"\\n\",\n    \"    def _node_in_tree(self, root, node):\\n\",\n    \"        if root is None:\\n\",\n    \"            return False\\n\",\n    \"        if root is node:\\n\",\n    \"            return True\\n\",\n    \"        left = self._node_in_tree(root.left, node)\\n\",\n    \"        right = self._node_in_tree(root.right, node)\\n\",\n    \"        return left or right\\n\",\n    \"\\n\",\n    \"    def _lca(self, root, node1, node2):\\n\",\n    \"        if root is None:\\n\",\n    \"            return None\\n\",\n    \"        if root is node1 or root is node2:\\n\",\n    \"            return root\\n\",\n    \"        left_node = self._lca(root.left, node1, node2)\\n\",\n    \"        right_node = self._lca(root.right, node1, node2)\\n\",\n    \"        if left_node is not None and right_node is not None:\\n\",\n    \"            return root\\n\",\n    \"        else:\\n\",\n    \"            return left_node if left_node is not None else right_node\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class LcaResult(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, node, is_ancestor):\\n\",\n    \"        self.node = node\\n\",\n    \"        self.is_ancestor = is_ancestor\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class BinaryTreeOptimized(object):\\n\",\n    \"\\n\",\n    \"    def lca(self, root, node1, node2):\\n\",\n    \"        if root is None:\\n\",\n    \"            raise TypeError('root cannot be None')\\n\",\n    \"        result = self._lca(root, node1, node2)\\n\",\n    \"        if result.is_ancestor:\\n\",\n    \"            return result.node\\n\",\n    \"        return None\\n\",\n    \"\\n\",\n    \"    def _lca(self, curr_node, node1, node2):\\n\",\n    \"        if curr_node is None:\\n\",\n    \"            return LcaResult(None, is_ancestor=False)\\n\",\n    \"        if curr_node is node1 and curr_node is node2:\\n\",\n    \"            return LcaResult(curr_node, is_ancestor=True)\\n\",\n    \"        left_result = self._lca(curr_node.left, node1, node2)\\n\",\n    \"        if left_result.is_ancestor:\\n\",\n    \"            return left_result\\n\",\n    \"        right_result = self._lca(curr_node.right, node1, node2)\\n\",\n    \"        if right_result.is_ancestor:\\n\",\n    \"            return right_result\\n\",\n    \"        if left_result.node is not None and right_result.node is not None:\\n\",\n    \"            return LcaResult(curr_node, is_ancestor=True)\\n\",\n    \"        elif curr_node is node1 or curr_node is node2:\\n\",\n    \"            is_ancestor = left_result.node is not None or \\\\\\n\",\n    \"                right_result.node is not None\\n\",\n    \"            return LcaResult(curr_node, is_ancestor)\\n\",\n    \"        else:\\n\",\n    \"            return LcaResult(left_result.node if left_result.node is not None \\\\\\n\",\n    \"                                 else right_result.node, is_ancestor=False)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_lca.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_lca.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestLowestCommonAncestor(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_lca(self):\\n\",\n    \"        node10 = Node(10)\\n\",\n    \"        node5 = Node(5)\\n\",\n    \"        node12 = Node(12)\\n\",\n    \"        node3 = Node(3)\\n\",\n    \"        node1 = Node(1)\\n\",\n    \"        node8 = Node(8)\\n\",\n    \"        node9 = Node(9)\\n\",\n    \"        node18 = Node(18)\\n\",\n    \"        node20 = Node(20)\\n\",\n    \"        node40 = Node(40)\\n\",\n    \"        node3.left = node1\\n\",\n    \"        node3.right = node8\\n\",\n    \"        node5.left = node12\\n\",\n    \"        node5.right = node3\\n\",\n    \"        node20.left = node40\\n\",\n    \"        node9.left = node18\\n\",\n    \"        node9.right = node20\\n\",\n    \"        node10.left = node5\\n\",\n    \"        node10.right = node9\\n\",\n    \"        root = node10\\n\",\n    \"        node0 = Node(0)\\n\",\n    \"        binary_tree = BinaryTree()\\n\",\n    \"        self.assertEqual(binary_tree.lca(root, node0, node5), None)\\n\",\n    \"        self.assertEqual(binary_tree.lca(root, node5, node0), None)\\n\",\n    \"        self.assertEqual(binary_tree.lca(root, node1, node8), node3)\\n\",\n    \"        self.assertEqual(binary_tree.lca(root, node12, node8), node5)\\n\",\n    \"        self.assertEqual(binary_tree.lca(root, node12, node40), node10)\\n\",\n    \"        self.assertEqual(binary_tree.lca(root, node9, node20), node9)\\n\",\n    \"        self.assertEqual(binary_tree.lca(root, node3, node5), node5)\\n\",\n    \"        print('Success: test_lca')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestLowestCommonAncestor()\\n\",\n    \"    test.test_lca()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_lca\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_lca.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/tree_level_lists/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/tree_level_lists/test_tree_level_lists.py",
    "content": "import unittest\n\n\nclass TestTreeLevelLists(unittest.TestCase):\n\n    def test_tree_level_lists(self):\n        bst = BstLevelLists(Node(5))\n        bst.insert(3)\n        bst.insert(8)\n        bst.insert(2)\n        bst.insert(4)\n        bst.insert(1)\n        bst.insert(7)\n        bst.insert(6)\n        bst.insert(9)\n        bst.insert(10)\n        bst.insert(11)\n\n        levels = bst.create_level_lists()\n        results_list = []\n        for level in levels:\n            results = Results()\n            for node in level:\n                results.add_result(node)\n            results_list.append(results)\n\n        self.assertEqual(str(results_list[0]), '[5]')\n        self.assertEqual(str(results_list[1]), '[3, 8]')\n        self.assertEqual(str(results_list[2]), '[2, 4, 7, 9]')\n        self.assertEqual(str(results_list[3]), '[1, 6, 10]')\n        self.assertEqual(str(results_list[4]), '[11]')\n\n        print('Success: test_tree_level_lists')\n\n\ndef main():\n    test = TestTreeLevelLists()\n    test.test_tree_level_lists()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/tree_level_lists/tree_level_lists_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Create a list for each level of a binary tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is this a binary search tree?\\n\",\n    \"    * Yes\\n\",\n    \"* Should each level be a list of nodes?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a Node class with an insert method?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* 5, 3, 8, 2, 4, 1, 7, 6, 9, 10, 11 -> [[5], [3, 8], [2, 4, 7, 9], [1, 6, 10], [11]]\\n\",\n    \"\\n\",\n    \"Note: Each number in the result is actually a node containing the number\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_level_lists/tree_level_lists_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\\n\",\n    \"%load ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BstLevelLists(Bst):\\n\",\n    \"\\n\",\n    \"    def create_level_lists(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../utils/results.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_tree_level_lists.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestTreeLevelLists(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_tree_level_lists(self):\\n\",\n    \"        bst = BstLevelLists(Node(5))\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(4)\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(7)\\n\",\n    \"        bst.insert(6)\\n\",\n    \"        bst.insert(9)\\n\",\n    \"        bst.insert(10)\\n\",\n    \"        bst.insert(11)\\n\",\n    \"\\n\",\n    \"        levels = bst.create_level_lists()\\n\",\n    \"        results_list = []\\n\",\n    \"        for level in levels:\\n\",\n    \"            results = Results()\\n\",\n    \"            for node in level:\\n\",\n    \"                results.add_result(node)\\n\",\n    \"            results_list.append(results)\\n\",\n    \"\\n\",\n    \"        self.assertEqual(str(results_list[0]), '[5]')\\n\",\n    \"        self.assertEqual(str(results_list[1]), '[3, 8]')\\n\",\n    \"        self.assertEqual(str(results_list[2]), '[2, 4, 7, 9]')\\n\",\n    \"        self.assertEqual(str(results_list[3]), '[1, 6, 10]')\\n\",\n    \"        self.assertEqual(str(results_list[4]), '[11]')\\n\",\n    \"\\n\",\n    \"        print('Success: test_tree_level_lists')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestTreeLevelLists()\\n\",\n    \"    test.test_tree_level_lists()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/tree_level_lists/tree_level_lists_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/tree_level_lists/tree_level_lists_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Create a list for each level of a binary tree.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is this a binary search tree?\\n\",\n    \"    * Yes\\n\",\n    \"* Should each level be a list of nodes?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a Node class with an insert method?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* 5, 3, 8, 2, 4, 1, 7, 6, 9, 10, 11 -> [[5], [3, 8], [2, 4, 7, 9], [1, 6, 10], [11]]\\n\",\n    \"\\n\",\n    \"Note: Each number in the result is actually a node containing the number\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We can use either a depth-first or a breadth-first search.  Intuitively, it seems like a breadth-first search might be a better fit as we are creating a linked list for each level.\\n\",\n    \"\\n\",\n    \"We can use a modified breadth-first search that keeps track of parents as we build the linked list for the current level.\\n\",\n    \"\\n\",\n    \"* Append the root to the current level's linked list `current`\\n\",\n    \"* While the `current` is not empty:\\n\",\n    \"    * Add `current` to `results`\\n\",\n    \"    * Set `parents` to `current` to prepare to go one level deeper\\n\",\n    \"    * Clear `current` so it can hold the next level\\n\",\n    \"    * For each `parent` in `parents`, add the children to `current`\\n\",\n    \"* Return the results\\n\",\n    \"    \\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../bst/bst.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BstLevelLists(Bst):\\n\",\n    \"\\n\",\n    \"    def create_level_lists(self):\\n\",\n    \"        if self.root is None:\\n\",\n    \"            return\\n\",\n    \"        results = []\\n\",\n    \"        current = []\\n\",\n    \"        parents = []\\n\",\n    \"        current.append(self.root)\\n\",\n    \"        while current:\\n\",\n    \"            results.append(current)\\n\",\n    \"            parents = list(current)\\n\",\n    \"            current = []\\n\",\n    \"            for parent in parents:\\n\",\n    \"                if parent.left is not None:\\n\",\n    \"                    current.append(parent.left)\\n\",\n    \"                if parent.right is not None:\\n\",\n    \"                    current.append(parent.right)\\n\",\n    \"        return results\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../utils/results.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_tree_level_lists.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_tree_level_lists.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestTreeLevelLists(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_tree_level_lists(self):\\n\",\n    \"        bst = BstLevelLists(Node(5))\\n\",\n    \"        bst.insert(3)\\n\",\n    \"        bst.insert(8)\\n\",\n    \"        bst.insert(2)\\n\",\n    \"        bst.insert(4)\\n\",\n    \"        bst.insert(1)\\n\",\n    \"        bst.insert(7)\\n\",\n    \"        bst.insert(6)\\n\",\n    \"        bst.insert(9)\\n\",\n    \"        bst.insert(10)\\n\",\n    \"        bst.insert(11)\\n\",\n    \"\\n\",\n    \"        levels = bst.create_level_lists()\\n\",\n    \"        results_list = []\\n\",\n    \"        for level in levels:\\n\",\n    \"            results = Results()\\n\",\n    \"            for node in level:\\n\",\n    \"                results.add_result(node)\\n\",\n    \"            results_list.append(results)\\n\",\n    \"\\n\",\n    \"        self.assertEqual(str(results_list[0]), '[5]')\\n\",\n    \"        self.assertEqual(str(results_list[1]), '[3, 8]')\\n\",\n    \"        self.assertEqual(str(results_list[2]), '[2, 4, 7, 9]')\\n\",\n    \"        self.assertEqual(str(results_list[3]), '[1, 6, 10]')\\n\",\n    \"        self.assertEqual(str(results_list[4]), '[11]')\\n\",\n    \"\\n\",\n    \"        print('Success: test_tree_level_lists')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestTreeLevelLists()\\n\",\n    \"    test.test_tree_level_lists()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_tree_level_lists\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_tree_level_lists.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/trie/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/trie/test_trie.py",
    "content": "import unittest\n\n\nclass TestTrie(unittest.TestCase):       \n\n    def test_trie(self):\n        trie = Trie()\n\n        print('Test: Insert')\n        words = ['a', 'at', 'has', 'hat', 'he',\n                 'me', 'men', 'mens', 'met']\n        for word in words:\n            trie.insert(word)\n        for word in trie.list_words():\n            self.assertTrue(trie.find(word) is not None)\n            \n        print('Test: Remove me')\n        trie.remove('me')\n        words_removed = ['me']\n        words = ['a', 'at', 'has', 'hat', 'he',\n                 'men', 'mens', 'met']\n        for word in words:\n            self.assertTrue(trie.find(word) is not None)\n        for word in words_removed:\n            self.assertTrue(trie.find(word) is None)\n\n        print('Test: Remove mens')\n        trie.remove('mens')\n        words_removed = ['me', 'mens']\n        words = ['a', 'at', 'has', 'hat', 'he',\n                 'men', 'met']\n        for word in words:\n            self.assertTrue(trie.find(word) is not None)\n        for word in words_removed:\n            self.assertTrue(trie.find(word) is None)\n\n        print('Test: Remove a')\n        trie.remove('a')\n        words_removed = ['a', 'me', 'mens']\n        words = ['at', 'has', 'hat', 'he',\n                 'men', 'met']\n        for word in words:\n            self.assertTrue(trie.find(word) is not None)\n        for word in words_removed:\n            self.assertTrue(trie.find(word) is None)\n\n        print('Test: Remove has')\n        trie.remove('has')\n        words_removed = ['a', 'has', 'me', 'mens']\n        words = ['at', 'hat', 'he',\n                 'men', 'met']\n        for word in words:\n            self.assertTrue(trie.find(word) is not None)\n        for word in words_removed:\n            self.assertTrue(trie.find(word) is None)\n\n        print('Success: test_trie')\n\n    def test_trie_remove_invalid(self):\n        print('Test: Remove from empty trie')\n        trie = Trie()\n        self.assertTrue(trie.remove('foo') is None) \n\n\ndef main():\n    test = TestTrie()\n    test.test_trie()\n    test.assertRaises(KeyError, test.test_trie_remove_invalid)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "graphs_trees/trie/trie.py",
    "content": "from collections import OrderedDict\n\n\nclass Node(object):\n\n    def __init__(self, key, parent=None, terminates=False):\n        self.key = key\n        self.terminates = False\n        self.parent = parent\n        self.children = {}\n\n\nclass Trie(object):\n\n    def __init__(self):\n        self.root = Node('')\n\n    def find(self, word):\n        if word is None:\n            raise TypeError('word cannot be None')\n        node = self.root\n        for char in word:\n            if char in node.children:\n                node = node.children[char]\n            else:\n                return None\n        return node if node.terminates else None\n\n    def insert(self, word):\n        if word is None:\n            raise TypeError('word cannot be None')\n        node = self.root\n        parent = None\n        for char in word:\n            if char in node.children:\n                node = node.children[char]\n            else:\n                node.children[char] = Node(char, parent=node)\n                node = node.children[char]\n        node.terminates = True\n\n    def remove(self, word):\n        if word is None:\n            raise TypeError('word cannot be None')\n        node = self.find(word)\n        if node is None:\n            raise KeyError('word does not exist')\n        node.terminates = False\n        parent = node.parent\n        while parent is not None:\n            # As we are propagating the delete up the \n            # parents, if this node has children, stop\n            # here to prevent orphaning its children.\n            # Or\n            # if this node is a terminating node that is\n            # not the terminating node of the input word, \n            # stop to prevent removing the associated word.\n            if node.children or node.terminates:\n                return\n            del parent.children[node.key]\n            node = parent\n            parent = parent.parent\n\n    def list_words(self):\n        result = []\n        curr_word = ''\n        self._list_words(self.root, curr_word, result)\n        return result\n\n    def _list_words(self, node, curr_word, result):\n        if node is None:\n            return\n        for key, child in node.children.items():\n            if child.terminates:\n                result.append(curr_word + key)\n            self._list_words(child, curr_word + key, result)\n"
  },
  {
    "path": "graphs_trees/trie/trie_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a trie with find, insert, remove, and list_words methods.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume we are working with strings?\\n\",\n    \"    * Yes\\n\",\n    \"* Are the strings in ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Should `find` only match exact words with a terminating character?\\n\",\n    \"    * Yes\\n\",\n    \"* Should `list_words` only return words with a terminating character?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"\\n\",\n    \"         root\\n\",\n    \"       /  |  \\\\\\n\",\n    \"      h   a*  m\\n\",\n    \"     / \\\\   \\\\   \\\\\\n\",\n    \"    a   e*  t*  e*\\n\",\n    \"   / \\\\         / \\\\\\n\",\n    \"  s*  t*      n*  t*\\n\",\n    \"             /\\n\",\n    \"            s*\\n\",\n    \"\\n\",\n    \"find\\n\",\n    \"\\n\",\n    \"* Find on an empty trie\\n\",\n    \"* Find non-matching\\n\",\n    \"* Find matching\\n\",\n    \"\\n\",\n    \"insert\\n\",\n    \"\\n\",\n    \"* Insert on empty trie\\n\",\n    \"* Insert to make a leaf terminator char\\n\",\n    \"* Insert to extend an existing terminator char\\n\",\n    \"\\n\",\n    \"remove\\n\",\n    \"\\n\",\n    \"* Remove me\\n\",\n    \"* Remove mens\\n\",\n    \"* Remove a\\n\",\n    \"* Remove has\\n\",\n    \"\\n\",\n    \"list_words\\n\",\n    \"\\n\",\n    \"* List empty\\n\",\n    \"* List general case\\n\",\n    \"</pre>\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/trie/trie_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from collections import OrderedDict\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Node(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, data, parent=None, terminates=False):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Trie(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def find(self, word):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def insert(self, word):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def remove(self, word):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def list_words(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_trie.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestTrie(unittest.TestCase):       \\n\",\n    \"\\n\",\n    \"    def test_trie(self):\\n\",\n    \"        trie = Trie()\\n\",\n    \"\\n\",\n    \"        print('Test: Insert')\\n\",\n    \"        words = ['a', 'at', 'has', 'hat', 'he',\\n\",\n    \"                 'me', 'men', 'mens', 'met']\\n\",\n    \"        for word in words:\\n\",\n    \"            trie.insert(word)\\n\",\n    \"        for word in trie.list_words():\\n\",\n    \"            self.assertTrue(trie.find(word) is not None)\\n\",\n    \"            \\n\",\n    \"        print('Test: Remove me')\\n\",\n    \"        trie.remove('me')\\n\",\n    \"        words_removed = ['me']\\n\",\n    \"        words = ['a', 'at', 'has', 'hat', 'he',\\n\",\n    \"                 'men', 'mens', 'met']\\n\",\n    \"        for word in words:\\n\",\n    \"            self.assertTrue(trie.find(word) is not None)\\n\",\n    \"        for word in words_removed:\\n\",\n    \"            self.assertTrue(trie.find(word) is None)\\n\",\n    \"\\n\",\n    \"        print('Test: Remove mens')\\n\",\n    \"        trie.remove('mens')\\n\",\n    \"        words_removed = ['me', 'mens']\\n\",\n    \"        words = ['a', 'at', 'has', 'hat', 'he',\\n\",\n    \"                 'men', 'met']\\n\",\n    \"        for word in words:\\n\",\n    \"            self.assertTrue(trie.find(word) is not None)\\n\",\n    \"        for word in words_removed:\\n\",\n    \"            self.assertTrue(trie.find(word) is None)\\n\",\n    \"\\n\",\n    \"        print('Test: Remove a')\\n\",\n    \"        trie.remove('a')\\n\",\n    \"        words_removed = ['a', 'me', 'mens']\\n\",\n    \"        words = ['at', 'has', 'hat', 'he',\\n\",\n    \"                 'men', 'met']\\n\",\n    \"        for word in words:\\n\",\n    \"            self.assertTrue(trie.find(word) is not None)\\n\",\n    \"        for word in words_removed:\\n\",\n    \"            self.assertTrue(trie.find(word) is None)\\n\",\n    \"\\n\",\n    \"        print('Test: Remove has')\\n\",\n    \"        trie.remove('has')\\n\",\n    \"        words_removed = ['a', 'has', 'me', 'mens']\\n\",\n    \"        words = ['at', 'hat', 'he',\\n\",\n    \"                 'men', 'met']\\n\",\n    \"        for word in words:\\n\",\n    \"            self.assertTrue(trie.find(word) is not None)\\n\",\n    \"        for word in words_removed:\\n\",\n    \"            self.assertTrue(trie.find(word) is None)\\n\",\n    \"\\n\",\n    \"        print('Success: test_trie')\\n\",\n    \"\\n\",\n    \"    def test_trie_remove_invalid(self):\\n\",\n    \"        print('Test: Remove from empty trie')\\n\",\n    \"        trie = Trie()\\n\",\n    \"        self.assertTrue(trie.remove('foo') is None) \\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestTrie()\\n\",\n    \"    test.test_trie()\\n\",\n    \"    test.assertRaises(KeyError, test.test_trie_remove_invalid)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/trie/trie_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/trie/trie_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a trie with find, insert, remove, and list_words methods.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume we are working with strings?\\n\",\n    \"    * Yes\\n\",\n    \"* Are the strings in ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Should `find` only match exact words with a terminating character?\\n\",\n    \"    * Yes\\n\",\n    \"* Should `list_words` only return words with a terminating character?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"\\n\",\n    \"root node is denoted by ''\\n\",\n    \"\\n\",\n    \"         ''\\n\",\n    \"       /  |  \\\\\\n\",\n    \"      h   a*  m\\n\",\n    \"     / \\\\   \\\\   \\\\\\n\",\n    \"    a   e*  t*  e*\\n\",\n    \"   / \\\\         / \\\\\\n\",\n    \"  s*  t*      n*  t*\\n\",\n    \"             /\\n\",\n    \"            s*\\n\",\n    \"\\n\",\n    \"find\\n\",\n    \"\\n\",\n    \"* Find on an empty trie\\n\",\n    \"* Find non-matching\\n\",\n    \"* Find matching\\n\",\n    \"\\n\",\n    \"insert\\n\",\n    \"\\n\",\n    \"* Insert on empty trie\\n\",\n    \"* Insert to make a leaf terminator char\\n\",\n    \"* Insert to extend an existing terminator char\\n\",\n    \"\\n\",\n    \"remove\\n\",\n    \"\\n\",\n    \"* Remove me\\n\",\n    \"* Remove mens\\n\",\n    \"* Remove a\\n\",\n    \"* Remove has\\n\",\n    \"\\n\",\n    \"list_words\\n\",\n    \"\\n\",\n    \"* List empty\\n\",\n    \"* List general case\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### find\\n\",\n    \"\\n\",\n    \"* Set node to the root\\n\",\n    \"* For each char in the input word\\n\",\n    \"    * Check the current node's children to see if it contains the char\\n\",\n    \"        * If a child has the char, set node to the child\\n\",\n    \"        * Else, return None\\n\",\n    \"* Return the last child node if it has a terminator, else None\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(m), where m is the length of the word\\n\",\n    \"* Space: O(h) for the recursion depth (tree height), or O(1) if using an iterative approach\\n\",\n    \"\\n\",\n    \"### insert\\n\",\n    \"\\n\",\n    \"* set node to the root\\n\",\n    \"* For each char in the input word\\n\",\n    \"    * Check the current node's children to see if it contains the char\\n\",\n    \"        * If a child has the char, set node to the child\\n\",\n    \"        * Else, insert a new node with the char\\n\",\n    \"            * Update children and parents\\n\",\n    \"* Set the last node as a terminating node\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(m), where m is the length of the word\\n\",\n    \"* Space: O(h) for the recursion depth (tree height), or O(1) if using an iterative approach\\n\",\n    \"\\n\",\n    \"### remove\\n\",\n    \"\\n\",\n    \"* Determine the matching terminating node by calling the find method\\n\",\n    \"* If the matching node has children, remove the terminator to prevent orphaning its children\\n\",\n    \"* Set the parent node to the matching node's parent\\n\",\n    \"* We'll be looping up the parent chain to propagate the delete\\n\",\n    \"* While the parent is valid\\n\",\n    \"    * If the node has children\\n\",\n    \"        * Return to prevent orphaning its remaining children\\n\",\n    \"    * If the node is a terminating node and it isn't the original matching node from the find call\\n\",\n    \"        * Return to prevent deleting this additional valid word\\n\",\n    \"    * Remove the parent node's child entry matching the node\\n\",\n    \"    * Set the node to the parent\\n\",\n    \"    * Set the parent to the parent's parent\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(m+h), where where m is the length of the word and h is the tree height\\n\",\n    \"* Space: O(h) for the recursion depth (tree height), or O(1) if using an iterative approach\\n\",\n    \"\\n\",\n    \"### list_words\\n\",\n    \"\\n\",\n    \"* Do a pre-order traversal, passing down the current word\\n\",\n    \"    * When you reach a terminating node, add it to the list of results\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(h) for the recursion depth (tree height), or O(1) if using an iterative approach\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting trie.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile trie.py\\n\",\n    \"from collections import OrderedDict\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Node(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, key, parent=None, terminates=False):\\n\",\n    \"        self.key = key\\n\",\n    \"        self.terminates = False\\n\",\n    \"        self.parent = parent\\n\",\n    \"        self.children = {}\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Trie(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self):\\n\",\n    \"        self.root = Node('')\\n\",\n    \"\\n\",\n    \"    def find(self, word):\\n\",\n    \"        if word is None:\\n\",\n    \"            raise TypeError('word cannot be None')\\n\",\n    \"        node = self.root\\n\",\n    \"        for char in word:\\n\",\n    \"            if char in node.children:\\n\",\n    \"                node = node.children[char]\\n\",\n    \"            else:\\n\",\n    \"                return None\\n\",\n    \"        return node if node.terminates else None\\n\",\n    \"\\n\",\n    \"    def insert(self, word):\\n\",\n    \"        if word is None:\\n\",\n    \"            raise TypeError('word cannot be None')\\n\",\n    \"        node = self.root\\n\",\n    \"        parent = None\\n\",\n    \"        for char in word:\\n\",\n    \"            if char in node.children:\\n\",\n    \"                node = node.children[char]\\n\",\n    \"            else:\\n\",\n    \"                node.children[char] = Node(char, parent=node)\\n\",\n    \"                node = node.children[char]\\n\",\n    \"        node.terminates = True\\n\",\n    \"\\n\",\n    \"    def remove(self, word):\\n\",\n    \"        if word is None:\\n\",\n    \"            raise TypeError('word cannot be None')\\n\",\n    \"        node = self.find(word)\\n\",\n    \"        if node is None:\\n\",\n    \"            raise KeyError('word does not exist')\\n\",\n    \"        node.terminates = False\\n\",\n    \"        parent = node.parent\\n\",\n    \"        while parent is not None:\\n\",\n    \"            # As we are propagating the delete up the \\n\",\n    \"            # parents, if this node has children, stop\\n\",\n    \"            # here to prevent orphaning its children.\\n\",\n    \"            # Or\\n\",\n    \"            # if this node is a terminating node that is\\n\",\n    \"            # not the terminating node of the input word, \\n\",\n    \"            # stop to prevent removing the associated word.\\n\",\n    \"            if node.children or node.terminates:\\n\",\n    \"                return\\n\",\n    \"            del parent.children[node.key]\\n\",\n    \"            node = parent\\n\",\n    \"            parent = parent.parent\\n\",\n    \"\\n\",\n    \"    def list_words(self):\\n\",\n    \"        result = []\\n\",\n    \"        curr_word = ''\\n\",\n    \"        self._list_words(self.root, curr_word, result)\\n\",\n    \"        return result\\n\",\n    \"\\n\",\n    \"    def _list_words(self, node, curr_word, result):\\n\",\n    \"        if node is None:\\n\",\n    \"            return\\n\",\n    \"        for key, child in node.children.items():\\n\",\n    \"            if child.terminates:\\n\",\n    \"                result.append(curr_word + key)\\n\",\n    \"            self._list_words(child, curr_word + key, result)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run trie.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_trie.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_trie.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestTrie(unittest.TestCase):       \\n\",\n    \"\\n\",\n    \"    def test_trie(self):\\n\",\n    \"        trie = Trie()\\n\",\n    \"\\n\",\n    \"        print('Test: Insert')\\n\",\n    \"        words = ['a', 'at', 'has', 'hat', 'he',\\n\",\n    \"                 'me', 'men', 'mens', 'met']\\n\",\n    \"        for word in words:\\n\",\n    \"            trie.insert(word)\\n\",\n    \"        for word in trie.list_words():\\n\",\n    \"            self.assertTrue(trie.find(word) is not None)\\n\",\n    \"            \\n\",\n    \"        print('Test: Remove me')\\n\",\n    \"        trie.remove('me')\\n\",\n    \"        words_removed = ['me']\\n\",\n    \"        words = ['a', 'at', 'has', 'hat', 'he',\\n\",\n    \"                 'men', 'mens', 'met']\\n\",\n    \"        for word in words:\\n\",\n    \"            self.assertTrue(trie.find(word) is not None)\\n\",\n    \"        for word in words_removed:\\n\",\n    \"            self.assertTrue(trie.find(word) is None)\\n\",\n    \"\\n\",\n    \"        print('Test: Remove mens')\\n\",\n    \"        trie.remove('mens')\\n\",\n    \"        words_removed = ['me', 'mens']\\n\",\n    \"        words = ['a', 'at', 'has', 'hat', 'he',\\n\",\n    \"                 'men', 'met']\\n\",\n    \"        for word in words:\\n\",\n    \"            self.assertTrue(trie.find(word) is not None)\\n\",\n    \"        for word in words_removed:\\n\",\n    \"            self.assertTrue(trie.find(word) is None)\\n\",\n    \"\\n\",\n    \"        print('Test: Remove a')\\n\",\n    \"        trie.remove('a')\\n\",\n    \"        words_removed = ['a', 'me', 'mens']\\n\",\n    \"        words = ['at', 'has', 'hat', 'he',\\n\",\n    \"                 'men', 'met']\\n\",\n    \"        for word in words:\\n\",\n    \"            self.assertTrue(trie.find(word) is not None)\\n\",\n    \"        for word in words_removed:\\n\",\n    \"            self.assertTrue(trie.find(word) is None)\\n\",\n    \"\\n\",\n    \"        print('Test: Remove has')\\n\",\n    \"        trie.remove('has')\\n\",\n    \"        words_removed = ['a', 'has', 'me', 'mens']\\n\",\n    \"        words = ['at', 'hat', 'he',\\n\",\n    \"                 'men', 'met']\\n\",\n    \"        for word in words:\\n\",\n    \"            self.assertTrue(trie.find(word) is not None)\\n\",\n    \"        for word in words_removed:\\n\",\n    \"            self.assertTrue(trie.find(word) is None)\\n\",\n    \"\\n\",\n    \"        print('Success: test_trie')\\n\",\n    \"\\n\",\n    \"    def test_trie_remove_invalid(self):\\n\",\n    \"        print('Test: Remove from empty trie')\\n\",\n    \"        trie = Trie()\\n\",\n    \"        self.assertTrue(trie.remove('foo') is None) \\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestTrie()\\n\",\n    \"    test.test_trie()\\n\",\n    \"    test.assertRaises(KeyError, test.test_trie_remove_invalid)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Insert\\n\",\n      \"Test: Remove me\\n\",\n      \"Test: Remove mens\\n\",\n      \"Test: Remove a\\n\",\n      \"Test: Remove has\\n\",\n      \"Success: test_trie\\n\",\n      \"Test: Remove from empty trie\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_trie.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "graphs_trees/utils/__init__.py",
    "content": ""
  },
  {
    "path": "graphs_trees/utils/captured_output.py",
    "content": "import sys\nfrom contextlib import contextmanager\nfrom StringIO import StringIO\n\n\n@contextmanager\ndef captured_output():\n    new_out, new_err = StringIO(), StringIO()\n    old_out, old_err = sys.stdout, sys.stderr\n    try:\n        sys.stdout, sys.stderr = new_out, new_err\n        yield sys.stdout, sys.stderr\n    finally:\n        sys.stdout, sys.stderr = old_out, old_err"
  },
  {
    "path": "graphs_trees/utils/results.py",
    "content": "class Results(object):\n\n    def __init__(self):\n        self.results = []\n\n    def add_result(self, result):\n        # TODO: Clean this up\n        # Simplifies challenge coding and unit testing\n        # but makes this function look less appealing\n        self.results.append(int(str(result)))\n\n    def clear_results(self):\n        self.results = []\n\n    def __str__(self):\n        return str(self.results)"
  },
  {
    "path": "linked_lists/__init__.py",
    "content": ""
  },
  {
    "path": "linked_lists/add_reverse/__init__.py",
    "content": ""
  },
  {
    "path": "linked_lists/add_reverse/add_reverse_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Add two numbers whose digits are stored in a linked list in reverse order.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a non-circular, singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we expect the return to be in reverse order too?\\n\",\n    \"    * Yes\\n\",\n    \"* What if one of the inputs is None?\\n\",\n    \"    * Return None for an invalid operation\\n\",\n    \"* How large are these numbers--can they fit in memory?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a linked list class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Empty list(s) -> None\\n\",\n    \"* Add values of different lengths\\n\",\n    \"    * Input 1: 6->5->None\\n\",\n    \"    * Input 2: 9->8->7\\n\",\n    \"    * Result: 5->4->8\\n\",\n    \"* Add values of same lengths\\n\",\n    \"    * Exercised from values of different lengths\\n\",\n    \"    * Done here for completeness\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/add_reverse/add_reverse_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../linked_list/linked_list.py\\n\",\n    \"%load ../linked_list/linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyLinkedList(LinkedList):\\n\",\n    \"\\n\",\n    \"    def add_reverse(self, first_list, second_list):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_add_reverse.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestAddReverse(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_add_reverse(self):\\n\",\n    \"        print('Test: Empty list(s)')\\n\",\n    \"        self.assertEqual(MyLinkedList().add_reverse(None, None), None)\\n\",\n    \"        self.assertEqual(MyLinkedList().add_reverse(Node(5), None), None)\\n\",\n    \"        self.assertEqual(MyLinkedList().add_reverse(None, Node(10)), None)\\n\",\n    \"\\n\",\n    \"        print('Test: Add values of different lengths')\\n\",\n    \"        # Input 1: 6->5->None\\n\",\n    \"        # Input 2: 9->8->7\\n\",\n    \"        # Result: 5->4->8\\n\",\n    \"        first_list = MyLinkedList(Node(6))\\n\",\n    \"        first_list.append(5)\\n\",\n    \"        second_list = MyLinkedList(Node(9))\\n\",\n    \"        second_list.append(8)\\n\",\n    \"        second_list.append(7)\\n\",\n    \"        result = MyLinkedList().add_reverse(first_list, second_list)\\n\",\n    \"        self.assertEqual(result.get_all_data(), [5, 4, 8])\\n\",\n    \"\\n\",\n    \"        print('Test: Add values of same lengths')\\n\",\n    \"        # Input 1: 6->5->4\\n\",\n    \"        # Input 2: 9->8->7\\n\",\n    \"        # Result: 5->4->2->1\\n\",\n    \"        first_head = Node(6)\\n\",\n    \"        first_list = MyLinkedList(first_head)\\n\",\n    \"        first_list.append(5)\\n\",\n    \"        first_list.append(4)\\n\",\n    \"        second_head = Node(9)\\n\",\n    \"        second_list = MyLinkedList(second_head)\\n\",\n    \"        second_list.append(8)\\n\",\n    \"        second_list.append(7)\\n\",\n    \"        result = MyLinkedList().add_reverse(first_list, second_list)\\n\",\n    \"        self.assertEqual(result.get_all_data(), [5, 4, 2, 1])\\n\",\n    \"\\n\",\n    \"        print('Success: test_add_reverse')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestAddReverse()\\n\",\n    \"    test.test_add_reverse()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/add_reverse/add_reverse_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/add_reverse/add_reverse_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Add two numbers whose digits are stored in a linked list in reverse order.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a non-circular, singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we expect the return to be in reverse order too?\\n\",\n    \"    * Yes\\n\",\n    \"* What if one of the inputs is None?\\n\",\n    \"    * Return None for an invalid operation\\n\",\n    \"* How large are these numbers--can they fit in memory?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a linked list class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Empty list(s) -> None\\n\",\n    \"* Add values of different lengths\\n\",\n    \"    * Input 1: 6->5->None\\n\",\n    \"    * Input 2: 9->8->7\\n\",\n    \"    * Result: 5->4->8\\n\",\n    \"* Add values of same lengths\\n\",\n    \"    * Exercised from values of different lengths\\n\",\n    \"    * Done here for completeness\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We could solve this with an iterative or a recursive algorithm, both are well suited for this exercise.  We'll use a recursive algorithm for practice with recursion.  Note this takes an extra space of O(m) where m is the recursion depth.\\n\",\n    \"\\n\",\n    \"* Base case:\\n\",\n    \"    * if first and second lists are None AND carry is zero\\n\",\n    \"        * Return None\\n\",\n    \"* Recursive case:\\n\",\n    \"    * Set `value` to `carry`\\n\",\n    \"    * Add both nodes' `data` to `value`\\n\",\n    \"    * Set the `carry` to 1 if `value >= 10, else 0`\\n\",\n    \"    * Set the `remainder` to `value % 10`\\n\",\n    \"    * Create a `node` with the `remainder`\\n\",\n    \"    * Set `node.next` to a recursive call on the `next` nodes, passing in the `carry`\\n\",\n    \"    * Return `node`\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(m), extra space for result and recursion depth\\n\",\n    \"\\n\",\n    \"Notes:\\n\",\n    \"* Careful with adding if the lists differ\\n\",\n    \"    * Only add if a node is not None\\n\",\n    \"    * Alternatively, we could add trailing zeroes to the smaller list\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../linked_list/linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyLinkedList(LinkedList):\\n\",\n    \"\\n\",\n    \"    def _add_reverse(self, first_node, second_node, carry):\\n\",\n    \"        # Base case\\n\",\n    \"        if first_node is None and second_node is None and not carry:\\n\",\n    \"            return None\\n\",\n    \"\\n\",\n    \"        # Recursive case\\n\",\n    \"        value = carry\\n\",\n    \"        value += first_node.data if first_node is not None else 0\\n\",\n    \"        value += second_node.data if second_node is not None else 0\\n\",\n    \"        carry = 1 if value >= 10 else 0\\n\",\n    \"        value %= 10\\n\",\n    \"        node = Node(value)\\n\",\n    \"        node.next = self._add_reverse(\\n\",\n    \"            first_node.next if first_node is not None else None,\\n\",\n    \"            second_node.next if first_node is not None else None,\\n\",\n    \"            carry)\\n\",\n    \"        return node\\n\",\n    \"\\n\",\n    \"    def add_reverse(self, first_list, second_list):\\n\",\n    \"        # See constraints\\n\",\n    \"        if first_list is None or second_list is None:\\n\",\n    \"            return None\\n\",\n    \"        head = self._add_reverse(first_list.head, second_list.head, 0)\\n\",\n    \"        return MyLinkedList(head)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_add_reverse.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_add_reverse.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestAddReverse(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_add_reverse(self):\\n\",\n    \"        print('Test: Empty list(s)')\\n\",\n    \"        self.assertEqual(MyLinkedList().add_reverse(None, None), None)\\n\",\n    \"        self.assertEqual(MyLinkedList().add_reverse(Node(5), None), None)\\n\",\n    \"        self.assertEqual(MyLinkedList().add_reverse(None, Node(10)), None)\\n\",\n    \"\\n\",\n    \"        print('Test: Add values of different lengths')\\n\",\n    \"        # Input 1: 6->5->None\\n\",\n    \"        # Input 2: 9->8->7\\n\",\n    \"        # Result: 5->4->8\\n\",\n    \"        first_list = MyLinkedList(Node(6))\\n\",\n    \"        first_list.append(5)\\n\",\n    \"        second_list = MyLinkedList(Node(9))\\n\",\n    \"        second_list.append(8)\\n\",\n    \"        second_list.append(7)\\n\",\n    \"        result = MyLinkedList().add_reverse(first_list, second_list)\\n\",\n    \"        self.assertEqual(result.get_all_data(), [5, 4, 8])\\n\",\n    \"\\n\",\n    \"        print('Test: Add values of same lengths')\\n\",\n    \"        # Input 1: 6->5->4\\n\",\n    \"        # Input 2: 9->8->7\\n\",\n    \"        # Result: 5->4->2->1\\n\",\n    \"        first_head = Node(6)\\n\",\n    \"        first_list = MyLinkedList(first_head)\\n\",\n    \"        first_list.append(5)\\n\",\n    \"        first_list.append(4)\\n\",\n    \"        second_head = Node(9)\\n\",\n    \"        second_list = MyLinkedList(second_head)\\n\",\n    \"        second_list.append(8)\\n\",\n    \"        second_list.append(7)\\n\",\n    \"        result = MyLinkedList().add_reverse(first_list, second_list)\\n\",\n    \"        self.assertEqual(result.get_all_data(), [5, 4, 2, 1])\\n\",\n    \"\\n\",\n    \"        print('Success: test_add_reverse')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestAddReverse()\\n\",\n    \"    test.test_add_reverse()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Empty list(s)\\n\",\n      \"Test: Add values of different lengths\\n\",\n      \"Test: Add values of same lengths\\n\",\n      \"Success: test_add_reverse\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_add_reverse.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/add_reverse/test_add_reverse.py",
    "content": "import unittest\n\n\nclass TestAddReverse(unittest.TestCase):\n\n    def test_add_reverse(self):\n        print('Test: Empty list(s)')\n        self.assertEqual(MyLinkedList().add_reverse(None, None), None)\n        self.assertEqual(MyLinkedList().add_reverse(Node(5), None), None)\n        self.assertEqual(MyLinkedList().add_reverse(None, Node(10)), None)\n\n        print('Test: Add values of different lengths')\n        # Input 1: 6->5->None\n        # Input 2: 9->8->7\n        # Result: 5->4->8\n        first_list = MyLinkedList(Node(6))\n        first_list.append(5)\n        second_list = MyLinkedList(Node(9))\n        second_list.append(8)\n        second_list.append(7)\n        result = MyLinkedList().add_reverse(first_list, second_list)\n        self.assertEqual(result.get_all_data(), [5, 4, 8])\n\n        print('Test: Add values of same lengths')\n        # Input 1: 6->5->4\n        # Input 2: 9->8->7\n        # Result: 5->4->2->1\n        first_head = Node(6)\n        first_list = MyLinkedList(first_head)\n        first_list.append(5)\n        first_list.append(4)\n        second_head = Node(9)\n        second_list = MyLinkedList(second_head)\n        second_list.append(8)\n        second_list.append(7)\n        result = MyLinkedList().add_reverse(first_list, second_list)\n        self.assertEqual(result.get_all_data(), [5, 4, 2, 1])\n\n        print('Success: test_add_reverse')\n\n\ndef main():\n    test = TestAddReverse()\n    test.test_add_reverse()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "linked_lists/delete_mid/__init__.py",
    "content": ""
  },
  {
    "path": "linked_lists/delete_mid/delete_mid_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Delete a node in the middle, given only access to that node.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a non-circular, singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* What if the final node is being deleted, do we make it a dummy with value None?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a linked list class that can be used for this problem?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Delete on empty list -> None\\n\",\n    \"* Delete None -> None\\n\",\n    \"* Delete on one node -> [None]\\n\",\n    \"* Delete on multiple nodes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/delete_mid/delete_mid_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../linked_list/linked_list.py\\n\",\n    \"%load ../linked_list/linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyLinkedList(LinkedList):\\n\",\n    \"\\n\",\n    \"    def delete_node(self, node):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_delete_mid.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestDeleteNode(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_delete_node(self):\\n\",\n    \"        print('Test: Empty list, null node to delete')\\n\",\n    \"        linked_list = MyLinkedList(None)\\n\",\n    \"        linked_list.delete_node(None)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [])\\n\",\n    \"\\n\",\n    \"        print('Test: One node')\\n\",\n    \"        head = Node(2)\\n\",\n    \"        linked_list = MyLinkedList(head)\\n\",\n    \"        linked_list.delete_node(head)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [None])\\n\",\n    \"\\n\",\n    \"        print('Test: Multiple nodes')\\n\",\n    \"        linked_list = MyLinkedList(None)\\n\",\n    \"        node0 = linked_list.insert_to_front(2)\\n\",\n    \"        node1 = linked_list.insert_to_front(3)\\n\",\n    \"        node2 = linked_list.insert_to_front(4)\\n\",\n    \"        node3 = linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.delete_node(node1)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [1, 4, 2])\\n\",\n    \"\\n\",\n    \"        print('Test: Multiple nodes, delete last element')\\n\",\n    \"        linked_list = MyLinkedList(None)\\n\",\n    \"        node0 = linked_list.insert_to_front(2)\\n\",\n    \"        node1 = linked_list.insert_to_front(3)\\n\",\n    \"        node2 = linked_list.insert_to_front(4)\\n\",\n    \"        node3 = linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.delete_node(node0)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [1, 4, 3, None])\\n\",\n    \"\\n\",\n    \"        print('Success: test_delete_node')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestDeleteNode()\\n\",\n    \"    test.test_delete_node()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/delete_mid/delete_mid_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/delete_mid/delete_mid_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Delete a node in the middle, given only access to that node.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a non-circular, singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* What if the final node is being deleted, do we make it a dummy with value None?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a linked list class that can be used for this problem?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Delete on empty list -> None\\n\",\n    \"* Delete None -> None\\n\",\n    \"* Delete on one node -> [None]\\n\",\n    \"* Delete on multiple nodes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll need two pointers, one to the current node and one to the next node.  We will copy the next node's data to the current node's data (effectively deleting the current node) and update the current node's next pointer.\\n\",\n    \"\\n\",\n    \"* set curr.data to next.data\\n\",\n    \"* set curr.next to next.next\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../linked_list/linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyLinkedList(LinkedList):\\n\",\n    \"\\n\",\n    \"    def delete_node(self, node):\\n\",\n    \"        if node is None:\\n\",\n    \"            return\\n\",\n    \"        if node.next is None:\\n\",\n    \"            node.data = None\\n\",\n    \"        else:\\n\",\n    \"            node.data = node.next.data\\n\",\n    \"            node.next = node.next.next\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_delete_mid.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_delete_mid.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestDeleteNode(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_delete_node(self):\\n\",\n    \"        print('Test: Empty list, null node to delete')\\n\",\n    \"        linked_list = MyLinkedList(None)\\n\",\n    \"        linked_list.delete_node(None)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [])\\n\",\n    \"\\n\",\n    \"        print('Test: One node')\\n\",\n    \"        head = Node(2)\\n\",\n    \"        linked_list = MyLinkedList(head)\\n\",\n    \"        linked_list.delete_node(head)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [None])\\n\",\n    \"\\n\",\n    \"        print('Test: Multiple nodes')\\n\",\n    \"        linked_list = MyLinkedList(None)\\n\",\n    \"        node0 = linked_list.insert_to_front(2)\\n\",\n    \"        node1 = linked_list.insert_to_front(3)\\n\",\n    \"        node2 = linked_list.insert_to_front(4)\\n\",\n    \"        node3 = linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.delete_node(node1)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [1, 4, 2])\\n\",\n    \"\\n\",\n    \"        print('Test: Multiple nodes, delete last element')\\n\",\n    \"        linked_list = MyLinkedList(None)\\n\",\n    \"        node0 = linked_list.insert_to_front(2)\\n\",\n    \"        node1 = linked_list.insert_to_front(3)\\n\",\n    \"        node2 = linked_list.insert_to_front(4)\\n\",\n    \"        node3 = linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.delete_node(node0)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [1, 4, 3, None])\\n\",\n    \"\\n\",\n    \"        print('Success: test_delete_node')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestDeleteNode()\\n\",\n    \"    test.test_delete_node()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Empty list, null node to delete\\n\",\n      \"Test: One node\\n\",\n      \"Test: Multiple nodes\\n\",\n      \"Test: Multiple nodes, delete last element\\n\",\n      \"Success: test_delete_node\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_delete_mid.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/delete_mid/test_delete_mid.py",
    "content": "import unittest\n\n\nclass TestDeleteNode(unittest.TestCase):\n\n    def test_delete_node(self):\n        print('Test: Empty list, null node to delete')\n        linked_list = MyLinkedList(None)\n        linked_list.delete_node(None)\n        self.assertEqual(linked_list.get_all_data(), [])\n\n        print('Test: One node')\n        head = Node(2)\n        linked_list = MyLinkedList(head)\n        linked_list.delete_node(head)\n        self.assertEqual(linked_list.get_all_data(), [None])\n\n        print('Test: Multiple nodes')\n        linked_list = MyLinkedList(None)\n        node0 = linked_list.insert_to_front(2)\n        node1 = linked_list.insert_to_front(3)\n        node2 = linked_list.insert_to_front(4)\n        node3 = linked_list.insert_to_front(1)\n        linked_list.delete_node(node1)\n        self.assertEqual(linked_list.get_all_data(), [1, 4, 2])\n\n        print('Test: Multiple nodes, delete last element')\n        linked_list = MyLinkedList(None)\n        node0 = linked_list.insert_to_front(2)\n        node1 = linked_list.insert_to_front(3)\n        node2 = linked_list.insert_to_front(4)\n        node3 = linked_list.insert_to_front(1)\n        linked_list.delete_node(node0)\n        self.assertEqual(linked_list.get_all_data(), [1, 4, 3, None])\n\n        print('Success: test_delete_node')\n\n\ndef main():\n    test = TestDeleteNode()\n    test.test_delete_node()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "linked_lists/find_loop_start/__init__.py",
    "content": ""
  },
  {
    "path": "linked_lists/find_loop_start/find_loop_start_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the start of a linked list loop.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is this a singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we are always passed a circular linked list?\\n\",\n    \"    * No\\n\",\n    \"* When we find a loop, do we return the node or the node's data?\\n\",\n    \"    * The node\\n\",\n    \"* Can we assume we already have a linked list class that can be used for this problem?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Empty list -> None\\n\",\n    \"* Not a circular linked list -> None\\n\",\n    \"    * One element\\n\",\n    \"    * Two or more elements\\n\",\n    \"* Circular linked list general case\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/find_loop_start/find_loop_start_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../linked_list/linked_list.py\\n\",\n    \"%load ../linked_list/linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyLinkedList(LinkedList):\\n\",\n    \"\\n\",\n    \"    def find_loop_start(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_find_loop_start.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestFindLoopStart(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_find_loop_start(self):\\n\",\n    \"        print('Test: Empty list')\\n\",\n    \"        linked_list = MyLinkedList()\\n\",\n    \"        self.assertEqual(linked_list.find_loop_start(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: Not a circular linked list: One element')\\n\",\n    \"        head = Node(1)\\n\",\n    \"        linked_list = MyLinkedList(head)\\n\",\n    \"        self.assertEqual(linked_list.find_loop_start(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: Not a circular linked list: Two elements')\\n\",\n    \"        linked_list.append(2)\\n\",\n    \"        self.assertEqual(linked_list.find_loop_start(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: Not a circular linked list: Three or more elements')\\n\",\n    \"        linked_list.append(3)\\n\",\n    \"        self.assertEqual(linked_list.find_loop_start(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: General case: Circular linked list')\\n\",\n    \"        node10 = Node(10)\\n\",\n    \"        node9 = Node(9, node10)\\n\",\n    \"        node8 = Node(8, node9)\\n\",\n    \"        node7 = Node(7, node8)\\n\",\n    \"        node6 = Node(6, node7)\\n\",\n    \"        node5 = Node(5, node6)\\n\",\n    \"        node4 = Node(4, node5)\\n\",\n    \"        node3 = Node(3, node4)\\n\",\n    \"        node2 = Node(2, node3)\\n\",\n    \"        node1 = Node(1, node2)\\n\",\n    \"        node0 = Node(0, node1)\\n\",\n    \"        node10.next = node3\\n\",\n    \"        linked_list = MyLinkedList(node0)\\n\",\n    \"        self.assertEqual(linked_list.find_loop_start(), node3)\\n\",\n    \"\\n\",\n    \"        print('Success: test_find_loop_start')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestFindLoopStart()\\n\",\n    \"    test.test_find_loop_start()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/find_loop_start/find_loop_start_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/find_loop_start/find_loop_start_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the start of a linked list loop.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is this a singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we are always passed a circular linked list?\\n\",\n    \"    * No\\n\",\n    \"* When we find a loop, do we return the node or the node's data?\\n\",\n    \"    * The node\\n\",\n    \"* Can we assume we already have a linked list class that can be used for this problem?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Empty list -> None\\n\",\n    \"* Not a circular linked list -> None\\n\",\n    \"    * One element\\n\",\n    \"    * Two or more elements\\n\",\n    \"* Circular linked list general case\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Use two references `slow`, `fast`, initialized to the `head`\\n\",\n    \"* Increment `slow` and `fast` until they meet\\n\",\n    \"    * `fast` is incremented twice as fast as `slow`\\n\",\n    \"        * If `fast.next` is `None`, we do not have a circular list\\n\",\n    \"* When `slow` and `fast` meet, move `slow` to the `head`\\n\",\n    \"* Increment `slow` and `fast` one node at a time until they meet\\n\",\n    \"* Where they meet is the start of the loop\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../linked_list/linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyLinkedList(LinkedList):\\n\",\n    \"\\n\",\n    \"    def find_loop_start(self):\\n\",\n    \"        if self.head is None or self.head.next is None:\\n\",\n    \"            return None\\n\",\n    \"        slow = self.head\\n\",\n    \"        fast = self.head\\n\",\n    \"        while fast.next is not None:\\n\",\n    \"            slow = slow.next\\n\",\n    \"            fast = fast.next.next\\n\",\n    \"            if fast is None:\\n\",\n    \"                return None\\n\",\n    \"            if slow == fast:\\n\",\n    \"                break\\n\",\n    \"        slow = self.head\\n\",\n    \"        while slow != fast:\\n\",\n    \"            slow = slow.next\\n\",\n    \"            fast = fast.next\\n\",\n    \"            if fast is None:\\n\",\n    \"                return None\\n\",\n    \"        return slow\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_find_loop_start.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_find_loop_start.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestFindLoopStart(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_find_loop_start(self):\\n\",\n    \"        print('Test: Empty list')\\n\",\n    \"        linked_list = MyLinkedList()\\n\",\n    \"        self.assertEqual(linked_list.find_loop_start(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: Not a circular linked list: One element')\\n\",\n    \"        head = Node(1)\\n\",\n    \"        linked_list = MyLinkedList(head)\\n\",\n    \"        self.assertEqual(linked_list.find_loop_start(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: Not a circular linked list: Two elements')\\n\",\n    \"        linked_list.append(2)\\n\",\n    \"        self.assertEqual(linked_list.find_loop_start(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: Not a circular linked list: Three or more elements')\\n\",\n    \"        linked_list.append(3)\\n\",\n    \"        self.assertEqual(linked_list.find_loop_start(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: General case: Circular linked list')\\n\",\n    \"        node10 = Node(10)\\n\",\n    \"        node9 = Node(9, node10)\\n\",\n    \"        node8 = Node(8, node9)\\n\",\n    \"        node7 = Node(7, node8)\\n\",\n    \"        node6 = Node(6, node7)\\n\",\n    \"        node5 = Node(5, node6)\\n\",\n    \"        node4 = Node(4, node5)\\n\",\n    \"        node3 = Node(3, node4)\\n\",\n    \"        node2 = Node(2, node3)\\n\",\n    \"        node1 = Node(1, node2)\\n\",\n    \"        node0 = Node(0, node1)\\n\",\n    \"        node10.next = node3\\n\",\n    \"        linked_list = MyLinkedList(node0)\\n\",\n    \"        self.assertEqual(linked_list.find_loop_start(), node3)\\n\",\n    \"\\n\",\n    \"        print('Success: test_find_loop_start')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestFindLoopStart()\\n\",\n    \"    test.test_find_loop_start()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {\n    \"scrolled\": true\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Empty list\\n\",\n      \"Test: Not a circular linked list: One element\\n\",\n      \"Test: Not a circular linked list: Two elements\\n\",\n      \"Test: Not a circular linked list: Three or more elements\\n\",\n      \"Test: General case: Circular linked list\\n\",\n      \"Success: test_find_loop_start\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_find_loop_start.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/find_loop_start/test_find_loop_start.py",
    "content": "import unittest\n\n\nclass TestFindLoopStart(unittest.TestCase):\n\n    def test_find_loop_start(self):\n        print('Test: Empty list')\n        linked_list = MyLinkedList()\n        self.assertEqual(linked_list.find_loop_start(), None)\n\n        print('Test: Not a circular linked list: One element')\n        head = Node(1)\n        linked_list = MyLinkedList(head)\n        self.assertEqual(linked_list.find_loop_start(), None)\n\n        print('Test: Not a circular linked list: Two elements')\n        linked_list.append(2)\n        self.assertEqual(linked_list.find_loop_start(), None)\n\n        print('Test: Not a circular linked list: Three or more elements')\n        linked_list.append(3)\n        self.assertEqual(linked_list.find_loop_start(), None)\n\n        print('Test: General case: Circular linked list')\n        node10 = Node(10)\n        node9 = Node(9, node10)\n        node8 = Node(8, node9)\n        node7 = Node(7, node8)\n        node6 = Node(6, node7)\n        node5 = Node(5, node6)\n        node4 = Node(4, node5)\n        node3 = Node(3, node4)\n        node2 = Node(2, node3)\n        node1 = Node(1, node2)\n        node0 = Node(0, node1)\n        node10.next = node3\n        linked_list = MyLinkedList(node0)\n        self.assertEqual(linked_list.find_loop_start(), node3)\n\n        print('Success: test_find_loop_start')\n\n\ndef main():\n    test = TestFindLoopStart()\n    test.test_find_loop_start()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "linked_lists/kth_to_last_elem/__init__.py",
    "content": ""
  },
  {
    "path": "linked_lists/kth_to_last_elem/kth_to_last_elem_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the kth to last element of a linked list.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a non-circular, singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume k is a valid integer?\\n\",\n    \"    * Yes\\n\",\n    \"* If k = 0, does this return the last element?\\n\",\n    \"    * Yes\\n\",\n    \"* What happens if k is greater than or equal to the length of the linked list?\\n\",\n    \"    * Return None\\n\",\n    \"* Can you use additional data structures?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume we already have a linked list class that can be used for this problem?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Empty list -> None\\n\",\n    \"* k is >= the length of the linked list -> None\\n\",\n    \"* One element, k = 0 -> element\\n\",\n    \"* General case with many elements, k < length of linked list\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/kth_to_last_elem/kth_to_last_elem_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../linked_list/linked_list.py\\n\",\n    \"%load ../linked_list/linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyLinkedList(LinkedList):\\n\",\n    \"\\n\",\n    \"    def kth_to_last_elem(self, k):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_kth_to_last_elem.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Test(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_kth_to_last_elem(self):\\n\",\n    \"        print('Test: Empty list')\\n\",\n    \"        linked_list = MyLinkedList(None)\\n\",\n    \"        self.assertEqual(linked_list.kth_to_last_elem(0), None)\\n\",\n    \"\\n\",\n    \"        print('Test: k >= len(list)')\\n\",\n    \"        self.assertEqual(linked_list.kth_to_last_elem(100), None)\\n\",\n    \"\\n\",\n    \"        print('Test: One element, k = 0')\\n\",\n    \"        head = Node(2)\\n\",\n    \"        linked_list = MyLinkedList(head)\\n\",\n    \"        self.assertEqual(linked_list.kth_to_last_elem(0), 2)\\n\",\n    \"\\n\",\n    \"        print('Test: General case')\\n\",\n    \"        linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.insert_to_front(3)\\n\",\n    \"        linked_list.insert_to_front(5)\\n\",\n    \"        linked_list.insert_to_front(7)\\n\",\n    \"        self.assertEqual(linked_list.kth_to_last_elem(2), 3)\\n\",\n    \"\\n\",\n    \"        print('Success: test_kth_to_last_elem')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = Test()\\n\",\n    \"    test.test_kth_to_last_elem()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/kth_to_last_elem/kth_to_last_elem_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/kth_to_last_elem/kth_to_last_elem_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the kth to last element of a linked list.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a non-circular, singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume k is a valid integer?\\n\",\n    \"    * Yes\\n\",\n    \"* If k = 0, does this return the last element?\\n\",\n    \"    * Yes\\n\",\n    \"* What happens if k is greater than or equal to the length of the linked list?\\n\",\n    \"    * Return None\\n\",\n    \"* Can you use additional data structures?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume we already have a linked list class that can be used for this problem?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Empty list -> None\\n\",\n    \"* k is >= the length of the linked list -> None\\n\",\n    \"* One element, k = 0 -> element\\n\",\n    \"* General case with many elements, k < length of linked list\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Setup two pointers, fast and slow\\n\",\n    \"* Give fast a headstart, incrementing it once if k = 1, twice if k = 2, ...\\n\",\n    \"* Increment both pointers until fast reaches the end\\n\",\n    \"* Return the value of slow\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../linked_list/linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyLinkedList(LinkedList):\\n\",\n    \"\\n\",\n    \"    def kth_to_last_elem(self, k):\\n\",\n    \"        if self.head is None:\\n\",\n    \"            return None\\n\",\n    \"        fast = self.head\\n\",\n    \"        slow = self.head\\n\",\n    \"\\n\",\n    \"        # Give fast a headstart, incrementing it\\n\",\n    \"        # once for k = 1, twice for k = 2, etc\\n\",\n    \"        for _ in range(k):\\n\",\n    \"            fast = fast.next\\n\",\n    \"            # If k >= num elements, return None\\n\",\n    \"            if fast is None:\\n\",\n    \"                return None\\n\",\n    \"\\n\",\n    \"        # Increment both pointers until fast reaches the end\\n\",\n    \"        while fast.next is not None:\\n\",\n    \"            fast = fast.next\\n\",\n    \"            slow = slow.next\\n\",\n    \"        return slow.data\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_kth_to_last_elem.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_kth_to_last_elem.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Test(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_kth_to_last_elem(self):\\n\",\n    \"        print('Test: Empty list')\\n\",\n    \"        linked_list = MyLinkedList(None)\\n\",\n    \"        self.assertEqual(linked_list.kth_to_last_elem(0), None)\\n\",\n    \"\\n\",\n    \"        print('Test: k >= len(list)')\\n\",\n    \"        self.assertEqual(linked_list.kth_to_last_elem(100), None)\\n\",\n    \"\\n\",\n    \"        print('Test: One element, k = 0')\\n\",\n    \"        head = Node(2)\\n\",\n    \"        linked_list = MyLinkedList(head)\\n\",\n    \"        self.assertEqual(linked_list.kth_to_last_elem(0), 2)\\n\",\n    \"\\n\",\n    \"        print('Test: General case')\\n\",\n    \"        linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.insert_to_front(3)\\n\",\n    \"        linked_list.insert_to_front(5)\\n\",\n    \"        linked_list.insert_to_front(7)\\n\",\n    \"        self.assertEqual(linked_list.kth_to_last_elem(2), 3)\\n\",\n    \"\\n\",\n    \"        print('Success: test_kth_to_last_elem')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = Test()\\n\",\n    \"    test.test_kth_to_last_elem()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Empty list\\n\",\n      \"Test: k >= len(list)\\n\",\n      \"Test: One element, k = 0\\n\",\n      \"Test: General case\\n\",\n      \"Success: test_kth_to_last_elem\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_kth_to_last_elem.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/kth_to_last_elem/test_kth_to_last_elem.py",
    "content": "import unittest\n\n\nclass Test(unittest.TestCase):\n\n    def test_kth_to_last_elem(self):\n        print('Test: Empty list')\n        linked_list = MyLinkedList(None)\n        self.assertEqual(linked_list.kth_to_last_elem(0), None)\n\n        print('Test: k >= len(list)')\n        self.assertEqual(linked_list.kth_to_last_elem(100), None)\n\n        print('Test: One element, k = 0')\n        head = Node(2)\n        linked_list = MyLinkedList(head)\n        self.assertEqual(linked_list.kth_to_last_elem(0), 2)\n\n        print('Test: General case')\n        linked_list.insert_to_front(1)\n        linked_list.insert_to_front(3)\n        linked_list.insert_to_front(5)\n        linked_list.insert_to_front(7)\n        self.assertEqual(linked_list.kth_to_last_elem(2), 3)\n\n        print('Success: test_kth_to_last_elem')\n\n\ndef main():\n    test = Test()\n    test.test_kth_to_last_elem()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "linked_lists/linked_list/__init__.py",
    "content": ""
  },
  {
    "path": "linked_lists/linked_list/linked_list.py",
    "content": "class Node(object):\n\n    def __init__(self, data, next=None):\n        self.next = next\n        self.data = data\n\n    def __str__(self):\n        return self.data\n\n\nclass LinkedList(object):\n\n    def __init__(self, head=None):\n        self.head = head\n\n    def __len__(self):\n        curr = self.head\n        counter = 0\n        while curr is not None:\n            counter += 1\n            curr = curr.next\n        return counter\n\n    def insert_to_front(self, data):\n        if data is None:\n            return None\n        node = Node(data, self.head)\n        self.head = node\n        return node\n\n    def append(self, data):\n        if data is None:\n            return None\n        node = Node(data)\n        if self.head is None:\n            self.head = node\n            return node\n        curr_node = self.head\n        while curr_node.next is not None:\n            curr_node = curr_node.next\n        curr_node.next = node\n        return node\n\n    def find(self, data):\n        if data is None:\n            return None\n        curr_node = self.head\n        while curr_node is not None:\n            if curr_node.data == data:\n                return curr_node\n            curr_node = curr_node.next\n        return None\n\n    def delete(self, data):\n        if data is None:\n            return\n        if self.head is None:\n            return\n        if self.head.data == data:\n            self.head = self.head.next\n            return\n        prev_node = self.head\n        curr_node = self.head.next\n        while curr_node is not None:\n            if curr_node.data == data:\n                prev_node.next = curr_node.next\n                return\n            prev_node = curr_node\n            curr_node = curr_node.next\n\n    def delete_alt(self, data):\n        if data is None:\n            return\n        if self.head is None:\n            return\n        curr_node = self.head\n        if curr_node.data == data:\n            curr_node = curr_node.next\n            return\n        while curr_node.next is not None:\n            if curr_node.next.data == data:\n                curr_node.next = curr_node.next.next\n                return\n            curr_node = curr_node.next\n\n    def print_list(self):\n        curr_node = self.head\n        while curr_node is not None:\n            print(curr_node.data)\n            curr_node = curr_node.next\n\n    def get_all_data(self):\n        data = []\n        curr_node = self.head\n        while curr_node is not None:\n            data.append(curr_node.data)\n            curr_node = curr_node.next\n        return data\n"
  },
  {
    "path": "linked_lists/linked_list/linked_list_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a linked list with insert, append, find, delete, length, and print methods.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a non-circular, singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we keep track of the tail or just the head?\\n\",\n    \"    * Just the head\\n\",\n    \"* Can we insert None values?\\n\",\n    \"    * No\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### Insert to Front\\n\",\n    \"\\n\",\n    \"* Insert a None\\n\",\n    \"* Insert in an empty list\\n\",\n    \"* Insert in a list with one element or more elements\\n\",\n    \"\\n\",\n    \"### Append\\n\",\n    \"\\n\",\n    \"* Append a None\\n\",\n    \"* Append in an empty list\\n\",\n    \"* Insert in a list with one element or more elements\\n\",\n    \"\\n\",\n    \"### Find\\n\",\n    \"\\n\",\n    \"* Find a None\\n\",\n    \"* Find in an empty list\\n\",\n    \"* Find in a list with one element or more matching elements\\n\",\n    \"* Find in a list with no matches\\n\",\n    \"\\n\",\n    \"### Delete\\n\",\n    \"\\n\",\n    \"* Delete a None\\n\",\n    \"* Delete in an empty list\\n\",\n    \"* Delete in a list with one element or more matching elements\\n\",\n    \"* Delete in a list with no matches\\n\",\n    \"\\n\",\n    \"### Length\\n\",\n    \"\\n\",\n    \"* Length of zero or more elements\\n\",\n    \"\\n\",\n    \"### Print\\n\",\n    \"\\n\",\n    \"* Print an empty list\\n\",\n    \"* Print a list with one or more elements\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/linked_list/linked_list_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Node(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, data, next_node=None):\\n\",\n    \"        pass\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"\\n\",\n    \"    def __str__(self):\\n\",\n    \"        pass\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class LinkedList(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, head=None):\\n\",\n    \"        pass\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"\\n\",\n    \"    def __len__(self):\\n\",\n    \"        pass\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"\\n\",\n    \"    def insert_to_front(self, data):\\n\",\n    \"        pass\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"\\n\",\n    \"    def append(self, data):\\n\",\n    \"        pass\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"\\n\",\n    \"    def find(self, data):\\n\",\n    \"        pass\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"\\n\",\n    \"    def delete(self, data):\\n\",\n    \"        pass\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"\\n\",\n    \"    def print_list(self):\\n\",\n    \"        pass\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"\\n\",\n    \"    def get_all_data(self):\\n\",\n    \"        pass\\n\",\n    \"        # TODO: Implement me\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_linked_list.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestLinkedList(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_insert_to_front(self):\\n\",\n    \"        print('Test: insert_to_front on an empty list')\\n\",\n    \"        linked_list = LinkedList(None)\\n\",\n    \"        linked_list.insert_to_front(10)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [10])\\n\",\n    \"\\n\",\n    \"        print('Test: insert_to_front on a None')\\n\",\n    \"        linked_list.insert_to_front(None)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [10])\\n\",\n    \"\\n\",\n    \"        print('Test: insert_to_front general case')\\n\",\n    \"        linked_list.insert_to_front('a')\\n\",\n    \"        linked_list.insert_to_front('bc')\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), ['bc', 'a', 10])\\n\",\n    \"\\n\",\n    \"        print('Success: test_insert_to_front\\\\n')\\n\",\n    \"\\n\",\n    \"    def test_append(self):\\n\",\n    \"        print('Test: append on an empty list')\\n\",\n    \"        linked_list = LinkedList(None)\\n\",\n    \"        linked_list.append(10)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [10])\\n\",\n    \"\\n\",\n    \"        print('Test: append a None')\\n\",\n    \"        linked_list.append(None)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [10])\\n\",\n    \"\\n\",\n    \"        print('Test: append general case')\\n\",\n    \"        linked_list.append('a')\\n\",\n    \"        linked_list.append('bc')\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [10, 'a', 'bc'])\\n\",\n    \"\\n\",\n    \"        print('Success: test_append\\\\n')\\n\",\n    \"\\n\",\n    \"    def test_find(self):\\n\",\n    \"        print('Test: find on an empty list')\\n\",\n    \"        linked_list = LinkedList(None)\\n\",\n    \"        node = linked_list.find('a')\\n\",\n    \"        self.assertEqual(node, None)\\n\",\n    \"\\n\",\n    \"        print('Test: find a None')\\n\",\n    \"        head = Node(10)\\n\",\n    \"        linked_list = LinkedList(head)\\n\",\n    \"        node = linked_list.find(None)\\n\",\n    \"        self.assertEqual(node, None)\\n\",\n    \"\\n\",\n    \"        print('Test: find general case with matches')\\n\",\n    \"        head = Node(10)\\n\",\n    \"        linked_list = LinkedList(head)\\n\",\n    \"        linked_list.insert_to_front('a')\\n\",\n    \"        linked_list.insert_to_front('bc')\\n\",\n    \"        node = linked_list.find('a')\\n\",\n    \"        self.assertEqual(str(node), 'a')\\n\",\n    \"\\n\",\n    \"        print('Test: find general case with no matches')\\n\",\n    \"        node = linked_list.find('aaa')\\n\",\n    \"        self.assertEqual(node, None)\\n\",\n    \"\\n\",\n    \"        print('Success: test_find\\\\n')\\n\",\n    \"\\n\",\n    \"    def test_delete(self):\\n\",\n    \"        print('Test: delete on an empty list')\\n\",\n    \"        linked_list = LinkedList(None)\\n\",\n    \"        linked_list.delete('a')\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [])\\n\",\n    \"\\n\",\n    \"        print('Test: delete a None')\\n\",\n    \"        head = Node(10)\\n\",\n    \"        linked_list = LinkedList(head)\\n\",\n    \"        linked_list.delete(None)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [10])\\n\",\n    \"\\n\",\n    \"        print('Test: delete general case with matches')\\n\",\n    \"        head = Node(10)\\n\",\n    \"        linked_list = LinkedList(head)\\n\",\n    \"        linked_list.insert_to_front('a')\\n\",\n    \"        linked_list.insert_to_front('bc')\\n\",\n    \"        linked_list.delete('a')\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), ['bc', 10])\\n\",\n    \"\\n\",\n    \"        print('Test: delete general case with no matches')\\n\",\n    \"        linked_list.delete('aa')\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), ['bc', 10])\\n\",\n    \"\\n\",\n    \"        print('Success: test_delete\\\\n')\\n\",\n    \"\\n\",\n    \"    def test_len(self):\\n\",\n    \"        print('Test: len on an empty list')\\n\",\n    \"        linked_list = LinkedList(None)\\n\",\n    \"        self.assertEqual(len(linked_list), 0)\\n\",\n    \"\\n\",\n    \"        print('Test: len general case')\\n\",\n    \"        head = Node(10)\\n\",\n    \"        linked_list = LinkedList(head)\\n\",\n    \"        linked_list.insert_to_front('a')\\n\",\n    \"        linked_list.insert_to_front('bc')\\n\",\n    \"        self.assertEqual(len(linked_list), 3)\\n\",\n    \"\\n\",\n    \"        print('Success: test_len\\\\n')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestLinkedList()\\n\",\n    \"    test.test_insert_to_front()\\n\",\n    \"    test.test_append()\\n\",\n    \"    test.test_find()\\n\",\n    \"    test.test_delete()\\n\",\n    \"    test.test_len()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/linked_list/linked_list_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/linked_list/linked_list_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a linked list with insert, append, find, delete, length, and print methods.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a non-circular, singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we keep track of the tail or just the head?\\n\",\n    \"    * Just the head\\n\",\n    \"* Can we insert None values?\\n\",\n    \"    * No\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### Insert to Front\\n\",\n    \"\\n\",\n    \"* Insert a None\\n\",\n    \"* Insert in an empty list\\n\",\n    \"* Insert in a list with one element or more elements\\n\",\n    \"\\n\",\n    \"### Append\\n\",\n    \"\\n\",\n    \"* Append a None\\n\",\n    \"* Append in an empty list\\n\",\n    \"* Insert in a list with one element or more elements\\n\",\n    \"\\n\",\n    \"### Find\\n\",\n    \"\\n\",\n    \"* Find a None\\n\",\n    \"* Find in an empty list\\n\",\n    \"* Find in a list with one element or more matching elements\\n\",\n    \"* Find in a list with no matches\\n\",\n    \"\\n\",\n    \"### Delete\\n\",\n    \"\\n\",\n    \"* Delete a None\\n\",\n    \"* Delete in an empty list\\n\",\n    \"* Delete in a list with one element or more matching elements\\n\",\n    \"* Delete in a list with no matches\\n\",\n    \"\\n\",\n    \"### Length\\n\",\n    \"\\n\",\n    \"* Length of zero or more elements\\n\",\n    \"\\n\",\n    \"### Print\\n\",\n    \"\\n\",\n    \"* Print an empty list\\n\",\n    \"* Print a list with one or more elements\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### Insert to Front\\n\",\n    \"\\n\",\n    \"* If the data we are inserting is None, return\\n\",\n    \"* Create a node with the input data, set node.next to head\\n\",\n    \"* Assign the head to the node\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Append\\n\",\n    \"\\n\",\n    \"* If the data we are inserting is None, return\\n\",\n    \"* Create a node with the input data\\n\",\n    \"* If this is an empty list\\n\",\n    \"    * Assign the head to the node\\n\",\n    \"* Else\\n\",\n    \"    * Iterate to the end of the list\\n\",\n    \"    * Set the final node's next to the new node\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Find\\n\",\n    \"\\n\",\n    \"* If data we are finding is None, return\\n\",\n    \"* If the list is empty, return\\n\",\n    \"* For each node\\n\",\n    \"    * If the value is a match, return it\\n\",\n    \"    * Else, move on to the next node\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Delete\\n\",\n    \"\\n\",\n    \"* If data we are deleting is None, return\\n\",\n    \"* If the list is empty, return\\n\",\n    \"* For each node, keep track of previous and current node\\n\",\n    \"    * If the value we are deleting is a match in the current node\\n\",\n    \"        * Update previous node's next pointer to the current node's next pointer\\n\",\n    \"        * We do not have have to explicitly delete in Python\\n\",\n    \"    * Else, move on to the next node\\n\",\n    \"* As an alternative, we could avoid the use of two pointers by evaluating the current node's next value:\\n\",\n    \"    * If the next value is a match, set the current node's next to next.next\\n\",\n    \"    * Special care should be taken if deleting the head node\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Length\\n\",\n    \"\\n\",\n    \"* For each node\\n\",\n    \"    * Increase length counter\\n\",\n    \"    \\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Print\\n\",\n    \"\\n\",\n    \"* For each node\\n\",\n    \"    * Print the node's value\\n\",\n    \"    \\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting linked_list.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile linked_list.py\\n\",\n    \"class Node(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, data, next=None):\\n\",\n    \"        self.next = next\\n\",\n    \"        self.data = data\\n\",\n    \"\\n\",\n    \"    def __str__(self):\\n\",\n    \"        return self.data\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class LinkedList(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, head=None):\\n\",\n    \"        self.head = head\\n\",\n    \"\\n\",\n    \"    def __len__(self):\\n\",\n    \"        curr = self.head\\n\",\n    \"        counter = 0\\n\",\n    \"        while curr is not None:\\n\",\n    \"            counter += 1\\n\",\n    \"            curr = curr.next\\n\",\n    \"        return counter\\n\",\n    \"\\n\",\n    \"    def insert_to_front(self, data):\\n\",\n    \"        if data is None:\\n\",\n    \"            return None\\n\",\n    \"        node = Node(data, self.head)\\n\",\n    \"        self.head = node\\n\",\n    \"        return node\\n\",\n    \"\\n\",\n    \"    def append(self, data):\\n\",\n    \"        if data is None:\\n\",\n    \"            return None\\n\",\n    \"        node = Node(data)\\n\",\n    \"        if self.head is None:\\n\",\n    \"            self.head = node\\n\",\n    \"            return node\\n\",\n    \"        curr_node = self.head\\n\",\n    \"        while curr_node.next is not None:\\n\",\n    \"            curr_node = curr_node.next\\n\",\n    \"        curr_node.next = node\\n\",\n    \"        return node\\n\",\n    \"\\n\",\n    \"    def find(self, data):\\n\",\n    \"        if data is None:\\n\",\n    \"            return None\\n\",\n    \"        curr_node = self.head\\n\",\n    \"        while curr_node is not None:\\n\",\n    \"            if curr_node.data == data:\\n\",\n    \"                return curr_node\\n\",\n    \"            curr_node = curr_node.next\\n\",\n    \"        return None\\n\",\n    \"\\n\",\n    \"    def delete(self, data):\\n\",\n    \"        if data is None:\\n\",\n    \"            return\\n\",\n    \"        if self.head is None:\\n\",\n    \"            return\\n\",\n    \"        if self.head.data == data:\\n\",\n    \"            self.head = self.head.next\\n\",\n    \"            return\\n\",\n    \"        prev_node = self.head\\n\",\n    \"        curr_node = self.head.next\\n\",\n    \"        while curr_node is not None:\\n\",\n    \"            if curr_node.data == data:\\n\",\n    \"                prev_node.next = curr_node.next\\n\",\n    \"                return\\n\",\n    \"            prev_node = curr_node\\n\",\n    \"            curr_node = curr_node.next\\n\",\n    \"\\n\",\n    \"    def delete_alt(self, data):\\n\",\n    \"        if data is None:\\n\",\n    \"            return\\n\",\n    \"        if self.head is None:\\n\",\n    \"            return\\n\",\n    \"        curr_node = self.head\\n\",\n    \"        if curr_node.data == data:\\n\",\n    \"            curr_node = curr_node.next\\n\",\n    \"            return\\n\",\n    \"        while curr_node.next is not None:\\n\",\n    \"            if curr_node.next.data == data:\\n\",\n    \"                curr_node.next = curr_node.next.next\\n\",\n    \"                return\\n\",\n    \"            curr_node = curr_node.next\\n\",\n    \"\\n\",\n    \"    def print_list(self):\\n\",\n    \"        curr_node = self.head\\n\",\n    \"        while curr_node is not None:\\n\",\n    \"            print(curr_node.data)\\n\",\n    \"            curr_node = curr_node.next\\n\",\n    \"\\n\",\n    \"    def get_all_data(self):\\n\",\n    \"        data = []\\n\",\n    \"        curr_node = self.head\\n\",\n    \"        while curr_node is not None:\\n\",\n    \"            data.append(curr_node.data)\\n\",\n    \"            curr_node = curr_node.next\\n\",\n    \"        return data\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_linked_list.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_linked_list.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestLinkedList(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_insert_to_front(self):\\n\",\n    \"        print('Test: insert_to_front on an empty list')\\n\",\n    \"        linked_list = LinkedList(None)\\n\",\n    \"        linked_list.insert_to_front(10)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [10])\\n\",\n    \"\\n\",\n    \"        print('Test: insert_to_front on a None')\\n\",\n    \"        linked_list.insert_to_front(None)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [10])\\n\",\n    \"\\n\",\n    \"        print('Test: insert_to_front general case')\\n\",\n    \"        linked_list.insert_to_front('a')\\n\",\n    \"        linked_list.insert_to_front('bc')\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), ['bc', 'a', 10])\\n\",\n    \"\\n\",\n    \"        print('Success: test_insert_to_front\\\\n')\\n\",\n    \"\\n\",\n    \"    def test_append(self):\\n\",\n    \"        print('Test: append on an empty list')\\n\",\n    \"        linked_list = LinkedList(None)\\n\",\n    \"        linked_list.append(10)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [10])\\n\",\n    \"\\n\",\n    \"        print('Test: append a None')\\n\",\n    \"        linked_list.append(None)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [10])\\n\",\n    \"\\n\",\n    \"        print('Test: append general case')\\n\",\n    \"        linked_list.append('a')\\n\",\n    \"        linked_list.append('bc')\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [10, 'a', 'bc'])\\n\",\n    \"\\n\",\n    \"        print('Success: test_append\\\\n')\\n\",\n    \"\\n\",\n    \"    def test_find(self):\\n\",\n    \"        print('Test: find on an empty list')\\n\",\n    \"        linked_list = LinkedList(None)\\n\",\n    \"        node = linked_list.find('a')\\n\",\n    \"        self.assertEqual(node, None)\\n\",\n    \"\\n\",\n    \"        print('Test: find a None')\\n\",\n    \"        head = Node(10)\\n\",\n    \"        linked_list = LinkedList(head)\\n\",\n    \"        node = linked_list.find(None)\\n\",\n    \"        self.assertEqual(node, None)\\n\",\n    \"\\n\",\n    \"        print('Test: find general case with matches')\\n\",\n    \"        head = Node(10)\\n\",\n    \"        linked_list = LinkedList(head)\\n\",\n    \"        linked_list.insert_to_front('a')\\n\",\n    \"        linked_list.insert_to_front('bc')\\n\",\n    \"        node = linked_list.find('a')\\n\",\n    \"        self.assertEqual(str(node), 'a')\\n\",\n    \"\\n\",\n    \"        print('Test: find general case with no matches')\\n\",\n    \"        node = linked_list.find('aaa')\\n\",\n    \"        self.assertEqual(node, None)\\n\",\n    \"\\n\",\n    \"        print('Success: test_find\\\\n')\\n\",\n    \"\\n\",\n    \"    def test_delete(self):\\n\",\n    \"        print('Test: delete on an empty list')\\n\",\n    \"        linked_list = LinkedList(None)\\n\",\n    \"        linked_list.delete('a')\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [])\\n\",\n    \"\\n\",\n    \"        print('Test: delete a None')\\n\",\n    \"        head = Node(10)\\n\",\n    \"        linked_list = LinkedList(head)\\n\",\n    \"        linked_list.delete(None)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [10])\\n\",\n    \"\\n\",\n    \"        print('Test: delete general case with matches')\\n\",\n    \"        head = Node(10)\\n\",\n    \"        linked_list = LinkedList(head)\\n\",\n    \"        linked_list.insert_to_front('a')\\n\",\n    \"        linked_list.insert_to_front('bc')\\n\",\n    \"        linked_list.delete('a')\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), ['bc', 10])\\n\",\n    \"\\n\",\n    \"        print('Test: delete general case with no matches')\\n\",\n    \"        linked_list.delete('aa')\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), ['bc', 10])\\n\",\n    \"\\n\",\n    \"        print('Success: test_delete\\\\n')\\n\",\n    \"\\n\",\n    \"    def test_len(self):\\n\",\n    \"        print('Test: len on an empty list')\\n\",\n    \"        linked_list = LinkedList(None)\\n\",\n    \"        self.assertEqual(len(linked_list), 0)\\n\",\n    \"\\n\",\n    \"        print('Test: len general case')\\n\",\n    \"        head = Node(10)\\n\",\n    \"        linked_list = LinkedList(head)\\n\",\n    \"        linked_list.insert_to_front('a')\\n\",\n    \"        linked_list.insert_to_front('bc')\\n\",\n    \"        self.assertEqual(len(linked_list), 3)\\n\",\n    \"\\n\",\n    \"        print('Success: test_len\\\\n')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestLinkedList()\\n\",\n    \"    test.test_insert_to_front()\\n\",\n    \"    test.test_append()\\n\",\n    \"    test.test_find()\\n\",\n    \"    test.test_delete()\\n\",\n    \"    test.test_len()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: insert_to_front on an empty list\\n\",\n      \"Test: insert_to_front on a None\\n\",\n      \"Test: insert_to_front general case\\n\",\n      \"Success: test_insert_to_front\\n\",\n      \"\\n\",\n      \"Test: append on an empty list\\n\",\n      \"Test: append a None\\n\",\n      \"Test: append general case\\n\",\n      \"Success: test_append\\n\",\n      \"\\n\",\n      \"Test: find on an empty list\\n\",\n      \"Test: find a None\\n\",\n      \"Test: find general case with matches\\n\",\n      \"Test: find general case with no matches\\n\",\n      \"Success: test_find\\n\",\n      \"\\n\",\n      \"Test: delete on an empty list\\n\",\n      \"Test: delete a None\\n\",\n      \"Test: delete general case with matches\\n\",\n      \"Test: delete general case with no matches\\n\",\n      \"Success: test_delete\\n\",\n      \"\\n\",\n      \"Test: len on an empty list\\n\",\n      \"Test: len general case\\n\",\n      \"Success: test_len\\n\",\n      \"\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_linked_list.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/linked_list/test_linked_list.py",
    "content": "import unittest\n\n\nclass TestLinkedList(unittest.TestCase):\n\n    def test_insert_to_front(self):\n        print('Test: insert_to_front on an empty list')\n        linked_list = LinkedList(None)\n        linked_list.insert_to_front(10)\n        self.assertEqual(linked_list.get_all_data(), [10])\n\n        print('Test: insert_to_front on a None')\n        linked_list.insert_to_front(None)\n        self.assertEqual(linked_list.get_all_data(), [10])\n\n        print('Test: insert_to_front general case')\n        linked_list.insert_to_front('a')\n        linked_list.insert_to_front('bc')\n        self.assertEqual(linked_list.get_all_data(), ['bc', 'a', 10])\n\n        print('Success: test_insert_to_front\\n')\n\n    def test_append(self):\n        print('Test: append on an empty list')\n        linked_list = LinkedList(None)\n        linked_list.append(10)\n        self.assertEqual(linked_list.get_all_data(), [10])\n\n        print('Test: append a None')\n        linked_list.append(None)\n        self.assertEqual(linked_list.get_all_data(), [10])\n\n        print('Test: append general case')\n        linked_list.append('a')\n        linked_list.append('bc')\n        self.assertEqual(linked_list.get_all_data(), [10, 'a', 'bc'])\n\n        print('Success: test_append\\n')\n\n    def test_find(self):\n        print('Test: find on an empty list')\n        linked_list = LinkedList(None)\n        node = linked_list.find('a')\n        self.assertEqual(node, None)\n\n        print('Test: find a None')\n        head = Node(10)\n        linked_list = LinkedList(head)\n        node = linked_list.find(None)\n        self.assertEqual(node, None)\n\n        print('Test: find general case with matches')\n        head = Node(10)\n        linked_list = LinkedList(head)\n        linked_list.insert_to_front('a')\n        linked_list.insert_to_front('bc')\n        node = linked_list.find('a')\n        self.assertEqual(str(node), 'a')\n\n        print('Test: find general case with no matches')\n        node = linked_list.find('aaa')\n        self.assertEqual(node, None)\n\n        print('Success: test_find\\n')\n\n    def test_delete(self):\n        print('Test: delete on an empty list')\n        linked_list = LinkedList(None)\n        linked_list.delete('a')\n        self.assertEqual(linked_list.get_all_data(), [])\n\n        print('Test: delete a None')\n        head = Node(10)\n        linked_list = LinkedList(head)\n        linked_list.delete(None)\n        self.assertEqual(linked_list.get_all_data(), [10])\n\n        print('Test: delete general case with matches')\n        head = Node(10)\n        linked_list = LinkedList(head)\n        linked_list.insert_to_front('a')\n        linked_list.insert_to_front('bc')\n        linked_list.delete('a')\n        self.assertEqual(linked_list.get_all_data(), ['bc', 10])\n\n        print('Test: delete general case with no matches')\n        linked_list.delete('aa')\n        self.assertEqual(linked_list.get_all_data(), ['bc', 10])\n\n        print('Success: test_delete\\n')\n\n    def test_len(self):\n        print('Test: len on an empty list')\n        linked_list = LinkedList(None)\n        self.assertEqual(len(linked_list), 0)\n\n        print('Test: len general case')\n        head = Node(10)\n        linked_list = LinkedList(head)\n        linked_list.insert_to_front('a')\n        linked_list.insert_to_front('bc')\n        self.assertEqual(len(linked_list), 3)\n\n        print('Success: test_len\\n')\n\n\ndef main():\n    test = TestLinkedList()\n    test.test_insert_to_front()\n    test.test_append()\n    test.test_find()\n    test.test_delete()\n    test.test_len()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "linked_lists/palindrome/__init__.py",
    "content": ""
  },
  {
    "path": "linked_lists/palindrome/palindrome_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine if a linked list is a palindrome.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a non-circular, singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* Is a single character or number a palindrome?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume we already have a linked list class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we use additional data structures?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"* Empty list -> False\\n\",\n    \"* Single element list -> False\\n\",\n    \"* Two or more element list, not a palindrome -> False\\n\",\n    \"* General case: Palindrome with even length -> True\\n\",\n    \"* General case: Palindrome with odd length -> True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/palindrome/palindrome_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../linked_list/linked_list.py\\n\",\n    \"%load ../linked_list/linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyLinkedList(LinkedList):\\n\",\n    \"\\n\",\n    \"    def is_palindrome(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_palindrome.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPalindrome(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_palindrome(self):\\n\",\n    \"        print('Test: Empty list')\\n\",\n    \"        linked_list = MyLinkedList()\\n\",\n    \"        self.assertEqual(linked_list.is_palindrome(), False)\\n\",\n    \"\\n\",\n    \"        print('Test: Single element list')\\n\",\n    \"        head = Node(1)\\n\",\n    \"        linked_list = MyLinkedList(head)\\n\",\n    \"        self.assertEqual(linked_list.is_palindrome(), False)\\n\",\n    \"\\n\",\n    \"        print('Test: Two element list, not a palindrome')\\n\",\n    \"        linked_list.append(2)\\n\",\n    \"        self.assertEqual(linked_list.is_palindrome(), False)\\n\",\n    \"\\n\",\n    \"        print('Test: General case: Palindrome with even length')\\n\",\n    \"        head = Node('a')\\n\",\n    \"        linked_list = MyLinkedList(head)\\n\",\n    \"        linked_list.append('b')\\n\",\n    \"        linked_list.append('b')\\n\",\n    \"        linked_list.append('a')\\n\",\n    \"        self.assertEqual(linked_list.is_palindrome(), True)\\n\",\n    \"\\n\",\n    \"        print('Test: General case: Palindrome with odd length')\\n\",\n    \"        head = Node(1)\\n\",\n    \"        linked_list = MyLinkedList(head)\\n\",\n    \"        linked_list.append(2)\\n\",\n    \"        linked_list.append(3)\\n\",\n    \"        linked_list.append(2)\\n\",\n    \"        linked_list.append(1)\\n\",\n    \"        self.assertEqual(linked_list.is_palindrome(), True)\\n\",\n    \"\\n\",\n    \"        print('Success: test_palindrome')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPalindrome()\\n\",\n    \"    test.test_palindrome()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/palindrome/palindrome_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/palindrome/palindrome_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine if a linked list is a palindrome.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a non-circular, singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* Is a single character or number a palindrome?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume we already have a linked list class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we use additional data structures?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"* Empty list -> False\\n\",\n    \"* Single element list -> False\\n\",\n    \"* Two or more element list, not a palindrome -> False\\n\",\n    \"* General case: Palindrome with even length -> True\\n\",\n    \"* General case: Palindrome with odd length -> True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Reverse the linked list\\n\",\n    \"    * Iterate through the current linked list\\n\",\n    \"        * Insert to front the current node into a new linked list\\n\",\n    \"* Compare the reversed list with the original list\\n\",\n    \"    * Only need to compare the first half\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\\n\",\n    \"\\n\",\n    \"Note:\\n\",\n    \"* We could also do this iteratively, using a stack to effectively reverse the first half of the string.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../linked_list/linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from __future__ import division\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class MyLinkedList(LinkedList):\\n\",\n    \"\\n\",\n    \"    def is_palindrome(self):\\n\",\n    \"        if self.head is None or self.head.next is None:\\n\",\n    \"            return False\\n\",\n    \"        curr = self.head\\n\",\n    \"        reversed_list = MyLinkedList()\\n\",\n    \"        length = 0\\n\",\n    \"\\n\",\n    \"        # Reverse the linked list\\n\",\n    \"        while curr is not None:\\n\",\n    \"            reversed_list.insert_to_front(curr.data)\\n\",\n    \"            length += 1\\n\",\n    \"            curr = curr.next\\n\",\n    \"\\n\",\n    \"        # Compare the reversed list with the original list\\n\",\n    \"        # Only need to compare the first half\\n\",\n    \"        iterations = length // 2\\n\",\n    \"        curr = self.head\\n\",\n    \"        curr_reversed = reversed_list.head\\n\",\n    \"        for _ in range(iterations):\\n\",\n    \"            if curr.data != curr_reversed.data:\\n\",\n    \"                return False\\n\",\n    \"            curr = curr.next\\n\",\n    \"            curr_reversed = curr_reversed.next\\n\",\n    \"        return True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_palindrome.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_palindrome.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPalindrome(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_palindrome(self):\\n\",\n    \"        print('Test: Empty list')\\n\",\n    \"        linked_list = MyLinkedList()\\n\",\n    \"        self.assertEqual(linked_list.is_palindrome(), False)\\n\",\n    \"\\n\",\n    \"        print('Test: Single element list')\\n\",\n    \"        head = Node(1)\\n\",\n    \"        linked_list = MyLinkedList(head)\\n\",\n    \"        self.assertEqual(linked_list.is_palindrome(), False)\\n\",\n    \"\\n\",\n    \"        print('Test: Two element list, not a palindrome')\\n\",\n    \"        linked_list.append(2)\\n\",\n    \"        self.assertEqual(linked_list.is_palindrome(), False)\\n\",\n    \"\\n\",\n    \"        print('Test: General case: Palindrome with even length')\\n\",\n    \"        head = Node('a')\\n\",\n    \"        linked_list = MyLinkedList(head)\\n\",\n    \"        linked_list.append('b')\\n\",\n    \"        linked_list.append('b')\\n\",\n    \"        linked_list.append('a')\\n\",\n    \"        self.assertEqual(linked_list.is_palindrome(), True)\\n\",\n    \"\\n\",\n    \"        print('Test: General case: Palindrome with odd length')\\n\",\n    \"        head = Node(1)\\n\",\n    \"        linked_list = MyLinkedList(head)\\n\",\n    \"        linked_list.append(2)\\n\",\n    \"        linked_list.append(3)\\n\",\n    \"        linked_list.append(2)\\n\",\n    \"        linked_list.append(1)\\n\",\n    \"        self.assertEqual(linked_list.is_palindrome(), True)\\n\",\n    \"\\n\",\n    \"        print('Success: test_palindrome')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPalindrome()\\n\",\n    \"    test.test_palindrome()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Empty list\\n\",\n      \"Test: Single element list\\n\",\n      \"Test: Two element list, not a palindrome\\n\",\n      \"Test: General case: Palindrome with even length\\n\",\n      \"Test: General case: Palindrome with odd length\\n\",\n      \"Success: test_palindrome\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_palindrome.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/palindrome/test_palindrome.py",
    "content": "import unittest\n\n\nclass TestPalindrome(unittest.TestCase):\n\n    def test_palindrome(self):\n        print('Test: Empty list')\n        linked_list = MyLinkedList()\n        self.assertEqual(linked_list.is_palindrome(), False)\n\n        print('Test: Single element list')\n        head = Node(1)\n        linked_list = MyLinkedList(head)\n        self.assertEqual(linked_list.is_palindrome(), False)\n\n        print('Test: Two element list, not a palindrome')\n        linked_list.append(2)\n        self.assertEqual(linked_list.is_palindrome(), False)\n\n        print('Test: General case: Palindrome with even length')\n        head = Node('a')\n        linked_list = MyLinkedList(head)\n        linked_list.append('b')\n        linked_list.append('b')\n        linked_list.append('a')\n        self.assertEqual(linked_list.is_palindrome(), True)\n\n        print('Test: General case: Palindrome with odd length')\n        head = Node(1)\n        linked_list = MyLinkedList(head)\n        linked_list.append(2)\n        linked_list.append(3)\n        linked_list.append(2)\n        linked_list.append(1)\n        self.assertEqual(linked_list.is_palindrome(), True)\n\n        print('Success: test_palindrome')\n\n\ndef main():\n    test = TestPalindrome()\n    test.test_palindrome()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "linked_lists/partition/__init__.py",
    "content": ""
  },
  {
    "path": "linked_lists/partition/partition_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Partition a linked list around a value x, such that all nodes less than x come before all nodes greater than or equal to x.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a non-circular, singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we expect the function to return a new list?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input x is valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a linked list class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we create additional data structures?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Empty list -> []\\n\",\n    \"* One element list -> [element]\\n\",\n    \"* Left linked list is empty\\n\",\n    \"* Right linked list is empty\\n\",\n    \"* General case\\n\",\n    \"    * Partition = 10\\n\",\n    \"    * Input:  4, 3, 7, 8, 10, 1, 10, 12\\n\",\n    \"    * Output: 4, 3, 7, 8, 1, 10, 10, 12\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/partition/partition_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../linked_list/linked_list.py\\n\",\n    \"%load ../linked_list/linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyLinkedList(LinkedList):\\n\",\n    \"\\n\",\n    \"    def partition(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_partition.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPartition(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_partition(self):\\n\",\n    \"        print('Test: Empty list')\\n\",\n    \"        linked_list = MyLinkedList(None)\\n\",\n    \"        linked_list.partition(10)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [])\\n\",\n    \"\\n\",\n    \"        print('Test: One element list, left list empty')\\n\",\n    \"        linked_list = MyLinkedList(Node(5))\\n\",\n    \"        linked_list.partition(0)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [5])\\n\",\n    \"\\n\",\n    \"        print('Test: Right list is empty')\\n\",\n    \"        linked_list = MyLinkedList(Node(5))\\n\",\n    \"        linked_list.partition(10)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [5])\\n\",\n    \"\\n\",\n    \"        print('Test: General case')\\n\",\n    \"        # Partition = 10\\n\",\n    \"        # Input: 4, 3, 13, 8, 10, 1, 14, 10, 12\\n\",\n    \"        # Output: 4, 3, 8, 1, 10, 10, 13, 14, 12\\n\",\n    \"        linked_list = MyLinkedList(Node(12))\\n\",\n    \"        linked_list.insert_to_front(10)\\n\",\n    \"        linked_list.insert_to_front(14)\\n\",\n    \"        linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.insert_to_front(10)\\n\",\n    \"        linked_list.insert_to_front(8)\\n\",\n    \"        linked_list.insert_to_front(13)\\n\",\n    \"        linked_list.insert_to_front(3)\\n\",\n    \"        linked_list.insert_to_front(4)\\n\",\n    \"        partitioned_list = linked_list.partition(10)\\n\",\n    \"        self.assertEqual(partitioned_list.get_all_data(),\\n\",\n    \"                     [4, 3, 8, 1, 10, 10, 13, 14, 12])\\n\",\n    \"\\n\",\n    \"        print('Success: test_partition')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPartition()\\n\",\n    \"    test.test_partition()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/partition/partition_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/partition/partition_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Partition a linked list around a value x, such that all nodes less than x come before all nodes greater than or equal to x.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a non-circular, singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we expect the function to return a new list?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input x is valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a linked list class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we create additional data structures?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Empty list -> []\\n\",\n    \"* One element list -> [element]\\n\",\n    \"* Left linked list is empty\\n\",\n    \"* Right linked list is empty\\n\",\n    \"* General case\\n\",\n    \"    * Partition = 10\\n\",\n    \"    * Input: 4, 3, 13, 8, 10, 1, 10, 12\\n\",\n    \"    * Output: 4, 3, 8, 1, 10, 10, 13, 12\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Create left and right linked lists\\n\",\n    \"* For each element in the list\\n\",\n    \"    * If elem < x, append to the left list\\n\",\n    \"    * else, append to the right list\\n\",\n    \"* Merge left and right lists\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../linked_list/linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyLinkedList(LinkedList):\\n\",\n    \"\\n\",\n    \"    def partition(self, data):\\n\",\n    \"        if self.head is None:\\n\",\n    \"            return\\n\",\n    \"        left = MyLinkedList(None)\\n\",\n    \"        right = MyLinkedList(None)\\n\",\n    \"        curr = self.head\\n\",\n    \"\\n\",\n    \"        # Build the left and right lists\\n\",\n    \"        while curr is not None:\\n\",\n    \"            if curr.data < data:\\n\",\n    \"                left.append(curr.data)\\n\",\n    \"            elif curr.data == data:\\n\",\n    \"                right.insert_to_front(curr.data)\\n\",\n    \"            else:\\n\",\n    \"                right.append(curr.data)\\n\",\n    \"            curr = curr.next\\n\",\n    \"        curr_left = left.head\\n\",\n    \"        if curr_left is None:\\n\",\n    \"            return right\\n\",\n    \"        else:\\n\",\n    \"            # Merge the two lists\\n\",\n    \"            while curr_left.next is not None:\\n\",\n    \"                curr_left = curr_left.next\\n\",\n    \"            curr_left.next = right.head\\n\",\n    \"            return left\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_partition.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_partition.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPartition(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_partition(self):\\n\",\n    \"        print('Test: Empty list')\\n\",\n    \"        linked_list = MyLinkedList(None)\\n\",\n    \"        linked_list.partition(10)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [])\\n\",\n    \"\\n\",\n    \"        print('Test: One element list, left list empty')\\n\",\n    \"        linked_list = MyLinkedList(Node(5))\\n\",\n    \"        linked_list.partition(0)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [5])\\n\",\n    \"\\n\",\n    \"        print('Test: Right list is empty')\\n\",\n    \"        linked_list = MyLinkedList(Node(5))\\n\",\n    \"        linked_list.partition(10)\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [5])\\n\",\n    \"\\n\",\n    \"        print('Test: General case')\\n\",\n    \"        # Partition = 10\\n\",\n    \"        # Input: 4, 3, 13, 8, 10, 1, 14, 10, 12\\n\",\n    \"        # Output: 4, 3, 8, 1, 10, 10, 13, 14, 12\\n\",\n    \"        linked_list = MyLinkedList(Node(12))\\n\",\n    \"        linked_list.insert_to_front(10)\\n\",\n    \"        linked_list.insert_to_front(14)\\n\",\n    \"        linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.insert_to_front(10)\\n\",\n    \"        linked_list.insert_to_front(8)\\n\",\n    \"        linked_list.insert_to_front(13)\\n\",\n    \"        linked_list.insert_to_front(3)\\n\",\n    \"        linked_list.insert_to_front(4)\\n\",\n    \"        partitioned_list = linked_list.partition(10)\\n\",\n    \"        self.assertEqual(partitioned_list.get_all_data(),\\n\",\n    \"                     [4, 3, 8, 1, 10, 10, 13, 14, 12])\\n\",\n    \"\\n\",\n    \"        print('Success: test_partition')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPartition()\\n\",\n    \"    test.test_partition()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Empty list\\n\",\n      \"Test: One element list, left list empty\\n\",\n      \"Test: Right list is empty\\n\",\n      \"Test: General case\\n\",\n      \"Success: test_partition\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"run -i test_partition.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/partition/test_partition.py",
    "content": "import unittest\n\n\nclass TestPartition(unittest.TestCase):\n\n    def test_partition(self):\n        print('Test: Empty list')\n        linked_list = MyLinkedList(None)\n        linked_list.partition(10)\n        self.assertEqual(linked_list.get_all_data(), [])\n\n        print('Test: One element list, left list empty')\n        linked_list = MyLinkedList(Node(5))\n        linked_list.partition(0)\n        self.assertEqual(linked_list.get_all_data(), [5])\n\n        print('Test: Right list is empty')\n        linked_list = MyLinkedList(Node(5))\n        linked_list.partition(10)\n        self.assertEqual(linked_list.get_all_data(), [5])\n\n        print('Test: General case')\n        # Partition = 10\n        # Input: 4, 3, 13, 8, 10, 1, 14, 10, 12\n        # Output: 4, 3, 8, 1, 10, 10, 13, 14, 12\n        linked_list = MyLinkedList(Node(12))\n        linked_list.insert_to_front(10)\n        linked_list.insert_to_front(14)\n        linked_list.insert_to_front(1)\n        linked_list.insert_to_front(10)\n        linked_list.insert_to_front(8)\n        linked_list.insert_to_front(13)\n        linked_list.insert_to_front(3)\n        linked_list.insert_to_front(4)\n        partitioned_list = linked_list.partition(10)\n        self.assertEqual(partitioned_list.get_all_data(),\n                     [4, 3, 8, 1, 10, 10, 13, 14, 12])\n\n        print('Success: test_partition')\n\n\ndef main():\n    test = TestPartition()\n    test.test_partition()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "linked_lists/remove_duplicates/__init__.py",
    "content": ""
  },
  {
    "path": "linked_lists/remove_duplicates/remove_duplicates_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Remove duplicates from a linked list.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a non-circular, singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* Can you insert None values in the list?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume we already have a linked list class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we use additional data structures?\\n\",\n    \"    * Implement both solutions\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Empty linked list -> []\\n\",\n    \"* One element linked list -> [element]\\n\",\n    \"* General case with no duplicates\\n\",\n    \"* General case with duplicates\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/remove_duplicates/remove_duplicates_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../linked_list/linked_list.py\\n\",\n    \"%load ../linked_list/linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyLinkedList(LinkedList):\\n\",\n    \"\\n\",\n    \"    def remove_dupes(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_remove_duplicates.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestRemoveDupes(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_remove_dupes(self, linked_list):\\n\",\n    \"        print('Test: Empty list')\\n\",\n    \"        linked_list.remove_dupes()\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [])\\n\",\n    \"\\n\",\n    \"        print('Test: One element list')\\n\",\n    \"        linked_list.insert_to_front(2)\\n\",\n    \"        linked_list.remove_dupes()\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [2])\\n\",\n    \"\\n\",\n    \"        print('Test: General case, duplicates')\\n\",\n    \"        linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.insert_to_front(3)\\n\",\n    \"        linked_list.insert_to_front(2)\\n\",\n    \"        linked_list.insert_to_front(3)\\n\",\n    \"        linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.remove_dupes()\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [1, 3, 2])\\n\",\n    \"\\n\",\n    \"        print('Test: General case, no duplicates')\\n\",\n    \"        linked_list.remove_dupes()\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [1, 3, 2])\\n\",\n    \"\\n\",\n    \"        print('Success: test_remove_dupes\\\\n')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestRemoveDupes()\\n\",\n    \"    linked_list = MyLinkedList(None)\\n\",\n    \"    test.test_remove_dupes(linked_list)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/linked_lists/remove_duplicates/remove_duplicates_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/remove_duplicates/remove_duplicates_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Remove duplicates from a linked list.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm: Hash Map Lookup](#Algorithm:-Hash-Map-Lookup)\\n\",\n    \"* [Algorithm: In-Place](#Algorithm:-In-Place)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a non-circular, singly linked list?\\n\",\n    \"    * Yes\\n\",\n    \"* Can you insert None values in the list?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume we already have a linked list class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we use additional data structures?\\n\",\n    \"    * Implement both solutions\\n\",\n    \"* Can we assume this fits in memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Empty linked list -> []\\n\",\n    \"* One element linked list -> [element]\\n\",\n    \"* General case with no duplicates\\n\",\n    \"* General case with duplicates\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm: Hash Map Lookup\\n\",\n    \"\\n\",\n    \"Loop through each node\\n\",\n    \"\\n\",\n    \"* For each node\\n\",\n    \"    * If the node's value is in the hash map\\n\",\n    \"        * Delete the node\\n\",\n    \"    * Else\\n\",\n    \"        * Add node's value to the hash map\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm: In-Place\\n\",\n    \"\\n\",\n    \"* For each node\\n\",\n    \"    * Compare node with every other node\\n\",\n    \"        * Delete nodes that match current node\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n^2)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"Note:\\n\",\n    \"* We'll need to use a 'runner' to check every other node and compare it to the current node\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../linked_list/linked_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyLinkedList(LinkedList):\\n\",\n    \"\\n\",\n    \"    def remove_dupes(self):\\n\",\n    \"        if self.head is None:\\n\",\n    \"            return\\n\",\n    \"        node = self.head\\n\",\n    \"        seen_data = set()\\n\",\n    \"        while node is not None:\\n\",\n    \"            if node.data not in seen_data:\\n\",\n    \"                seen_data.add(node.data)\\n\",\n    \"                prev = node\\n\",\n    \"                node = node.next\\n\",\n    \"            else:\\n\",\n    \"                prev.next = node.next\\n\",\n    \"                node = node.next\\n\",\n    \"\\n\",\n    \"    def remove_dupes_single_pointer(self):\\n\",\n    \"        if self.head is None:\\n\",\n    \"            return\\n\",\n    \"        node = self.head\\n\",\n    \"        seen_data = set({node.data})\\n\",\n    \"        while node.next is not None:\\n\",\n    \"            if node.next.data in seen_data:\\n\",\n    \"                node.next = node.next.next\\n\",\n    \"            else:\\n\",\n    \"                seen_data.add(node.next.data)\\n\",\n    \"                node = node.next\\n\",\n    \"\\n\",\n    \"    def remove_dupes_in_place(self):\\n\",\n    \"        curr = self.head\\n\",\n    \"        while curr is not None:\\n\",\n    \"            runner = curr\\n\",\n    \"            while runner.next is not None:\\n\",\n    \"                if runner.next.data == curr.data:\\n\",\n    \"                    runner.next = runner.next.next\\n\",\n    \"                else:\\n\",\n    \"                    runner = runner.next\\n\",\n    \"            curr = curr.next\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_remove_duplicates.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_remove_duplicates.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestRemoveDupes(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_remove_dupes(self, linked_list):\\n\",\n    \"        print('Test: Empty list')\\n\",\n    \"        linked_list.remove_dupes()\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [])\\n\",\n    \"\\n\",\n    \"        print('Test: One element list')\\n\",\n    \"        linked_list.insert_to_front(2)\\n\",\n    \"        linked_list.remove_dupes()\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [2])\\n\",\n    \"\\n\",\n    \"        print('Test: General case, duplicates')\\n\",\n    \"        linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.insert_to_front(3)\\n\",\n    \"        linked_list.insert_to_front(2)\\n\",\n    \"        linked_list.insert_to_front(3)\\n\",\n    \"        linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.insert_to_front(1)\\n\",\n    \"        linked_list.remove_dupes()\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [1, 3, 2])\\n\",\n    \"\\n\",\n    \"        print('Test: General case, no duplicates')\\n\",\n    \"        linked_list.remove_dupes()\\n\",\n    \"        self.assertEqual(linked_list.get_all_data(), [1, 3, 2])\\n\",\n    \"\\n\",\n    \"        print('Success: test_remove_dupes\\\\n')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestRemoveDupes()\\n\",\n    \"    linked_list = MyLinkedList(None)\\n\",\n    \"    test.test_remove_dupes(linked_list)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Empty list\\n\",\n      \"Test: One element list\\n\",\n      \"Test: General case, duplicates\\n\",\n      \"Test: General case, no duplicates\\n\",\n      \"Success: test_remove_dupes\\n\",\n      \"\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"run -i test_remove_duplicates.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "linked_lists/remove_duplicates/test_remove_duplicates.py",
    "content": "import unittest\n\n\nclass TestRemoveDupes(unittest.TestCase):\n\n    def test_remove_dupes(self, linked_list):\n        print('Test: Empty list')\n        linked_list.remove_dupes()\n        self.assertEqual(linked_list.get_all_data(), [])\n\n        print('Test: One element list')\n        linked_list.insert_to_front(2)\n        linked_list.remove_dupes()\n        self.assertEqual(linked_list.get_all_data(), [2])\n\n        print('Test: General case, duplicates')\n        linked_list.insert_to_front(1)\n        linked_list.insert_to_front(1)\n        linked_list.insert_to_front(3)\n        linked_list.insert_to_front(2)\n        linked_list.insert_to_front(3)\n        linked_list.insert_to_front(1)\n        linked_list.insert_to_front(1)\n        linked_list.remove_dupes()\n        self.assertEqual(linked_list.get_all_data(), [1, 3, 2])\n\n        print('Test: General case, no duplicates')\n        linked_list.remove_dupes()\n        self.assertEqual(linked_list.get_all_data(), [1, 3, 2])\n\n        print('Success: test_remove_dupes\\n')\n\n\ndef main():\n    test = TestRemoveDupes()\n    linked_list = MyLinkedList(None)\n    test.test_remove_dupes(linked_list)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "math_probability/add_digits/__init__.py",
    "content": ""
  },
  {
    "path": "math_probability/add_digits/add_digits_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given an int, repeatedly add its digits until the result is one digit.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume num is not negative?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* negative input -> ValueError\\n\",\n    \"* 9 -> 9\\n\",\n    \"* 138 -> 3\\n\",\n    \"* 65536 -> 7\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def add_digits(self, val):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_add_digits.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestAddDigits(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_add_digits(self, func):\\n\",\n    \"        self.assertRaises(TypeError, func, None)\\n\",\n    \"        self.assertRaises(ValueError, func, -1)\\n\",\n    \"        self.assertEqual(func(0), 0)\\n\",\n    \"        self.assertEqual(func(9), 9)\\n\",\n    \"        self.assertEqual(func(138), 3)\\n\",\n    \"        self.assertEqual(func(65536), 7) \\n\",\n    \"        print('Success: test_add_digits')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestAddDigits()\\n\",\n    \"    solution = Solution()\\n\",\n    \"    test.test_add_digits(solution.add_digits)\\n\",\n    \"    try:\\n\",\n    \"        test.test_add_digits(solution.add_digits_optimized)\\n\",\n    \"    except AttributeError:\\n\",\n    \"        # Alternate solutions are only defined\\n\",\n    \"        # in the solutions file\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "math_probability/add_digits/add_digits_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given an int, repeatedly add its digits until the result is one digit.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume num is not negative?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* negative input -> ValueError\\n\",\n    \"* 9 -> 9\\n\",\n    \"* 138 -> 3\\n\",\n    \"* 65536 -> 7\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"The naive solution simply isolates each digit with with modulo and integer division.  We'll add each isolated digit to  a list and sum the values.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"138 % 10 = 8 -> isolated\\n\",\n    \"138 // 10 = 13\\n\",\n    \"13 % 10 = 3 -> isolated\\n\",\n    \"13 // 10 = 1\\n\",\n    \"1 % 10 = 1 -> isolated\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"A more optimal solution exists, by recognizing this is a digital root.  See the [Wikipedia article](https://en.wikipedia.org/wiki/Digital_root) for more information.\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def add_digits(self, num):\\n\",\n    \"        if num is None:\\n\",\n    \"            raise TypeError('num cannot be None')\\n\",\n    \"        if num < 0:\\n\",\n    \"            raise ValueError('num cannot be negative')\\n\",\n    \"        digits = []\\n\",\n    \"        while num != 0:\\n\",\n    \"            digits.append(num % 10)\\n\",\n    \"            num //= 10\\n\",\n    \"        digits_sum = sum(digits)\\n\",\n    \"        if digits_sum >= 10:\\n\",\n    \"            return self.add_digits(digits_sum)\\n\",\n    \"        else:\\n\",\n    \"            return digits_sum\\n\",\n    \"\\n\",\n    \"    def add_digits_optimized(self, num):\\n\",\n    \"        if num is None:\\n\",\n    \"            raise TypeError('num cannot be None')\\n\",\n    \"        if num < 0:\\n\",\n    \"            raise ValueError('num cannot be negative')\\n\",\n    \"        if num == 0:\\n\",\n    \"            return 0\\n\",\n    \"        elif num % 9 == 0:\\n\",\n    \"            return 9\\n\",\n    \"        else:\\n\",\n    \"            return num % 9\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_add_digits.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_add_digits.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestAddDigits(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_add_digits(self, func):\\n\",\n    \"        self.assertRaises(TypeError, func, None)\\n\",\n    \"        self.assertRaises(ValueError, func, -1)\\n\",\n    \"        self.assertEqual(func(0), 0)\\n\",\n    \"        self.assertEqual(func(9), 9)\\n\",\n    \"        self.assertEqual(func(138), 3)\\n\",\n    \"        self.assertEqual(func(65536), 7) \\n\",\n    \"        print('Success: test_add_digits')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestAddDigits()\\n\",\n    \"    solution = Solution()\\n\",\n    \"    test.test_add_digits(solution.add_digits)\\n\",\n    \"    try:\\n\",\n    \"        test.test_add_digits(solution.add_digits_optimized)\\n\",\n    \"    except NameError:\\n\",\n    \"        # Alternate solutions are only defined\\n\",\n    \"        # in the solutions file\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_add_digits\\n\",\n      \"Success: test_add_digits\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_add_digits.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "math_probability/add_digits/test_add_digits.py",
    "content": "import unittest\n\n\nclass TestAddDigits(unittest.TestCase):\n\n    def test_add_digits(self, func):\n        self.assertRaises(TypeError, func, None)\n        self.assertRaises(ValueError, func, -1)\n        self.assertEqual(func(0), 0)\n        self.assertEqual(func(9), 9)\n        self.assertEqual(func(138), 3)\n        self.assertEqual(func(65536), 7) \n        print('Success: test_add_digits')\n\n\ndef main():\n    test = TestAddDigits()\n    solution = Solution()\n    test.test_add_digits(solution.add_digits)\n    try:\n        test.test_add_digits(solution.add_digits_optimized)\n    except NameError:\n        # Alternate solutions are only defined\n        # in the solutions file\n        pass\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "math_probability/check_prime/__init__.py",
    "content": ""
  },
  {
    "path": "math_probability/check_prime/check_prime_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Check if a number is prime.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is it correct that 1 is not considered a prime number?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* Not an int -> Exception\\n\",\n    \"* Less than 2 -> False\\n\",\n    \"* General case\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Math(object):\\n\",\n    \"\\n\",\n    \"    def check_prime(self, num):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_check_prime.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMath(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_check_prime(self):\\n\",\n    \"        math = Math()\\n\",\n    \"        self.assertRaises(TypeError, math.check_prime, None)\\n\",\n    \"        self.assertRaises(TypeError, math.check_prime, 98.6)\\n\",\n    \"        self.assertEqual(math.check_prime(0), False)\\n\",\n    \"        self.assertEqual(math.check_prime(1), False)\\n\",\n    \"        self.assertEqual(math.check_prime(97), True)\\n\",\n    \"        print('Success: test_check_prime')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMath()\\n\",\n    \"    test.test_check_prime()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "math_probability/check_prime/check_prime_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Check if a number is prime.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is it correct that 1 is not considered a prime number?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* Not an int -> Exception\\n\",\n    \"* Less than 2 -> False\\n\",\n    \"* General case\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"For a number to be prime, it must be 2 or greater and cannot be divisible by another number other than itself (and 1).\\n\",\n    \"\\n\",\n    \"We'll check by dividing all numbers from 2 to the input number to determine if the number is prime.\\n\",\n    \"\\n\",\n    \"As an optimization, we can divide from 2 to the square root of the input number.  For each value that divides the input number evenly, there is a complement b where a * b = n.  If a > sqrt(n) then b < sqrt(n) because sqrt(n^2) = n.\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n) where n is the value of the input number\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Sieve of Eratosthenes\\n\",\n    \"\\n\",\n    \"The Sieve of Eratosthenes provides a more efficient way of computing and generating primes.  See the challenge [\\\"Generate a list of primes\\\"]() for more details.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import math\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Math(object):\\n\",\n    \"\\n\",\n    \"    def check_prime(self, num):\\n\",\n    \"        if num is None:\\n\",\n    \"            raise TypeError('num cannot be None')\\n\",\n    \"        if num < 2:\\n\",\n    \"            return False\\n\",\n    \"        for i in range(2, num):\\n\",\n    \"            if num % i == 0:\\n\",\n    \"                return False\\n\",\n    \"        return True\\n\",\n    \"\\n\",\n    \"    def check_prime_optimized(self, num):\\n\",\n    \"        if num is None:\\n\",\n    \"            raise TypeError('num cannot be None')\\n\",\n    \"        if num < 2:\\n\",\n    \"            return False\\n\",\n    \"        for i in range(2, int(math.sqrt(num)+1)):\\n\",\n    \"            if num % i == 0:\\n\",\n    \"                return False\\n\",\n    \"        return True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_check_prime.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_check_prime.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMath(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_check_prime(self):\\n\",\n    \"        math = Math()\\n\",\n    \"        self.assertRaises(TypeError, math.check_prime, None)\\n\",\n    \"        self.assertRaises(TypeError, math.check_prime, 98.6)\\n\",\n    \"        self.assertEqual(math.check_prime(0), False)\\n\",\n    \"        self.assertEqual(math.check_prime(1), False)\\n\",\n    \"        self.assertEqual(math.check_prime(97), True)\\n\",\n    \"        print('Success: test_check_prime')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMath()\\n\",\n    \"    test.test_check_prime()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_check_prime\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_check_prime.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "math_probability/check_prime/test_check_prime.py",
    "content": "import unittest\n\n\nclass TestMath(unittest.TestCase):\n\n    def test_check_prime(self):\n        math = Math()\n        self.assertRaises(TypeError, math.check_prime, None)\n        self.assertRaises(TypeError, math.check_prime, 98.6)\n        self.assertEqual(math.check_prime(0), False)\n        self.assertEqual(math.check_prime(1), False)\n        self.assertEqual(math.check_prime(97), True)\n        print('Success: test_check_prime')\n\n\ndef main():\n    test = TestMath()\n    test.test_check_prime()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "math_probability/generate_primes/__init__.py",
    "content": ""
  },
  {
    "path": "math_probability/generate_primes/check_prime_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Generate a list of primes.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is it correct that 1 is not considered a prime number?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* Not an int -> Exception\\n\",\n    \"* 20 -> [False, False, True, True, False, True, False, True, False, False, False, True, False, True, False, False, False, True, False, True]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class PrimeGenerator(object):\\n\",\n    \"\\n\",\n    \"    def generate_primes(self, max_num):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_generate_primes.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMath(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_generate_primes(self):\\n\",\n    \"        prime_generator = PrimeGenerator()\\n\",\n    \"        self.assertRaises(TypeError, prime_generator.generate_primes, None)\\n\",\n    \"        self.assertRaises(TypeError, prime_generator.generate_primes, 98.6)\\n\",\n    \"        self.assertEqual(prime_generator.generate_primes(20), [False, False, True, \\n\",\n    \"                                                           True, False, True, \\n\",\n    \"                                                           False, True, False, \\n\",\n    \"                                                           False, False, True, \\n\",\n    \"                                                           False, True, False, \\n\",\n    \"                                                           False, False, True, \\n\",\n    \"                                                           False, True])\\n\",\n    \"        print('Success: generate_primes')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMath()\\n\",\n    \"    test.test_generate_primes()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "math_probability/generate_primes/check_prime_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Generate a list of primes.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is it correct that 1 is not considered a prime number?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* Not an int -> Exception\\n\",\n    \"* 20 -> [False, False, True, True, False, True, False, True, False, False, False, True, False, True, False, False, False, True, False, True]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"For a number to be prime, it must be 2 or greater and cannot be divisible by another number other than itself (and 1).\\n\",\n    \"\\n\",\n    \"We'll use the Sieve of Eratosthenes.  All non-prime numbers are divisible by a prime number.\\n\",\n    \"\\n\",\n    \"* Use an array (or bit array, bit vector) to keep track of each integer up to the max\\n\",\n    \"* Start at 2, end at sqrt(max)\\n\",\n    \"    * We can use sqrt(max) instead of max because:\\n\",\n    \"        * For each value that divides the input number evenly, there is a complement b where a * b = n\\n\",\n    \"        * If a > sqrt(n) then b < sqrt(n) because sqrt(n^2) = n\\n\",\n    \"    * \\\"Cross off\\\" all numbers divisible by 2, 3, 5, 7, ... by setting array[index] to False\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n log log n)\\n\",\n    \"* Space: O(n)\\n\",\n    \"\\n\",\n    \"Wikipedia's animation:\\n\",\n    \"\\n\",\n    \"![alt text](https://upload.wikimedia.org/wikipedia/commons/b/b9/Sieve_of_Eratosthenes_animation.gif)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import math\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class PrimeGenerator(object):\\n\",\n    \"\\n\",\n    \"    def generate_primes(self, max_num):\\n\",\n    \"        if max_num is None:\\n\",\n    \"            raise TypeError('max_num cannot be None')\\n\",\n    \"        array = [True] * max_num\\n\",\n    \"        array[0] = False\\n\",\n    \"        array[1] = False\\n\",\n    \"        prime = 2\\n\",\n    \"        while prime <= math.sqrt(max_num):\\n\",\n    \"            self._cross_off(array, prime)\\n\",\n    \"            prime = self._next_prime(array, prime)\\n\",\n    \"        return array\\n\",\n    \"\\n\",\n    \"    def _cross_off(self, array, prime):\\n\",\n    \"        for index in range(prime*prime, len(array), prime):\\n\",\n    \"            # Start with prime*prime because if we have a k*prime\\n\",\n    \"            # where k < prime, this value would have already been\\n\",\n    \"            # previously crossed off\\n\",\n    \"            array[index] = False\\n\",\n    \"\\n\",\n    \"    def _next_prime(self, array, prime):\\n\",\n    \"        next = prime + 1\\n\",\n    \"        while next < len(array) and not array[next]:\\n\",\n    \"            next += 1\\n\",\n    \"        return next\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_generate_primes.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_generate_primes.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMath(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_generate_primes(self):\\n\",\n    \"        prime_generator = PrimeGenerator()\\n\",\n    \"        self.assertRaises(TypeError, prime_generator.generate_primes, None)\\n\",\n    \"        self.assertRaises(TypeError, prime_generator.generate_primes, 98.6)\\n\",\n    \"        self.assertEqual(prime_generator.generate_primes(20), [False, False, True, \\n\",\n    \"                                                           True, False, True, \\n\",\n    \"                                                           False, True, False, \\n\",\n    \"                                                           False, False, True, \\n\",\n    \"                                                           False, True, False, \\n\",\n    \"                                                           False, False, True, \\n\",\n    \"                                                           False, True])\\n\",\n    \"        print('Success: generate_primes')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMath()\\n\",\n    \"    test.test_generate_primes()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: generate_primes\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_generate_primes.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "math_probability/generate_primes/test_generate_primes.py",
    "content": "import unittest\n\n\nclass TestMath(unittest.TestCase):\n\n    def test_generate_primes(self):\n        prime_generator = PrimeGenerator()\n        self.assertRaises(TypeError, prime_generator.generate_primes, None)\n        self.assertRaises(TypeError, prime_generator.generate_primes, 98.6)\n        self.assertEqual(prime_generator.generate_primes(20), [False, False, True, \n                                                           True, False, True, \n                                                           False, True, False, \n                                                           False, False, True, \n                                                           False, True, False, \n                                                           False, False, True, \n                                                           False, True])\n        print('Success: generate_primes')\n\n\ndef main():\n    test = TestMath()\n    test.test_generate_primes()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "math_probability/math_ops/__init__.py",
    "content": ""
  },
  {
    "path": "math_probability/math_ops/math_ops_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Create a class with an insert method to insert an int to a list.  It should also support calculating the max, min, mean, and mode in O(1).\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Is there a range of inputs?\\n\",\n    \"    * 0 <= item <= 100\\n\",\n    \"* Should mean return a float?\\n\",\n    \"    * Yes\\n\",\n    \"* Should the other results return an int?\\n\",\n    \"    * Yes\\n\",\n    \"* If there are multiple modes, what do we return?\\n\",\n    \"    * Any of the modes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* [] -> ValueError\\n\",\n    \"* [5, 2, 7, 9, 9, 2, 9, 4, 3, 3, 2]\\n\",\n    \"    * max: 9\\n\",\n    \"    * min: 2\\n\",\n    \"    * mean: 55\\n\",\n    \"    * mode: 9 or 2\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, upper_limit=100):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def insert(self, val):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_math_ops.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMathOps(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_math_ops(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.insert, None)\\n\",\n    \"        solution.insert(5)\\n\",\n    \"        solution.insert(2)\\n\",\n    \"        solution.insert(7)\\n\",\n    \"        solution.insert(9)\\n\",\n    \"        solution.insert(9)\\n\",\n    \"        solution.insert(2)\\n\",\n    \"        solution.insert(9)\\n\",\n    \"        solution.insert(4)\\n\",\n    \"        solution.insert(3)\\n\",\n    \"        solution.insert(3)\\n\",\n    \"        solution.insert(2)\\n\",\n    \"        self.assertEqual(solution.max, 9)\\n\",\n    \"        self.assertEqual(solution.min, 2)\\n\",\n    \"        self.assertEqual(solution.mean, 5)\\n\",\n    \"        self.assertTrue(solution.mode in (2, 9))\\n\",\n    \"        print('Success: test_math_ops')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMathOps()\\n\",\n    \"    test.test_math_ops()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "math_probability/math_ops/math_ops_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Create a class with an insert method to insert an int to a list.  It should also support calculating the max, min, mean, and mode in O(1).\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Is there a range of inputs?\\n\",\n    \"    * 0 <= item <= 100\\n\",\n    \"* Should mean return a float?\\n\",\n    \"    * Yes\\n\",\n    \"* Should the other results return an int?\\n\",\n    \"    * Yes\\n\",\n    \"* If there are multiple modes, what do we return?\\n\",\n    \"    * Any of the modes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* [] -> ValueError\\n\",\n    \"* [5, 2, 7, 9, 9, 2, 9, 4, 3, 3, 2]\\n\",\n    \"    * max: 9\\n\",\n    \"    * min: 2\\n\",\n    \"    * mean: 55\\n\",\n    \"    * mode: 9 or 2\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* We'll init our max and min to None.  Alternatively, we can init them to -sys.maxsize and sys.maxsize, respectively.\\n\",\n    \"* For mean, we'll keep track of the number of items we have inserted so far, as well as the running sum.\\n\",\n    \"* For mode, we'll keep track of the current mode and an array with the size of the given upper limit\\n\",\n    \"    * Each element in the array will be init to 0\\n\",\n    \"    * Each time we insert, we'll increment the element corresponding to the inserted item's value\\n\",\n    \"* On each insert:\\n\",\n    \"    * Update the max and min\\n\",\n    \"    * Update the mean by calculating running_sum / num_items\\n\",\n    \"    * Update the mode by comparing the mode array's value with the current mode\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1), we are treating the 101 element array as a constant O(1), we could also see this as O(k)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from __future__ import division\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, upper_limit=100):\\n\",\n    \"        self.max = None\\n\",\n    \"        self.min = None\\n\",\n    \"        # Mean\\n\",\n    \"        self.num_items = 0\\n\",\n    \"        self.running_sum = 0\\n\",\n    \"        self.mean = None\\n\",\n    \"        # Mode\\n\",\n    \"        self.array = [0] * (upper_limit + 1)\\n\",\n    \"        self.mode_occurrences = 0\\n\",\n    \"        self.mode = None\\n\",\n    \"\\n\",\n    \"    def insert(self, val):\\n\",\n    \"        if val is None:\\n\",\n    \"            raise TypeError('val cannot be None')\\n\",\n    \"        if self.max is None or val > self.max:\\n\",\n    \"            self.max = val\\n\",\n    \"        if self.min is None or val < self.min:\\n\",\n    \"            self.min = val\\n\",\n    \"        # Calculate the mean\\n\",\n    \"        self.num_items += 1\\n\",\n    \"        self.running_sum += val\\n\",\n    \"        self.mean = self.running_sum / self.num_items\\n\",\n    \"        # Calculate the mode\\n\",\n    \"        self.array[val] += 1\\n\",\n    \"        if self.array[val] > self.mode_occurrences:\\n\",\n    \"            self.mode_occurrences = self.array[val]\\n\",\n    \"            self.mode = val\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_math_ops.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_math_ops.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMathOps(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_math_ops(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.insert, None)\\n\",\n    \"        solution.insert(5)\\n\",\n    \"        solution.insert(2)\\n\",\n    \"        solution.insert(7)\\n\",\n    \"        solution.insert(9)\\n\",\n    \"        solution.insert(9)\\n\",\n    \"        solution.insert(2)\\n\",\n    \"        solution.insert(9)\\n\",\n    \"        solution.insert(4)\\n\",\n    \"        solution.insert(3)\\n\",\n    \"        solution.insert(3)\\n\",\n    \"        solution.insert(2)\\n\",\n    \"        self.assertEqual(solution.max, 9)\\n\",\n    \"        self.assertEqual(solution.min, 2)\\n\",\n    \"        self.assertEqual(solution.mean, 5)\\n\",\n    \"        self.assertTrue(solution.mode in (2, 9))\\n\",\n    \"        print('Success: test_math_ops')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMathOps()\\n\",\n    \"    test.test_math_ops()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_math_ops\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_math_ops.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "math_probability/math_ops/test_math_ops.py",
    "content": "import unittest\n\n\nclass TestMathOps(unittest.TestCase):\n\n    def test_math_ops(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.insert, None)\n        solution.insert(5)\n        solution.insert(2)\n        solution.insert(7)\n        solution.insert(9)\n        solution.insert(9)\n        solution.insert(2)\n        solution.insert(9)\n        solution.insert(4)\n        solution.insert(3)\n        solution.insert(3)\n        solution.insert(2)\n        self.assertEqual(solution.max, 9)\n        self.assertEqual(solution.min, 2)\n        self.assertEqual(solution.mean, 5)\n        self.assertTrue(solution.mode in (2, 9))\n        print('Success: test_math_ops')\n\n\ndef main():\n    test = TestMathOps()\n    test.test_math_ops()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "math_probability/power_two/__init__.py",
    "content": ""
  },
  {
    "path": "math_probability/power_two/power_two_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine if a number is a power of two.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input number an int?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Is the output a boolean?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* 0 -> False\\n\",\n    \"* 1 -> True\\n\",\n    \"* 2 -> True\\n\",\n    \"* 15 -> False\\n\",\n    \"* 16 -> True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def is_power_of_two(self, val):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_is_power_of_two.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_is_power_of_two(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.is_power_of_two, None)\\n\",\n    \"        self.assertEqual(solution.is_power_of_two(0), False)\\n\",\n    \"        self.assertEqual(solution.is_power_of_two(1), True)\\n\",\n    \"        self.assertEqual(solution.is_power_of_two(2), True)\\n\",\n    \"        self.assertEqual(solution.is_power_of_two(15), False)\\n\",\n    \"        self.assertEqual(solution.is_power_of_two(16), True)\\n\",\n    \"        print('Success: test_is_power_of_two')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_is_power_of_two()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "math_probability/power_two/power_two_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine if a number is a power of two.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input number an int?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Is the output a boolean?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* 0 -> False\\n\",\n    \"* 1 -> True\\n\",\n    \"* 2 -> True\\n\",\n    \"* 15 -> False\\n\",\n    \"* 16 -> True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We can use bit manipulation to determine if a number is a power of two.  \\n\",\n    \"\\n\",\n    \"For a number to be a power of two, there must only be one bit that is a `1`.  \\n\",\n    \"\\n\",\n    \"We can use the following bit manipulation trick to determine this:\\n\",\n    \"\\n\",\n    \"`n & (n - 1)`\\n\",\n    \"\\n\",\n    \"Here's an example why:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"0000 1000 = n\\n\",\n    \"0000 0001 = 1\\n\",\n    \"0000 0111 = n-1\\n\",\n    \"\\n\",\n    \"0000 1000 = n\\n\",\n    \"0000 0111 = n-1\\n\",\n    \"0000 0000 = n & n-1, result = 0\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def is_power_of_two(self, n):\\n\",\n    \"        if n is None:\\n\",\n    \"            raise TypeError('n cannot be None')\\n\",\n    \"        if n <= 0:\\n\",\n    \"            return False\\n\",\n    \"        return (n & (n - 1)) == 0\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_is_power_of_two.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_is_power_of_two.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_is_power_of_two(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.is_power_of_two, None)\\n\",\n    \"        self.assertEqual(solution.is_power_of_two(0), False)\\n\",\n    \"        self.assertEqual(solution.is_power_of_two(1), True)\\n\",\n    \"        self.assertEqual(solution.is_power_of_two(2), True)\\n\",\n    \"        self.assertEqual(solution.is_power_of_two(15), False)\\n\",\n    \"        self.assertEqual(solution.is_power_of_two(16), True)\\n\",\n    \"        print('Success: test_is_power_of_two')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_is_power_of_two()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_is_power_of_two\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_is_power_of_two.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "math_probability/power_two/test_is_power_of_two.py",
    "content": "import unittest\n\n\nclass TestSolution(unittest.TestCase):\n\n    def test_is_power_of_two(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.is_power_of_two, None)\n        self.assertEqual(solution.is_power_of_two(0), False)\n        self.assertEqual(solution.is_power_of_two(1), True)\n        self.assertEqual(solution.is_power_of_two(2), True)\n        self.assertEqual(solution.is_power_of_two(15), False)\n        self.assertEqual(solution.is_power_of_two(16), True)\n        print('Success: test_is_power_of_two')\n\n\ndef main():\n    test = TestSolution()\n    test.test_is_power_of_two()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "math_probability/sub_two/__init__.py",
    "content": ""
  },
  {
    "path": "math_probability/sub_two/sub_two_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the difference of two integers without using the + or - sign.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* 7, 5 -> 2\\n\",\n    \"* -5, -7 -> 2\\n\",\n    \"* -5, 7 -> -12\\n\",\n    \"* 5, -7 -> 12\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def sub_two(self, val):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_sub_two.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSubTwo(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_sub_two(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.sub_two, None)\\n\",\n    \"        self.assertEqual(solution.sub_two(7, 5), 2)\\n\",\n    \"        self.assertEqual(solution.sub_two(-5, -7), 2)\\n\",\n    \"        self.assertEqual(solution.sub_two(-5, 7), -12)\\n\",\n    \"        self.assertEqual(solution.sub_two(5, -7), 12)\\n\",\n    \"        print('Success: test_sub_two')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSubTwo()\\n\",\n    \"    test.test_sub_two()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "math_probability/sub_two/sub_two_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the difference of two integers without using the + or - sign.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* 7, 5 -> 2\\n\",\n    \"* -5, -7 -> 2\\n\",\n    \"* -5, 7 -> -12\\n\",\n    \"* 5, -7 -> 12\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll look at the following example, subtracting a and b:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"a 0110 = 6 \\n\",\n    \"b 0101 = 5\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"First, subtract a and b, without worrying about the borrow (0-0=0, 0-1=1, 1-1=0):\\n\",\n    \"\\n\",\n    \"result = a ^ b = 0011\\n\",\n    \"\\n\",\n    \"Next, calculate the borrow (0-1=1).  We'll need to left shift one to prepare for the next iteration when we move to the next most significant bit:\\n\",\n    \"\\n\",\n    \"~a     = 1001\\n\",\n    \" b     = 0101\\n\",\n    \"~a & b = 0001\\n\",\n    \"\\n\",\n    \"borrow = (~a&b) << 1 = 0010\\n\",\n    \"\\n\",\n    \"If the borrow is not zero, we'll need to subtract the borrow from the result.  Recursively call the function, passing in result and borrow.\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(b), where b is the number of bits\\n\",\n    \"* Space: O(b), where b is the number of bits\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def sub_two(self, a, b):\\n\",\n    \"        if a is None or b is None:\\n\",\n    \"            raise TypeError('a or b cannot be None')\\n\",\n    \"        result = a ^ b;\\n\",\n    \"        borrow = (~a & b) << 1\\n\",\n    \"        if borrow != 0:\\n\",\n    \"            return self.sub_two(result, borrow)\\n\",\n    \"        return result;\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_sub_two.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_sub_two.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSubTwo(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_sub_two(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.sub_two, None)\\n\",\n    \"        self.assertEqual(solution.sub_two(7, 5), 2)\\n\",\n    \"        self.assertEqual(solution.sub_two(-5, -7), 2)\\n\",\n    \"        self.assertEqual(solution.sub_two(-5, 7), -12)\\n\",\n    \"        self.assertEqual(solution.sub_two(5, -7), 12)\\n\",\n    \"        print('Success: test_sub_two')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSubTwo()\\n\",\n    \"    test.test_sub_two()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {\n    \"scrolled\": true\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_sub_two\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_sub_two.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "math_probability/sub_two/test_sub_two.py",
    "content": "import unittest\n\n\nclass TestSubTwo(unittest.TestCase):\n\n    def test_sub_two(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.sub_two, None)\n        self.assertEqual(solution.sub_two(7, 5), 2)\n        self.assertEqual(solution.sub_two(-5, -7), 2)\n        self.assertEqual(solution.sub_two(-5, 7), -12)\n        self.assertEqual(solution.sub_two(5, -7), 12)\n        print('Success: test_sub_two')\n\n\ndef main():\n    test = TestSubTwo()\n    test.test_sub_two()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "math_probability/sum_two/__init__.py",
    "content": ""
  },
  {
    "path": "math_probability/sum_two/sum_two_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the sum of two integers without using the + or - sign.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/sum-of-two-integers/) problem page.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def sum_two(self, val):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_sum_two.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSumTwo(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_sum_two(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.sum_two, None)\\n\",\n    \"        self.assertEqual(solution.sum_two(5, 7), 12)\\n\",\n    \"        self.assertEqual(solution.sum_two(-5, -7), -12)\\n\",\n    \"        self.assertEqual(solution.sum_two(5, -7), -2)\\n\",\n    \"        print('Success: test_sum_two')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSumTwo()\\n\",\n    \"    test.test_sum_two()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "math_probability/sum_two/sum_two_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the sum of two integers without using the + or - sign.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* 5, 7 -> 12\\n\",\n    \"* -5, -7 -> -12\\n\",\n    \"* 5, -7 -> -2\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll look at the following example, adding a and b:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"a 0111 \\n\",\n    \"b 0101\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"First, add a and b, without worrying about the carry (0+0=0, 0+1=1, 1+1=0):\\n\",\n    \"\\n\",\n    \"result = a ^ b = 0010\\n\",\n    \"\\n\",\n    \"Next, calculate the carry (1+1=2).  We'll need to left shift one to prepare for the next iteration when we move to the next most significant bit:\\n\",\n    \"\\n\",\n    \"carry = (a&b) << 1 = 1010\\n\",\n    \"\\n\",\n    \"If the carry is not zero, we'll need to add the carry to the result.  Recursively call the function, passing in result and carry.\\n\",\n    \"\\n\",\n    \"Below are the values of a, b, and the carry of a = 7 and b = 5, producing the result of 12.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"a 0111 \\n\",\n    \"b 0101 \\n\",\n    \"----- \\n\",\n    \"c 0101 \\n\",\n    \"a 0010 \\n\",\n    \"b 1010 \\n\",\n    \"----- \\n\",\n    \"c 0010 \\n\",\n    \"a 1000 \\n\",\n    \"b 0100 \\n\",\n    \"----- \\n\",\n    \"c 0000 \\n\",\n    \"a 1100 \\n\",\n    \"b 0000\\n\",\n    \"\\n\",\n    \"c = carry = 0, return the result 1100\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(b), where b is the number of bits\\n\",\n    \"* Space: O(b), where b is the number of bits\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def sum_two(self, a, b):\\n\",\n    \"        if a is None or b is None:\\n\",\n    \"            raise TypeError('a or b cannot be None')\\n\",\n    \"        result = a ^ b;\\n\",\n    \"        carry = (a&b) << 1\\n\",\n    \"        if carry != 0:\\n\",\n    \"            return self.sum_two(result, carry)\\n\",\n    \"        return result;\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_sum_two.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_sum_two.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSumTwo(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_sum_two(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.sum_two, None)\\n\",\n    \"        self.assertEqual(solution.sum_two(5, 7), 12)\\n\",\n    \"        self.assertEqual(solution.sum_two(-5, -7), -12)\\n\",\n    \"        self.assertEqual(solution.sum_two(5, -7), -2)\\n\",\n    \"        print('Success: test_sum_two')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSumTwo()\\n\",\n    \"    test.test_sum_two()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {\n    \"scrolled\": true\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_sum_two\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_sum_two.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "math_probability/sum_two/test_sum_two.py",
    "content": "import unittest\n\n\nclass TestSumTwo(unittest.TestCase):\n\n    def test_sum_two(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.sum_two, None)\n        self.assertEqual(solution.sum_two(5, 7), 12)\n        self.assertEqual(solution.sum_two(-5, -7), -12)\n        self.assertEqual(solution.sum_two(5, -7), -2)\n        print('Success: test_sum_two')\n\n\ndef main():\n    test = TestSumTwo()\n    test.test_sum_two()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/assign_cookies/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/assign_cookies/assign_cookies_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Assign Cookies.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/assign-cookies/) problem page.\\n\",\n    \"\\n\",\n    \"Assume you are an awesome parent and want to give your children some cookies. But, you should give each child at most one cookie. Each child i has a greed factor gi, which is the minimum size of a cookie that the child will be content with; and each cookie j has a size sj. If sj >= gi, we can assign the cookie j to the child i, and the child i will be content. Your goal is to maximize the number of your content children and output the maximum number.\\n\",\n    \"\\n\",\n    \"Note:\\n\",\n    \"You may assume the greed factor is always positive. \\n\",\n    \"You cannot assign more than one cookie to one child.\\n\",\n    \"\\n\",\n    \"Example 1:\\n\",\n    \"Input: [1,2,3], [1,1]\\n\",\n    \"\\n\",\n    \"Output: 1\\n\",\n    \"\\n\",\n    \"Explanation: You have 3 children and 2 cookies. The greed factors of 3 children are 1, 2, 3. \\n\",\n    \"And even though you have 2 cookies, since their size is both 1, you could only make the child whose greed factor is 1 content.\\n\",\n    \"You need to output 1.\\n\",\n    \"Example 2:\\n\",\n    \"Input: [1,2], [1,2,3]\\n\",\n    \"\\n\",\n    \"Output: 2\\n\",\n    \"\\n\",\n    \"Explanation: You have 2 children and 3 cookies. The greed factors of 2 children are 1, 2. \\n\",\n    \"You have 3 cookies and their sizes are big enough to gratify all of the children, \\n\",\n    \"You need to output 2.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are the inputs two list(int), one for greed factor and the other for cookie size?\\n\",\n    \"    * Yes\\n\",\n    \"* Are the inputs are sorted increasing order?\\n\",\n    \"    * No\\n\",\n    \"* Can we change inputs themselves, or do we need to make a copy?\\n\",\n    \"    * You can change them\\n\",\n    \"* Is the output an int?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the greed factor always >= 1?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None input -> TypeError\\n\",\n    \"[1, 2, 3], [1, 1] -> 1\\n\",\n    \"[1, 2], [1, 2, 3] -> 2\\n\",\n    \"[7, 8, 9, 10], [5, 6, 7, 8] -> 2\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def find_content_children(self, g, s):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_assign_cookie.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestAssignCookie(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_assign_cookie(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.find_content_children, None, None)\\n\",\n    \"        self.assertEqual(solution.find_content_children([1, 2, 3], \\n\",\n    \"                                                    [1, 1]), 1)\\n\",\n    \"        self.assertEqual(solution.find_content_children([1, 2], \\n\",\n    \"                                                    [1, 2, 3]), 2)\\n\",\n    \"        self.assertEqual(solution.find_content_children([7, 8, 9, 10], \\n\",\n    \"                                                    [5, 6, 7, 8]), 2)\\n\",\n    \"        print('Success: test_find_content_children')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestAssignCookie()\\n\",\n    \"    test.test_assign_cookie()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/assign_cookies/assign_cookies_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Assign Cookies.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/assign-cookies/) problem page.\\n\",\n    \"\\n\",\n    \"Assume you are an awesome parent and want to give your children some cookies. But, you should give each child at most one cookie. Each child i has a greed factor gi, which is the minimum size of a cookie that the child will be content with; and each cookie j has a size sj. If sj >= gi, we can assign the cookie j to the child i, and the child i will be content. Your goal is to maximize the number of your content children and output the maximum number.\\n\",\n    \"\\n\",\n    \"Note:\\n\",\n    \"You may assume the greed factor is always positive. \\n\",\n    \"You cannot assign more than one cookie to one child.\\n\",\n    \"\\n\",\n    \"Example 1:\\n\",\n    \"Input: [1,2,3], [1,1]\\n\",\n    \"\\n\",\n    \"Output: 1\\n\",\n    \"\\n\",\n    \"Explanation: You have 3 children and 2 cookies. The greed factors of 3 children are 1, 2, 3. \\n\",\n    \"And even though you have 2 cookies, since their size is both 1, you could only make the child whose greed factor is 1 content.\\n\",\n    \"You need to output 1.\\n\",\n    \"Example 2:\\n\",\n    \"Input: [1,2], [1,2,3]\\n\",\n    \"\\n\",\n    \"Output: 2\\n\",\n    \"\\n\",\n    \"Explanation: You have 2 children and 3 cookies. The greed factors of 2 children are 1, 2. \\n\",\n    \"You have 3 cookies and their sizes are big enough to gratify all of the children, \\n\",\n    \"You need to output 2.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are the inputs two list(int), one for greed factor and the other for cookie size?\\n\",\n    \"    * Yes\\n\",\n    \"* Are the inputs are sorted increasing order?\\n\",\n    \"    * No\\n\",\n    \"* Can we change inputs themselves, or do we need to make a copy?\\n\",\n    \"    * You can change them\\n\",\n    \"* Is the output an int?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the greed factor always >= 1?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None input -> TypeError\\n\",\n    \"[1, 2, 3], [1, 1] -> 1\\n\",\n    \"[1, 2], [1, 2, 3] -> 2\\n\",\n    \"[7, 8, 9, 10], [5, 6, 7, 8] -> 2\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Sort the inputs\\n\",\n    \"* We'll keep an index to the current greed factor\\n\",\n    \"* For each cookie\\n\",\n    \"    * Assign it to a child if its size >= the child's greed factor\\n\",\n    \"        * Increment result counter\\n\",\n    \"        * Increment the index to the greed factor\\n\",\n    \"            * Careful of this index going out of bounds\\n\",\n    \"* Return the result counter\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n log n) for the sort\\n\",\n    \"* Space: O(1), assuming the sort is in-place\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def find_content_children(self, greed_indices, cookie_sizes):\\n\",\n    \"        if greed_indices is None or cookie_sizes is None:\\n\",\n    \"            raise TypeError('greed_indices or cookie_sizes cannot be None')\\n\",\n    \"        if not greed_indices or not cookie_sizes:\\n\",\n    \"            return 0\\n\",\n    \"        greed_indices.sort()\\n\",\n    \"        cookie_sizes.sort()\\n\",\n    \"        greed_index = 0\\n\",\n    \"        num_children = 0\\n\",\n    \"        for size in cookie_sizes:\\n\",\n    \"            if greed_index >= len(greed_indices):\\n\",\n    \"                break\\n\",\n    \"            if size >= greed_indices[greed_index]:\\n\",\n    \"                num_children += 1\\n\",\n    \"                greed_index += 1\\n\",\n    \"        return num_children\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_assign_cookie.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_assign_cookie.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestAssignCookie(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_assign_cookie(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.find_content_children, None, None)\\n\",\n    \"        self.assertEqual(solution.find_content_children([1, 2, 3], \\n\",\n    \"                                                    [1, 1]), 1)\\n\",\n    \"        self.assertEqual(solution.find_content_children([1, 2], \\n\",\n    \"                                                    [1, 2, 3]), 2)\\n\",\n    \"        self.assertEqual(solution.find_content_children([7, 8, 9, 10], \\n\",\n    \"                                                    [5, 6, 7, 8]), 2)\\n\",\n    \"        print('Success: test_find_content_children')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestAssignCookie()\\n\",\n    \"    test.test_assign_cookie()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_find_content_children\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_assign_cookie.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/assign_cookies/test_assign_cookie.py",
    "content": "import unittest\n\n\nclass TestAssignCookie(unittest.TestCase):\n\n    def test_assign_cookie(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.find_content_children, None, None)\n        self.assertEqual(solution.find_content_children([1, 2, 3], \n                                                    [1, 1]), 1)\n        self.assertEqual(solution.find_content_children([1, 2], \n                                                    [1, 2, 3]), 2)\n        self.assertEqual(solution.find_content_children([7, 8, 9, 10], \n                                                    [5, 6, 7, 8]), 2)\n        print('Success: test_find_content_children')\n\n\ndef main():\n    test = TestAssignCookie()\n    test.test_assign_cookie()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/busiest_period/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/busiest_period/busiest_period_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given an array of (unix_timestamp, num_people, EventType.ENTER or EventType.EXIT), find the busiest period.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the input array is valid?\\n\",\n    \"    * Check for None\\n\",\n    \"* Can we assume the elements of the input array are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the input sorted by time?\\n\",\n    \"    * No\\n\",\n    \"* Can you have enter and exit elements for the same timestamp?\\n\",\n    \"    * Yes you can, order of enter and exit is not guaranteed\\n\",\n    \"* Could we have multiple enter events (or multiple exit events) for the same timestamp?\\n\",\n    \"    * No\\n\",\n    \"* What is the format of the output?\\n\",\n    \"    * An array of timestamps [t1, t2]\\n\",\n    \"* Can we assume the starting number of people is zero?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* [] -> None\\n\",\n    \"* General case\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"timestamp  num_people  event_type\\n\",\n    \"1          2           EventType.ENTER\\n\",\n    \"3          1           EventType.ENTER\\n\",\n    \"3          2           EventType.EXIT\\n\",\n    \"7          3           EventType.ENTER\\n\",\n    \"8          2           EventType.EXIT\\n\",\n    \"9          2           EventType.EXIT\\n\",\n    \"\\n\",\n    \"result = Period(7, 8)\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"from enum import Enum\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Data(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, timestamp, num_people, event_type):\\n\",\n    \"        self.timestamp = timestamp\\n\",\n    \"        self.num_people = num_people\\n\",\n    \"        self.event_type = event_type\\n\",\n    \"\\n\",\n    \"    def __lt__(self, other):\\n\",\n    \"        return self.timestamp < other.timestamp\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Period(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, start, end):\\n\",\n    \"        self.start = start\\n\",\n    \"        self.end = end\\n\",\n    \"\\n\",\n    \"    def __eq__(self, other):\\n\",\n    \"        return self.start == other.start and self.end == other.end\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return str(self.start) + ', ' + str(self.end)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class EventType(Enum):\\n\",\n    \"\\n\",\n    \"    ENTER = 0\\n\",\n    \"    EXIT = 1\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def find_busiest_period(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_find_busiest_period.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_find_busiest_period(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.find_busiest_period, None)\\n\",\n    \"        self.assertEqual(solution.find_busiest_period([]), None)\\n\",\n    \"        data = [\\n\",\n    \"            Data(3, 2, EventType.EXIT),\\n\",\n    \"            Data(1, 2, EventType.ENTER),\\n\",\n    \"            Data(3, 1, EventType.ENTER),\\n\",\n    \"            Data(7, 3, EventType.ENTER),\\n\",\n    \"            Data(9, 2, EventType.EXIT),\\n\",\n    \"            Data(8, 2, EventType.EXIT),\\n\",\n    \"        ]\\n\",\n    \"        self.assertEqual(solution.find_busiest_period(data), Period(7, 8))\\n\",\n    \"        print('Success: test_find_busiest_period')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_find_busiest_period()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/busiest_period/busiest_period_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given an array of (unix_timestamp, num_people, EventType.ENTER or EventType.EXIT), find the busiest period.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the input array is valid?\\n\",\n    \"    * Check for None\\n\",\n    \"* Can we assume the elements of the input array are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the input sorted by time?\\n\",\n    \"    * No\\n\",\n    \"* Can you have enter and exit elements for the same timestamp?\\n\",\n    \"    * Yes you can, order of enter and exit is not guaranteed\\n\",\n    \"* Could we have multiple enter events (or multiple exit events) for the same timestamp?\\n\",\n    \"    * No\\n\",\n    \"* What is the format of the output?\\n\",\n    \"    * An array of timestamps [t1, t2]\\n\",\n    \"* Can we assume the starting number of people is zero?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* [] -> None\\n\",\n    \"* General case\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"timestamp  num_people  event_type\\n\",\n    \"3          2           EventType.EXIT\\n\",\n    \"1          2           EventType.ENTER\\n\",\n    \"3          1           EventType.ENTER\\n\",\n    \"7          3           EventType.ENTER\\n\",\n    \"9          2           EventType.EXIT\\n\",\n    \"8          2           EventType.EXIT\\n\",\n    \"\\n\",\n    \"result = Period(7, 8)\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Since the input is not sorted, we'll need to sort it first by timestamp, ascending.\\n\",\n    \"\\n\",\n    \"For each interval in the data set:\\n\",\n    \"\\n\",\n    \"* If this is an \\\"enter\\\" event, increment `curr_people`, else, decrement\\n\",\n    \"* Since we can have an \\\"enter\\\" and \\\"exit\\\" event for the same timestamp, we'll need to look ahead one\\n\",\n    \"    * If the next element has the same timestamp, hold off (continue) on updating `max_people` and `max_period`\\n\",\n    \"    * Watch out for indexing out-of-bounds at the end of the array\\n\",\n    \"* Update `max_people` and `max_period`\\n\",\n    \"\\n\",\n    \"Sorted:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"timestamp  num_people  event_type       curr_people  max_people       max_period\\n\",\n    \"1          2           EventType.ENTER  2            2                [1, 3]\\n\",\n    \"3          1           EventType.ENTER  3            2 (not updated)  [1, 3]\\n\",\n    \"3          2           EventType.EXIT   1            2                [3, 7]\\n\",\n    \"7          3           EventType.ENTER  4            4                [7, 8]\\n\",\n    \"8          2           EventType.EXIT   2            4                [7, 8]\\n\",\n    \"9          2           EventType.EXIT   0            4                [7, 8]\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(nlog(n)) for the sort\\n\",\n    \"* Space: O(1), assuming the sort is in-place\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from enum import Enum\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Data(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, timestamp, num_people, event_type):\\n\",\n    \"        self.timestamp = timestamp\\n\",\n    \"        self.num_people = num_people\\n\",\n    \"        self.event_type = event_type\\n\",\n    \"\\n\",\n    \"    def __lt__(self, other):\\n\",\n    \"        return self.timestamp < other.timestamp\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Period(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, start, end):\\n\",\n    \"        self.start = start\\n\",\n    \"        self.end = end\\n\",\n    \"\\n\",\n    \"    def __eq__(self, other):\\n\",\n    \"        return self.start == other.start and self.end == other.end\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return str(self.start) + ', ' + str(self.end)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class EventType(Enum):\\n\",\n    \"\\n\",\n    \"    ENTER = 0\\n\",\n    \"    EXIT = 1\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def find_busiest_period(self, data):\\n\",\n    \"        if data is None:\\n\",\n    \"            raise TypeError('data cannot be None')\\n\",\n    \"        if not data:\\n\",\n    \"            return None\\n\",\n    \"        data.sort()\\n\",\n    \"        max_period = Period(0, 0)\\n\",\n    \"        max_people = 0\\n\",\n    \"        curr_people = 0\\n\",\n    \"        for index, interval in enumerate(data):\\n\",\n    \"            if interval.event_type == EventType.ENTER:\\n\",\n    \"                curr_people += interval.num_people\\n\",\n    \"            elif interval.event_type == EventType.EXIT:\\n\",\n    \"                curr_people -= interval.num_people\\n\",\n    \"            else:\\n\",\n    \"                raise ValueError('Invalid event type')\\n\",\n    \"            if (index < len(data) - 1 and \\n\",\n    \"                    data[index].timestamp == data[index + 1].timestamp):\\n\",\n    \"                continue\\n\",\n    \"            if curr_people > max_people:\\n\",\n    \"                max_people = curr_people\\n\",\n    \"                max_period.start = data[index].timestamp\\n\",\n    \"                if index < len(data) - 1:\\n\",\n    \"                    max_period.end = data[index + 1].timestamp\\n\",\n    \"                else:\\n\",\n    \"                    max_period.end = data[index].timestamp\\n\",\n    \"        return max_period\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_find_busiest_period.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_find_busiest_period.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_find_busiest_period(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.find_busiest_period, None)\\n\",\n    \"        self.assertEqual(solution.find_busiest_period([]), None)\\n\",\n    \"        data = [\\n\",\n    \"            Data(3, 2, EventType.EXIT),\\n\",\n    \"            Data(1, 2, EventType.ENTER),\\n\",\n    \"            Data(3, 1, EventType.ENTER),\\n\",\n    \"            Data(7, 3, EventType.ENTER),\\n\",\n    \"            Data(9, 2, EventType.EXIT),\\n\",\n    \"            Data(8, 2, EventType.EXIT),\\n\",\n    \"        ]\\n\",\n    \"        self.assertEqual(solution.find_busiest_period(data), Period(7, 8))\\n\",\n    \"        print('Success: test_find_busiest_period')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_find_busiest_period()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_find_busiest_period\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_find_busiest_period.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/busiest_period/test_find_busiest_period.py",
    "content": "import unittest\n\n\nclass TestSolution(unittest.TestCase):\n\n    def test_find_busiest_period(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.find_busiest_period, None)\n        self.assertEqual(solution.find_busiest_period([]), None)\n        data = [\n            Data(3, 2, EventType.EXIT),\n            Data(1, 2, EventType.ENTER),\n            Data(3, 1, EventType.ENTER),\n            Data(7, 3, EventType.ENTER),\n            Data(9, 2, EventType.EXIT),\n            Data(8, 2, EventType.EXIT),\n        ]\n        self.assertEqual(solution.find_busiest_period(data), Period(7, 8))\n        print('Success: test_find_busiest_period')\n\n\ndef main():\n    test = TestSolution()\n    test.test_find_busiest_period()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/island_perimeter/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/island_perimeter/island_perimeter_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Island Perimeter.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/island-perimeter/) problem page.\\n\",\n    \"\\n\",\n    \"You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). The island doesn't have \\\"lakes\\\" (water inside that isn't connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don't exceed 100. Determine the perimeter of the island.\\n\",\n    \"\\n\",\n    \"Example:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"[[0,1,0,0],\\n\",\n    \" [1,1,1,0],\\n\",\n    \" [0,1,0,0],\\n\",\n    \" [1,1,0,0]]\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Answer: 16\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None -> TypeError\\n\",\n    \"* [[1, 0]] -> 4\\n\",\n    \"* [[0, 1, 0, 0],\\n\",\n    \"   [1, 1, 1, 0],\\n\",\n    \"   [0, 1, 0, 0],\\n\",\n    \"   [1, 1, 0, 0]] -> 16\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def island_perimeter(self, grid):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_island_perimeter.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestIslandPerimeter(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_island_perimeter(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.island_perimeter, None)\\n\",\n    \"        data = [[1, 0]]\\n\",\n    \"        expected = 4\\n\",\n    \"        self.assertEqual(solution.island_perimeter(data), expected)\\n\",\n    \"        data = [[0, 1, 0, 0],\\n\",\n    \"                [1, 1, 1, 0],\\n\",\n    \"                [0, 1, 0, 0],\\n\",\n    \"                [1, 1, 0, 0]]\\n\",\n    \"        expected = 16\\n\",\n    \"        self.assertEqual(solution.island_perimeter(data), expected)\\n\",\n    \"        print('Success: test_island_perimeter')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestIslandPerimeter()\\n\",\n    \"    test.test_island_perimeter()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/island_perimeter/island_perimeter_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Island Perimeter.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/island-perimeter/) problem page.\\n\",\n    \"\\n\",\n    \"You are given a map in form of a two-dimensional integer grid where 1 represents land and 0 represents water. Grid cells are connected horizontally/vertically (not diagonally). The grid is completely surrounded by water, and there is exactly one island (i.e., one or more connected land cells). The island doesn't have \\\"lakes\\\" (water inside that isn't connected to the water around the island). One cell is a square with side length 1. The grid is rectangular, width and height don't exceed 100. Determine the perimeter of the island.\\n\",\n    \"\\n\",\n    \"Example:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"[[0,1,0,0],\\n\",\n    \" [1,1,1,0],\\n\",\n    \" [0,1,0,0],\\n\",\n    \" [1,1,0,0]]\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Answer: 16\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None -> TypeError\\n\",\n    \"* [[1, 0]] -> 4\\n\",\n    \"* [[0, 1, 0, 0],\\n\",\n    \"   [1, 1, 1, 0],\\n\",\n    \"   [0, 1, 0, 0],\\n\",\n    \"   [1, 1, 0, 0]] -> 16\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"For each cell in the grid:\\n\",\n    \"* Check left, right, up, down\\n\",\n    \"    * For each check, if we are at the edge or the cell we are checking is land, increment sides\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(rows * cols)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def island_perimeter(self, grid):\\n\",\n    \"        if grid is None:\\n\",\n    \"            raise TypeError('grid cannot be None')\\n\",\n    \"        sides = 0\\n\",\n    \"        num_rows = len(grid)\\n\",\n    \"        num_cols = len(grid[0])\\n\",\n    \"        for i in range(num_rows):\\n\",\n    \"            for j in range(num_cols):\\n\",\n    \"                if grid[i][j] == 1:\\n\",\n    \"                    # Check left\\n\",\n    \"                    if j == 0 or grid[i][j - 1] == 0:\\n\",\n    \"                        sides += 1\\n\",\n    \"                    # Check right\\n\",\n    \"                    if j == num_cols - 1 or grid[i][j + 1] == 0:\\n\",\n    \"                        sides += 1\\n\",\n    \"                    # Check up\\n\",\n    \"                    if i == 0 or grid[i - 1][j] == 0:\\n\",\n    \"                        sides += 1\\n\",\n    \"                    # Check down\\n\",\n    \"                    if i == num_rows - 1 or grid[i + 1][j] == 0:\\n\",\n    \"                        sides += 1\\n\",\n    \"        return sides\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_island_perimeter.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_island_perimeter.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestIslandPerimeter(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_island_perimeter(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.island_perimeter, None)\\n\",\n    \"        data = [[1, 0]]\\n\",\n    \"        expected = 4\\n\",\n    \"        self.assertEqual(solution.island_perimeter(data), expected)\\n\",\n    \"        data = [[0, 1, 0, 0],\\n\",\n    \"                [1, 1, 1, 0],\\n\",\n    \"                [0, 1, 0, 0],\\n\",\n    \"                [1, 1, 0, 0]]\\n\",\n    \"        expected = 16\\n\",\n    \"        self.assertEqual(solution.island_perimeter(data), expected)\\n\",\n    \"        print('Success: test_island_perimeter')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestIslandPerimeter()\\n\",\n    \"    test.test_island_perimeter()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_island_perimeter\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_island_perimeter.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/island_perimeter/test_island_perimeter.py",
    "content": "import unittest\n\n\nclass TestIslandPerimeter(unittest.TestCase):\n\n    def test_island_perimeter(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.island_perimeter, None)\n        data = [[1, 0]]\n        expected = 4\n        self.assertEqual(solution.island_perimeter(data), expected)\n        data = [[0, 1, 0, 0],\n                [1, 1, 1, 0],\n                [0, 1, 0, 0],\n                [1, 1, 0, 0]]\n        expected = 16\n        self.assertEqual(solution.island_perimeter(data), expected)\n        print('Success: test_island_perimeter')\n\n\ndef main():\n    test = TestIslandPerimeter()\n    test.test_island_perimeter()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/license_key/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/license_key/format_license_key_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Format license keys.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/license-key-formatting/) problem page.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Now you are given a string S, which represents a software license key which we would like to format. The string S is composed of alphanumerical characters and dashes. The dashes split the alphanumerical characters within the string into groups. (i.e. if there are M dashes, the string is split into M+1 groups). The dashes in the given string are possibly misplaced.\\n\",\n    \"\\n\",\n    \"We want each group of characters to be of length K (except for possibly the first group, which could be shorter, but still must contain at least one character). To satisfy this requirement, we will reinsert dashes. Additionally, all the lower case letters in the string must be converted to upper case.\\n\",\n    \"\\n\",\n    \"So, you are given a non-empty string S, representing a license key to format, and an integer K. And you need to return the license key formatted according to the description above.\\n\",\n    \"\\n\",\n    \"Example 1:\\n\",\n    \"Input: S = \\\"2-4A0r7-4k\\\", K = 4\\n\",\n    \"\\n\",\n    \"Output: \\\"24A0-R74K\\\"\\n\",\n    \"\\n\",\n    \"Explanation: The string S has been split into two parts, each part has 4 characters.\\n\",\n    \"Example 2:\\n\",\n    \"Input: S = \\\"2-4A0r7-4k\\\", K = 3\\n\",\n    \"\\n\",\n    \"Output: \\\"24-A0R-74K\\\"\\n\",\n    \"\\n\",\n    \"Explanation: The string S has been split into three parts, each part has 3 characters except the first part as it could be shorter as said above.\\n\",\n    \"Note:\\n\",\n    \"The length of string S will not exceed 12,000, and K is a positive integer.\\n\",\n    \"String S consists only of alphanumerical characters (a-z and/or A-Z and/or 0-9) and dashes(-).\\n\",\n    \"String S is non-empty.\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the output a string?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we change the input string?\\n\",\n    \"    * No, you can't modify the input string\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* '---', k=3 -> ''\\n\",\n    \"* '2-4A0r7-4k', k=3 -> '24-A0R-74K'\\n\",\n    \"* '2-4A0r7-4k', k=4 -> '24A0-R74K'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def format_license_key(self, license_key, k):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_format_license_key.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_format_license_key(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.format_license_key, None, None)\\n\",\n    \"        license_key = '---'\\n\",\n    \"        k = 3\\n\",\n    \"        expected = ''\\n\",\n    \"        self.assertEqual(solution.format_license_key(license_key, k), expected)\\n\",\n    \"        license_key = '2-4A0r7-4k'\\n\",\n    \"        k = 3\\n\",\n    \"        expected = '24-A0R-74K'\\n\",\n    \"        self.assertEqual(solution.format_license_key(license_key, k), expected)\\n\",\n    \"        license_key = '2-4A0r7-4k'\\n\",\n    \"        k = 4\\n\",\n    \"        expected = '24A0-R74K'\\n\",\n    \"        self.assertEqual(solution.format_license_key(license_key, k), expected)\\n\",\n    \"        print('Success: test_format_license_key')\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_format_license_key()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/license_key/format_license_key_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Format license keys.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/license-key-formatting/) problem page.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Now you are given a string S, which represents a software license key which we would like to format. The string S is composed of alphanumerical characters and dashes. The dashes split the alphanumerical characters within the string into groups. (i.e. if there are M dashes, the string is split into M+1 groups). The dashes in the given string are possibly misplaced.\\n\",\n    \"\\n\",\n    \"We want each group of characters to be of length K (except for possibly the first group, which could be shorter, but still must contain at least one character). To satisfy this requirement, we will reinsert dashes. Additionally, all the lower case letters in the string must be converted to upper case.\\n\",\n    \"\\n\",\n    \"So, you are given a non-empty string S, representing a license key to format, and an integer K. And you need to return the license key formatted according to the description above.\\n\",\n    \"\\n\",\n    \"Example 1:\\n\",\n    \"Input: S = \\\"2-4A0r7-4k\\\", K = 4\\n\",\n    \"\\n\",\n    \"Output: \\\"24A0-R74K\\\"\\n\",\n    \"\\n\",\n    \"Explanation: The string S has been split into two parts, each part has 4 characters.\\n\",\n    \"Example 2:\\n\",\n    \"Input: S = \\\"2-4A0r7-4k\\\", K = 3\\n\",\n    \"\\n\",\n    \"Output: \\\"24-A0R-74K\\\"\\n\",\n    \"\\n\",\n    \"Explanation: The string S has been split into three parts, each part has 3 characters except the first part as it could be shorter as said above.\\n\",\n    \"\\n\",\n    \"Note:\\n\",\n    \"The length of string S will not exceed 12,000, and K is a positive integer.\\n\",\n    \"String S consists only of alphanumerical characters (a-z and/or A-Z and/or 0-9) and dashes(-).\\n\",\n    \"String S is non-empty.\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the output a string?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we change the input string?\\n\",\n    \"    * No, you can't modify the input string\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* '---', k=3 -> ''\\n\",\n    \"* '2-4A0r7-4k', k=3 -> '24-A0R-74K'\\n\",\n    \"* '2-4A0r7-4k', k=4 -> '24A0-R74K'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Loop through each character in the license key backwards, keeping a count of the number of chars we've reached so far, while inserting each character into a result list (convert to upper case)\\n\",\n    \"    * If we reach a '-', skip it\\n\",\n    \"    * Whenever we reach a char count of k, append a '-' character to the result list, reset the char count\\n\",\n    \"* Careful that we don't have a leading '-', which we might hit with test case: '2-4A0r7-4k', k=4 -> '24A0-R74K'\\n\",\n    \"* Reverse the result list and return it\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def format_license_key(self, license_key, k):\\n\",\n    \"        if license_key is None:\\n\",\n    \"            raise TypeError('license_key must be a str')\\n\",\n    \"        if not license_key:\\n\",\n    \"            raise ValueError('license_key must not be empty')\\n\",\n    \"        formatted_license_key = []\\n\",\n    \"        num_chars = 0\\n\",\n    \"        for char in license_key[::-1]:\\n\",\n    \"            if char == '-':\\n\",\n    \"                continue\\n\",\n    \"            num_chars += 1\\n\",\n    \"            formatted_license_key.append(char.upper())\\n\",\n    \"            if num_chars >= k:\\n\",\n    \"                formatted_license_key.append('-')\\n\",\n    \"                num_chars = 0\\n\",\n    \"        if formatted_license_key and formatted_license_key[-1] == '-':\\n\",\n    \"            formatted_license_key.pop(-1)\\n\",\n    \"        return ''.join(formatted_license_key[::-1])\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_format_license_key.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_format_license_key.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_format_license_key(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.format_license_key, None, None)\\n\",\n    \"        license_key = '---'\\n\",\n    \"        k = 3\\n\",\n    \"        expected = ''\\n\",\n    \"        self.assertEqual(solution.format_license_key(license_key, k), expected)\\n\",\n    \"        license_key = '2-4A0r7-4k'\\n\",\n    \"        k = 3\\n\",\n    \"        expected = '24-A0R-74K'\\n\",\n    \"        self.assertEqual(solution.format_license_key(license_key, k), expected)\\n\",\n    \"        license_key = '2-4A0r7-4k'\\n\",\n    \"        k = 4\\n\",\n    \"        expected = '24A0-R74K'\\n\",\n    \"        self.assertEqual(solution.format_license_key(license_key, k), expected)\\n\",\n    \"        print('Success: test_format_license_key')\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_format_license_key()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_format_license_key\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_format_license_key.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/license_key/test_format_license_key.py",
    "content": "import unittest\n\n\nclass TestSolution(unittest.TestCase):\n\n    def test_format_license_key(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.format_license_key, None, None)\n        license_key = '---'\n        k = 3\n        expected = ''\n        self.assertEqual(solution.format_license_key(license_key, k), expected)\n        license_key = '2-4A0r7-4k'\n        k = 3\n        expected = '24-A0R-74K'\n        self.assertEqual(solution.format_license_key(license_key, k), expected)\n        license_key = '2-4A0r7-4k'\n        k = 4\n        expected = '24A0-R74K'\n        self.assertEqual(solution.format_license_key(license_key, k), expected)\n        print('Success: test_format_license_key')\n\ndef main():\n    test = TestSolution()\n    test.test_format_license_key()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/longest_abs_file_path/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/longest_abs_file_path/longest_path_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the longest absolute file path.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/longest-absolute-file-path/) problem page.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Suppose we abstract our file system by a string in the following manner:\\n\",\n    \"\\n\",\n    \"The string \\\"dir\\\\n\\\\tsubdir1\\\\n\\\\tsubdir2\\\\n\\\\t\\\\tfile.ext\\\" represents:\\n\",\n    \"\\n\",\n    \"dir\\n\",\n    \"    subdir1\\n\",\n    \"    subdir2\\n\",\n    \"        file.ext\\n\",\n    \"The directory dir contains an empty sub-directory subdir1 and a sub-directory subdir2 containing a file file.ext.\\n\",\n    \"\\n\",\n    \"The string \\\"dir\\\\n\\\\tsubdir1\\\\n\\\\t\\\\tfile1.ext\\\\n\\\\t\\\\tsubsubdir1\\\\n\\\\tsubdir2\\\\n\\\\t\\\\tsubsubdir2\\\\n\\\\t\\\\t\\\\tfile2.ext\\\" represents:\\n\",\n    \"\\n\",\n    \"dir\\n\",\n    \"    subdir1\\n\",\n    \"        file1.ext\\n\",\n    \"        subsubdir1\\n\",\n    \"    subdir2\\n\",\n    \"        subsubdir2\\n\",\n    \"            file2.ext\\n\",\n    \"\\n\",\n    \"The directory dir contains two sub-directories subdir1 and subdir2. subdir1 contains a file file1.ext and an empty second-level sub-directory subsubdir1. subdir2 contains a second-level sub-directory subsubdir2 containing a file file2.ext.\\n\",\n    \"\\n\",\n    \"We are interested in finding the longest (number of characters) absolute path to a file within our file system. For example, in the second example above, the longest absolute path is \\\"dir/subdir2/subsubdir2/file2.ext\\\", and its length is 32 (not including the double quotes).\\n\",\n    \"\\n\",\n    \"Given a string representing the file system in the above format, return the length of the longest absolute path to file in the abstracted file system. If there is no file in the system, return 0.\\n\",\n    \"\\n\",\n    \"Note:\\n\",\n    \"The name of a file contains at least a . and an extension.\\n\",\n    \"The name of a directory or sub-directory will not contain a .\\n\",\n    \"Time complexity required: O(n) where n is the size of the input string.\\n\",\n    \"\\n\",\n    \"Notice that a/aa/aaa/file1.txt is not the longest file path, if there is another path aaaaaaaaaaaaaaaaaaaaa/sth.png.\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input a string?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input is valid?\\n\",\n    \"    * No\\n\",\n    \"* Will there always be a file in the input?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output an int?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* '' -> 0\\n\",\n    \"* 'dir\\\\n\\\\tsubdir1\\\\n\\\\t\\\\tfile1.ext\\\\n\\\\t\\\\tsubsubdir1\\\\n\\\\tsubdir2\\\\n\\\\t\\\\tsubsubdir2\\\\n\\\\t\\\\t\\\\tfile2.ext' -> 32\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def length_longest_path(self, file_system):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_length_longest_path.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_length_longest_path(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.length_longest_path, None)\\n\",\n    \"        self.assertEqual(solution.length_longest_path(''), 0)\\n\",\n    \"        file_system = 'dir\\\\n\\\\tsubdir1\\\\n\\\\t\\\\tfile1.ext\\\\n\\\\t\\\\tsubsubdir1\\\\n\\\\tsubdir2\\\\n\\\\t\\\\tsubsubdir2\\\\n\\\\t\\\\t\\\\tfile2.ext'\\n\",\n    \"        expected = 32\\n\",\n    \"        self.assertEqual(solution.length_longest_path(file_system), expected)\\n\",\n    \"        print('Success: test_length_longest_path')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_length_longest_path()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/longest_abs_file_path/longest_path_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the longest absolute file path.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/longest-absolute-file-path/) problem page.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Suppose we abstract our file system by a string in the following manner:\\n\",\n    \"\\n\",\n    \"The string \\\"dir\\\\n\\\\tsubdir1\\\\n\\\\tsubdir2\\\\n\\\\t\\\\tfile.ext\\\" represents:\\n\",\n    \"\\n\",\n    \"dir\\n\",\n    \"    subdir1\\n\",\n    \"    subdir2\\n\",\n    \"        file.ext\\n\",\n    \"The directory dir contains an empty sub-directory subdir1 and a sub-directory subdir2 containing a file file.ext.\\n\",\n    \"\\n\",\n    \"The string \\\"dir\\\\n\\\\tsubdir1\\\\n\\\\t\\\\tfile1.ext\\\\n\\\\t\\\\tsubsubdir1\\\\n\\\\tsubdir2\\\\n\\\\t\\\\tsubsubdir2\\\\n\\\\t\\\\t\\\\tfile2.ext\\\" represents:\\n\",\n    \"\\n\",\n    \"dir\\n\",\n    \"    subdir1\\n\",\n    \"        file1.ext\\n\",\n    \"        subsubdir1\\n\",\n    \"    subdir2\\n\",\n    \"        subsubdir2\\n\",\n    \"            file2.ext\\n\",\n    \"\\n\",\n    \"The directory dir contains two sub-directories subdir1 and subdir2. subdir1 contains a file file1.ext and an empty second-level sub-directory subsubdir1. subdir2 contains a second-level sub-directory subsubdir2 containing a file file2.ext.\\n\",\n    \"\\n\",\n    \"We are interested in finding the longest (number of characters) absolute path to a file within our file system. For example, in the second example above, the longest absolute path is \\\"dir/subdir2/subsubdir2/file2.ext\\\", and its length is 32 (not including the double quotes).\\n\",\n    \"\\n\",\n    \"Given a string representing the file system in the above format, return the length of the longest absolute path to file in the abstracted file system. If there is no file in the system, return 0.\\n\",\n    \"\\n\",\n    \"Note:\\n\",\n    \"The name of a file contains at least a . and an extension.\\n\",\n    \"The name of a directory or sub-directory will not contain a ..\\n\",\n    \"Time complexity required: O(n) where n is the size of the input string.\\n\",\n    \"\\n\",\n    \"Notice that a/aa/aaa/file1.txt is not the longest file path, if there is another path aaaaaaaaaaaaaaaaaaaaa/sth.png.\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input a string?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input is valid?\\n\",\n    \"    * No\\n\",\n    \"* Will there always be a file in the input?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output an int?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* '' -> 0\\n\",\n    \"* 'dir\\\\n\\\\tsubdir1\\\\n\\\\t\\\\tfile1.ext\\\\n\\\\t\\\\tsubsubdir1\\\\n\\\\tsubdir2\\\\n\\\\t\\\\tsubsubdir2\\\\n\\\\t\\\\t\\\\tfile2.ext' -> 32\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use a dictionary `path_len` to keep track of the current character length (values) at each depth (keys).  Depth 0 will have a length of 0.\\n\",\n    \"\\n\",\n    \"Initialize `max_len` to 0.\\n\",\n    \"\\n\",\n    \"Split the input based on the newline character.  Iterate on each resulting line:\\n\",\n    \"\\n\",\n    \"* Extract the `name` by excluding the tab characters\\n\",\n    \"* Calculate the depth length by taking into account the tab characters\\n\",\n    \"* If we are dealing with a file path (there is a '.' in `name`)\\n\",\n    \"    * Calculate `path_len[depth] + len(name)` and update `max_len` if needed\\n\",\n    \"* Else, update `path_len[depth + 1] = path_len[depth] + len(name) + 1`\\n\",\n    \"    * We add `+ 1` because each depth is separated by the '/' character\\n\",\n    \"* Return `max_len`\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def length_longest_path(self, file_system):\\n\",\n    \"        if file_system is None:\\n\",\n    \"            raise TypeError('file_system cannot be None')\\n\",\n    \"        max_len = 0\\n\",\n    \"        path_len = {0: 0}\\n\",\n    \"        for line in file_system.splitlines():\\n\",\n    \"            name = line.lstrip('\\\\t')\\n\",\n    \"            depth = len(line) - len(name)\\n\",\n    \"            if '.' in name:\\n\",\n    \"                max_len = max(max_len, path_len[depth] + len(name))\\n\",\n    \"            else:\\n\",\n    \"                path_len[depth + 1] = path_len[depth] + len(name) + 1\\n\",\n    \"        return max_len\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_length_longest_path.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_length_longest_path.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_length_longest_path(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.length_longest_path, None)\\n\",\n    \"        self.assertEqual(solution.length_longest_path(''), 0)\\n\",\n    \"        file_system = 'dir\\\\n\\\\tsubdir1\\\\n\\\\t\\\\tfile1.ext\\\\n\\\\t\\\\tsubsubdir1\\\\n\\\\tsubdir2\\\\n\\\\t\\\\tsubsubdir2\\\\n\\\\t\\\\t\\\\tfile2.ext'\\n\",\n    \"        expected = 32\\n\",\n    \"        self.assertEqual(solution.length_longest_path(file_system), expected)\\n\",\n    \"        print('Success: test_length_longest_path')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_length_longest_path()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_length_longest_path\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_length_longest_path.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/longest_abs_file_path/test_length_longest_path.py",
    "content": "import unittest\n\n\nclass TestSolution(unittest.TestCase):\n\n    def test_length_longest_path(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.length_longest_path, None)\n        self.assertEqual(solution.length_longest_path(''), 0)\n        file_system = 'dir\\n\\tsubdir1\\n\\t\\tfile1.ext\\n\\t\\tsubsubdir1\\n\\tsubdir2\\n\\t\\tsubsubdir2\\n\\t\\t\\tfile2.ext'\n        expected = 32\n        self.assertEqual(solution.length_longest_path(file_system), expected)\n        print('Success: test_length_longest_path')\n\n\ndef main():\n    test = TestSolution()\n    test.test_length_longest_path()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/longest_substr_k_distinct/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/longest_substr_k_distinct/longest_substr_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the length of the longest substring with at most k distinct characters.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the strings are ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Is a substring a contiguous block of chars?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we expect an int as a result?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* '', k = 3 -> 0\\n\",\n    \"* 'abcabcdefgghiij', k=3 -> 6\\n\",\n    \"* 'abcabcdefgghighij', k=3 -> 7\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def longest_substr(self, string, k):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_longest_substr.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_longest_substr(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.longest_substr, None)\\n\",\n    \"        self.assertEqual(solution.longest_substr('', k=3), 0)\\n\",\n    \"        self.assertEqual(solution.longest_substr('abcabcdefgghiij', k=3), 6)\\n\",\n    \"        self.assertEqual(solution.longest_substr('abcabcdefgghighij', k=3), 7)\\n\",\n    \"        print('Success: test_longest_substr')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_longest_substr()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/longest_substr_k_distinct/longest_substr_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the length of the longest substring with at most k distinct characters.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the strings are ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Is a substring a contiguous block of chars?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we expect an int as a result?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* '', k = 3 -> 0\\n\",\n    \"* 'abcabcdefgghiij', k=3 -> 6\\n\",\n    \"* 'abcabcdefgghighij', k=3 -> 7\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use a `chars_to_index_map` dictionary: char (key) to index (val) map to maintain a sliding window.\\n\",\n    \"\\n\",\n    \"The index (val) will keep track of the character index in the input string.\\n\",\n    \"\\n\",\n    \"For each character in the string:\\n\",\n    \"\\n\",\n    \"* Add the char (key) and index (value) to the map\\n\",\n    \"* If the length of our map is greater than k, then we'll need to eliminate one item\\n\",\n    \"    * Scan the map to find the lowest index and remove it\\n\",\n    \"    * The new lowest index will therefore be incremented by 1\\n\",\n    \"* The max length will be the current index minus the lower index + 1\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n * k), where n is the number of chars, k is the length of the map due to the min() call\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def longest_substr(self, string, k):\\n\",\n    \"        if string is None:\\n\",\n    \"            raise TypeError('string cannot be None')\\n\",\n    \"        if k is None:\\n\",\n    \"            raise TypeError('k cannot be None')\\n\",\n    \"        low_index = 0\\n\",\n    \"        max_length = 0\\n\",\n    \"        chars_to_index_map = {}\\n\",\n    \"        for index, char in enumerate(string):\\n\",\n    \"            chars_to_index_map[char] = index\\n\",\n    \"            if len(chars_to_index_map) > k:\\n\",\n    \"                low_index = min(chars_to_index_map.values())\\n\",\n    \"                del chars_to_index_map[string[low_index]]\\n\",\n    \"                low_index += 1\\n\",\n    \"            max_length = max(max_length, index - low_index + 1)\\n\",\n    \"        return max_length\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_longest_substr.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_longest_substr.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_longest_substr(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.longest_substr, None)\\n\",\n    \"        self.assertEqual(solution.longest_substr('', k=3), 0)\\n\",\n    \"        self.assertEqual(solution.longest_substr('abcabcdefgghiij', k=3), 6)\\n\",\n    \"        self.assertEqual(solution.longest_substr('abcabcdefgghighij', k=3), 7)\\n\",\n    \"        print('Success: test_longest_substr')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_longest_substr()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_longest_substr\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_longest_substr.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/longest_substr_k_distinct/test_longest_substr.py",
    "content": "import unittest\n\n\nclass TestSolution(unittest.TestCase):\n\n    def test_longest_substr(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.longest_substr, None)\n        self.assertEqual(solution.longest_substr('', k=3), 0)\n        self.assertEqual(solution.longest_substr('abcabcdefgghiij', k=3), 6)\n        self.assertEqual(solution.longest_substr('abcabcdefgghighij', k=3), 7)\n        print('Success: test_longest_substr')\n\n\ndef main():\n    test = TestSolution()\n    test.test_longest_substr()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/math_ops/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/math_ops/math_ops_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Create a class with an insert method to insert an int to a list.  It should also support calculating the max, min, mean, and mode in O(1).\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Is there a range of inputs?\\n\",\n    \"    * 0 <= item <= 100\\n\",\n    \"* Should mean return a float?\\n\",\n    \"    * Yes\\n\",\n    \"* Should the other results return an int?\\n\",\n    \"    * Yes\\n\",\n    \"* If there are multiple modes, what do we return?\\n\",\n    \"    * Any of the modes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* [] -> ValueError\\n\",\n    \"* [5, 2, 7, 9, 9, 2, 9, 4, 3, 3, 2]\\n\",\n    \"    * max: 9\\n\",\n    \"    * min: 2\\n\",\n    \"    * mean: 55\\n\",\n    \"    * mode: 9 or 2\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, upper_limit=100):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def insert(self, val):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_math_ops.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMathOps(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_math_ops(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.insert, None)\\n\",\n    \"        solution.insert(5)\\n\",\n    \"        solution.insert(2)\\n\",\n    \"        solution.insert(7)\\n\",\n    \"        solution.insert(9)\\n\",\n    \"        solution.insert(9)\\n\",\n    \"        solution.insert(2)\\n\",\n    \"        solution.insert(9)\\n\",\n    \"        solution.insert(4)\\n\",\n    \"        solution.insert(3)\\n\",\n    \"        solution.insert(3)\\n\",\n    \"        solution.insert(2)\\n\",\n    \"        self.assertEqual(solution.max, 9)\\n\",\n    \"        self.assertEqual(solution.min, 2)\\n\",\n    \"        self.assertEqual(solution.mean, 5)\\n\",\n    \"        self.assertTrue(solution.mode in (2, 92))\\n\",\n    \"        print('Success: test_math_ops')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMathOps()\\n\",\n    \"    test.test_math_ops()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/math_ops/math_ops_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Create a class with an insert method to insert an int to a list.  It should also support calculating the max, min, mean, and mode in O(1).\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Is there a range of inputs?\\n\",\n    \"    * 0 <= item <= 100\\n\",\n    \"* Should mean return a float?\\n\",\n    \"    * Yes\\n\",\n    \"* Should the other results return an int?\\n\",\n    \"    * Yes\\n\",\n    \"* If there are multiple modes, what do we return?\\n\",\n    \"    * Any of the modes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* [] -> ValueError\\n\",\n    \"* [5, 2, 7, 9, 9, 2, 9, 4, 3, 3, 2]\\n\",\n    \"    * max: 9\\n\",\n    \"    * min: 2\\n\",\n    \"    * mean: 55\\n\",\n    \"    * mode: 9 or 2\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Return the input, val\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from __future__ import division\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, upper_limit=100):\\n\",\n    \"        self.max = None\\n\",\n    \"        self.min = None\\n\",\n    \"        # Mean\\n\",\n    \"        self.num_items = 0\\n\",\n    \"        self.running_sum = 0\\n\",\n    \"        self.mean = None\\n\",\n    \"        # Mode\\n\",\n    \"        self.array = [0] * (upper_limit+1)\\n\",\n    \"        self.mode_ocurrences = 0\\n\",\n    \"        self.mode = None\\n\",\n    \"\\n\",\n    \"    def insert(self, val):\\n\",\n    \"        if val is None:\\n\",\n    \"            raise TypeError('val cannot be None')\\n\",\n    \"        if self.max is None or val > self.max:\\n\",\n    \"            self.max = val\\n\",\n    \"        if self.min is None or val < self.min:\\n\",\n    \"            self.min = val\\n\",\n    \"        # Calculate the mean\\n\",\n    \"        self.num_items += 1\\n\",\n    \"        self.running_sum += val\\n\",\n    \"        self.mean = self.running_sum / self.num_items\\n\",\n    \"        # Calculate the mode\\n\",\n    \"        self.array[val] += 1\\n\",\n    \"        if self.array[val] > self.mode_ocurrences:\\n\",\n    \"            self.mode_ocurrences = self.array[val]\\n\",\n    \"            self.mode = val\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_math_ops.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_math_ops.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMathOps(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_math_ops(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.insert, None)\\n\",\n    \"        solution.insert(5)\\n\",\n    \"        solution.insert(2)\\n\",\n    \"        solution.insert(7)\\n\",\n    \"        solution.insert(9)\\n\",\n    \"        solution.insert(9)\\n\",\n    \"        solution.insert(2)\\n\",\n    \"        solution.insert(9)\\n\",\n    \"        solution.insert(4)\\n\",\n    \"        solution.insert(3)\\n\",\n    \"        solution.insert(3)\\n\",\n    \"        solution.insert(2)\\n\",\n    \"        self.assertEqual(solution.max, 9)\\n\",\n    \"        self.assertEqual(solution.min, 2)\\n\",\n    \"        self.assertEqual(solution.mean, 5)\\n\",\n    \"        self.assertTrue(solution.mode in (2, 9))\\n\",\n    \"        print('Success: test_math_ops')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMathOps()\\n\",\n    \"    test.test_math_ops()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_math_ops\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_math_ops.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/math_ops/test_math_ops.py",
    "content": "import unittest\n\n\nclass TestMathOps(unittest.TestCase):\n\n    def test_math_ops(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.insert, None)\n        solution.insert(5)\n        solution.insert(2)\n        solution.insert(7)\n        solution.insert(9)\n        solution.insert(9)\n        solution.insert(2)\n        solution.insert(9)\n        solution.insert(4)\n        solution.insert(3)\n        solution.insert(3)\n        solution.insert(2)\n        self.assertEqual(solution.max, 9)\n        self.assertEqual(solution.min, 2)\n        self.assertEqual(solution.mean, 5)\n        self.assertTrue(solution.mode in (2, 9))\n        print('Success: test_math_ops')\n\n\ndef main():\n    test = TestMathOps()\n    test.test_math_ops()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/max_profit/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/max_profit/max_profit_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a list of stock prices, find the max profit from 1 buy and 1 sell.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/) problem page.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are all prices positive ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output an int?\\n\",\n    \"    * Yes\\n\",\n    \"* If profit is negative, do we return the smallest negative loss?\\n\",\n    \"    * Yes\\n\",\n    \"* If there are less than two prices, what do we return?\\n\",\n    \"    * Exception\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* Zero or one price -> ValueError\\n\",\n    \"* No profit\\n\",\n    \"    * [8, 5, 3, 2, 1] -> -1\\n\",\n    \"* General case\\n\",\n    \"    * [5, 3, 7, 4, 2, 6, 9] -> 7\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def find_max_profit(self, prices):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_max_profit.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMaxProfit(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_max_profit(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.find_max_profit, None)\\n\",\n    \"        self.assertRaises(ValueError, solution.find_max_profit, [])\\n\",\n    \"        self.assertEqual(solution.find_max_profit([8, 5, 3, 2, 1]), -1)\\n\",\n    \"        self.assertEqual(solution.find_max_profit([5, 3, 7, 4, 2, 6, 9]), 7)\\n\",\n    \"        print('Success: test_max_profit')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMaxProfit()\\n\",\n    \"    test.test_max_profit()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/max_profit/max_profit_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a list of stock prices, find the max profit from 1 buy and 1 sell.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are all prices positive ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output an int?\\n\",\n    \"    * Yes\\n\",\n    \"* If profit is negative, do we return the smallest negative loss?\\n\",\n    \"    * Yes\\n\",\n    \"* If there are less than two prices, what do we return?\\n\",\n    \"    * Exception\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* Zero or one price -> ValueError\\n\",\n    \"* No profit\\n\",\n    \"    * [8, 5, 3, 2, 1] -> -1\\n\",\n    \"* General case\\n\",\n    \"    * [5, 3, 7, 4, 2, 6, 9] -> 7\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use a greedy approach and iterate through the prices once.\\n\",\n    \"\\n\",\n    \"* Loop through the prices\\n\",\n    \"    * Update current profit (price = min_price)\\n\",\n    \"    * Update the min price\\n\",\n    \"    * Update the max profit\\n\",\n    \"* Return max profit\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import sys\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def find_max_profit(self, prices):\\n\",\n    \"        if prices is None:\\n\",\n    \"            raise TypeError('prices cannot be None')\\n\",\n    \"        if len(prices) < 2:\\n\",\n    \"            raise ValueError('prices must have at least two values')\\n\",\n    \"        min_price = prices.pop(0)\\n\",\n    \"        max_profit = prices[0] - min_price\\n\",\n    \"        for price in prices:\\n\",\n    \"            profit = price - min_price\\n\",\n    \"            min_price = min(price, min_price)\\n\",\n    \"            max_profit = max(profit, max_profit)\\n\",\n    \"        return max_profit\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_max_profit.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_max_profit.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMaxProfit(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_max_profit(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.find_max_profit, None)\\n\",\n    \"        self.assertRaises(ValueError, solution.find_max_profit, [])\\n\",\n    \"        self.assertEqual(solution.find_max_profit([8, 5, 3, 2, 1]), -1)\\n\",\n    \"        self.assertEqual(solution.find_max_profit([5, 3, 7, 4, 2, 6, 9]), 7)\\n\",\n    \"        print('Success: test_max_profit')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMaxProfit()\\n\",\n    \"    test.test_max_profit()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_max_profit\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_max_profit.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/max_profit/test_max_profit.py",
    "content": "import unittest\n\n\nclass TestMaxProfit(unittest.TestCase):\n\n    def test_max_profit(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.find_max_profit, None)\n        self.assertRaises(ValueError, solution.find_max_profit, [])\n        self.assertEqual(solution.find_max_profit([8, 5, 3, 2, 1]), -1)\n        self.assertEqual(solution.find_max_profit([5, 3, 7, 4, 2, 6, 9]), 7)\n        print('Success: test_max_profit')\n\n\ndef main():\n    test = TestMaxProfit()\n    test.test_max_profit()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/maximizing_xor/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/maximizing_xor/maximizing_xor_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Maximizing XOR\\n\",\n    \"\\n\",\n    \"See the [HackerRank problem page](https://www.hackerrank.com/challenges/maximizing-xor).\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"See the [HackerRank problem page](https://www.hackerrank.com/challenges/maximizing-xor).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"See the [HackerRank problem page](https://www.hackerrank.com/challenges/maximizing-xor).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/hackerrank_topcoder/utopian_tree/maximizing_xor_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def max_xor(self, lower, upper):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_maximizing_xor.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMaximizingXor(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_maximizing_xor(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertEqual(solution.max_xor(10, 15), 7)\\n\",\n    \"        print('Success: test_maximizing_xor')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMaximizingXor()\\n\",\n    \"    test.test_maximizing_xor()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/hackerrank_topcoder/utopian_tree/maximizing_xor_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/maximizing_xor/maximizing_xor_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Maximizing XOR\\n\",\n    \"\\n\",\n    \"See the [HackerRank problem page](https://www.hackerrank.com/challenges/maximizing-xor).\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"See the [HackerRank problem page](https://www.hackerrank.com/challenges/maximizing-xor).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"See the [HackerRank problem page](https://www.hackerrank.com/challenges/maximizing-xor).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Set max to 0\\n\",\n    \"* For i in the range (lower, upper) inclusive\\n\",\n    \"    * For j in the range (lower, upper) inclusive\\n\",\n    \"        * Compare i ^ j with max, update max if needed\\n\",\n    \"* return max\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n^2) - See note below\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"Note:\\n\",\n    \"* TODO: Add more optimal solutions such as those discussed [here](https://www.hackerrank.com/challenges/maximizing-xor/editorial).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def max_xor(self, lower, upper):\\n\",\n    \"        result = 0\\n\",\n    \"        for l in range(lower, upper + 1):\\n\",\n    \"            for u in range(lower, upper + 1):\\n\",\n    \"                curr = l ^ u\\n\",\n    \"                if result < curr:\\n\",\n    \"                    result = curr\\n\",\n    \"        return result\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_maximizing_xor.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_maximizing_xor.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMaximizingXor(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_maximizing_xor(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertEqual(solution.max_xor(10, 15), 7)\\n\",\n    \"        print('Success: test_maximizing_xor')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMaximizingXor()\\n\",\n    \"    test.test_maximizing_xor()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_maximizing_xor\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_maximizing_xor.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/maximizing_xor/test_maximizing_xor.py",
    "content": "import unittest\n\n\nclass TestMaximizingXor(unittest.TestCase):\n\n    def test_maximizing_xor(self):\n        solution = Solution()\n        self.assertEqual(solution.max_xor(10, 15), 7)\n        print('Success: test_maximizing_xor')\n\n\ndef main():\n    test = TestMaximizingXor()\n    test.test_maximizing_xor()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/merge_ranges/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/merge_ranges/merge_ranges_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a list of tuples representing ranges, condense the ranges.  \\n\",\n    \"\\n\",\n    \"Example: [(2, 3), (3, 5), (7, 9), (8, 10)] -> [(2, 5), (7, 10)]\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are the tuples in sorted order?\\n\",\n    \"    * No\\n\",\n    \"* Are the tuples ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Will all tuples have the first element less than the second?\\n\",\n    \"    * Yes\\n\",\n    \"* Is there an upper bound on the input range?\\n\",\n    \"    * No\\n\",\n    \"* Is the output a list of tuples?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output a new array?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* [] - []\\n\",\n    \"* [(2, 3), (7, 9)] -> [(2, 3), (7, 9)]\\n\",\n    \"* [(2, 3), (3, 5), (7, 9), (8, 10)] -> [(2, 5), (7, 10)]\\n\",\n    \"* [(2, 3), (3, 5), (7, 9), (8, 10), (1, 11)] -> [(1, 11)]\\n\",\n    \"* [(2, 3), (3, 8), (7, 9), (8, 10)] -> [(2, 10)]\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def merge_ranges(self, array):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_merge_ranges.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMergeRanges(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_merge_ranges(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.merge_ranges, None)\\n\",\n    \"        self.assertEqual(solution.merge_ranges([]), [])\\n\",\n    \"        array = [(2, 3), (7, 9)]\\n\",\n    \"        expected = [(2, 3), (7, 9)]\\n\",\n    \"        self.assertEqual(solution.merge_ranges(array), expected)\\n\",\n    \"        array = [(2, 3), (3, 5), (7, 9), (8, 10)]\\n\",\n    \"        expected = [(2, 5), (7, 10)]\\n\",\n    \"        self.assertEqual(solution.merge_ranges(array), expected)\\n\",\n    \"        array = [(2, 3), (3, 5), (7, 9), (8, 10), (1, 11)]\\n\",\n    \"        expected = [(1, 11)]\\n\",\n    \"        self.assertEqual(solution.merge_ranges(array), expected)\\n\",\n    \"        print('Success: test_merge_ranges')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMergeRanges()\\n\",\n    \"    test.test_merge_ranges()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/merge_ranges/merge_ranges_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a list of tuples representing ranges, condense the ranges.  \\n\",\n    \"\\n\",\n    \"Example: [(2, 3), (3, 5), (7, 9), (8, 10)] -> [(2, 5), (7, 10)]\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are the tuples in sorted order?\\n\",\n    \"    * No\\n\",\n    \"* Are the tuples ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Will all tuples have the first element less than the second?\\n\",\n    \"    * Yes\\n\",\n    \"* Is there an upper bound on the input range?\\n\",\n    \"    * No\\n\",\n    \"* Is the output a list of tuples?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output a new array?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* [] - []\\n\",\n    \"* [(2, 3), (7, 9)] -> [(2, 3), (7, 9)]\\n\",\n    \"* [(2, 3), (3, 5), (7, 9), (8, 10)] -> [(2, 5), (7, 10)]\\n\",\n    \"* [(2, 3), (3, 5), (7, 9), (8, 10), (1, 11)] -> [(1, 11)]\\n\",\n    \"* [(2, 3), (3, 8), (7, 9), (8, 10)] -> [(2, 10)]\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Sort the tuples based on start time\\n\",\n    \"* Check each adjacent tuple to see if they can be merged\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Case: * [(2, 3), (3, 8), (7, 9), (8, 10)] -> [(2, 10)]\\n\",\n    \"\\n\",\n    \"* Sort by start time (already sorted)\\n\",\n    \"* Add the first tuple to the merged_array\\n\",\n    \"* Loop through each item in sorted_array starting at index 1\\n\",\n    \"    * If there is no overlap\\n\",\n    \"        * Add the current item to merged_array\\n\",\n    \"    * Else\\n\",\n    \"        * Update the last item in merged_array\\n\",\n    \"            * The end time will be the max of merged_array[-1][1] and sorted_array[i][1]\\n\",\n    \"\\n\",\n    \"Start:\\n\",\n    \"                           i\\n\",\n    \"                   0       1       2       3\\n\",\n    \"sorted_array = [(2, 3), (3, 8), (7, 9), (8, 10)]\\n\",\n    \"merged_array = [(2, 3)]\\n\",\n    \"\\n\",\n    \"Overlap with (2, 3), (3, 8):\\n\",\n    \"                           i\\n\",\n    \"                   0       1       2       3\\n\",\n    \"sorted_array = [(2, 3), (3, 8), (7, 9), (8, 10)]\\n\",\n    \"merged_array = [(2, 8)]\\n\",\n    \"\\n\",\n    \"Overlap with (2, 8), (7, 9):\\n\",\n    \"                                   i\\n\",\n    \"                   0       1       2       3\\n\",\n    \"sorted_array = [(2, 3), (3, 8), (7, 9), (8, 10)]\\n\",\n    \"merged_array = [(2, 9)]\\n\",\n    \"\\n\",\n    \"Overlap with (2, 9) (8, 10):\\n\",\n    \"                                   i\\n\",\n    \"                   0       1       2       3\\n\",\n    \"sorted_array = [(2, 3), (3, 8), (7, 9), (8, 10)]\\n\",\n    \"merged_array = [(2, 10)]\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n log(n))\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def merge_ranges(self, array):\\n\",\n    \"        if array is None:\\n\",\n    \"            raise TypeError('array cannot be None')\\n\",\n    \"        if not array:\\n\",\n    \"            return array\\n\",\n    \"        sorted_array = sorted(array)\\n\",\n    \"        merged_array = [sorted_array[0]]\\n\",\n    \"        for index, item in enumerate(sorted_array):\\n\",\n    \"            if index == 0:\\n\",\n    \"                continue\\n\",\n    \"            start_prev, end_prev = merged_array[-1]\\n\",\n    \"            start_curr, end_curr = item\\n\",\n    \"            if end_prev < start_curr:\\n\",\n    \"                # No overlap, add the entry\\n\",\n    \"                merged_array.append(item)\\n\",\n    \"            else:\\n\",\n    \"                # Overlap, update the previous entry's end value\\n\",\n    \"                merged_array[-1] = (start_prev, max(end_prev, end_curr))\\n\",\n    \"        return merged_array\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_merge_ranges.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_merge_ranges.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMergeRanges(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_merge_ranges(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.merge_ranges, None)\\n\",\n    \"        self.assertEqual(solution.merge_ranges([]), [])\\n\",\n    \"        array = [(2, 3), (7, 9)]\\n\",\n    \"        expected = [(2, 3), (7, 9)]\\n\",\n    \"        self.assertEqual(solution.merge_ranges(array), expected)\\n\",\n    \"        array = [(3, 5), (2, 3), (7, 9), (8, 10)]\\n\",\n    \"        expected = [(2, 5), (7, 10)]\\n\",\n    \"        self.assertEqual(solution.merge_ranges(array), expected)\\n\",\n    \"        array = [(2, 3), (3, 5), (7, 9), (8, 10), (1, 11)]\\n\",\n    \"        expected = [(1, 11)]\\n\",\n    \"        self.assertEqual(solution.merge_ranges(array), expected)\\n\",\n    \"        print('Success: test_merge_ranges')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMergeRanges()\\n\",\n    \"    test.test_merge_ranges()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_merge_ranges\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_merge_ranges.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/merge_ranges/test_merge_ranges.py",
    "content": "import unittest\n\n\nclass TestMergeRanges(unittest.TestCase):\n\n    def test_merge_ranges(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.merge_ranges, None)\n        self.assertEqual(solution.merge_ranges([]), [])\n        array = [(2, 3), (7, 9)]\n        expected = [(2, 3), (7, 9)]\n        self.assertEqual(solution.merge_ranges(array), expected)\n        array = [(3, 5), (2, 3), (7, 9), (8, 10)]\n        expected = [(2, 5), (7, 10)]\n        self.assertEqual(solution.merge_ranges(array), expected)\n        array = [(2, 3), (3, 5), (7, 9), (8, 10), (1, 11)]\n        expected = [(1, 11)]\n        self.assertEqual(solution.merge_ranges(array), expected)\n        print('Success: test_merge_ranges')\n\n\ndef main():\n    test = TestMergeRanges()\n    test.test_merge_ranges()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/move_zeroes/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/move_zeroes/move_zeroes_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Move all zeroes in a list to the end.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input an array of ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output a new array of ints?\\n\",\n    \"    * No, do this in-place\\n\",\n    \"* Do we need to maintain ordering of non-zero values?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None -> TypeError\\n\",\n    \"* [0, 1, 0, 3, 12]\\n\",\n    \"* [1, 0] -> [1, 0]\\n\",\n    \"* [0, 1] -> [1, 0]\\n\",\n    \"* [0] -> [0]\\n\",\n    \"* [1] -> [1]\\n\",\n    \"* [1, 1] -> [1, 1]\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def move_zeroes(self, nums):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_move_zeroes.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMoveZeroes(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_move_zeroes(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.move_zeroes, None)\\n\",\n    \"        array = [0, 1, 0, 3, 12]\\n\",\n    \"        solution.move_zeroes(array)\\n\",\n    \"        self.assertEqual(array, [1, 3, 12, 0, 0])\\n\",\n    \"        array = [1, 0]\\n\",\n    \"        solution.move_zeroes(array)\\n\",\n    \"        self.assertEqual(array, [1, 0])\\n\",\n    \"        array = [0, 1]\\n\",\n    \"        solution.move_zeroes(array)\\n\",\n    \"        self.assertEqual(array, [1, 0])\\n\",\n    \"        array = [0]\\n\",\n    \"        solution.move_zeroes(array)\\n\",\n    \"        self.assertEqual(array, [0])\\n\",\n    \"        array = [1]\\n\",\n    \"        solution.move_zeroes(array)\\n\",\n    \"        self.assertEqual(array, [1])\\n\",\n    \"        array = [1, 1]\\n\",\n    \"        solution.move_zeroes(array)\\n\",\n    \"        self.assertEqual(array, [1, 1])\\n\",\n    \"        print('Success: test_move_zeroes')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMoveZeroes()\\n\",\n    \"    test.test_move_zeroes()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/move_zeroes/move_zeroes_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Move all zeroes in a list to the end.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input an array of ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output a new array of ints?\\n\",\n    \"    * No, do this in-place\\n\",\n    \"* Do we need to maintain ordering of non-zero values?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None -> TypeError\\n\",\n    \"* [0, 1, 0, 3, 12] -> [1, 3, 12, 0, 0]\\n\",\n    \"* [1, 0] -> [1, 0]\\n\",\n    \"* [0, 1] -> [1, 0]\\n\",\n    \"* [0] -> [0]\\n\",\n    \"* [1] -> [1]\\n\",\n    \"* [1, 1] -> [1, 1]\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* pos = 0\\n\",\n    \"* Loop through each item in the input\\n\",\n    \"    * If the item != 0, set input[pos] = item\\n\",\n    \"        * pos++\\n\",\n    \"* Fill input[pos:] with zeroes\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \" |\\n\",\n    \"[0, 1, 0, 3, 12]\\n\",\n    \" ^\\n\",\n    \"    |\\n\",\n    \"[0, 1, 0, 3, 12]\\n\",\n    \" ^\\n\",\n    \"    |\\n\",\n    \"[1, 1, 0, 3, 12]\\n\",\n    \" ^\\n\",\n    \"       |\\n\",\n    \"[1, 1, 0, 3, 12]\\n\",\n    \"    ^\\n\",\n    \"          |\\n\",\n    \"[1, 1, 0, 3, 12]\\n\",\n    \"    ^\\n\",\n    \"          |\\n\",\n    \"[1, 3, 0, 3, 12]\\n\",\n    \"    ^\\n\",\n    \"              |\\n\",\n    \"[1, 3, 0, 3, 12]\\n\",\n    \"       ^\\n\",\n    \"              |\\n\",\n    \"[1, 3, 12, 3, 12]\\n\",\n    \"       ^\\n\",\n    \"\\n\",\n    \"Fill right with zeroes:\\n\",\n    \"\\n\",\n    \"[1, 3, 12, 3, 12]\\n\",\n    \"           ^\\n\",\n    \"[1, 3, 12, 0, 12]\\n\",\n    \"           ^\\n\",\n    \"[1, 3, 12, 0, 0]\\n\",\n    \"              ^\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def move_zeroes(self, nums):\\n\",\n    \"        if nums is None:\\n\",\n    \"            raise TypeError('nums cannot be None')\\n\",\n    \"        pos = 0\\n\",\n    \"        for num in nums:\\n\",\n    \"            if num != 0:\\n\",\n    \"                nums[pos] = num\\n\",\n    \"                pos += 1\\n\",\n    \"        if pos < len(nums):\\n\",\n    \"            nums[pos:] = [0] * (len(nums) - pos)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_move_zeroes.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_move_zeroes.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMoveZeroes(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_move_zeroes(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.move_zeroes, None)\\n\",\n    \"        array = [0, 1, 0, 3, 12]\\n\",\n    \"        solution.move_zeroes(array)\\n\",\n    \"        self.assertEqual(array, [1, 3, 12, 0, 0])\\n\",\n    \"        array = [1, 0]\\n\",\n    \"        solution.move_zeroes(array)\\n\",\n    \"        self.assertEqual(array, [1, 0])\\n\",\n    \"        array = [0, 1]\\n\",\n    \"        solution.move_zeroes(array)\\n\",\n    \"        self.assertEqual(array, [1, 0])\\n\",\n    \"        array = [0]\\n\",\n    \"        solution.move_zeroes(array)\\n\",\n    \"        self.assertEqual(array, [0])\\n\",\n    \"        array = [1]\\n\",\n    \"        solution.move_zeroes(array)\\n\",\n    \"        self.assertEqual(array, [1])\\n\",\n    \"        array = [1, 1]\\n\",\n    \"        solution.move_zeroes(array)\\n\",\n    \"        self.assertEqual(array, [1, 1])\\n\",\n    \"        print('Success: test_move_zeroes')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMoveZeroes()\\n\",\n    \"    test.test_move_zeroes()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_move_zeroes\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_move_zeroes.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/move_zeroes/test_move_zeroes.py",
    "content": "import unittest\n\n\nclass TestMoveZeroes(unittest.TestCase):\n\n    def test_move_zeroes(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.move_zeroes, None)\n        array = [0, 1, 0, 3, 12]\n        solution.move_zeroes(array)\n        self.assertEqual(array, [1, 3, 12, 0, 0])\n        array = [1, 0]\n        solution.move_zeroes(array)\n        self.assertEqual(array, [1, 0])\n        array = [0, 1]\n        solution.move_zeroes(array)\n        self.assertEqual(array, [1, 0])\n        array = [0]\n        solution.move_zeroes(array)\n        self.assertEqual(array, [0])\n        array = [1]\n        solution.move_zeroes(array)\n        self.assertEqual(array, [1])\n        array = [1, 1]\n        solution.move_zeroes(array)\n        self.assertEqual(array, [1, 1])\n        print('Success: test_move_zeroes')\n\n\ndef main():\n    test = TestMoveZeroes()\n    test.test_move_zeroes()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/mult_other_numbers/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/mult_other_numbers/mult_other_numbers_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a list of ints, find the products of every other int for each index.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we use division?\\n\",\n    \"    * No\\n\",\n    \"* Is the output a list of ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None -> TypeError\\n\",\n    \"* [] -> []\\n\",\n    \"* [0] -> []\\n\",\n    \"* [0, 1] -> [1, 0]\\n\",\n    \"* [0, 1, 2] -> [2, 0, 0]\\n\",\n    \"* [1, 2, 3, 4] -> [24, 12, 8, 6]\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def mult_other_numbers(self, array):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_mult_other_numbers.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMultOtherNumbers(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_mult_other_numbers(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.mult_other_numbers, None)\\n\",\n    \"        self.assertEqual(solution.mult_other_numbers([0]), [])\\n\",\n    \"        self.assertEqual(solution.mult_other_numbers([0, 1]), [1, 0])\\n\",\n    \"        self.assertEqual(solution.mult_other_numbers([0, 1, 2]), [2, 0, 0])\\n\",\n    \"        self.assertEqual(solution.mult_other_numbers([1, 2, 3, 4]), [24, 12, 8, 6])\\n\",\n    \"        print('Success: test_mult_other_numbers')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMultOtherNumbers()\\n\",\n    \"    test.test_mult_other_numbers()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/mult_other_numbers/mult_other_numbers_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a list of ints, find the products of every other int for each index.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we use division?\\n\",\n    \"    * No\\n\",\n    \"* Is the output a list of ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None -> TypeError\\n\",\n    \"* [] -> []\\n\",\n    \"* [0] -> []\\n\",\n    \"* [0, 1] -> [1, 0]\\n\",\n    \"* [0, 1, 2] -> [2, 0, 0]\\n\",\n    \"* [1, 2, 3, 4] -> [24, 12, 8, 6]\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### Brute force:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"sum = 1\\n\",\n    \" |\\n\",\n    \"[1, 2, 3, 4]\\n\",\n    \" ^\\n\",\n    \"skip if both pointers are pointing to the same spot\\n\",\n    \"    |\\n\",\n    \"[1, 2, 3, 4]\\n\",\n    \" ^\\n\",\n    \"sum *= 2\\n\",\n    \"       |\\n\",\n    \"[1, 2, 3, 4]\\n\",\n    \" ^\\n\",\n    \"sum *= 3\\n\",\n    \"          |\\n\",\n    \"[1, 2, 3, 4]\\n\",\n    \" ^\\n\",\n    \"sum *= 4\\n\",\n    \"results.append(sum)\\n\",\n    \"results = [24]\\n\",\n    \"\\n\",\n    \"repeat for every element in the input list to obtain:\\n\",\n    \"\\n\",\n    \"[24, 12, 8, 6]\\n\",\n    \" \\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n^2)\\n\",\n    \"* Space: O(n)\\n\",\n    \"\\n\",\n    \"### Greedy\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"input  = [1, 2, 3, 4]\\n\",\n    \"result = [2*3*4, 1*3*4, 1*2*4, 1*2*3]\\n\",\n    \"\\n\",\n    \"Note we are duplicating multiplications with the brute force approach.\\n\",\n    \"\\n\",\n    \"We'll calculate all products before an index, and all products after an index.\\n\",\n    \"We'll then multiple these two together to form the result.\\n\",\n    \"\\n\",\n    \"input  = [1,         2,     3,     4]\\n\",\n    \"before = [1,         1,   1*2, 1*2*3]\\n\",\n    \"after  = [2*3*4, 1*3*4, 1*2*4,     1]\\n\",\n    \"result = [   24,    12,     8,     6] \\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def mult_other_numbers_brute(self, array):\\n\",\n    \"        if array is None:\\n\",\n    \"            raise TypeError('array cannot be None')\\n\",\n    \"        if not array:\\n\",\n    \"            return array\\n\",\n    \"        if len(array) == 1:\\n\",\n    \"            return []\\n\",\n    \"        result = []\\n\",\n    \"        for i in range(len(array)):\\n\",\n    \"            curr_sum = 1\\n\",\n    \"            for j in range(len(array)):\\n\",\n    \"                if i == j:\\n\",\n    \"                    continue\\n\",\n    \"                curr_sum *= array[j]\\n\",\n    \"            result.append(curr_sum)\\n\",\n    \"        return result\\n\",\n    \"\\n\",\n    \"    def mult_other_numbers(self, array):\\n\",\n    \"        if array is None:\\n\",\n    \"            raise TypeError('array cannot be None')\\n\",\n    \"        if not array:\\n\",\n    \"            return array\\n\",\n    \"        if len(array) == 1:\\n\",\n    \"            return []\\n\",\n    \"        result = [None] * len(array)\\n\",\n    \"        curr_product = 1\\n\",\n    \"        for i in range(len(array)):\\n\",\n    \"            result[i] = curr_product\\n\",\n    \"            curr_product *= array[i]\\n\",\n    \"        curr_product = 1\\n\",\n    \"        for i in range(len(array))[::-1]:\\n\",\n    \"            result[i] *= curr_product\\n\",\n    \"            curr_product *= array[i]\\n\",\n    \"        return result\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_mult_other_numbers.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_mult_other_numbers.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMultOtherNumbers(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_mult_other_numbers(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.mult_other_numbers, None)\\n\",\n    \"        self.assertEqual(solution.mult_other_numbers([0]), [])\\n\",\n    \"        self.assertEqual(solution.mult_other_numbers([0, 1]), [1, 0])\\n\",\n    \"        self.assertEqual(solution.mult_other_numbers([0, 1, 2]), [2, 0, 0])\\n\",\n    \"        self.assertEqual(solution.mult_other_numbers([1, 2, 3, 4]), [24, 12, 8, 6])\\n\",\n    \"        print('Success: test_mult_other_numbers')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMultOtherNumbers()\\n\",\n    \"    test.test_mult_other_numbers()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_mult_other_numbers\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_mult_other_numbers.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/mult_other_numbers/test_mult_other_numbers.py",
    "content": "import unittest\n\n\nclass TestMultOtherNumbers(unittest.TestCase):\n\n    def test_mult_other_numbers(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.mult_other_numbers, None)\n        self.assertEqual(solution.mult_other_numbers([0]), [])\n        self.assertEqual(solution.mult_other_numbers([0, 1]), [1, 0])\n        self.assertEqual(solution.mult_other_numbers([0, 1, 2]), [2, 0, 0])\n        self.assertEqual(solution.mult_other_numbers([1, 2, 3, 4]), [24, 12, 8, 6])\n        print('Success: test_mult_other_numbers')\n\n\ndef main():\n    test = TestMultOtherNumbers()\n    test.test_mult_other_numbers()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/nim/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/nim/nim_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine whether you can win the Nim game given the remaining stones.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/nim-game/) problem page.\\n\",\n    \"\\n\",\n    \"You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove the stones.\\n\",\n    \"\\n\",\n    \"Both of you are very clever and have optimal strategies for the game. Write a function to determine whether you can win the game given the number of stones in the heap.\\n\",\n    \"\\n\",\n    \"For example, if there are 4 stones in the heap, then you will never win the game: no matter 1, 2, or 3 stones you remove, the last stone will always be removed by your friend.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input an int?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output a boolean?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* 1, 2, or 3 -> True\\n\",\n    \"* 4 -> False\\n\",\n    \"* 7 -> True\\n\",\n    \"* 40 -> False\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def can_win_nim(self, num_stones_left):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_can_win_nim.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_can_win_nim(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.can_win_nim, None)\\n\",\n    \"        self.assertEqual(solution.can_win_nim(1), True)\\n\",\n    \"        self.assertEqual(solution.can_win_nim(2), True)\\n\",\n    \"        self.assertEqual(solution.can_win_nim(3), True)\\n\",\n    \"        self.assertEqual(solution.can_win_nim(4), False)\\n\",\n    \"        self.assertEqual(solution.can_win_nim(7), True)\\n\",\n    \"        self.assertEqual(solution.can_win_nim(40), False)\\n\",\n    \"        print('Success: test_can_win_nim')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_can_win_nim()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/nim/nim_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine whether you can win the Nim game given the remaining stones.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/nim-game/) problem page.\\n\",\n    \"\\n\",\n    \"You are playing the following Nim Game with your friend: There is a heap of stones on the table, each time one of you take turns to remove 1 to 3 stones. The one who removes the last stone will be the winner. You will take the first turn to remove the stones.\\n\",\n    \"\\n\",\n    \"Both of you are very clever and have optimal strategies for the game. Write a function to determine whether you can win the game given the number of stones in the heap.\\n\",\n    \"\\n\",\n    \"For example, if there are 4 stones in the heap, then you will never win the game: no matter 1, 2, or 3 stones you remove, the last stone will always be removed by your friend.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input an int?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the output a boolean?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* 1, 2, or 3 -> True\\n\",\n    \"* 4 -> False\\n\",\n    \"* 7 -> True\\n\",\n    \"* 40 -> False\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"This is somewhat of a one-trick puzzle, where the only way you can lose if you take the first stone while playing optimally is if the number of remaining stones is divisible by 4.\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def can_win_nim(self, num_stones_left):\\n\",\n    \"        return num_stones_left % 4 != 0\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_can_win_nim.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_can_win_nim.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_can_win_nim(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.can_win_nim, None)\\n\",\n    \"        self.assertEqual(solution.can_win_nim(1), True)\\n\",\n    \"        self.assertEqual(solution.can_win_nim(2), True)\\n\",\n    \"        self.assertEqual(solution.can_win_nim(3), True)\\n\",\n    \"        self.assertEqual(solution.can_win_nim(4), False)\\n\",\n    \"        self.assertEqual(solution.can_win_nim(7), True)\\n\",\n    \"        self.assertEqual(solution.can_win_nim(40), False)\\n\",\n    \"        print('Success: test_can_win_nim')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_can_win_nim()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_can_win_nim\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_can_win_nim.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/nim/test_can_win_nim.py",
    "content": "import unittest\n\n\nclass TestSolution(unittest.TestCase):\n\n    def test_can_win_nim(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.can_win_nim, None)\n        self.assertEqual(solution.can_win_nim(1), True)\n        self.assertEqual(solution.can_win_nim(2), True)\n        self.assertEqual(solution.can_win_nim(3), True)\n        self.assertEqual(solution.can_win_nim(4), False)\n        self.assertEqual(solution.can_win_nim(7), True)\n        self.assertEqual(solution.can_win_nim(40), False)\n        print('Success: test_can_win_nim')\n\n\ndef main():\n    test = TestSolution()\n    test.test_can_win_nim()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/prod_three/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/prod_three/prod_three_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the highest product of three numbers in a list.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input a list of integers?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we get negative inputs?\\n\",\n    \"    * Yes\\n\",\n    \"* Can there be duplicate entries in the input?\\n\",\n    \"    * Yes\\n\",\n    \"* Will there always be at least three integers?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None input\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* Less than three ints -> ValueError\\n\",\n    \"* [5, -2, 3] -> -30\\n\",\n    \"* [5, -2, 3, 1, -1, 4] -> 60\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def max_prod_three(self, array):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_prod_three.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestProdThree(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_prod_three(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.max_prod_three, None)\\n\",\n    \"        self.assertRaises(ValueError, solution.max_prod_three, [1, 2])\\n\",\n    \"        self.assertEqual(solution.max_prod_three([5, -2, 3]), -30)\\n\",\n    \"        self.assertEqual(solution.max_prod_three([5, -2, 3, 1, -1, 4]), 60)\\n\",\n    \"        print('Success: test_prod_three')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestProdThree()\\n\",\n    \"    test.test_prod_three()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/prod_three/prod_three_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the highest product of three numbers in a list.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input a list of integers?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we get negative inputs?\\n\",\n    \"    * Yes\\n\",\n    \"* Can there be duplicate entries in the input?\\n\",\n    \"    * Yes\\n\",\n    \"* Will there always be at least three integers?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None input\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* Less than three ints -> ValueError\\n\",\n    \"* [5, -2, 3] -> -30\\n\",\n    \"* [5, -2, 3, 1, -1, 4] -> 60\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### Brute force:\\n\",\n    \"\\n\",\n    \"Use three loops and multiple each numbers.\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n^3)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Sorting:\\n\",\n    \"\\n\",\n    \"Sort the list, multiply the last three elements.\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n log(n))\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Greedy:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \" 0   1  2  3   4  5\\n\",\n    \"[5, -2, 3, 1, -1, 4] -> 60\\n\",\n    \"\\n\",\n    \"max_prod_of_three = -30\\n\",\n    \"max_prod_of_two = -10\\n\",\n    \"max_num = 5\\n\",\n    \"min_prod_of_two = -10\\n\",\n    \"min_num = -2\\n\",\n    \"\\n\",\n    \" 0   1  2  3   4  5\\n\",\n    \"[5, -2, 3, 1, -1, 4] -> 60\\n\",\n    \"        ^\\n\",\n    \"max_prod_of_three = -30\\n\",\n    \"max_prod_of_two = 15\\n\",\n    \"max_num = 5\\n\",\n    \"min_prod_of_two = -10\\n\",\n    \"min_num = -2\\n\",\n    \"\\n\",\n    \" 0   1  2  3   4  5\\n\",\n    \"[5, -2, 3, 1, -1, 4] -> 60\\n\",\n    \"           ^\\n\",\n    \"max_prod_of_three = 15\\n\",\n    \"max_prod_of_two = 15\\n\",\n    \"max_num = 5\\n\",\n    \"min_prod_of_two = -10\\n\",\n    \"min_num = -2\\n\",\n    \"\\n\",\n    \" 0   1  2  3   4  5\\n\",\n    \"[5, -2, 3, 1, -1, 4] -> 60\\n\",\n    \"               ^\\n\",\n    \"max_prod_of_three = 15\\n\",\n    \"max_prod_of_two = 15\\n\",\n    \"max_num = 5\\n\",\n    \"min_prod_of_two = -10\\n\",\n    \"min_num = -2\\n\",\n    \"\\n\",\n    \" 0   1  2  3   4  5\\n\",\n    \"[5, -2, 3, 1, -1, 4] -> 60\\n\",\n    \"                  ^\\n\",\n    \"max_prod_of_three = 60\\n\",\n    \"max_prod_of_two = 15\\n\",\n    \"max_num = 5\\n\",\n    \"min_prod_of_two = -10\\n\",\n    \"min_num = -2\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def max_prod_three_nlogn(self, array):\\n\",\n    \"        if array is None:\\n\",\n    \"            raise TypeError('array cannot be None')\\n\",\n    \"        if len(array) < 3:\\n\",\n    \"            raise ValueError('array must have 3 or more ints')\\n\",\n    \"        array.sort()\\n\",\n    \"        product = 1\\n\",\n    \"        for item in array[-3:]:\\n\",\n    \"            product *= item\\n\",\n    \"        return product\\n\",\n    \"\\n\",\n    \"    def max_prod_three(self, array):\\n\",\n    \"        if array is None:\\n\",\n    \"            raise TypeError('array cannot be None')\\n\",\n    \"        if len(array) < 3:\\n\",\n    \"            raise ValueError('array must have 3 or more ints')\\n\",\n    \"        curr_max_prod_three = array[0] * array[1] * array[2]\\n\",\n    \"        max_prod_two = array[0] * array[1]\\n\",\n    \"        min_prod_two = array[0] * array[1]\\n\",\n    \"        max_num = max(array[0], array[1])\\n\",\n    \"        min_num = min(array[0], array[1])\\n\",\n    \"        for i in range(2, len(array)):\\n\",\n    \"            curr_max_prod_three = max(curr_max_prod_three,\\n\",\n    \"                                      max_prod_two * array[i],\\n\",\n    \"                                      min_prod_two * array[i])\\n\",\n    \"            max_prod_two = max(max_prod_two,\\n\",\n    \"                               max_num * array[i],\\n\",\n    \"                               min_num * array[i])\\n\",\n    \"            min_prod_two = min(min_prod_two,\\n\",\n    \"                               max_num * array[i],\\n\",\n    \"                               min_num * array[i])\\n\",\n    \"            max_num = max(max_num, array[i])\\n\",\n    \"            min_num = min(min_num, array[i])\\n\",\n    \"        return curr_max_prod_three\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_prod_three.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_prod_three.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestProdThree(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_prod_three(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.max_prod_three, None)\\n\",\n    \"        self.assertRaises(ValueError, solution.max_prod_three, [1, 2])\\n\",\n    \"        self.assertEqual(solution.max_prod_three([5, -2, 3]), -30)\\n\",\n    \"        self.assertEqual(solution.max_prod_three([5, -2, 3, 1, -1, 4]), 60)\\n\",\n    \"        print('Success: test_prod_three')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestProdThree()\\n\",\n    \"    test.test_prod_three()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_prod_three\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_prod_three.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/prod_three/test_prod_three.py",
    "content": "import unittest\n\n\nclass TestProdThree(unittest.TestCase):\n\n    def test_prod_three(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.max_prod_three, None)\n        self.assertRaises(ValueError, solution.max_prod_three, [1, 2])\n        self.assertEqual(solution.max_prod_three([5, -2, 3]), -30)\n        self.assertEqual(solution.max_prod_three([5, -2, 3, 1, -1, 4]), 60)\n        print('Success: test_prod_three')\n\n\ndef main():\n    test = TestProdThree()\n    test.test_prod_three()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/ransom_note/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/ransom_note/ransom_note_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a magazine, see if a ransom note could have been written using the letters in the magazine.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we're working with ASCII characters?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we scan the entire magazine, or should we scan only when necessary?\\n\",\n    \"    * You can scan the entire magazine\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* '', '' -> Exception\\n\",\n    \"* 'a', 'b' -> False\\n\",\n    \"* 'aa', 'ab' -> False\\n\",\n    \"* 'aa', 'aab' -> True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def match_note_to_magazine(self, ransom_note, magazine):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_ransom_note.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestRansomNote(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_ransom_note(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.match_note_to_magazine, None, None)\\n\",\n    \"        self.assertEqual(solution.match_note_to_magazine('', ''), True)\\n\",\n    \"        self.assertEqual(solution.match_note_to_magazine('a', 'b'), False)\\n\",\n    \"        self.assertEqual(solution.match_note_to_magazine('aa', 'ab'), False)\\n\",\n    \"        self.assertEqual(solution.match_note_to_magazine('aa', 'aab'), True)\\n\",\n    \"        print('Success: test_ransom_note')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestRansomNote()\\n\",\n    \"    test.test_ransom_note()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/ransom_note/ransom_note_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a magazine, see if a ransom note could have been written using the letters in the magazine.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we're working with ASCII characters?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we scan the entire magazine, or should we scan only when necessary?\\n\",\n    \"    * You can scan the entire magazine\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* '', '' -> Exception\\n\",\n    \"* 'a', 'b' -> False\\n\",\n    \"* 'aa', 'ab' -> False\\n\",\n    \"* 'aa', 'aab' -> True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Build a dictionary of the magazine characters and counts.\\n\",\n    \"* Loop through each letter in the ransom note and see if there are enough letters in the magazine's dictionary.\\n\",\n    \"* Note: You could make this more efficient by not scanning the entire magazine all at once, but instead scan just in time as you run out of letters in the dictionary.\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n+m), where n is the length of the ransom note and m is the length of the magazine\\n\",\n    \"* Space: O(n+m)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def match_note_to_magazine(self, ransom_note, magazine):\\n\",\n    \"        if ransom_note is None or magazine is None:\\n\",\n    \"            raise TypeError('ransom_note or magazine cannot be None')\\n\",\n    \"        seen_chars = {}\\n\",\n    \"        for char in magazine:\\n\",\n    \"            if char in seen_chars:\\n\",\n    \"                seen_chars[char] += 1\\n\",\n    \"            else:\\n\",\n    \"                seen_chars[char] = 1\\n\",\n    \"        for char in ransom_note:\\n\",\n    \"            try:\\n\",\n    \"                seen_chars[char] -= 1\\n\",\n    \"            except KeyError:\\n\",\n    \"                return False\\n\",\n    \"            if seen_chars[char] < 0:\\n\",\n    \"                return False\\n\",\n    \"        return True\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_ransom_note.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_ransom_note.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestRansomNote(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_ransom_note(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.match_note_to_magazine, None, None)\\n\",\n    \"        self.assertEqual(solution.match_note_to_magazine('', ''), True)\\n\",\n    \"        self.assertEqual(solution.match_note_to_magazine('a', 'b'), False)\\n\",\n    \"        self.assertEqual(solution.match_note_to_magazine('aa', 'ab'), False)\\n\",\n    \"        self.assertEqual(solution.match_note_to_magazine('aa', 'aab'), True)\\n\",\n    \"        print('Success: test_ransom_note')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestRansomNote()\\n\",\n    \"    test.test_ransom_note()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_ransom_note\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_ransom_note.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/ransom_note/test_ransom_note.py",
    "content": "import unittest\n\n\nclass TestRansomNote(unittest.TestCase):\n\n    def test_ransom_note(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.match_note_to_magazine, None, None)\n        self.assertEqual(solution.match_note_to_magazine('', ''), True)\n        self.assertEqual(solution.match_note_to_magazine('a', 'b'), False)\n        self.assertEqual(solution.match_note_to_magazine('aa', 'ab'), False)\n        self.assertEqual(solution.match_note_to_magazine('aa', 'aab'), True)\n        print('Success: test_ransom_note')\n\n\ndef main():\n    test = TestRansomNote()\n    test.test_ransom_note()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/sentence_screen_fit/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/sentence_screen_fit/sentence_screen_fit_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find how many times a sentence can fit on a screen.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/sentence-screen-fitting/) problem page.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Given a rows x cols screen and a sentence represented by a list of non-empty words, find how many times the given sentence can be fitted on the screen.\\n\",\n    \"\\n\",\n    \"Note:\\n\",\n    \"\\n\",\n    \"A word cannot be split into two lines.\\n\",\n    \"The order of words in the sentence must remain unchanged.\\n\",\n    \"Two consecutive words in a line must be separated by a single space.\\n\",\n    \"Total words in the sentence won't exceed 100.\\n\",\n    \"Length of each word is greater than 0 and won't exceed 10.\\n\",\n    \"1 ≤ rows, cols ≤ 20,000.\\n\",\n    \"Example 1:\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"rows = 2, cols = 8, sentence = [\\\"hello\\\", \\\"world\\\"]\\n\",\n    \"\\n\",\n    \"Output: \\n\",\n    \"1\\n\",\n    \"\\n\",\n    \"Explanation:\\n\",\n    \"hello---\\n\",\n    \"world---\\n\",\n    \"\\n\",\n    \"The character '-' signifies an empty space on the screen.\\n\",\n    \"Example 2:\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"rows = 3, cols = 6, sentence = [\\\"a\\\", \\\"bcd\\\", \\\"e\\\"]\\n\",\n    \"\\n\",\n    \"Output: \\n\",\n    \"2\\n\",\n    \"\\n\",\n    \"Explanation:\\n\",\n    \"a-bcd- \\n\",\n    \"e-a---\\n\",\n    \"bcd-e-\\n\",\n    \"\\n\",\n    \"The character '-' signifies an empty space on the screen.\\n\",\n    \"Example 3:\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"rows = 4, cols = 5, sentence = [\\\"I\\\", \\\"had\\\", \\\"apple\\\", \\\"pie\\\"]\\n\",\n    \"\\n\",\n    \"Output: \\n\",\n    \"1\\n\",\n    \"\\n\",\n    \"Explanation:\\n\",\n    \"I-had\\n\",\n    \"apple\\n\",\n    \"pie-I\\n\",\n    \"had--\\n\",\n    \"\\n\",\n    \"The character '-' signifies an empty space on the screen.\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume sentence is ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Is the output an integer?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* rows < 0 or cols < 0 -> ValueError\\n\",\n    \"* cols = 0 -> 0\\n\",\n    \"* sentence = '' -> 0\\n\",\n    \"* rows = 2, cols = 8, sentence = [\\\"hello\\\", \\\"world\\\"] -> 1\\n\",\n    \"* rows = 3, cols = 6, sentence = [\\\"a\\\", \\\"bcd\\\", \\\"e\\\"] -> 2\\n\",\n    \"* rows = 4, cols = 5, sentence = [\\\"I\\\", \\\"had\\\", \\\"apple\\\", \\\"pie\\\"] -> 1\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def count_sentence_fit(self, sentence, rows, cols):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_count_sentence_fit.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_count_sentence_fit(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.count_sentence_fit, \\n\",\n    \"                      None, None, None)\\n\",\n    \"        self.assertRaises(ValueError, solution.count_sentence_fit, \\n\",\n    \"                      'abc', rows=-1, cols=-1)\\n\",\n    \"        sentence = [\\\"hello\\\", \\\"world\\\"]\\n\",\n    \"        expected = 1\\n\",\n    \"        self.assertEqual(solution.count_sentence_fit(sentence, rows=2, cols=8),\\n\",\n    \"                     expected)\\n\",\n    \"        sentence = [\\\"a\\\", \\\"bcd\\\", \\\"e\\\"]\\n\",\n    \"        expected = 2\\n\",\n    \"        self.assertEqual(solution.count_sentence_fit(sentence, rows=3, cols=6),\\n\",\n    \"                     expected)\\n\",\n    \"        sentence = [\\\"I\\\", \\\"had\\\", \\\"apple\\\", \\\"pie\\\"]\\n\",\n    \"        expected = 1\\n\",\n    \"        self.assertEqual(solution.count_sentence_fit(sentence, rows=4, cols=5),\\n\",\n    \"                     expected)\\n\",\n    \"        print('Success: test_count_sentence_fit')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_count_sentence_fit()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/sentence_screen_fit/sentence_screen_fit_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find how many times a sentence can fit on a screen.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/sentence-screen-fitting/) problem page.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Given a rows x cols screen and a sentence represented by a list of non-empty words, find how many times the given sentence can be fitted on the screen.\\n\",\n    \"\\n\",\n    \"Note:\\n\",\n    \"\\n\",\n    \"A word cannot be split into two lines.\\n\",\n    \"The order of words in the sentence must remain unchanged.\\n\",\n    \"Two consecutive words in a line must be separated by a single space.\\n\",\n    \"Total words in the sentence won't exceed 100.\\n\",\n    \"Length of each word is greater than 0 and won't exceed 10.\\n\",\n    \"1 ≤ rows, cols ≤ 20,000.\\n\",\n    \"Example 1:\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"rows = 2, cols = 8, sentence = [\\\"hello\\\", \\\"world\\\"]\\n\",\n    \"\\n\",\n    \"Output: \\n\",\n    \"1\\n\",\n    \"\\n\",\n    \"Explanation:\\n\",\n    \"hello---\\n\",\n    \"world---\\n\",\n    \"\\n\",\n    \"The character '-' signifies an empty space on the screen.\\n\",\n    \"Example 2:\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"rows = 3, cols = 6, sentence = [\\\"a\\\", \\\"bcd\\\", \\\"e\\\"]\\n\",\n    \"\\n\",\n    \"Output: \\n\",\n    \"2\\n\",\n    \"\\n\",\n    \"Explanation:\\n\",\n    \"a-bcd- \\n\",\n    \"e-a---\\n\",\n    \"bcd-e-\\n\",\n    \"\\n\",\n    \"The character '-' signifies an empty space on the screen.\\n\",\n    \"Example 3:\\n\",\n    \"\\n\",\n    \"Input:\\n\",\n    \"rows = 4, cols = 5, sentence = [\\\"I\\\", \\\"had\\\", \\\"apple\\\", \\\"pie\\\"]\\n\",\n    \"\\n\",\n    \"Output: \\n\",\n    \"1\\n\",\n    \"\\n\",\n    \"Explanation:\\n\",\n    \"I-had\\n\",\n    \"apple\\n\",\n    \"pie-I\\n\",\n    \"had--\\n\",\n    \"\\n\",\n    \"The character '-' signifies an empty space on the screen.\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume sentence is ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Is the output an integer?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* rows < 0 or cols < 0 -> ValueError\\n\",\n    \"* cols = 0 -> 0\\n\",\n    \"* sentence = '' -> 0\\n\",\n    \"* rows = 2, cols = 8, sentence = [\\\"hello\\\", \\\"world\\\"] -> 1\\n\",\n    \"* rows = 3, cols = 6, sentence = [\\\"a\\\", \\\"bcd\\\", \\\"e\\\"] -> 2\\n\",\n    \"* rows = 4, cols = 5, sentence = [\\\"I\\\", \\\"had\\\", \\\"apple\\\", \\\"pie\\\"] -> 1\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"It can be relatively straightforward to come up with the brute force solution, check out the method `count_sentence_fit_brute_force` below.  \\n\",\n    \"\\n\",\n    \"The optimized solutions is discussed in more depth [here](https://discuss.leetcode.com/topic/62455/21ms-18-lines-java-solution/25).\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"rows = 4\\n\",\n    \"cols = 6\\n\",\n    \"sentence = ['abc', 'de', 'f']\\n\",\n    \"\\n\",\n    \"\\\"abc de f abc de f abc de f ...\\\" // start=0\\n\",\n    \" 012345                          // start=start+cols+adjustment=0+6+1=7 (1 space removed in screen string)\\n\",\n    \"        012345                   // start=7+6+0=13\\n\",\n    \"              012345             // start=13+6-1=18 (1 space added)\\n\",\n    \"                   012345        // start=18+6+1=25 (1 space added)\\n\",\n    \"                          012345\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def count_sentence_fit_brute_force(self, sentence, rows, cols):\\n\",\n    \"        if sentence is None:\\n\",\n    \"            raise TypeError('sentence cannot be None')\\n\",\n    \"        if rows is None or cols is None:\\n\",\n    \"            raise TypeError('rows and cols cannot be None')\\n\",\n    \"        if rows < 0 or cols < 0:\\n\",\n    \"            raise ValueError('rows and cols cannot be negative')\\n\",\n    \"        if cols == 0 or not sentence:\\n\",\n    \"            return 0\\n\",\n    \"        curr_row = 0\\n\",\n    \"        curr_col = 0\\n\",\n    \"        count = 0\\n\",\n    \"        while curr_row < cols:\\n\",\n    \"            for word in sentence:\\n\",\n    \"                # If the current word doesn't fit on the current line,\\n\",\n    \"                # move to the next line\\n\",\n    \"                if len(word) > cols - curr_col:\\n\",\n    \"                    curr_col = 0\\n\",\n    \"                    curr_row += 1\\n\",\n    \"                # If we are beyond the number of rows, return\\n\",\n    \"                if curr_row >= rows:\\n\",\n    \"                    return count\\n\",\n    \"                # If the current word fits on the current line,\\n\",\n    \"                # 'insert' it here\\n\",\n    \"                if len(word) <= cols - curr_col:\\n\",\n    \"                    curr_col += len(word) + 1\\n\",\n    \"                # If it still doesn't fit, then the word is too long\\n\",\n    \"                # and we should just return the current count\\n\",\n    \"                else:\\n\",\n    \"                    return count\\n\",\n    \"            count += 1\\n\",\n    \"        return count\\n\",\n    \"\\n\",\n    \"    def count_sentence_fit(self, sentence, rows, cols):\\n\",\n    \"        if sentence is None:\\n\",\n    \"            raise TypeError('sentence cannot be None')\\n\",\n    \"        if rows is None or cols is None:\\n\",\n    \"            raise TypeError('rows and cols cannot be None')\\n\",\n    \"        if rows < 0 or cols < 0:\\n\",\n    \"            raise ValueError('rows and cols cannot be negative')\\n\",\n    \"        if cols == 0 or not sentence:\\n\",\n    \"            return 0\\n\",\n    \"        string = ' '.join(sentence) + ' '\\n\",\n    \"        start = 0\\n\",\n    \"        str_len = len(string)\\n\",\n    \"        for row in range(rows):\\n\",\n    \"            start += cols\\n\",\n    \"            # We don't need extra space for the current row\\n\",\n    \"            if string[start % str_len] == ' ':\\n\",\n    \"                start += 1\\n\",\n    \"            # The current row can't fit, so we'll need to \\n\",\n    \"            # remove characters from the next word\\n\",\n    \"            else:\\n\",\n    \"                while (start > 0 and string[(start - 1) % str_len] != ' '):\\n\",\n    \"                    start -= 1\\n\",\n    \"        return start // str_len\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_count_sentence_fit.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_count_sentence_fit.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_count_sentence_fit(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.count_sentence_fit, \\n\",\n    \"                      None, None, None)\\n\",\n    \"        self.assertRaises(ValueError, solution.count_sentence_fit, \\n\",\n    \"                      'abc', rows=-1, cols=-1)\\n\",\n    \"        sentence = [\\\"hello\\\", \\\"world\\\"]\\n\",\n    \"        expected = 1\\n\",\n    \"        self.assertEqual(solution.count_sentence_fit(sentence, rows=2, cols=8),\\n\",\n    \"                     expected)\\n\",\n    \"        sentence = [\\\"a\\\", \\\"bcd\\\", \\\"e\\\"]\\n\",\n    \"        expected = 2\\n\",\n    \"        self.assertEqual(solution.count_sentence_fit(sentence, rows=3, cols=6),\\n\",\n    \"                     expected)\\n\",\n    \"        sentence = [\\\"I\\\", \\\"had\\\", \\\"apple\\\", \\\"pie\\\"]\\n\",\n    \"        expected = 1\\n\",\n    \"        self.assertEqual(solution.count_sentence_fit(sentence, rows=4, cols=5),\\n\",\n    \"                     expected)\\n\",\n    \"        print('Success: test_count_sentence_fit')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_count_sentence_fit()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_count_sentence_fit\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_count_sentence_fit.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/sentence_screen_fit/test_count_sentence_fit.py",
    "content": "import unittest\n\n\nclass TestSolution(unittest.TestCase):\n\n    def test_count_sentence_fit(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.count_sentence_fit, \n                      None, None, None)\n        self.assertRaises(ValueError, solution.count_sentence_fit, \n                      'abc', rows=-1, cols=-1)\n        sentence = [\"hello\", \"world\"]\n        expected = 1\n        self.assertEqual(solution.count_sentence_fit(sentence, rows=2, cols=8),\n                     expected)\n        sentence = [\"a\", \"bcd\", \"e\"]\n        expected = 2\n        self.assertEqual(solution.count_sentence_fit(sentence, rows=3, cols=6),\n                     expected)\n        sentence = [\"I\", \"had\", \"apple\", \"pie\"]\n        expected = 1\n        self.assertEqual(solution.count_sentence_fit(sentence, rows=4, cols=5),\n                     expected)\n        print('Success: test_count_sentence_fit')\n\n\ndef main():\n    test = TestSolution()\n    test.test_count_sentence_fit()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/str_diff/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/str_diff/str_diff_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the Difference.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/find-the-difference/) problem page.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the strings are ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Is case important?\\n\",\n    \"    * The strings are lower case\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* 'aaabbcdd', 'abdbacade' -> 'e'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def find_diff(self, s, t):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_str_diff.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestFindDiff(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_find_diff(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.find_diff, None)\\n\",\n    \"        self.assertEqual(solution.find_diff('aaabbcdd', 'abdbacade'), 'e')\\n\",\n    \"        print('Success: test_find_diff')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestFindDiff()\\n\",\n    \"    test.test_find_diff()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/str_diff/str_diff_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the Difference.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/find-the-difference/) problem page.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the strings are ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Is case important?\\n\",\n    \"    * The strings are lower case\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* 'aaabbcdd', 'abdbacade' -> 'e'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Keep a dictionary of seen values in s\\n\",\n    \"* Loop through t, decrementing the seen values\\n\",\n    \"    * If the char is not there or if the decrement results in a negative value, return the char\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(m+n), where m and n are the lengths of s, t\\n\",\n    \"* Space: O(h), for the dict, where h is the unique chars in s\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def find_diff(self, s, t):\\n\",\n    \"        if s is None or t is None:\\n\",\n    \"            raise TypeError('s or t cannot be None')\\n\",\n    \"        seen = {}\\n\",\n    \"        for char in s:\\n\",\n    \"            if char in seen:\\n\",\n    \"                seen[char] += 1\\n\",\n    \"            else:\\n\",\n    \"                seen[char] = 1\\n\",\n    \"        for char in t:\\n\",\n    \"            try:\\n\",\n    \"                seen[char] -= 1\\n\",\n    \"            except KeyError:\\n\",\n    \"                return char\\n\",\n    \"            if seen[char] < 0:\\n\",\n    \"                return char\\n\",\n    \"        return None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_str_diff.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_str_diff.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestFindDiff(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_find_diff(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.find_diff, None)\\n\",\n    \"        self.assertEqual(solution.find_diff('aaabbcdd', 'abdbacade'), 'e')\\n\",\n    \"        print('Success: test_find_diff')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestFindDiff()\\n\",\n    \"    test.test_find_diff()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_find_diff\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_str_diff.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/str_diff/test_str_diff.py",
    "content": "import unittest\n\n\nclass TestFindDiff(unittest.TestCase):\n\n    def test_find_diff(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.find_diff, None)\n        self.assertEqual(solution.find_diff('aaabbcdd', 'abdbacade'), 'e')\n        print('Success: test_find_diff')\n\n\ndef main():\n    test = TestFindDiff()\n    test.test_find_diff()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/sub_two/sub_two_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Sum of Two Integers (Subtraction Variant).\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/sum-of-two-integers/) problem page.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume we're working with 32 bit ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* 7, 5 -> 2\\n\",\n    \"* -5, -7 -> 2\\n\",\n    \"* -5, 7 -> -12\\n\",\n    \"* 5, -7 -> 12\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def sub_two(self, val):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_sub_two.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSubTwo(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_sub_two(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.sub_two, None)\\n\",\n    \"        self.assertEqual(solution.sub_two(7, 5), 2)\\n\",\n    \"        self.assertEqual(solution.sub_two(-5, -7), 2)\\n\",\n    \"        self.assertEqual(solution.sub_two(-5, 7), -12)\\n\",\n    \"        self.assertEqual(solution.sub_two(5, -7), 12)\\n\",\n    \"        print('Success: test_sub_two')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSubTwo()\\n\",\n    \"    test.test_sub_two()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/sub_two/sub_two_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Sum of Two Integers (Subtraction Variant).\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/sum-of-two-integers/) problem page.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume we're working with 32 bit ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* 7, 5 -> 2\\n\",\n    \"* -5, -7 -> 2\\n\",\n    \"* -5, 7 -> -12\\n\",\n    \"* 5, -7 -> 12\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll look at the following example, subtracting a and b:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"a 0110 = 6 \\n\",\n    \"b 0101 = 5\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"First, subtract a and b, without worrying about the borrow (0-0=0, 0-1=1, 1-1=0):\\n\",\n    \"\\n\",\n    \"result = a ^ b = 0011\\n\",\n    \"\\n\",\n    \"Next, calculate the borrow (0-1=1).  We'll need to left shift one to prepare for the next iteration when we move to the next most significant bit:\\n\",\n    \"\\n\",\n    \"~a     = 1001\\n\",\n    \" b     = 0101\\n\",\n    \"~a & b = 0001\\n\",\n    \"\\n\",\n    \"borrow = (~a&b) << 1 = 0010\\n\",\n    \"\\n\",\n    \"If the borrow is not zero, we'll need to subtract the borrow from the result.  Recursively call the function, passing in result and borrow.\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(b), where b is the number of bits\\n\",\n    \"* Space: O(b), where b is the number of bits\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def sub_two(self, a, b):\\n\",\n    \"        if a is None or b is None:\\n\",\n    \"            raise TypeError('a or b cannot be None')\\n\",\n    \"        result = a ^ b;\\n\",\n    \"        borrow = (~a&b) << 1\\n\",\n    \"        if borrow != 0:\\n\",\n    \"            return self.sub_two(result, borrow)\\n\",\n    \"        return result;\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_sub_two.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_sub_two.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSubTwo(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_sub_two(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.sub_two, None)\\n\",\n    \"        self.assertEqual(solution.sub_two(7, 5), 2)\\n\",\n    \"        self.assertEqual(solution.sub_two(-5, -7), 2)\\n\",\n    \"        self.assertEqual(solution.sub_two(-5, 7), -12)\\n\",\n    \"        self.assertEqual(solution.sub_two(5, -7), 12)\\n\",\n    \"        print('Success: test_sub_two')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSubTwo()\\n\",\n    \"    test.test_sub_two()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {\n    \"scrolled\": true\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_sub_two\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_sub_two.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/sub_two/test_sub_two.py",
    "content": "import unittest\n\n\nclass TestSubTwo(unittest.TestCase):\n\n    def test_sub_two(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.sub_two, None)\n        self.assertEqual(solution.sub_two(7, 5), 2)\n        self.assertEqual(solution.sub_two(-5, -7), 2)\n        self.assertEqual(solution.sub_two(-5, 7), -12)\n        self.assertEqual(solution.sub_two(5, -7), 12)\n        print('Success: test_sub_two')\n\n\ndef main():\n    test = TestSubTwo()\n    test.test_sub_two()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/sum_two/sum_two_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Sum of Two Integers.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/sum-of-two-integers/) problem page.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume we're working with 32 bit ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/sum-of-two-integers/) problem page.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def sum_two(self, val):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_sum_two.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSumTwo(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_sum_two(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.sum_two, None)\\n\",\n    \"        self.assertEqual(solution.sum_two(5, 7), 12)\\n\",\n    \"        self.assertEqual(solution.sum_two(-5, -7), -12)\\n\",\n    \"        self.assertEqual(solution.sum_two(5, -7), -2)\\n\",\n    \"        print('Success: test_sum_two')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSumTwo()\\n\",\n    \"    test.test_sum_two()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/sum_two/sum_two_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Sum of Two Integers.\\n\",\n    \"\\n\",\n    \"See the [LeetCode](https://leetcode.com/problems/sum-of-two-integers/) problem page.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume we're working with 32 bit ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No, check for None\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None input -> TypeError\\n\",\n    \"* 5, 7 -> 12\\n\",\n    \"* -5, -7 -> -12\\n\",\n    \"* 5, -7 -> -2\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll look at the following example, adding a and b:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"a 0111 \\n\",\n    \"b 0101\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"First, add a and b, without worrying about the carry (0+0=0, 0+1=1, 1+1=0):\\n\",\n    \"\\n\",\n    \"result = a ^ b = 0010\\n\",\n    \"\\n\",\n    \"Next, calculate the carry (1+1=2).  We'll need to left shift one to prepare for the next iteration when we move to the next most significant bit:\\n\",\n    \"\\n\",\n    \"carry = (a&b) << 1 = 1010\\n\",\n    \"\\n\",\n    \"If the carry is not zero, we'll need to add the carry to the result.  Recursively call the function, passing in result and carry.\\n\",\n    \"\\n\",\n    \"Below are the values of a, b, and the carry of a = 7 and b = 5, producing the result of 12.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"a 0111 \\n\",\n    \"b 0101 \\n\",\n    \"----- \\n\",\n    \"c 0101 \\n\",\n    \"a 0010 \\n\",\n    \"b 1010 \\n\",\n    \"----- \\n\",\n    \"c 0010 \\n\",\n    \"a 1000 \\n\",\n    \"b 0100 \\n\",\n    \"----- \\n\",\n    \"c 0000 \\n\",\n    \"a 1100 \\n\",\n    \"b 0000\\n\",\n    \"\\n\",\n    \"c = carry = 0, return the result 1100\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(b), where b is the number of bits\\n\",\n    \"* Space: O(b), where b is the number of bits\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def sum_two(self, a, b):\\n\",\n    \"        if a is None or b is None:\\n\",\n    \"            raise TypeError('a or b cannot be None')\\n\",\n    \"        result = a ^ b;\\n\",\n    \"        carry = (a&b) << 1\\n\",\n    \"        if carry != 0:\\n\",\n    \"            return self.sum_two(result, carry)\\n\",\n    \"        return result;\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_sum_two.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_sum_two.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSumTwo(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_sum_two(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.sum_two, None)\\n\",\n    \"        self.assertEqual(solution.sum_two(5, 7), 12)\\n\",\n    \"        self.assertEqual(solution.sum_two(-5, -7), -12)\\n\",\n    \"        self.assertEqual(solution.sum_two(5, -7), -2)\\n\",\n    \"        print('Success: test_sum_two')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSumTwo()\\n\",\n    \"    test.test_sum_two()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {\n    \"scrolled\": true\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_sum_two\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_sum_two.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/sum_two/test_sum_two.py",
    "content": "import unittest\n\n\nclass TestSumTwo(unittest.TestCase):\n\n    def test_sum_two(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.sum_two, None)\n        self.assertEqual(solution.sum_two(5, 7), 12)\n        self.assertEqual(solution.sum_two(-5, -7), -12)\n        self.assertEqual(solution.sum_two(5, -7), -2)\n        print('Success: test_sum_two')\n\n\ndef main():\n    test = TestSumTwo()\n    test.test_sum_two()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/utopian_tree/__init__.py",
    "content": ""
  },
  {
    "path": "online_judges/utopian_tree/test_utopian_tree.py",
    "content": "import unittest\n\n\nclass TestUtopianTree(unittest.TestCase):\n\n    def test_utopian_tree(self):\n        solution = Solution()\n        self.assertEqual(solution.calc_utopian_tree_height(0), 1)\n        self.assertEqual(solution.calc_utopian_tree_height(1), 2)\n        self.assertEqual(solution.calc_utopian_tree_height(4), 7)\n        print('Success: test_utopian_tree')\n\n\ndef main():\n    test = TestUtopianTree()\n    test.test_utopian_tree()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "online_judges/utopian_tree/utopian_tree_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Utopian Tree\\n\",\n    \"\\n\",\n    \"See the [HackerRank problem page](https://www.hackerrank.com/challenges/utopian-tree).\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"See the [HackerRank problem page](https://www.hackerrank.com/challenges/utopian-tree).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"See the [HackerRank problem page](https://www.hackerrank.com/challenges/utopian-tree).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/hackerrank_topcoder/utopian_tree/utopian_tree_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def calc_utopian_tree_height(self, cycles):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_utopian_tree.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestUtopianTree(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_utopian_tree(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertEqual(solution.calc_utopian_tree_height(0), 1)\\n\",\n    \"        self.assertEqual(solution.calc_utopian_tree_height(1), 2)\\n\",\n    \"        self.assertEqual(solution.calc_utopian_tree_height(4), 7)\\n\",\n    \"        print('Success: test_utopian_tree')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestUtopianTree()\\n\",\n    \"    test.test_utopian_tree()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/hackerrank_topcoder/utopian_tree/utopian_tree_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "online_judges/utopian_tree/utopian_tree_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Utopian Tree\\n\",\n    \"\\n\",\n    \"See the [HackerRank problem page](https://www.hackerrank.com/challenges/utopian-tree).\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"See the [HackerRank problem page](https://www.hackerrank.com/challenges/utopian-tree).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"See the [HackerRank problem page](https://www.hackerrank.com/challenges/utopian-tree).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* If cycles is 0, return height of 1\\n\",\n    \"* For 1 to cycles:\\n\",\n    \"    * If cycle is odd, double height\\n\",\n    \"    * Else, increment height\\n\",\n    \"* Return height\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def calc_utopian_tree_height(self, cycles):\\n\",\n    \"        height = 1\\n\",\n    \"        if cycles == 0:\\n\",\n    \"            return height\\n\",\n    \"        for i in range(1, cycles+1):\\n\",\n    \"            if i % 2 == 1:\\n\",\n    \"                height *= 2\\n\",\n    \"            else:\\n\",\n    \"                height += 1\\n\",\n    \"        return height\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_utopian_tree.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_utopian_tree.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestUtopianTree(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_utopian_tree(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertEqual(solution.calc_utopian_tree_height(0), 1)\\n\",\n    \"        self.assertEqual(solution.calc_utopian_tree_height(1), 2)\\n\",\n    \"        self.assertEqual(solution.calc_utopian_tree_height(4), 7)\\n\",\n    \"        print('Success: test_utopian_tree')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestUtopianTree()\\n\",\n    \"    test.test_utopian_tree()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_utopian_tree\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"run -i test_utopian_tree.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/coin_change/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/coin_change/coin_change_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine the total number of unique ways to make n cents, given coins of denominations less than n cents.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Do the coins have to reach exactly n cents?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we have an infinite number of coins to make n cents?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we need to report the combination(s) of coins that represent the minimum?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the coin denominations are given in sorted order?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* coins: None or n: None -> Exception\\n\",\n    \"* coins: [] or n: 0 -> 0\\n\",\n    \"* coins: [1, 2, 3], n: 5 -> 5\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/coin_change/coin_change_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class CoinChanger(object):\\n\",\n    \"\\n\",\n    \"    def make_change(self, coins, total):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        return n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_coin_change.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Challenge(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_coin_change(self):\\n\",\n    \"        coin_changer = CoinChanger()\\n\",\n    \"        self.assertEqual(coin_changer.make_change([1, 2], 0), 0)\\n\",\n    \"        self.assertEqual(coin_changer.make_change([1, 2, 3], 5), 5)\\n\",\n    \"        self.assertEqual(coin_changer.make_change([1, 5, 25, 50], 10), 3)\\n\",\n    \"        print('Success: test_coin_change')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = Challenge()\\n\",\n    \"    test.test_coin_change()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/coin_change/coin_change_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/coin_change/coin_change_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine the total number of unique ways to make n cents, given coins of denominations less than n cents.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Do the coins have to reach exactly n cents?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we have an infinite number of coins to make n cents?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we need to report the combination(s) of coins that represent the minimum?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the coin denominations are given in sorted order?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* coins: None or n: None -> Exception\\n\",\n    \"* coins: [] or n: 0 -> 0\\n\",\n    \"* coins: [1, 2, 3], n: 5 -> 5\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use a bottom-up dynamic programming approach.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"The rows (i) represent the coin values.\\n\",\n    \"The columns (j) represent the totals.\\n\",\n    \"\\n\",\n    \"  -------------------------\\n\",\n    \"  | 0 | 1 | 2 | 3 | 4 | 5 |\\n\",\n    \"  -------------------------\\n\",\n    \"0 | 1 | 0 | 0 | 0 | 0 | 0 |\\n\",\n    \"1 | 1 | 1 | 1 | 1 | 1 | 1 |\\n\",\n    \"2 | 1 | 1 | 2 | 2 | 3 | 3 |\\n\",\n    \"3 | 1 | 1 | 2 | 3 | 4 | 5 |\\n\",\n    \"  -------------------------\\n\",\n    \"\\n\",\n    \"Number of ways to get total n with coin[n] equals:\\n\",\n    \"* Number of ways to get total n with coin[n - 1] plus\\n\",\n    \"* Number of ways to get total n - coin[n]\\n\",\n    \"\\n\",\n    \"if j == 0:\\n\",\n    \"    T[i][j] = 1\\n\",\n    \"if row == 0:\\n\",\n    \"    T[i][j] = 0\\n\",\n    \"if coins[i] >= j\\n\",\n    \"    T[i][j] = T[i - 1][j] + T[i][j - coins[i]]\\n\",\n    \"else:\\n\",\n    \"    T[i][j] = T[i - 1][j]\\n\",\n    \"\\n\",\n    \"The answer will be in the bottom right corner of the matrix.\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(i * j)\\n\",\n    \"* Space: O(i * j)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class CoinChanger(object):\\n\",\n    \"\\n\",\n    \"    def make_change(self, coins, total):\\n\",\n    \"        if coins is None or total is None:\\n\",\n    \"            return None\\n\",\n    \"        if not coins or total == 0:\\n\",\n    \"            return 0\\n\",\n    \"        coins = [0] + coins\\n\",\n    \"        num_rows = len(coins)\\n\",\n    \"        num_cols = total + 1\\n\",\n    \"        T = [[None] * num_cols for _ in range(num_rows)]\\n\",\n    \"        for i in range(num_rows):\\n\",\n    \"            for j in range(num_cols):\\n\",\n    \"                if i == 0:\\n\",\n    \"                    T[i][j] = 0\\n\",\n    \"                    continue\\n\",\n    \"                if j == 0:\\n\",\n    \"                    T[i][j] = 1\\n\",\n    \"                    continue\\n\",\n    \"                if coins[i] <= j:\\n\",\n    \"                    T[i][j] = T[i - 1][j] + T[i][j - coins[i]]\\n\",\n    \"                else:\\n\",\n    \"                    T[i][j] = T[i - 1][j]\\n\",\n    \"        return T[num_rows - 1][num_cols - 1]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_coin_change.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_coin_change.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Challenge(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_coin_change(self):\\n\",\n    \"        coin_changer = CoinChanger()\\n\",\n    \"        self.assertEqual(coin_changer.make_change([1, 2], 0), 0)\\n\",\n    \"        self.assertEqual(coin_changer.make_change([1, 2, 3], 5), 5)\\n\",\n    \"        self.assertEqual(coin_changer.make_change([1, 5, 25, 50], 10), 3)\\n\",\n    \"        print('Success: test_coin_change')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = Challenge()\\n\",\n    \"    test.test_coin_change()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_coin_change\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_coin_change.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/coin_change/test_coin_change.py",
    "content": "import unittest\n\n\nclass Challenge(unittest.TestCase):\n\n    def test_coin_change(self):\n        coin_changer = CoinChanger()\n        self.assertEqual(coin_changer.make_change([1, 2], 0), 0)\n        self.assertEqual(coin_changer.make_change([1, 2, 3], 5), 5)\n        self.assertEqual(coin_changer.make_change([1, 5, 25, 50], 10), 3)\n        print('Success: test_coin_change')\n\n\ndef main():\n    test = Challenge()\n    test.test_coin_change()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/coin_change_min/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/coin_change_min/coin_change_min_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine the minimum number of ways to make n cents, given coins of denominations less than n cents.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Do the coins have to reach exactly n cents?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we have an infinite number of coins to make n cents?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we need to report the combination(s) of coins that represent the minimum?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the coin denominations are given in sorted order?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* coins: None or n: None -> Exception\\n\",\n    \"* coins: [] or n: 0 -> 0\\n\",\n    \"* coins: [1, 2, 3] or [3, 2, 1] -> 2\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/coin_change_min/coin_change_min_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class CoinChanger(object):\\n\",\n    \"\\n\",\n    \"    def make_change(self, coins, total):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_coin_change_min.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestCoinChange(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_coin_change(self):\\n\",\n    \"        coin_changer = CoinChanger()\\n\",\n    \"        self.assertRaises(TypeError, coin_changer.make_change, None, None)\\n\",\n    \"        self.assertEqual(coin_changer.make_change([], 0), 0)\\n\",\n    \"        self.assertEqual(coin_changer.make_change([1, 2, 3], 5), 2)\\n\",\n    \"        self.assertEqual(coin_changer.make_change([3, 2, 1], 5), 2)\\n\",\n    \"        self.assertEqual(coin_changer.make_change([3, 2, 1], 8), 3)\\n\",\n    \"        print('Success: test_coin_change')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestCoinChange()\\n\",\n    \"    test.test_coin_change()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/coin_change_min/coin_change_min_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/coin_change_min/coin_change_min_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Determine the minimum number of ways to make n cents, given coins of denominations less than n cents.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Do the coins have to reach exactly n cents?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we have an infinite number of coins to make n cents?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we need to report the combination(s) of coins that represent the minimum?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the coin denominations are given in sorted order?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* coins: None or n: None -> Exception\\n\",\n    \"* coins: [] or n: 0 -> 0\\n\",\n    \"* coins: [1, 2, 3] or [3, 2, 1], n: 5 -> 2\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use top down dynamic programming with memoization.\\n\",\n    \"\\n\",\n    \"* Base case: If the total is 0, return 0\\n\",\n    \"* If the total is already in the memo, return it\\n\",\n    \"* For each coin denomination:\\n\",\n    \"    * If this coin > total, continue\\n\",\n    \"    * Recurse, decreasing total by the coin denomination, keeping track of the min return\\n\",\n    \"* Set memo[total] to the min value + 1\\n\",\n    \"* Return the memo[total]\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"total: 5\\n\",\n    \"coins: [1,2,3]\\n\",\n    \"memo key: total value: min ways\\n\",\n    \"memo = {\\n\",\n    \"    1: 1,\\n\",\n    \"    2: 1,\\n\",\n    \"    3: 1,\\n\",\n    \"    4: 2,\\n\",\n    \"    5: 2\\n\",\n    \"}\\n\",\n    \"                              5\\n\",\n    \"                           1, 2, 3\\n\",\n    \"                          /\\n\",\n    \"                         4\\n\",\n    \"                      1, 2, 3\\n\",\n    \"                     /\\n\",\n    \"                    3\\n\",\n    \"              1,    2,    3\\n\",\n    \"             /       \\\\     \\\\____\\n\",\n    \"            2         1         0\\n\",\n    \"         1, 2, 3   1, 2, 3\\n\",\n    \"        /   |\\n\",\n    \"       1    0\\n\",\n    \"    1, 2, 3\\n\",\n    \"   /\\n\",\n    \"  0\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(t * n), where t is the total and n is the number of coin denominations\\n\",\n    \"* Space: O(t) for the recursion depth\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import sys\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class CoinChanger(object):\\n\",\n    \"\\n\",\n    \"    def make_change(self, coins, total):\\n\",\n    \"        if coins is None or total is None:\\n\",\n    \"            raise TypeError('coins or total cannot be None')\\n\",\n    \"        if not coins or total == 0:\\n\",\n    \"            return 0\\n\",\n    \"        cache = {}\\n\",\n    \"        return self._make_change(coins, total, cache)\\n\",\n    \"\\n\",\n    \"    def _make_change(self, coins, total, cache):\\n\",\n    \"        if total == 0:\\n\",\n    \"            return 0\\n\",\n    \"        if total in cache:\\n\",\n    \"            return cache[total]\\n\",\n    \"        min_ways = sys.maxsize\\n\",\n    \"        for coin in coins:\\n\",\n    \"            if total - coin < 0:\\n\",\n    \"                continue\\n\",\n    \"            ways = self._make_change(coins, total - coin, cache)\\n\",\n    \"            if ways < min_ways:\\n\",\n    \"                min_ways = ways\\n\",\n    \"        cache[total] = min_ways + 1\\n\",\n    \"        return cache[total]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_coin_change_min.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_coin_change_min.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestCoinChange(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_coin_change(self):\\n\",\n    \"        coin_changer = CoinChanger()\\n\",\n    \"        self.assertRaises(TypeError, coin_changer.make_change, None, None)\\n\",\n    \"        self.assertEqual(coin_changer.make_change([], 0), 0)\\n\",\n    \"        self.assertEqual(coin_changer.make_change([1, 2, 3], 5), 2)\\n\",\n    \"        self.assertEqual(coin_changer.make_change([3, 2, 1], 5), 2)\\n\",\n    \"        self.assertEqual(coin_changer.make_change([3, 2, 1], 8), 3)\\n\",\n    \"        print('Success: test_coin_change')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestCoinChange()\\n\",\n    \"    test.test_coin_change()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_coin_change\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_coin_change_min.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/coin_change_min/test_coin_change_min.py",
    "content": "import unittest\n\n\nclass TestCoinChange(unittest.TestCase):\n\n    def test_coin_change(self):\n        coin_changer = CoinChanger()\n        self.assertRaises(TypeError, coin_changer.make_change, None, None)\n        self.assertEqual(coin_changer.make_change([], 0), 0)\n        self.assertEqual(coin_changer.make_change([1, 2, 3], 5), 2)\n        self.assertEqual(coin_changer.make_change([3, 2, 1], 5), 2)\n        self.assertEqual(coin_changer.make_change([3, 2, 1], 8), 3)\n        print('Success: test_coin_change')\n\n\ndef main():\n    test = TestCoinChange()\n    test.test_coin_change()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/coin_change_ways/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/coin_change_ways/coin_change_ways_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [mrb00l34n](http://github.com/mrb00l34n). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Counting Ways of Making Change.\\n\",\n    \"\\n\",\n    \"* [Explanation](#Explanation)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Explanation\\n\",\n    \"\\n\",\n    \"How many ways are there of making change for n, given an array of distinct coins? For example:\\n\",\n    \"\\n\",\n    \"Input: n = 4, coins = [1, 2]\\n\",\n    \"\\n\",\n    \"Output: 3. 1+1+1+1, 1+2+1, 2+2, would be the ways of making change.\\n\",\n    \"\\n\",\n    \"Note that a coin can be used any number of times, and we are counting unique combinations.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Input: n = 0, coins = [1, 2] -> Output: 0\\n\",\n    \"* Input: n = 100, coins = [1, 2, 3] -> Output: 884\\n\",\n    \"* Input: n = 1000, coins = [1, 2, 3...99, 100] -> Output: 15658181104580771094597751280645\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/coin_change_ways/coin_change_ways_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def change_ways(n, coins):\\n\",\n    \"    # TODO: Implement me\\n\",\n    \"    return n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_coin_change_ways.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Challenge(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_coin_change_ways(self,solution):\\n\",\n    \"        self.assertEqual(solution(0, [1, 2]), 0)\\n\",\n    \"        self.assertEqual(solution(100, [1, 2, 3]), 884)\\n\",\n    \"        self.assertEqual(solution(1000, range(1, 101)), \\n\",\n    \"                     15658181104580771094597751280645)\\n\",\n    \"        print('Success: test_coin_change_ways')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = Challenge()\\n\",\n    \"    test.test_coin_change_ways(change_ways)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/coin_change_ways/coin_change_ways_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/coin_change_ways/coin_change_ways_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [mrb00l34n](http://github.com/mrb00l34n). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Counting Ways of Making Change.\\n\",\n    \"\\n\",\n    \"* [Hints](#Hints)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Hints\\n\",\n    \"\\n\",\n    \"* Can you think of a way to build up to a solution?\\n\",\n    \"* If there are 2 ways of making 3, and you are now given a coin of value v, how many ways can you make 3 + v?\\n\",\n    \"* Can you think of a way to divide the problem into smaller subproblems?\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"One possible solution using dynamic programming:\\n\",\n    \"* Create an array, s.t arr[i] = # of ways to make change for i\\n\",\n    \"* Initialize arr[0] = 1, arr[i>0] = 0\\n\",\n    \"* For each coin, and for each index from coin to n, increment arr[i] by arr[i - coin]\\n\",\n    \"\\n\",\n    \"How does this work?\\n\",\n    \"* As we iterate through each coin, we are adding the ways of making arr[i - coin] to arr[i]\\n\",\n    \"* If we have 2 ways of making 4, and are now iterating on a coin of value 3, there should be 2 ways of making 7.\\n\",\n    \"* We are essentially adding the coin we are iterating on to the # of ways of making arr[i].\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(mn); let the number of coins be m. We iterate from arr[coin] -> arr[n], or ~ n operations on each coin, hence n*m. \\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def change_ways(n, coins):\\n\",\n    \"    arr = [1] + [0] * n\\n\",\n    \"    for coin in coins:\\n\",\n    \"        for i in range(coin, n + 1):\\n\",\n    \"            arr[i] += arr[i - coin]\\n\",\n    \"    return 0 if n == 0 else arr[n]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_coin_change_ways.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_coin_change_ways.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Challenge(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_coin_change_ways(self,solution):\\n\",\n    \"        self.assertEqual(solution(0, [1, 2]), 0)\\n\",\n    \"        self.assertEqual(solution(100, [1, 2, 3]), 884)\\n\",\n    \"        self.assertEqual(solution(1000, range(1, 101)), \\n\",\n    \"                     15658181104580771094597751280645)\\n\",\n    \"        print('Success: test_coin_change_ways')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = Challenge()\\n\",\n    \"    test.test_coin_change_ways(change_ways)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_coin_change_ways\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_coin_change_ways.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/coin_change_ways/test_coin_change_ways.py",
    "content": "import unittest\n\n\nclass Challenge(unittest.TestCase):\n\n    def test_coin_change_ways(self,solution):\n        self.assertEqual(solution(0, [1, 2]), 0)\n        self.assertEqual(solution(100, [1, 2, 3]), 884)\n        self.assertEqual(solution(1000, range(1, 101)), \n                     15658181104580771094597751280645)\n        print('Success: test_coin_change_ways')\n\n\ndef main():\n    test = Challenge()\n    test.test_coin_change_ways(change_ways)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/fibonacci/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/fibonacci/fibonacci_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement fibonacci recursively, dynamically, and iteratively.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Does the sequence start at 0 or 1?\\n\",\n    \"    * 0\\n\",\n    \"* Can we assume the inputs are valid non-negative ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Are you looking for a recursive or iterative solution?\\n\",\n    \"    * Implement both\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* n = 0 -> 0\\n\",\n    \"* n = 1 -> 1\\n\",\n    \"* n = 6 -> 8\\n\",\n    \"* Fib sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34...\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/fibonacci/fibonacci_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"class Math(object):\\n\",\n    \"\\n\",\n    \"    def fib_iterative(self, n):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def fib_recursive(self, n):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def fib_dynamic(self, n):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_fibonacci.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestFib(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_fib(self, func):\\n\",\n    \"        result = []\\n\",\n    \"        expected = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]\\n\",\n    \"        for i in range(len(expected)):\\n\",\n    \"            result.append(func(i))\\n\",\n    \"        self.assertEqual(result, expected)\\n\",\n    \"        print('Success: test_fib')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestFib()\\n\",\n    \"    math = Math()\\n\",\n    \"    test.test_fib(math.fib_recursive)\\n\",\n    \"    test.test_fib(math.fib_dynamic)\\n\",\n    \"    test.test_fib(math.fib_iterative)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/fibonacci/fibonacci_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/fibonacci/fibonacci_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement fibonacci recursively, dynamically, and iteratively.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Does the sequence start at 0 or 1?\\n\",\n    \"    * 0\\n\",\n    \"* Can we assume the inputs are valid non-negative ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Are you looking for a recursive or iterative solution?\\n\",\n    \"    * Either\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* n = 0 -> 0\\n\",\n    \"* n = 1 -> 1\\n\",\n    \"* n = 6 -> 8\\n\",\n    \"* Fib sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34...\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Recursive:\\n\",\n    \"* Fibonacci is as follows: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34...\\n\",\n    \"* If n = 0 or 1, return n\\n\",\n    \"* Else return fib(n-1) + fib(n-2)\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(2^n) if recursive or iterative, O(n) if dynamic\\n\",\n    \"* Space: O(n) if recursive, O(1) if iterative, O(n) if dynamic\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Math(object):\\n\",\n    \"\\n\",\n    \"    def fib_iterative(self, n):\\n\",\n    \"        a = 0\\n\",\n    \"        b = 1\\n\",\n    \"        for _ in range(n):\\n\",\n    \"            a, b = b, a + b\\n\",\n    \"        return a\\n\",\n    \"\\n\",\n    \"    def fib_recursive(self, n):\\n\",\n    \"        if n == 0 or n == 1:\\n\",\n    \"            return n\\n\",\n    \"        else:\\n\",\n    \"            return self.fib_recursive(n-1) + self.fib_recursive(n-2)\\n\",\n    \"\\n\",\n    \"    def fib_dynamic(self, n):\\n\",\n    \"        cache = {}\\n\",\n    \"        return self._fib_dynamic(n, cache)\\n\",\n    \"\\n\",\n    \"    def _fib_dynamic(self, n, cache):\\n\",\n    \"        if n == 0 or n == 1:\\n\",\n    \"            return n\\n\",\n    \"        if n in cache:\\n\",\n    \"            return cache[n]\\n\",\n    \"        cache[n] = self._fib_dynamic(n-1, cache) + self._fib_dynamic(n-2, cache)\\n\",\n    \"        return cache[n]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_fibonacci.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_fibonacci.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestFib(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_fib(self, func):\\n\",\n    \"        result = []\\n\",\n    \"        expected = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]\\n\",\n    \"        for i in range(len(expected)):\\n\",\n    \"            result.append(func(i))\\n\",\n    \"        self.assertEqual(result, expected)\\n\",\n    \"        print('Success: test_fib')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestFib()\\n\",\n    \"    math = Math()\\n\",\n    \"    test.test_fib(math.fib_recursive)\\n\",\n    \"    test.test_fib(math.fib_dynamic)\\n\",\n    \"    test.test_fib(math.fib_iterative)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_fib\\n\",\n      \"Success: test_fib\\n\",\n      \"Success: test_fib\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_fibonacci.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/fibonacci/test_fibonacci.py",
    "content": "import unittest\n\n\nclass TestFib(unittest.TestCase):\n\n    def test_fib(self, func):\n        result = []\n        expected = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]\n        for i in range(len(expected)):\n            result.append(func(i))\n        self.assertEqual(result, expected)\n        print('Success: test_fib')\n\n\ndef main():\n    test = TestFib()\n    math = Math()\n    test.test_fib(math.fib_recursive)\n    test.test_fib(math.fib_dynamic)\n    test.test_fib(math.fib_iterative)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/grid_path/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/grid_path/grid_path_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement an algorithm to have a robot move from the upper left corner to the bottom right corner of a grid.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are there restrictions to how the robot moves?\\n\",\n    \"    * The robot can only move right and down\\n\",\n    \"* Are some cells off limits?\\n\",\n    \"    * Yes\\n\",\n    \"* Is this a rectangular grid? i.e. the grid is not jagged?\\n\",\n    \"    * Yes\\n\",\n    \"* Will there always be a valid way for the robot to get to the bottom right?\\n\",\n    \"    * No, return None\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"o = valid cell\\n\",\n    \"x = invalid cell\\n\",\n    \"\\n\",\n    \"   0  1  2  3\\n\",\n    \"0  o  o  o  o\\n\",\n    \"1  o  x  o  o\\n\",\n    \"2  o  o  x  o\\n\",\n    \"3  x  o  o  o\\n\",\n    \"4  o  o  x  o\\n\",\n    \"5  o  o  o  x\\n\",\n    \"6  o  x  o  x\\n\",\n    \"7  o  x  o  o\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"* General case\\n\",\n    \"\\n\",\n    \"```\\n\",\n    \"expected = [(0, 0), (1, 0), (2, 0),\\n\",\n    \"            (2, 1), (3, 1), (4, 1),\\n\",\n    \"            (5, 1), (5, 2), (6, 2), \\n\",\n    \"            (7, 2), (7, 3)]\\n\",\n    \"```\\n\",\n    \"\\n\",\n    \"* No valid path: In above example, row 7 col 2 is also invalid -> None\\n\",\n    \"* None input -> None\\n\",\n    \"* Empty matrix -> None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Grid(object):\\n\",\n    \"\\n\",\n    \"    def find_path(self, matrix):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_grid_path.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestGridPath(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_grid_path(self):\\n\",\n    \"        grid = Grid()\\n\",\n    \"        self.assertEqual(grid.find_path(None), None)\\n\",\n    \"        self.assertEqual(grid.find_path([[]]), None)\\n\",\n    \"        max_rows = 8\\n\",\n    \"        max_cols = 4\\n\",\n    \"        matrix = [[1] * max_cols for _ in range(max_rows)]\\n\",\n    \"        matrix[1][1] = 0\\n\",\n    \"        matrix[2][2] = 0\\n\",\n    \"        matrix[3][0] = 0\\n\",\n    \"        matrix[4][2] = 0\\n\",\n    \"        matrix[5][3] = 0\\n\",\n    \"        matrix[6][1] = 0\\n\",\n    \"        matrix[6][3] = 0\\n\",\n    \"        matrix[7][1] = 0\\n\",\n    \"        result = grid.find_path(matrix)\\n\",\n    \"        expected = [(0, 0), (1, 0), (2, 0),\\n\",\n    \"                    (2, 1), (3, 1), (4, 1),\\n\",\n    \"                    (5, 1), (5, 2), (6, 2), \\n\",\n    \"                    (7, 2), (7, 3)]\\n\",\n    \"        self.assertEqual(result, expected)\\n\",\n    \"        matrix[7][2] = 0\\n\",\n    \"        result = grid.find_path(matrix)\\n\",\n    \"        self.assertEqual(result, None)\\n\",\n    \"        print('Success: test_grid_path')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestGridPath()\\n\",\n    \"    test.test_grid_path()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/grid_path/grid_path_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement an algorithm to have a robot move from the upper left corner to the bottom right corner of a grid.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are there restrictions to how the robot moves?\\n\",\n    \"    * The robot can only move right and down\\n\",\n    \"* Are some cells invalid (off limits)?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the starting and ending cells are valid cells?\\n\",\n    \"    * Yes\\n\",\n    \"* Is this a rectangular grid? i.e. the grid is not jagged?\\n\",\n    \"    * Yes\\n\",\n    \"* Will there always be a valid way for the robot to get to the bottom right?\\n\",\n    \"    * No, return None\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"o = valid cell\\n\",\n    \"x = invalid cell\\n\",\n    \"\\n\",\n    \"   0  1  2  3\\n\",\n    \"0  o  o  o  o\\n\",\n    \"1  o  x  o  o\\n\",\n    \"2  o  o  x  o\\n\",\n    \"3  x  o  o  o\\n\",\n    \"4  o  o  x  o\\n\",\n    \"5  o  o  o  x\\n\",\n    \"6  o  x  o  x\\n\",\n    \"7  o  x  o  o\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"* General case\\n\",\n    \"\\n\",\n    \"```\\n\",\n    \"expected = [(0, 0), (1, 0), (2, 0),\\n\",\n    \"            (2, 1), (3, 1), (4, 1),\\n\",\n    \"            (5, 1), (5, 2), (6, 2), \\n\",\n    \"            (7, 2), (7, 3)]\\n\",\n    \"```\\n\",\n    \"\\n\",\n    \"* No valid path, say row 7, col 2 is invalid\\n\",\n    \"* None input\\n\",\n    \"* Empty matrix\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"To get to row r and column c [r, c], we will need to have gone:\\n\",\n    \"\\n\",\n    \"* Right from [r, c-1] if this is a valid cell - [Path 1] \\n\",\n    \"* Down from [r-1, c] if this is a valid cell - [Path 2]\\n\",\n    \"\\n\",\n    \"If we look at [Path 1], to get to [r, c-1], we will need to have gone:\\n\",\n    \"\\n\",\n    \"* Right from [r, c-2] if this is a valid cell\\n\",\n    \"* Down from [r-1, c-1] if this is a valid cell\\n\",\n    \"\\n\",\n    \"Continue this process until we reach the start cell or until we find that there is no path.\\n\",\n    \"\\n\",\n    \"Base case:\\n\",\n    \"\\n\",\n    \"* If the input row or col are < 0, or if [row, col] is not a valid cell\\n\",\n    \"    * Return False\\n\",\n    \"\\n\",\n    \"Recursive case:\\n\",\n    \"\\n\",\n    \"We'll memoize the solution to improve performance.\\n\",\n    \"\\n\",\n    \"* Use the memo to see if we've already processed the current cell\\n\",\n    \"* If any of the following is True, append the current cell to the path and set our result to True:\\n\",\n    \"    * We are at the start cell\\n\",\n    \"    * We get a True result from a recursive call on:\\n\",\n    \"        * [row, col-1]\\n\",\n    \"        * [row-1, col]\\n\",\n    \"* Update the memo\\n\",\n    \"* Return the result\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(row * col)\\n\",\n    \"* Space: O(row * col) for the recursion depth\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Grid(object):\\n\",\n    \"\\n\",\n    \"    def find_path(self, matrix):\\n\",\n    \"        if matrix is None or not matrix:\\n\",\n    \"            return None\\n\",\n    \"        cache = {}\\n\",\n    \"        path = []\\n\",\n    \"        if self._find_path(matrix, len(matrix) - 1, \\n\",\n    \"                           len(matrix[0]) - 1, cache, path):\\n\",\n    \"            return path\\n\",\n    \"        else:\\n\",\n    \"            return None\\n\",\n    \"\\n\",\n    \"    def _find_path(self, matrix, row, col, cache, path):\\n\",\n    \"        if row < 0 or col < 0 or not matrix[row][col]:\\n\",\n    \"            return False\\n\",\n    \"        cell = (row, col)\\n\",\n    \"        if cell in cache:\\n\",\n    \"            return cache[cell]\\n\",\n    \"        cache[cell] = (row == 0 and col == 0 or\\n\",\n    \"                       self._find_path(matrix, row, col - 1, cache, path) or\\n\",\n    \"                       self._find_path(matrix, row - 1, col, cache, path))\\n\",\n    \"        if cache[cell]:\\n\",\n    \"            path.append(cell)\\n\",\n    \"        return cache[cell]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_grid_path.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_grid_path.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestGridPath(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_grid_path(self):\\n\",\n    \"        grid = Grid()\\n\",\n    \"        self.assertEqual(grid.find_path(None), None)\\n\",\n    \"        self.assertEqual(grid.find_path([[]]), None)\\n\",\n    \"        max_rows = 8\\n\",\n    \"        max_cols = 4\\n\",\n    \"        matrix = [[1] * max_cols for _ in range(max_rows)]\\n\",\n    \"        matrix[1][1] = 0\\n\",\n    \"        matrix[2][2] = 0\\n\",\n    \"        matrix[3][0] = 0\\n\",\n    \"        matrix[4][2] = 0\\n\",\n    \"        matrix[5][3] = 0\\n\",\n    \"        matrix[6][1] = 0\\n\",\n    \"        matrix[6][3] = 0\\n\",\n    \"        matrix[7][1] = 0\\n\",\n    \"        result = grid.find_path(matrix)\\n\",\n    \"        expected = [(0, 0), (1, 0), (2, 0),\\n\",\n    \"                    (2, 1), (3, 1), (4, 1),\\n\",\n    \"                    (5, 1), (5, 2), (6, 2), \\n\",\n    \"                    (7, 2), (7, 3)]\\n\",\n    \"        self.assertEqual(result, expected)\\n\",\n    \"        matrix[7][2] = 0\\n\",\n    \"        result = grid.find_path(matrix)\\n\",\n    \"        self.assertEqual(result, None)\\n\",\n    \"        print('Success: test_grid_path')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestGridPath()\\n\",\n    \"    test.test_grid_path()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_grid_path\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_grid_path.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/grid_path/test_grid_path.py",
    "content": "import unittest\n\n\nclass TestGridPath(unittest.TestCase):\n\n    def test_grid_path(self):\n        grid = Grid()\n        self.assertEqual(grid.find_path(None), None)\n        self.assertEqual(grid.find_path([[]]), None)\n        max_rows = 8\n        max_cols = 4\n        matrix = [[1] * max_cols for _ in range(max_rows)]\n        matrix[1][1] = 0\n        matrix[2][2] = 0\n        matrix[3][0] = 0\n        matrix[4][2] = 0\n        matrix[5][3] = 0\n        matrix[6][1] = 0\n        matrix[6][3] = 0\n        matrix[7][1] = 0\n        result = grid.find_path(matrix)\n        expected = [(0, 0), (1, 0), (2, 0),\n                    (2, 1), (3, 1), (4, 1),\n                    (5, 1), (5, 2), (6, 2), \n                    (7, 2), (7, 3)]\n        self.assertEqual(result, expected)\n        matrix[7][2] = 0\n        result = grid.find_path(matrix)\n        self.assertEqual(result, None)\n        print('Success: test_grid_path')\n\n\ndef main():\n    test = TestGridPath()\n    test.test_grid_path()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/hanoi/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/hanoi/hanoi_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement the [Towers of Hanoi](http://en.wikipedia.org/wiki/Tower_of_Hanoi) with 3 towers and N disks.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume we already have a stack class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None tower(s) -> Exception\\n\",\n    \"* 0 disks -> None\\n\",\n    \"* 1 disk\\n\",\n    \"* 2 or more disks\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-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.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../../stacks_queues/stack/stack.py\\n\",\n    \"%load ../../stacks_queues/stack/stack.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Hanoi(object):\\n\",\n    \"\\n\",\n    \"    def move_disks(self, num_disks, src, dest, buff):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_hanoi.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestHanoi(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_hanoi(self):\\n\",\n    \"        hanoi = Hanoi()\\n\",\n    \"        num_disks = 3\\n\",\n    \"        src = Stack()\\n\",\n    \"        buff = Stack()\\n\",\n    \"        dest = Stack()\\n\",\n    \"\\n\",\n    \"        print('Test: None towers')\\n\",\n    \"        self.assertRaises(TypeError, hanoi.move_disks, num_disks, None, None, None)\\n\",\n    \"\\n\",\n    \"        print('Test: 0 disks')\\n\",\n    \"        hanoi.move_disks(num_disks, src, dest, buff)\\n\",\n    \"        self.assertEqual(dest.pop(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: 1 disk')\\n\",\n    \"        src.push(5)\\n\",\n    \"        hanoi.move_disks(num_disks, src, dest, buff)\\n\",\n    \"        self.assertEqual(dest.pop(), 5)\\n\",\n    \"\\n\",\n    \"        print('Test: 2 or more disks')\\n\",\n    \"        for disk_index in range(num_disks, -1, -1):\\n\",\n    \"            src.push(disk_index)\\n\",\n    \"        hanoi.move_disks(num_disks, src, dest, buff)\\n\",\n    \"        for disk_index in range(0, num_disks):\\n\",\n    \"            self.assertEqual(dest.pop(), disk_index)\\n\",\n    \"\\n\",\n    \"        print('Success: test_hanoi')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestHanoi()\\n\",\n    \"    test.test_hanoi()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/hanoi/hanoi_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/hanoi/hanoi_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement the [Towers of Hanoi](http://en.wikipedia.org/wiki/Tower_of_Hanoi) with 3 towers and N disks.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume we already have a stack class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None tower(s) -> Exception\\n\",\n    \"* 0 disks -> None\\n\",\n    \"* 1 disk\\n\",\n    \"* 2 or more disks\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Create three stacks to represent each tower\\n\",\n    \"* def hanoi(n, src, dest, buffer):\\n\",\n    \"    * If 0 disks return\\n\",\n    \"    * hanoi(n-1, src, buffer, dest)\\n\",\n    \"    * Move remaining element from src to dest\\n\",\n    \"    * hanoi(n-1, buffer, dest, src)\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(2^n)\\n\",\n    \"* Space: O(m) where m is the number of recursion levels\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../../stacks_queues/stack/stack.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Hanoi(object):\\n\",\n    \"\\n\",\n    \"    def move_disks(self, num_disks, src, dest, buff):\\n\",\n    \"        if src is None or dest is None or buff is None:\\n\",\n    \"            raise TypeError('Cannot have a None input')\\n\",\n    \"        self._move_disks(num_disks, src, dest, buff)\\n\",\n    \"\\n\",\n    \"    def _move_disks(self, num_disks, src, dest, buff):\\n\",\n    \"        if num_disks == 0:\\n\",\n    \"            return\\n\",\n    \"        self.move_disks(num_disks - 1, src, buff, dest)\\n\",\n    \"        dest.push(src.pop())\\n\",\n    \"        self.move_disks(num_disks - 1, buff, dest, src)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_hanoi.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_hanoi.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestHanoi(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_hanoi(self):\\n\",\n    \"        hanoi = Hanoi()\\n\",\n    \"        num_disks = 3\\n\",\n    \"        src = Stack()\\n\",\n    \"        buff = Stack()\\n\",\n    \"        dest = Stack()\\n\",\n    \"\\n\",\n    \"        print('Test: None towers')\\n\",\n    \"        self.assertRaises(TypeError, hanoi.move_disks, num_disks, None, None, None)\\n\",\n    \"\\n\",\n    \"        print('Test: 0 disks')\\n\",\n    \"        hanoi.move_disks(num_disks, src, dest, buff)\\n\",\n    \"        self.assertEqual(dest.pop(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: 1 disk')\\n\",\n    \"        src.push(5)\\n\",\n    \"        hanoi.move_disks(num_disks, src, dest, buff)\\n\",\n    \"        self.assertEqual(dest.pop(), 5)\\n\",\n    \"\\n\",\n    \"        print('Test: 2 or more disks')\\n\",\n    \"        for disk_index in range(num_disks, -1, -1):\\n\",\n    \"            src.push(disk_index)\\n\",\n    \"        hanoi.move_disks(num_disks, src, dest, buff)\\n\",\n    \"        for disk_index in range(0, num_disks):\\n\",\n    \"            self.assertEqual(dest.pop(), disk_index)\\n\",\n    \"\\n\",\n    \"        print('Success: test_hanoi')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestHanoi()\\n\",\n    \"    test.test_hanoi()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: None towers\\n\",\n      \"Test: 0 disks\\n\",\n      \"Test: 1 disk\\n\",\n      \"Test: 2 or more disks\\n\",\n      \"Success: test_hanoi\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_hanoi.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/hanoi/test_hanoi.py",
    "content": "import unittest\n\n\nclass TestHanoi(unittest.TestCase):\n\n    def test_hanoi(self):\n        hanoi = Hanoi()\n        num_disks = 3\n        src = Stack()\n        buff = Stack()\n        dest = Stack()\n\n        print('Test: None towers')\n        self.assertRaises(TypeError, hanoi.move_disks, num_disks, None, None, None)\n\n        print('Test: 0 disks')\n        hanoi.move_disks(num_disks, src, dest, buff)\n        self.assertEqual(dest.pop(), None)\n\n        print('Test: 1 disk')\n        src.push(5)\n        hanoi.move_disks(num_disks, src, dest, buff)\n        self.assertEqual(dest.pop(), 5)\n\n        print('Test: 2 or more disks')\n        for disk_index in range(num_disks, -1, -1):\n            src.push(disk_index)\n        hanoi.move_disks(num_disks, src, dest, buff)\n        for disk_index in range(0, num_disks):\n            self.assertEqual(dest.pop(), disk_index)\n\n        print('Success: test_hanoi')\n\n\ndef main():\n    test = TestHanoi()\n    test.test_hanoi()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/knapsack_01/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/knapsack_01/knapsack_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a knapsack with a total weight capacity and a list of items with weight w(i) and value v(i), determine which items to select to maximize total value.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we replace the items once they are placed in the knapsack?\\n\",\n    \"    * No, this is the 0/1 knapsack problem\\n\",\n    \"* Can we split an item?\\n\",\n    \"    * No\\n\",\n    \"* Can we get an input item with weight of 0 or value of 0?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Are the inputs in sorted order by val/weight?\\n\",\n    \"    * Yes, if not we'd need to sort them first\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* items or total weight is None -> Exception\\n\",\n    \"* items or total weight is 0 -> 0\\n\",\n    \"* General case\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"total_weight = 8\\n\",\n    \"items\\n\",\n    \"  v | w\\n\",\n    \"  0 | 0\\n\",\n    \"a 2 | 2\\n\",\n    \"b 4 | 2\\n\",\n    \"c 6 | 4\\n\",\n    \"d 9 | 5\\n\",\n    \"\\n\",\n    \"max value = 13\\n\",\n    \"items\\n\",\n    \"  v | w\\n\",\n    \"b 4 | 2\\n\",\n    \"d 9 | 5 \\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/knapsack_01/knapsack_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"class Item(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, label, value, weight):\\n\",\n    \"        self.label = label\\n\",\n    \"        self.value = value\\n\",\n    \"        self.weight = weight\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return self.label + ' v:' + str(self.value) + ' w:' + str(self.weight)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Knapsack(object):\\n\",\n    \"\\n\",\n    \"    def fill_knapsack(self, input_items, total_weight):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_knapsack.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestKnapsack(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_knapsack_bottom_up(self):\\n\",\n    \"        knapsack = Knapsack()\\n\",\n    \"        self.assertRaises(TypeError, knapsack.fill_knapsack, None, None)\\n\",\n    \"        self.assertEqual(knapsack.fill_knapsack(0, 0), 0)\\n\",\n    \"        items = []\\n\",\n    \"        items.append(Item(label='a', value=2, weight=2))\\n\",\n    \"        items.append(Item(label='b', value=4, weight=2))\\n\",\n    \"        items.append(Item(label='c', value=6, weight=4))\\n\",\n    \"        items.append(Item(label='d', value=9, weight=5))\\n\",\n    \"        total_weight = 8\\n\",\n    \"        expected_value = 13\\n\",\n    \"        results = knapsack.fill_knapsack(items, total_weight)\\n\",\n    \"        self.assertEqual(results[0].label, 'd')\\n\",\n    \"        self.assertEqual(results[1].label, 'b')\\n\",\n    \"        total_value = 0\\n\",\n    \"        for item in results:\\n\",\n    \"            total_value += item.value\\n\",\n    \"        self.assertEqual(total_value, expected_value)\\n\",\n    \"        print('Success: test_knapsack_bottom_up')\\n\",\n    \"\\n\",\n    \"    def test_knapsack_top_down(self):\\n\",\n    \"        knapsack = KnapsackTopDown()\\n\",\n    \"        self.assertRaises(TypeError, knapsack.fill_knapsack, None, None)\\n\",\n    \"        self.assertEqual(knapsack.fill_knapsack(0, 0), 0)\\n\",\n    \"        items = []\\n\",\n    \"        items.append(Item(label='a', value=2, weight=2))\\n\",\n    \"        items.append(Item(label='b', value=4, weight=2))\\n\",\n    \"        items.append(Item(label='c', value=6, weight=4))\\n\",\n    \"        items.append(Item(label='d', value=9, weight=5))\\n\",\n    \"        total_weight = 8\\n\",\n    \"        expected_value = 13\\n\",\n    \"        self.assertEqual(knapsack.fill_knapsack(items, total_weight), expected_value)\\n\",\n    \"        print('Success: test_knapsack_top_down')\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestKnapsack()\\n\",\n    \"    test.test_knapsack_bottom_up()\\n\",\n    \"    test.test_knapsack_top_down()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/knapsack_01/knapsack_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a knapsack with a total weight capacity and a list of items with weight w(i) and value v(i), determine which items to select to maximize total value.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we replace the items once they are placed in the knapsack?\\n\",\n    \"    * No, this is the 0/1 knapsack problem\\n\",\n    \"* Can we split an item?\\n\",\n    \"    * No\\n\",\n    \"* Can we get an input item with weight of 0 or value of 0?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Are the inputs in sorted order by val/weight?\\n\",\n    \"    * Yes, if not we'd need to sort them first\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* items or total weight is None -> Exception\\n\",\n    \"* items or total weight is 0 -> 0\\n\",\n    \"* General case\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"total_weight = 8\\n\",\n    \"items\\n\",\n    \"  v | w\\n\",\n    \"  0 | 0\\n\",\n    \"a 2 | 2\\n\",\n    \"b 4 | 2\\n\",\n    \"c 6 | 4\\n\",\n    \"d 9 | 5\\n\",\n    \"\\n\",\n    \"max value = 13\\n\",\n    \"items\\n\",\n    \"  v | w\\n\",\n    \"b 4 | 2\\n\",\n    \"d 9 | 5 \\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use bottom up dynamic programming to build a table.\\n\",\n    \"\\n\",\n    \"The solution for the top down approach is also provided below.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"v = value\\n\",\n    \"w = weight\\n\",\n    \"\\n\",\n    \"               j              \\n\",\n    \"    -------------------------------------------------\\n\",\n    \"    | v | w || 0 | 1 | 2 | 3 | 4 | 5 | 6  | 7  | 8  |\\n\",\n    \"    -------------------------------------------------\\n\",\n    \"    | 0 | 0 || 0 | 0 | 0 | 0 | 0 | 0 | 0  | 0  | 0  |\\n\",\n    \"i a | 2 | 2 || 0 | 0 | 2 | 2 | 2 | 2 | 2  | 2  | 2  |\\n\",\n    \"  b | 4 | 2 || 0 | 0 | 4 | 4 | 6 | 6 | 6  | 6  | 6  |\\n\",\n    \"  c | 6 | 4 || 0 | 0 | 4 | 4 | 6 | 6 | 10 | 10 | 12 |\\n\",\n    \"  d | 9 | 5 || 0 | 0 | 4 | 4 | 6 | 9 | 10 | 13 | 13 |\\n\",\n    \"    -------------------------------------------------\\n\",\n    \"\\n\",\n    \"i = row\\n\",\n    \"j = col\\n\",\n    \"\\n\",\n    \"if j >= item[i].weight:\\n\",\n    \"    T[i][j] = max(item[i].value + T[i - 1][j - item[i].weight],\\n\",\n    \"                  T[i - 1][j])\\n\",\n    \"else:\\n\",\n    \"    T[i][j] = T[i - 1][j]\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n * w), where n is the number of items and w is the total weight\\n\",\n    \"* Space: O(n * w), where n is the number of items and w is the total weight\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"### Item Class\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Item(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, label, value, weight):\\n\",\n    \"        self.label = label\\n\",\n    \"        self.value = value\\n\",\n    \"        self.weight = weight\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return self.label + ' v:' + str(self.value) + ' w:' + str(self.weight)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"### Knapsack Bottom Up\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Knapsack(object):\\n\",\n    \"\\n\",\n    \"    def fill_knapsack(self, input_items, total_weight):\\n\",\n    \"        if input_items is None or total_weight is None:\\n\",\n    \"            raise TypeError('input_items or total_weight cannot be None')\\n\",\n    \"        if not input_items or total_weight == 0:\\n\",\n    \"            return 0\\n\",\n    \"        items = list([Item(label='', value=0, weight=0)] + input_items)\\n\",\n    \"        num_rows = len(items)\\n\",\n    \"        num_cols = total_weight + 1\\n\",\n    \"        T = [[None] * num_cols for _ in range(num_rows)]\\n\",\n    \"        for i in range(num_rows):\\n\",\n    \"            for j in range(num_cols):\\n\",\n    \"                if i == 0 or j == 0:\\n\",\n    \"                    T[i][j] = 0\\n\",\n    \"                elif j >= items[i].weight:\\n\",\n    \"                    T[i][j] = max(items[i].value + T[i - 1][j - items[i].weight],\\n\",\n    \"                                  T[i - 1][j])\\n\",\n    \"                else:\\n\",\n    \"                    T[i][j] = T[i - 1][j]\\n\",\n    \"        results = []\\n\",\n    \"        i = num_rows - 1\\n\",\n    \"        j = num_cols - 1\\n\",\n    \"        while T[i][j] != 0:\\n\",\n    \"            if T[i - 1][j] ==  T[i][j]:\\n\",\n    \"                i -= 1\\n\",\n    \"            elif T[i][j - 1] ==  T[i][j]:\\n\",\n    \"                j -= 1\\n\",\n    \"            else:\\n\",\n    \"                results.append(items[i])\\n\",\n    \"                i -= 1\\n\",\n    \"                j -= items[i].weight\\n\",\n    \"        return results\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"### Knapsack Top Down\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class KnapsackTopDown(object):\\n\",\n    \"\\n\",\n    \"    def fill_knapsack(self, items, total_weight):\\n\",\n    \"        if items is None or total_weight is None:\\n\",\n    \"            raise TypeError('input_items or total_weight cannot be None')\\n\",\n    \"        if not items or not total_weight:\\n\",\n    \"            return 0\\n\",\n    \"        memo = {}\\n\",\n    \"        result = self._fill_knapsack(items, total_weight, memo, index=0)\\n\",\n    \"        return result\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"    def _fill_knapsack(self, items, total_weight, memo, index):\\n\",\n    \"        if total_weight < 0:\\n\",\n    \"            return 0\\n\",\n    \"        if not total_weight or index >= len(items):\\n\",\n    \"            return items[index - 1].value\\n\",\n    \"        if (total_weight, len(items) - index - 1) in memo:\\n\",\n    \"            return memo[(total_weight, len(items) - index - 1)] + items[index - 1].value\\n\",\n    \"        results = []\\n\",\n    \"        for i in range(index, len(items)):\\n\",\n    \"            total_weight -= items[i].weight\\n\",\n    \"            result = self._fill_knapsack(items, total_weight, memo, index=i + 1)\\n\",\n    \"            total_weight += items[i].weight\\n\",\n    \"            results.append(result)\\n\",\n    \"        results_index = 0\\n\",\n    \"        for i in range(index, len(items)):\\n\",\n    \"            memo[total_weight, len(items) - i] = max(results[results_index:])\\n\",\n    \"            results_index += 1\\n\",\n    \"        return max(results) + (items[index - 1].value if index > 0 else 0)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"### Knapsack Top Down Alternate\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Result(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, total_weight, item):\\n\",\n    \"        self.total_weight = total_weight\\n\",\n    \"        self.item = item\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return 'w:' + str(self.total_weight) + ' i:' + str(self.item)\\n\",\n    \"\\n\",\n    \"    def __lt__(self, other):\\n\",\n    \"        return self.total_weight < other.total_weight\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def knapsack_top_down_alt(items, total_weight):\\n\",\n    \"    if items is None or total_weight is None:\\n\",\n    \"        raise TypeError('input_items or total_weight cannot be None')\\n\",\n    \"    if not items or not total_weight:\\n\",\n    \"        return 0\\n\",\n    \"    memo = {}\\n\",\n    \"    result = _knapsack_top_down_alt(items, total_weight, memo, index=0)\\n\",\n    \"    curr_item = result.item\\n\",\n    \"    curr_weight = curr_item.weight\\n\",\n    \"    picked_items = [curr_item]\\n\",\n    \"    while curr_weight > 0:\\n\",\n    \"        total_weight -= curr_item.weight\\n\",\n    \"        curr_item = memo[(total_weight, len(items) - len(picked_items))].item\\n\",\n    \"    return result\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def _knapsack_top_down_alt(items, total_weight, memo, index):\\n\",\n    \"    if total_weight < 0:\\n\",\n    \"        return Result(total_weight=0, item=None)\\n\",\n    \"    if not total_weight or index >= len(items):\\n\",\n    \"        return Result(total_weight=items[index - 1].value, item=items[index - 1])\\n\",\n    \"    if (total_weight, len(items) - index - 1) in memo:\\n\",\n    \"        weight=memo[(total_weight, \\n\",\n    \"                     len(items) - index - 1)].total_weight + items[index - 1].value\\n\",\n    \"        return Result(total_weight=weight,\\n\",\n    \"                      item=items[index-1])\\n\",\n    \"    results = []\\n\",\n    \"    for i in range(index, len(items)):\\n\",\n    \"        total_weight -= items[i].weight\\n\",\n    \"        result = _knapsack_top_down_alt(items, total_weight, memo, index=i + 1)\\n\",\n    \"        total_weight += items[i].weight\\n\",\n    \"        results.append(result)\\n\",\n    \"    results_index = 0\\n\",\n    \"    for i in range(index, len(items)):\\n\",\n    \"        memo[(total_weight, len(items) - i)] = max(results[results_index:])\\n\",\n    \"        results_index += 1\\n\",\n    \"    if index == 0:\\n\",\n    \"        result_item = memo[(total_weight, len(items) - 1)].item\\n\",\n    \"    else:\\n\",\n    \"        result_item = items[index - 1]\\n\",\n    \"    weight = max(results).total_weight + (items[index - 1].value if index > 0 else 0)\\n\",\n    \"    return Result(total_weight=weight,\\n\",\n    \"                  item=result_item)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_knapsack.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_knapsack.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestKnapsack(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_knapsack_bottom_up(self):\\n\",\n    \"        knapsack = Knapsack()\\n\",\n    \"        self.assertRaises(TypeError, knapsack.fill_knapsack, None, None)\\n\",\n    \"        self.assertEqual(knapsack.fill_knapsack(0, 0), 0)\\n\",\n    \"        items = []\\n\",\n    \"        items.append(Item(label='a', value=2, weight=2))\\n\",\n    \"        items.append(Item(label='b', value=4, weight=2))\\n\",\n    \"        items.append(Item(label='c', value=6, weight=4))\\n\",\n    \"        items.append(Item(label='d', value=9, weight=5))\\n\",\n    \"        total_weight = 8\\n\",\n    \"        expected_value = 13\\n\",\n    \"        results = knapsack.fill_knapsack(items, total_weight)\\n\",\n    \"        self.assertEqual(results[0].label, 'd')\\n\",\n    \"        self.assertEqual(results[1].label, 'b')\\n\",\n    \"        total_value = 0\\n\",\n    \"        for item in results:\\n\",\n    \"            total_value += item.value\\n\",\n    \"        self.assertEqual(total_value, expected_value)\\n\",\n    \"        print('Success: test_knapsack_bottom_up')\\n\",\n    \"\\n\",\n    \"    def test_knapsack_top_down(self):\\n\",\n    \"        knapsack = KnapsackTopDown()\\n\",\n    \"        self.assertRaises(TypeError, knapsack.fill_knapsack, None, None)\\n\",\n    \"        self.assertEqual(knapsack.fill_knapsack(0, 0), 0)\\n\",\n    \"        items = []\\n\",\n    \"        items.append(Item(label='a', value=2, weight=2))\\n\",\n    \"        items.append(Item(label='b', value=4, weight=2))\\n\",\n    \"        items.append(Item(label='c', value=6, weight=4))\\n\",\n    \"        items.append(Item(label='d', value=9, weight=5))\\n\",\n    \"        total_weight = 8\\n\",\n    \"        expected_value = 13\\n\",\n    \"        self.assertEqual(knapsack.fill_knapsack(items, total_weight), expected_value)\\n\",\n    \"        print('Success: test_knapsack_top_down')\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestKnapsack()\\n\",\n    \"    test.test_knapsack_bottom_up()\\n\",\n    \"    test.test_knapsack_top_down()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 6,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_knapsack_bottom_up\\n\",\n      \"Success: test_knapsack_top_down\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_knapsack.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/knapsack_01/test_knapsack.py",
    "content": "import unittest\n\n\nclass TestKnapsack(unittest.TestCase):\n\n    def test_knapsack_bottom_up(self):\n        knapsack = Knapsack()\n        self.assertRaises(TypeError, knapsack.fill_knapsack, None, None)\n        self.assertEqual(knapsack.fill_knapsack(0, 0), 0)\n        items = []\n        items.append(Item(label='a', value=2, weight=2))\n        items.append(Item(label='b', value=4, weight=2))\n        items.append(Item(label='c', value=6, weight=4))\n        items.append(Item(label='d', value=9, weight=5))\n        total_weight = 8\n        expected_value = 13\n        results = knapsack.fill_knapsack(items, total_weight)\n        self.assertEqual(results[0].label, 'd')\n        self.assertEqual(results[1].label, 'b')\n        total_value = 0\n        for item in results:\n            total_value += item.value\n        self.assertEqual(total_value, expected_value)\n        print('Success: test_knapsack_bottom_up')\n\n    def test_knapsack_top_down(self):\n        knapsack = KnapsackTopDown()\n        self.assertRaises(TypeError, knapsack.fill_knapsack, None, None)\n        self.assertEqual(knapsack.fill_knapsack(0, 0), 0)\n        items = []\n        items.append(Item(label='a', value=2, weight=2))\n        items.append(Item(label='b', value=4, weight=2))\n        items.append(Item(label='c', value=6, weight=4))\n        items.append(Item(label='d', value=9, weight=5))\n        total_weight = 8\n        expected_value = 13\n        self.assertEqual(knapsack.fill_knapsack(items, total_weight), expected_value)\n        print('Success: test_knapsack_top_down')\n\ndef main():\n    test = TestKnapsack()\n    test.test_knapsack_bottom_up()\n    test.test_knapsack_top_down()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/knapsack_unbounded/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/knapsack_unbounded/knapsack_unbounded_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a knapsack with a total weight capacity and a list of items with weight w(i) and value v(i), determine the max total value you can carry.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we replace the items once they are placed in the knapsack?\\n\",\n    \"    * Yes, this is the unbounded knapsack problem\\n\",\n    \"* Can we split an item?\\n\",\n    \"    * No\\n\",\n    \"* Can we get an input item with weight of 0 or value of 0?\\n\",\n    \"    * No\\n\",\n    \"* Do we need to return the items that make up the max total value?\\n\",\n    \"    * No, just the total value\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Are the inputs in sorted order by val/weight?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* items or total weight is None -> Exception\\n\",\n    \"* items or total weight is 0 -> 0\\n\",\n    \"* General case\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"total_weight = 8\\n\",\n    \"items\\n\",\n    \"  v | w\\n\",\n    \"  0 | 0\\n\",\n    \"a 1 | 1\\n\",\n    \"b 3 | 2\\n\",\n    \"c 7 | 4\\n\",\n    \"\\n\",\n    \"max value = 14 \\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"class Item(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, label, value, weight):\\n\",\n    \"        self.label = label\\n\",\n    \"        self.value = value\\n\",\n    \"        self.weight = weight\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return self.label + ' v:' + str(self.value) + ' w:' + str(self.weight)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Knapsack(object):\\n\",\n    \"\\n\",\n    \"    def fill_knapsack(self, input_items, total_weight):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_knapsack_unbounded.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestKnapsack(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_knapsack(self):\\n\",\n    \"        knapsack = Knapsack()\\n\",\n    \"        self.assertRaises(TypeError, knapsack.fill_knapsack, None, None)\\n\",\n    \"        self.assertEqual(knapsack.fill_knapsack(0, 0), 0)\\n\",\n    \"        items = []\\n\",\n    \"        items.append(Item(label='a', value=1, weight=1))\\n\",\n    \"        items.append(Item(label='b', value=3, weight=2))\\n\",\n    \"        items.append(Item(label='c', value=7, weight=4))\\n\",\n    \"        total_weight = 8\\n\",\n    \"        expected_value = 14\\n\",\n    \"        results = knapsack.fill_knapsack(items, total_weight)\\n\",\n    \"        total_weight = 7\\n\",\n    \"        expected_value = 11\\n\",\n    \"        results = knapsack.fill_knapsack(items, total_weight)\\n\",\n    \"        self.assertEqual(results, expected_value)\\n\",\n    \"        print('Success: test_knapsack')\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestKnapsack()\\n\",\n    \"    test.test_knapsack()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/knapsack_unbounded/knapsack_unbounded_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a knapsack with a total weight capacity and a list of items with weight w(i) and value v(i), determine the max total value you can carry.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we replace the items once they are placed in the knapsack?\\n\",\n    \"    * Yes, this is the unbounded knapsack problem\\n\",\n    \"* Can we split an item?\\n\",\n    \"    * No\\n\",\n    \"* Can we get an input item with weight of 0 or value of 0?\\n\",\n    \"    * No\\n\",\n    \"* Do we need to return the items that make up the max total value?\\n\",\n    \"    * No, just the total value\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Are the inputs in sorted order by val/weight?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* items or total weight is None -> Exception\\n\",\n    \"* items or total weight is 0 -> 0\\n\",\n    \"* General case\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"total_weight = 8\\n\",\n    \"items\\n\",\n    \"  v | w\\n\",\n    \"  0 | 0\\n\",\n    \"a 1 | 1\\n\",\n    \"b 3 | 2\\n\",\n    \"c 7 | 4\\n\",\n    \"\\n\",\n    \"max value = 14 \\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use bottom up dynamic programming to build a table.  \\n\",\n    \"\\n\",\n    \"Taking what we learned with the 0/1 knapsack problem, we could solve the problem like the following:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"\\n\",\n    \"v = value\\n\",\n    \"w = weight\\n\",\n    \"\\n\",\n    \"               j              \\n\",\n    \"    -------------------------------------------------\\n\",\n    \"    | v | w || 0 | 1 | 2 | 3 | 4 | 5 |  6 |  7 |  8  |\\n\",\n    \"    -------------------------------------------------\\n\",\n    \"    | 0 | 0 || 0 | 0 | 0 | 0 | 0 | 0 |  0 |  0 |  0  |\\n\",\n    \"  a | 1 | 1 || 0 | 1 | 2 | 3 | 4 | 5 |  6 |  7 |  8  |\\n\",\n    \"i b | 3 | 2 || 0 | 1 | 3 | 4 | 6 | 7 |  9 | 10 | 12  |\\n\",\n    \"  c | 7 | 4 || 0 | 1 | 3 | 4 | 7 | 8 | 10 | 11 | 14  |\\n\",\n    \"    -------------------------------------------------\\n\",\n    \"\\n\",\n    \"i = row\\n\",\n    \"j = col\\n\",\n    \"\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"However, unlike the 0/1 knapsack variant, we don't actually need to keep space of O(n * w), where n is the number of items and w is the total weight.  We just need a single array that we update after we process each item:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"\\n\",\n    \"    -------------------------------------------------\\n\",\n    \"    | v | w || 0 | 1 | 2 | 3 | 4 | 5 |  6 |  7 |  8  |\\n\",\n    \"    -------------------------------------------------\\n\",\n    \"\\n\",\n    \"    -------------------------------------------------\\n\",\n    \"  a | 1 | 1 || 0 | 1 | 2 | 3 | 4 | 5 |  6 |  7 |  8  |\\n\",\n    \"    -------------------------------------------------\\n\",\n    \"\\n\",\n    \"    -------------------------------------------------\\n\",\n    \"  b | 3 | 2 || 0 | 1 | 3 | 4 | 6 | 7 |  9 | 10 | 12  |\\n\",\n    \"    -------------------------------------------------\\n\",\n    \"\\n\",\n    \"    -------------------------------------------------\\n\",\n    \"  c | 7 | 4 || 0 | 1 | 3 | 4 | 7 | 8 | 10 | 11 | 14  |\\n\",\n    \"    -------------------------------------------------\\n\",\n    \"\\n\",\n    \"if j >= items[i].weight:\\n\",\n    \"    T[j] = max(items[i].value + T[j - items[i].weight],\\n\",\n    \"               T[j])\\n\",\n    \"\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n * w), where n is the number of items and w is the total weight\\n\",\n    \"* Space: O(w), where w is the total weight\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"### Item Class\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Item(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, label, value, weight):\\n\",\n    \"        self.label = label\\n\",\n    \"        self.value = value\\n\",\n    \"        self.weight = weight\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return self.label + ' v:' + str(self.value) + ' w:' + str(self.weight)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"### Knapsack Bottom Up\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Knapsack(object):\\n\",\n    \"\\n\",\n    \"    def fill_knapsack(self, items, total_weight):\\n\",\n    \"        if items is None or total_weight is None:\\n\",\n    \"            raise TypeError('items or total_weight cannot be None')\\n\",\n    \"        if not items or total_weight == 0:\\n\",\n    \"            return 0\\n\",\n    \"        num_rows = len(items)\\n\",\n    \"        num_cols = total_weight + 1\\n\",\n    \"        T = [0] * (num_cols)\\n\",\n    \"        for i in range(num_rows):\\n\",\n    \"            for j in range(num_cols):\\n\",\n    \"                if j >= items[i].weight:\\n\",\n    \"                    T[j] = max(items[i].value + T[j - items[i].weight],\\n\",\n    \"                               T[j])\\n\",\n    \"        return T[-1]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_knapsack_unbounded.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_knapsack_unbounded.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestKnapsack(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_knapsack(self):\\n\",\n    \"        knapsack = Knapsack()\\n\",\n    \"        self.assertRaises(TypeError, knapsack.fill_knapsack, None, None)\\n\",\n    \"        self.assertEqual(knapsack.fill_knapsack(0, 0), 0)\\n\",\n    \"        items = []\\n\",\n    \"        items.append(Item(label='a', value=1, weight=1))\\n\",\n    \"        items.append(Item(label='b', value=3, weight=2))\\n\",\n    \"        items.append(Item(label='c', value=7, weight=4))\\n\",\n    \"        total_weight = 8\\n\",\n    \"        expected_value = 14\\n\",\n    \"        results = knapsack.fill_knapsack(items, total_weight)\\n\",\n    \"        total_weight = 7\\n\",\n    \"        expected_value = 11\\n\",\n    \"        results = knapsack.fill_knapsack(items, total_weight)\\n\",\n    \"        self.assertEqual(results, expected_value)\\n\",\n    \"        print('Success: test_knapsack')\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestKnapsack()\\n\",\n    \"    test.test_knapsack()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_knapsack\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_knapsack_unbounded.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/knapsack_unbounded/test_knapsack_unbounded.py",
    "content": "import unittest\n\n\nclass TestKnapsack(unittest.TestCase):\n\n    def test_knapsack(self):\n        knapsack = Knapsack()\n        self.assertRaises(TypeError, knapsack.fill_knapsack, None, None)\n        self.assertEqual(knapsack.fill_knapsack(0, 0), 0)\n        items = []\n        items.append(Item(label='a', value=1, weight=1))\n        items.append(Item(label='b', value=3, weight=2))\n        items.append(Item(label='c', value=7, weight=4))\n        total_weight = 8\n        expected_value = 14\n        results = knapsack.fill_knapsack(items, total_weight)\n        total_weight = 7\n        expected_value = 11\n        results = knapsack.fill_knapsack(items, total_weight)\n        self.assertEqual(results, expected_value)\n        print('Success: test_knapsack')\n\ndef main():\n    test = TestKnapsack()\n    test.test_knapsack()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/longest_common_subsequence/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/longest_common_subsequence/longest_common_subseq_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given two strings, find the longest common subsequence.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the strings are ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Is a subsequence a non-contiguous block of chars?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we expect a string as a result?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* str0 or str1 is None -> Exception\\n\",\n    \"* str0 or str1 equals 0 -> ''\\n\",\n    \"* General case\\n\",\n    \"\\n\",\n    \"str0 = 'ABCDEFGHIJ'\\n\",\n    \"str1 = 'FOOBCDBCDE'\\n\",\n    \"\\n\",\n    \"result: 'BCDE'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class StringCompare(object):\\n\",\n    \"\\n\",\n    \"    def longest_common_subseq(self, str0, str1):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_longest_common_subseq.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestLongestCommonSubseq(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_longest_common_subseq(self):\\n\",\n    \"        str_comp = StringCompare()\\n\",\n    \"        self.assertRaises(TypeError, str_comp.longest_common_subseq, None, None)\\n\",\n    \"        self.assertEqual(str_comp.longest_common_subseq('', ''), '')\\n\",\n    \"        str0 = 'ABCDEFGHIJ'\\n\",\n    \"        str1 = 'FOOBCDBCDE'\\n\",\n    \"        expected = 'BCDE'\\n\",\n    \"        self.assertEqual(str_comp.longest_common_subseq(str0, str1), expected)\\n\",\n    \"        print('Success: test_longest_common_subseq')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestLongestCommonSubseq()\\n\",\n    \"    test.test_longest_common_subseq()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/longest_common_subsequence/longest_common_subseq_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given two strings, find the longest common subsequence.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the strings are ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Is a subsequence a non-contiguous block of chars?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we expect a string as a result?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* str0 or str1 is None -> Exception\\n\",\n    \"* str0 or str1 equals 0 -> ''\\n\",\n    \"* General case\\n\",\n    \"\\n\",\n    \"str0 = 'ABCDEFGHIJ'\\n\",\n    \"str1 = 'FOOBCDBCDE'\\n\",\n    \"\\n\",\n    \"result: 'BCDE'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use bottom up dynamic programming to build a table.  \\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"\\n\",\n    \"The rows (i) represent str0.\\n\",\n    \"The columns (j) represent str1.\\n\",\n    \"\\n\",\n    \"                       str1\\n\",\n    \"  -------------------------------------------------\\n\",\n    \"  |   |   | A | B | C | D | E | F | G | H | I | J |\\n\",\n    \"  -------------------------------------------------\\n\",\n    \"  |   | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |\\n\",\n    \"  | F | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |\\n\",\n    \"  | O | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |\\n\",\n    \"s | O | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |\\n\",\n    \"t | B | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |\\n\",\n    \"r | C | 0 | 0 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |\\n\",\n    \"0 | D | 0 | 0 | 1 | 2 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |\\n\",\n    \"  | B | 0 | 0 | 1 | 2 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |\\n\",\n    \"  | C | 0 | 0 | 1 | 2 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |\\n\",\n    \"  | D | 0 | 0 | 1 | 2 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |\\n\",\n    \"  | E | 0 | 0 | 1 | 2 | 3 | 4 | 4 | 4 | 4 | 4 | 4 |\\n\",\n    \"  -------------------------------------------------\\n\",\n    \"\\n\",\n    \"if str1[j] != str0[i]:\\n\",\n    \"    T[i][j] = max(\\n\",\n    \"        T[i][j - 1],\\n\",\n    \"        T[i - 1][j])\\n\",\n    \"else:\\n\",\n    \"    T[i][j] = T[i - 1][j - 1] + 1\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(m * n), where m is the length of str0 and n is the length of str1\\n\",\n    \"* Space: O(m * n), where m is the length of str0 and n is the length of str1\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class StringCompare(object):\\n\",\n    \"\\n\",\n    \"    def longest_common_subseq(self, str0, str1):\\n\",\n    \"        if str0 is None or str1 is None:\\n\",\n    \"            raise TypeError('str input cannot be None')\\n\",\n    \"        # Add one to number of rows and cols for the dp table's\\n\",\n    \"        # first row of 0's and first col of 0's\\n\",\n    \"        num_rows = len(str0) + 1\\n\",\n    \"        num_cols = len(str1) + 1\\n\",\n    \"        T = [[None] * num_cols for _ in range(num_rows)]\\n\",\n    \"        for i in range(num_rows):\\n\",\n    \"            for j in range(num_cols):\\n\",\n    \"                if i == 0 or j == 0:\\n\",\n    \"                    T[i][j] = 0\\n\",\n    \"                elif str0[j - 1] != str1[i - 1]:\\n\",\n    \"                    T[i][j] = max(T[i][j - 1],\\n\",\n    \"                                  T[i - 1][j])\\n\",\n    \"                else:\\n\",\n    \"                    T[i][j] = T[i - 1][j - 1] + 1\\n\",\n    \"        results = ''\\n\",\n    \"        i = num_rows - 1\\n\",\n    \"        j = num_cols - 1\\n\",\n    \"        # Walk backwards to determine the subsequence\\n\",\n    \"        while T[i][j]:\\n\",\n    \"            if T[i][j] == T[i][j - 1]:\\n\",\n    \"                j -= 1\\n\",\n    \"            elif T[i][j] == T[i - 1][j]:\\n\",\n    \"                i -= 1\\n\",\n    \"            elif T[i][j] == T[i - 1][j - 1] + 1:\\n\",\n    \"                results += str1[i - 1]\\n\",\n    \"                i -= 1\\n\",\n    \"                j -= 1\\n\",\n    \"            else:\\n\",\n    \"                raise Exception('Error constructing table')\\n\",\n    \"        # Walking backwards results in a string in reverse order\\n\",\n    \"        return results[::-1]                \"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_longest_common_subseq.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_longest_common_subseq.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestLongestCommonSubseq(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_longest_common_subseq(self):\\n\",\n    \"        str_comp = StringCompare()\\n\",\n    \"        self.assertRaises(TypeError, str_comp.longest_common_subseq, None, None)\\n\",\n    \"        self.assertEqual(str_comp.longest_common_subseq('', ''), '')\\n\",\n    \"        str0 = 'ABCDEFGHIJ'\\n\",\n    \"        str1 = 'FOOBCDBCDE'\\n\",\n    \"        expected = 'BCDE'\\n\",\n    \"        self.assertEqual(str_comp.longest_common_subseq(str0, str1), expected)\\n\",\n    \"        print('Success: test_longest_common_subseq')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestLongestCommonSubseq()\\n\",\n    \"    test.test_longest_common_subseq()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_longest_common_subseq\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_longest_common_subseq.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/longest_common_subsequence/test_longest_common_subseq.py",
    "content": "import unittest\n\n\nclass TestLongestCommonSubseq(unittest.TestCase):\n\n    def test_longest_common_subseq(self):\n        str_comp = StringCompare()\n        self.assertRaises(TypeError, str_comp.longest_common_subseq, None, None)\n        self.assertEqual(str_comp.longest_common_subseq('', ''), '')\n        str0 = 'ABCDEFGHIJ'\n        str1 = 'FOOBCDBCDE'\n        expected = 'BCDE'\n        self.assertEqual(str_comp.longest_common_subseq(str0, str1), expected)\n        print('Success: test_longest_common_subseq')\n\n\ndef main():\n    test = TestLongestCommonSubseq()\n    test.test_longest_common_subseq()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/longest_inc_subseq/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/longest_inc_subseq/longest_inc_subseq_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the longest increasing subsequence.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are duplicates possible?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are integers?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Do we expect the result to be an array of the longest increasing subsequence?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* [] -> []\\n\",\n    \"* [3, 4, -1, 0, 6, 2, 3] -> [-1, 0, 2, 3]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Subsequence(object):\\n\",\n    \"\\n\",\n    \"    def longest_inc_subseq(self, seq):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_longest_increasing_subseq.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestLongestIncreasingSubseq(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_longest_increasing_subseq(self):\\n\",\n    \"        subseq = Subsequence()\\n\",\n    \"        self.assertRaises(TypeError, subseq.longest_inc_subseq, None)\\n\",\n    \"        self.assertEqual(subseq.longest_inc_subseq([]), [])\\n\",\n    \"        seq = [3, 4, -1, 0, 6, 2, 3]\\n\",\n    \"        expected = [-1, 0, 2, 3]\\n\",\n    \"        self.assertEqual(subseq.longest_inc_subseq(seq), expected)\\n\",\n    \"        print('Success: test_longest_increasing_subseq')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestLongestIncreasingSubseq()\\n\",\n    \"    test.test_longest_increasing_subseq()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/longest_inc_subseq/longest_inc_subseq_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the longest increasing subsequence.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are duplicates possible?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are integers?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Do we expect the result to be an array of the longest increasing subsequence?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* [] -> []\\n\",\n    \"* [3, 4, -1, 0, 6, 2, 3] -> [-1, 0, 2, 3]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use bottom up dynamic programming to build a table.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Init a temp array of size len(input) to 1.  \\n\",\n    \"We'll use l and r to iterate through the input.\\n\",\n    \"Array prev will hold the index of the prior smaller value, used to reconstruct the final sequence.\\n\",\n    \"\\n\",\n    \"if input[l] < input[r]:\\n\",\n    \"    if temp[r] < temp[l] + 1:\\n\",\n    \"        temp[r] = temp[l] + 1\\n\",\n    \"        prev[r] = l\\n\",\n    \"\\n\",\n    \"        l  r\\n\",\n    \"index:  0  1  2  3  4  5  6\\n\",\n    \"---------------------------\\n\",\n    \"input:  3  4 -1  0  6  2  3\\n\",\n    \"temp:   1  2  1  1  1  1  1\\n\",\n    \"prev:   x  x  x  x  x  x  x\\n\",\n    \"\\n\",\n    \"End result:\\n\",\n    \"\\n\",\n    \"index:  0  1  2  3  4  5  6\\n\",\n    \"---------------------------\\n\",\n    \"input:  3  4 -1  0  6  2  3\\n\",\n    \"temp:   1  2  1  2  3  3  4\\n\",\n    \"prev:   x  0  x  2  1  3  5\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n^2)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Subsequence(object):\\n\",\n    \"\\n\",\n    \"    def longest_inc_subseq(self, seq):\\n\",\n    \"        if seq is None:\\n\",\n    \"            raise TypeError('seq cannot be None')\\n\",\n    \"        if not seq:\\n\",\n    \"            return []\\n\",\n    \"        temp = [1] * len(seq)\\n\",\n    \"        prev = [None] * len(seq)\\n\",\n    \"        for r in range(1, len(seq)):\\n\",\n    \"            for l in range(r):\\n\",\n    \"                if seq[l] < seq[r]:\\n\",\n    \"                    if temp[r] < temp[l] + 1:\\n\",\n    \"                        temp[r] = temp[l] + 1\\n\",\n    \"                        prev[r] = l\\n\",\n    \"        max_val = 0\\n\",\n    \"        max_index = -1\\n\",\n    \"        results = []\\n\",\n    \"        for index, value in enumerate(temp):\\n\",\n    \"            if value > max_val:\\n\",\n    \"                max_val = value\\n\",\n    \"                max_index = index\\n\",\n    \"        curr_index = max_index\\n\",\n    \"        while curr_index is not None:\\n\",\n    \"            results.append(seq[curr_index])\\n\",\n    \"            curr_index = prev[curr_index]\\n\",\n    \"        return results[::-1]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_longest_increasing_subseq.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_longest_increasing_subseq.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestLongestIncreasingSubseq(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_longest_increasing_subseq(self):\\n\",\n    \"        subseq = Subsequence()\\n\",\n    \"        self.assertRaises(TypeError, subseq.longest_inc_subseq, None)\\n\",\n    \"        self.assertEqual(subseq.longest_inc_subseq([]), [])\\n\",\n    \"        seq = [3, 4, -1, 0, 6, 2, 3]\\n\",\n    \"        expected = [-1, 0, 2, 3]\\n\",\n    \"        self.assertEqual(subseq.longest_inc_subseq(seq), expected)\\n\",\n    \"        print('Success: test_longest_increasing_subseq')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestLongestIncreasingSubseq()\\n\",\n    \"    test.test_longest_increasing_subseq()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_longest_increasing_subseq\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_longest_increasing_subseq.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/longest_inc_subseq/test_longest_increasing_subseq.py",
    "content": "import unittest\n\n\nclass TestLongestIncreasingSubseq(unittest.TestCase):\n\n    def test_longest_increasing_subseq(self):\n        subseq = Subsequence()\n        self.assertRaises(TypeError, subseq.longest_inc_subseq, None)\n        self.assertEqual(subseq.longest_inc_subseq([]), [])\n        seq = [3, 4, -1, 0, 6, 2, 3]\n        expected = [-1, 0, 2, 3]\n        self.assertEqual(subseq.longest_inc_subseq(seq), expected)\n        print('Success: test_longest_increasing_subseq')\n\n\ndef main():\n    test = TestLongestIncreasingSubseq()\n    test.test_longest_increasing_subseq()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/longest_substr_k_distinct/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/longest_substr_k_distinct/longest_substr_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the longest substring with at most k distinct characters.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the strings are ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Is a substring a contiguous block of chars?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we expect an int as a result?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* '', k = 3 -> 0\\n\",\n    \"* 'abcabcdefgghiij', k=3 -> 6\\n\",\n    \"* 'abcabcdefgghighij', k=3 -> 7\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def longest_substr(self, string, k):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_longest_substr.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_longest_substr(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.longest_substr, None)\\n\",\n    \"        self.assertEqual(solution.longest_substr('', k=3), 0)\\n\",\n    \"        self.assertEqual(solution.longest_substr('abcabcdefgghiij', k=3), 6)\\n\",\n    \"        self.assertEqual(solution.longest_substr('abcabcdefgghighij', k=3), 7)\\n\",\n    \"        print('Success: test_longest_substr')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_longest_substr()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/longest_substr_k_distinct/longest_substr_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the length longest substring with at most k distinct characters.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the strings are ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Is a substring a contiguous block of chars?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we expect an int as a result?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> TypeError\\n\",\n    \"* '', k = 3 -> 0\\n\",\n    \"* 'abcabcdefgghiij', k=3 -> 6\\n\",\n    \"* 'abcabcdefgghighij', k=3 -> 7\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use a `chars_to_index_map` dictionary: char (key) to index (val) map to maintain a sliding window.\\n\",\n    \"\\n\",\n    \"The index (val) will keep track of the character index in the input string.\\n\",\n    \"\\n\",\n    \"For each character in the string:\\n\",\n    \"\\n\",\n    \"* Add the char (key) and index (value) to the map\\n\",\n    \"* If the length of our map is greater than k, then we'll need to eliminate one item\\n\",\n    \"    * Scan the map to find the lowest index and remove it\\n\",\n    \"    * The new lowest index will therefore be incremented by 1\\n\",\n    \"* The max length will be the current index minus the lower index + 1\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n*k), where n is the number of chars, k is the length of the map due to the min() call\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Solution(object):\\n\",\n    \"\\n\",\n    \"    def longest_substr(self, string, k):\\n\",\n    \"        if not isinstance(string, str):\\n\",\n    \"            raise TypeError('string must be of type str')\\n\",\n    \"        if not isinstance(k, int):\\n\",\n    \"            raise TypeError('k must be of type int')\\n\",\n    \"        low_index = 0\\n\",\n    \"        max_length = 0\\n\",\n    \"        chars_to_index_map = {}\\n\",\n    \"        for index, char in enumerate(string):\\n\",\n    \"            chars_to_index_map[char] = index\\n\",\n    \"            if len(chars_to_index_map) > k:\\n\",\n    \"                low_index = min(chars_to_index_map.values())\\n\",\n    \"                del chars_to_index_map[string[low_index]]\\n\",\n    \"                low_index += 1\\n\",\n    \"            max_length = max(max_length, index - low_index + 1)\\n\",\n    \"        return max_length\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_longest_substr.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_longest_substr.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSolution(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_longest_substr(self):\\n\",\n    \"        solution = Solution()\\n\",\n    \"        self.assertRaises(TypeError, solution.longest_substr, None)\\n\",\n    \"        self.assertEqual(solution.longest_substr('', k=3), 0)\\n\",\n    \"        self.assertEqual(solution.longest_substr('abcabcdefgghiij', k=3), 6)\\n\",\n    \"        self.assertEqual(solution.longest_substr('abcabcdefgghighij', k=3), 7)\\n\",\n    \"        print('Success: test_longest_substr')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSolution()\\n\",\n    \"    test.test_longest_substr()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_longest_substr\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_longest_substr.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/longest_substr_k_distinct/test_longest_substr.py",
    "content": "import unittest\n\n\nclass TestSolution(unittest.TestCase):\n\n    def test_longest_substr(self):\n        solution = Solution()\n        self.assertRaises(TypeError, solution.longest_substr, None)\n        self.assertEqual(solution.longest_substr('', k=3), 0)\n        self.assertEqual(solution.longest_substr('abcabcdefgghiij', k=3), 6)\n        self.assertEqual(solution.longest_substr('abcabcdefgghighij', k=3), 7)\n        print('Success: test_longest_substr')\n\n\ndef main():\n    test = TestSolution()\n    test.test_longest_substr()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/longest_substring/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/longest_substring/longest_common_substr_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given two strings, find the longest common substring.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the strings are ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Is a substring a contiguous block of chars?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we expect a string as a result?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* str0 or str1 is None -> Exception\\n\",\n    \"* str0 or str1 equals 0 -> ''\\n\",\n    \"* General case\\n\",\n    \"\\n\",\n    \"str0 = 'ABCDEFGHIJ'\\n\",\n    \"str1 = 'FOOBCDBCDE'\\n\",\n    \"\\n\",\n    \"result: 'BCDE'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class StringCompare(object):\\n\",\n    \"\\n\",\n    \"    def longest_common_substr(self, str0, str1):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_longest_common_substr.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestLongestCommonSubstr(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_longest_common_substr(self):\\n\",\n    \"        str_comp = StringCompare()\\n\",\n    \"        self.assertRaises(TypeError, str_comp.longest_common_substr, None, None)\\n\",\n    \"        self.assertEqual(str_comp.longest_common_substr('', ''), '')\\n\",\n    \"        str0 = 'ABCDEFGHIJ'\\n\",\n    \"        str1 = 'FOOBCDBCDE'\\n\",\n    \"        expected = 'BCDE'\\n\",\n    \"        self.assertEqual(str_comp.longest_common_substr(str0, str1), expected)\\n\",\n    \"        print('Success: test_longest_common_substr')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestLongestCommonSubstr()\\n\",\n    \"    test.test_longest_common_substr()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/longest_substring/longest_common_substr_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given two strings, find the longest common substring.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the strings are ASCII?\\n\",\n    \"    * Yes\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"    * Yes\\n\",\n    \"* Is a substring a contiguous block of chars?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we expect a string as a result?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* str0 or str1 is None -> Exception\\n\",\n    \"* str0 or str1 equals 0 -> ''\\n\",\n    \"* General case\\n\",\n    \"\\n\",\n    \"str0 = 'ABCDEFGHIJ'\\n\",\n    \"str1 = 'FOOBCDBCDE'\\n\",\n    \"\\n\",\n    \"result: 'BCDE'\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use bottom up dynamic programming to build a table.  \\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"\\n\",\n    \"The rows (i) represent str0.\\n\",\n    \"The columns (j) represent str1.\\n\",\n    \"\\n\",\n    \"                       str1\\n\",\n    \"  -------------------------------------------------\\n\",\n    \"  |   |   | A | B | C | D | E | F | G | H | I | J |\\n\",\n    \"  -------------------------------------------------\\n\",\n    \"  |   | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |\\n\",\n    \"  | F | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |\\n\",\n    \"  | O | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |\\n\",\n    \"s | O | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |\\n\",\n    \"t | B | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |\\n\",\n    \"r | C | 0 | 0 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |\\n\",\n    \"0 | D | 0 | 0 | 1 | 2 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |\\n\",\n    \"  | B | 0 | 0 | 1 | 2 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |\\n\",\n    \"  | C | 0 | 0 | 1 | 2 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |\\n\",\n    \"  | D | 0 | 0 | 1 | 2 | 3 | 3 | 3 | 3 | 3 | 3 | 3 |\\n\",\n    \"  | E | 0 | 0 | 1 | 2 | 3 | 4 | 4 | 4 | 4 | 4 | 4 |\\n\",\n    \"  -------------------------------------------------\\n\",\n    \"\\n\",\n    \"if str1[j] != str0[i]:\\n\",\n    \"    T[i][j] = max(\\n\",\n    \"        T[i][j-1],\\n\",\n    \"        T[i-1][j])\\n\",\n    \"else:\\n\",\n    \"    T[i][j] = T[i-1][j-1] + 1\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(m * n), where m is the length of str0 and n is the length of str1\\n\",\n    \"* Space: O(m * n), where m is the length of str0 and n is the length of str1\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class StringCompare(object):\\n\",\n    \"\\n\",\n    \"    def longest_common_substr(self, str0, str1):\\n\",\n    \"        if str0 is None or str1 is None:\\n\",\n    \"            raise TypeError('str input cannot be None')\\n\",\n    \"        # Add one to number of rows and cols for the dp table's\\n\",\n    \"        # first row of 0's and first col of 0's\\n\",\n    \"        num_rows = len(str0) + 1\\n\",\n    \"        num_cols = len(str1) + 1\\n\",\n    \"        T = [[None] * num_cols for _ in range(num_rows)]\\n\",\n    \"        for i in range(num_rows):\\n\",\n    \"            for j in range(num_cols):\\n\",\n    \"                if i == 0 or j == 0:\\n\",\n    \"                    T[i][j] = 0\\n\",\n    \"                elif str0[j-1] != str1[i-1]:\\n\",\n    \"                    T[i][j] = max(T[i][j-1],\\n\",\n    \"                                  T[i-1][j])\\n\",\n    \"                else:\\n\",\n    \"                    T[i][j] = T[i-1][j-1] + 1\\n\",\n    \"        results = ''\\n\",\n    \"        i = num_rows - 1\\n\",\n    \"        j = num_cols - 1\\n\",\n    \"        # Walk backwards to determine the substring\\n\",\n    \"        while T[i][j]:\\n\",\n    \"            if T[i][j] == T[i][j-1]:\\n\",\n    \"                j -= 1\\n\",\n    \"            elif T[i][j] == T[i-1][j]:\\n\",\n    \"                i -= 1\\n\",\n    \"            elif T[i][j] == T[i-1][j-1] + 1:\\n\",\n    \"                results += str1[i-1]\\n\",\n    \"                i -= 1\\n\",\n    \"                j -= 1\\n\",\n    \"            else:\\n\",\n    \"                raise Exception('Error constructing table')\\n\",\n    \"        # Walking backwards results in a string in reverse order\\n\",\n    \"        return results[::-1]                \"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_longest_common_substr.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_longest_common_substr.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestLongestCommonSubstr(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_longest_common_substr(self):\\n\",\n    \"        str_comp = StringCompare()\\n\",\n    \"        self.assertRaises(TypeError, str_comp.longest_common_substr, None, None)\\n\",\n    \"        self.assertEqual(str_comp.longest_common_substr('', ''), '')\\n\",\n    \"        str0 = 'ABCDEFGHIJ'\\n\",\n    \"        str1 = 'FOOBCDBCDE'\\n\",\n    \"        expected = 'BCDE'\\n\",\n    \"        self.assertEqual(str_comp.longest_common_substr(str0, str1), expected)\\n\",\n    \"        print('Success: test_longest_common_substr')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestLongestCommonSubstr()\\n\",\n    \"    test.test_longest_common_substr()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_longest_common_substr\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_longest_common_substr.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/longest_substring/test_longest_common_substr.py",
    "content": "import unittest\n\n\nclass TestLongestCommonSubstr(unittest.TestCase):\n\n    def test_longest_common_substr(self):\n        str_comp = StringCompare()\n        self.assertRaises(TypeError, str_comp.longest_common_substr, None, None)\n        self.assertEqual(str_comp.longest_common_substr('', ''), '')\n        str0 = 'ABCDEFGHIJ'\n        str1 = 'FOOBCDBCDE'\n        expected = 'BCDE'\n        self.assertEqual(str_comp.longest_common_substr(str0, str1), expected)\n        print('Success: test_longest_common_substr')\n\n\ndef main():\n    test = TestLongestCommonSubstr()\n    test.test_longest_common_substr()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/magic_index/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/magic_index/magic_index_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the magic index in an array, where array[i] = i.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the array sorted?\\n\",\n    \"    * Yes\\n\",\n    \"* Are the elements in the array distinct?\\n\",\n    \"    * No\\n\",\n    \"* Does a magic index always exist?\\n\",\n    \"    * No\\n\",\n    \"* If there is no magic index, do we just return -1?\\n\",\n    \"    * Yes\\n\",\n    \"* Are negative values allowed in the array?\\n\",\n    \"    * Yes\\n\",\n    \"* If there are multiple magic values, what do we return?\\n\",\n    \"    * Return the left-most one\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None input -> -1\\n\",\n    \"* Empty array -> -1\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"a[i]  -4 -2  2  6  6  6  6 10\\n\",\n    \"  i    0  1  2  3  4  5  6  7\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Result: 2\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"a[i]  -4 -2  1  6  6  6  6 10\\n\",\n    \"  i    0  1  2  3  4  5  6  7\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Result: 6\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"a[i]  -4 -2  1  6  6  6  7 10\\n\",\n    \"  i    0  1  2  3  4  5  6  7\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Result: -1\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MagicIndex(object):\\n\",\n    \"\\n\",\n    \"    def find_magic_index(self, array):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_find_magic_index.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestFindMagicIndex(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_find_magic_index(self):\\n\",\n    \"        magic_index = MagicIndex()\\n\",\n    \"        self.assertEqual(magic_index.find_magic_index(None), -1)\\n\",\n    \"        self.assertEqual(magic_index.find_magic_index([]), -1)\\n\",\n    \"        array = [-4, -2, 2, 6, 6, 6, 6, 10]\\n\",\n    \"        self.assertEqual(magic_index.find_magic_index(array), 2)\\n\",\n    \"        array = [-4, -2, 1, 6, 6, 6, 6, 10]\\n\",\n    \"        self.assertEqual(magic_index.find_magic_index(array), 6)\\n\",\n    \"        array = [-4, -2, 1, 6, 6, 6, 7, 10]\\n\",\n    \"        self.assertEqual(magic_index.find_magic_index(array), -1)\\n\",\n    \"        print('Success: test_find_magic')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestFindMagicIndex()\\n\",\n    \"    test.test_find_magic_index()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/magic_index/magic_index_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find the magic index in an array, where array[i] = i.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the array sorted?\\n\",\n    \"    * Yes\\n\",\n    \"* Are the elements in the array distinct?\\n\",\n    \"    * No\\n\",\n    \"* Does a magic index always exist?\\n\",\n    \"    * No\\n\",\n    \"* If there is no magic index, do we just return -1?\\n\",\n    \"    * Yes\\n\",\n    \"* Are negative values allowed in the array?\\n\",\n    \"    * Yes\\n\",\n    \"* If there are multiple magic values, what do we return?\\n\",\n    \"    * Return the left-most one\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None input -> -1\\n\",\n    \"* Empty array -> -1\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"a[i]  -4 -2  2  6  6  6  6 10\\n\",\n    \"  i    0  1  2  3  4  5  6  7\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Result: 2\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"a[i]  -4 -2  1  6  6  6  6 10\\n\",\n    \"  i    0  1  2  3  4  5  6  7\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Result: 6\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"a[i]  -4 -2  1  6  6  6  7 10\\n\",\n    \"  i    0  1  2  3  4  5  6  7\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Result: -1\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use a binary search to split the search space in half on each iteration.  To obtain more efficiency, we can do a little better than a naive left and half split.\\n\",\n    \"\\n\",\n    \"In the example below, we see that i == 5 cannot be the magic index, otherwise a[5] would have to equal 5 (note a[4] == 6).\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"a[i]  -4 -2  2  6  6  6  6 10\\n\",\n    \"  i    0  1  1  3  4  5  6  7\\n\",\n    \"                  mid\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Similarly, in the example below we can further trim the left search space.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"a[i]  -4 -2  2  2  2  6  6 10\\n\",\n    \"  i    0  1  2  3  4  5  6  7\\n\",\n    \"                  mid\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"* Calculate mid\\n\",\n    \"* If mid == array[mid], return mid\\n\",\n    \"* Recurse on the left side of the array\\n\",\n    \"    * start: 0\\n\",\n    \"    * end: min(mid-1, array[mid]\\n\",\n    \"* Recurse on the right side of the array\\n\",\n    \"    * start: max(mid+1, array[mid]\\n\",\n    \"    * end: end\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(log(n))\\n\",\n    \"* Space: O(log(n))\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from __future__ import division\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class MagicIndex(object):\\n\",\n    \"\\n\",\n    \"    def find_magic_index(self, array):\\n\",\n    \"        if array is None or not array:\\n\",\n    \"            return -1\\n\",\n    \"        return self._find_magic_index(array, 0, len(array) - 1)\\n\",\n    \"\\n\",\n    \"    def _find_magic_index(self, array, start, end):\\n\",\n    \"        if end < start or start < 0 or end >= len(array):\\n\",\n    \"            return -1\\n\",\n    \"        mid = (start + end) // 2\\n\",\n    \"        if mid == array[mid]:\\n\",\n    \"            return mid\\n\",\n    \"        left_end = min(mid - 1, array[mid])\\n\",\n    \"        left_result = self._find_magic_index(array, start, end=left_end)\\n\",\n    \"        if left_result != -1:\\n\",\n    \"            return left_result\\n\",\n    \"        right_start = max(mid + 1, array[mid])\\n\",\n    \"        right_result = self._find_magic_index(array, start=right_start, end=end)\\n\",\n    \"        if right_result != -1:\\n\",\n    \"            return right_result\\n\",\n    \"        return -1\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_find_magic_index.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_find_magic_index.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestFindMagicIndex(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_find_magic_index(self):\\n\",\n    \"        magic_index = MagicIndex()\\n\",\n    \"        self.assertEqual(magic_index.find_magic_index(None), -1)\\n\",\n    \"        self.assertEqual(magic_index.find_magic_index([]), -1)\\n\",\n    \"        array = [-4, -2, 2, 6, 6, 6, 6, 10]\\n\",\n    \"        self.assertEqual(magic_index.find_magic_index(array), 2)\\n\",\n    \"        array = [-4, -2, 1, 6, 6, 6, 6, 10]\\n\",\n    \"        self.assertEqual(magic_index.find_magic_index(array), 6)\\n\",\n    \"        array = [-4, -2, 1, 6, 6, 6, 7, 10]\\n\",\n    \"        self.assertEqual(magic_index.find_magic_index(array), -1)\\n\",\n    \"        print('Success: test_find_magic')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestFindMagicIndex()\\n\",\n    \"    test.test_find_magic_index()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_find_magic\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_find_magic_index.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/magic_index/test_find_magic_index.py",
    "content": "import unittest\n\n\nclass TestFindMagicIndex(unittest.TestCase):\n\n    def test_find_magic_index(self):\n        magic_index = MagicIndex()\n        self.assertEqual(magic_index.find_magic_index(None), -1)\n        self.assertEqual(magic_index.find_magic_index([]), -1)\n        array = [-4, -2, 2, 6, 6, 6, 6, 10]\n        self.assertEqual(magic_index.find_magic_index(array), 2)\n        array = [-4, -2, 1, 6, 6, 6, 6, 10]\n        self.assertEqual(magic_index.find_magic_index(array), 6)\n        array = [-4, -2, 1, 6, 6, 6, 7, 10]\n        self.assertEqual(magic_index.find_magic_index(array), -1)\n        print('Success: test_find_magic')\n\n\ndef main():\n    test = TestFindMagicIndex()\n    test.test_find_magic_index()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/matrix_mult/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/matrix_mult/find_min_cost_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a list of 2x2 matrices, minimize the cost of matrix multiplication.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Do we just want to calculate the cost and not list the actual order of operations?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* [] -> 0\\n\",\n    \"* [Matrix(2, 3), Matrix(3, 6), Matrix(6, 4), Matrix(4, 5)] -> 124\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"class Matrix(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, first, second):\\n\",\n    \"        self.first = first\\n\",\n    \"        self.second = second\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MatrixMultiplicationCost(object):\\n\",\n    \"\\n\",\n    \"    def find_min_cost(self, matrices):\\n\",\n    \"    # TODO: Implement me\\n\",\n    \"    pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_find_min_cost.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMatrixMultiplicationCost(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_find_min_cost(self):\\n\",\n    \"        matrix_mult_cost = MatrixMultiplicationCost()\\n\",\n    \"        self.assertRaises(TypeError, matrix_mult_cost.find_min_cost, None)\\n\",\n    \"        self.assertEqual(matrix_mult_cost.find_min_cost([]), 0)\\n\",\n    \"        matrices = [Matrix(2, 3),\\n\",\n    \"                    Matrix(3, 6),\\n\",\n    \"                    Matrix(6, 4),\\n\",\n    \"                    Matrix(4, 5)]\\n\",\n    \"        expected_cost = 124\\n\",\n    \"        self.assertEqual(matrix_mult_cost.find_min_cost(matrices), expected_cost)\\n\",\n    \"        print('Success: test_find_min_cost')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMatrixMultiplicationCost()\\n\",\n    \"    test.test_find_min_cost()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/matrix_mult/find_min_cost_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a list of 2x2 matrices, minimize the cost of matrix multiplication.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Do we just want to calculate the cost and not list the actual order of operations?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* [] -> 0\\n\",\n    \"* [Matrix(2, 3), Matrix(3, 6), Matrix(6, 4), Matrix(4, 5)] -> 124\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use bottom up dynamic programming to build a table.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"\\n\",\n    \"  0    1    2    3\\n\",\n    \"[2,3][3,6][6,4][4,5]\\n\",\n    \"\\n\",\n    \"Case: 0 * 1\\n\",\n    \"2 * 3 * 6 = 36\\n\",\n    \"\\n\",\n    \"Case: 1 * 2\\n\",\n    \"3 * 6 * 4 = 72\\n\",\n    \"\\n\",\n    \"Case: 2 * 3\\n\",\n    \"6 * 4 * 5 = 120\\n\",\n    \"\\n\",\n    \"Case: 0 * 1 * 2\\n\",\n    \"0 * (1 * 2) = 2 * 3 * 4 + 72 = 96\\n\",\n    \"(0 * 1) * 2 = 36 + 2 * 6 * 4 = 84\\n\",\n    \"min: 84\\n\",\n    \"\\n\",\n    \"Case: 1 * 2 * 3\\n\",\n    \"1 * (2 * 3) = 3 * 6 * 5 + 120 = 210\\n\",\n    \"(1 * 2) * 3 = 72 + 3 * 4 * 5 = 132\\n\",\n    \"min: 132\\n\",\n    \"\\n\",\n    \"Case: 0 * 1 * 2 * 3\\n\",\n    \"0 * (1 * 2 * 3) = 2 * 3 * 5 + 132 = 162\\n\",\n    \"(0 * 1) * (2 * 3) = 36 + 120 + 2 * 6 * 5 = 216\\n\",\n    \"(0 * 1 * 2) * 3 = 84 + 2 * 4 * 5 = 124\\n\",\n    \"min: 124\\n\",\n    \"\\n\",\n    \"  ---------------------\\n\",\n    \"  | 0 |  1 |  2 |   3 |\\n\",\n    \"  ---------------------\\n\",\n    \"0 | 0 | 36 | 84 | 124 |\\n\",\n    \"1 | x |  0 | 72 | 132 |\\n\",\n    \"2 | x |  x |  0 | 120 |\\n\",\n    \"3 | x |  x |  x |   0 |\\n\",\n    \"  ---------------------\\n\",\n    \"\\n\",\n    \"min cost = T[0][cols-1] = 124\\n\",\n    \"\\n\",\n    \"for k in range(i, j):\\n\",\n    \"    T[i][j] = minimum of (T[i][k] + T[k+1][j] +\\n\",\n    \"                          m[i].first * m[k].second * m[j].second) for all k\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"### Explanation of k\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"<pre>\\n\",\n    \"  0    1    2    3\\n\",\n    \"[2,3][3,6][6,4][4,5]\\n\",\n    \"\\n\",\n    \"Fill in the missing cell, where i = 0, j = 3\\n\",\n    \"\\n\",\n    \"  ---------------------\\n\",\n    \"  | 0 |  1 |  2 |   3 |\\n\",\n    \"  ---------------------\\n\",\n    \"0 | 0 | 36 | 84 | ??? |\\n\",\n    \"1 | x |  0 | 72 | 132 |\\n\",\n    \"2 | x |  x |  0 | 120 |\\n\",\n    \"3 | x |  x |  x |   0 |\\n\",\n    \"  ---------------------\\n\",\n    \"\\n\",\n    \"Case: 0 * (1 * 2 * 3), k = 0\\n\",\n    \"i = 0, j = 3\\n\",\n    \"\\n\",\n    \"0 * (1 * 2 * 3) = 2 * 3 * 5 + 132 = 162\\n\",\n    \"T[i][k] + T[k+1][j] + m[i].first * m[k].second * m[j].second\\n\",\n    \"T[0][0] + T[1][3] + 2 * 3 * 5\\n\",\n    \"0 + 132 + 30 = 162\\n\",\n    \"\\n\",\n    \"Case: (0 * 1) * (2 * 3), k = 1\\n\",\n    \"i = 0, j = 3\\n\",\n    \"\\n\",\n    \"(0 * 1) * (2 * 3) = 36 + 120 + 2 * 6 * 5 = 216\\n\",\n    \"T[i][k] + T[k+1][j] + m[i].first * m[k].second * m[j].second\\n\",\n    \"T[0][1] + T[2][3] + 2 * 6 * 5\\n\",\n    \"36 + 120 + 60 = 216\\n\",\n    \"\\n\",\n    \"Case: (0 * 1 * 2) * 3, k = 2\\n\",\n    \"i = 0, j = 3\\n\",\n    \"\\n\",\n    \"(0 * 1 * 2) * 3 = 84 + 2 * 4 * 5 = 124\\n\",\n    \"T[i][k] + T[k+1][j] + m[i].first * m[k].second * m[j].second\\n\",\n    \"T[0][2] + T[3][3] + 2 * 4 * 5\\n\",\n    \"84 + 0 + 40 = 124\\n\",\n    \"\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n^3)\\n\",\n    \"* Space: O(n^2)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Matrix(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, first, second):\\n\",\n    \"        self.first = first\\n\",\n    \"        self.second = second\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import sys\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class MatrixMultiplicationCost(object):\\n\",\n    \"\\n\",\n    \"    def find_min_cost(self, matrices):\\n\",\n    \"        if matrices is None:\\n\",\n    \"            raise TypeError('matrices cannot be None')\\n\",\n    \"        if not matrices:\\n\",\n    \"            return 0\\n\",\n    \"        size = len(matrices)\\n\",\n    \"        T = [[0] * size for _ in range(size)]\\n\",\n    \"        for offset in range(1, size):\\n\",\n    \"            for i in range(size-offset):\\n\",\n    \"                j = i + offset\\n\",\n    \"                min_cost = sys.maxsize\\n\",\n    \"                for k in range(i, j):\\n\",\n    \"                    cost = (T[i][k] + T[k+1][j] +\\n\",\n    \"                            matrices[i].first *\\n\",\n    \"                            matrices[k].second *\\n\",\n    \"                            matrices[j].second)\\n\",\n    \"                    if cost < min_cost:\\n\",\n    \"                        min_cost = cost\\n\",\n    \"                T[i][j] = min_cost\\n\",\n    \"        return T[0][size-1]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_find_min_cost.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_find_min_cost.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMatrixMultiplicationCost(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_find_min_cost(self):\\n\",\n    \"        matrix_mult_cost = MatrixMultiplicationCost()\\n\",\n    \"        self.assertRaises(TypeError, matrix_mult_cost.find_min_cost, None)\\n\",\n    \"        self.assertEqual(matrix_mult_cost.find_min_cost([]), 0)\\n\",\n    \"        matrices = [Matrix(2, 3),\\n\",\n    \"                    Matrix(3, 6),\\n\",\n    \"                    Matrix(6, 4),\\n\",\n    \"                    Matrix(4, 5)]\\n\",\n    \"        expected_cost = 124\\n\",\n    \"        self.assertEqual(matrix_mult_cost.find_min_cost(matrices), expected_cost)\\n\",\n    \"        print('Success: test_find_min_cost')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMatrixMultiplicationCost()\\n\",\n    \"    test.test_find_min_cost()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_find_min_cost\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_find_min_cost.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/matrix_mult/test_find_min_cost.py",
    "content": "import unittest\n\n\nclass TestMatrixMultiplicationCost(unittest.TestCase):\n\n    def test_find_min_cost(self):\n        matrix_mult_cost = MatrixMultiplicationCost()\n        self.assertRaises(TypeError, matrix_mult_cost.find_min_cost, None)\n        self.assertEqual(matrix_mult_cost.find_min_cost([]), 0)\n        matrices = [Matrix(2, 3),\n                    Matrix(3, 6),\n                    Matrix(6, 4),\n                    Matrix(4, 5)]\n        expected_cost = 124\n        self.assertEqual(matrix_mult_cost.find_min_cost(matrices), expected_cost)\n        print('Success: test_find_min_cost')\n\n\ndef main():\n    test = TestMatrixMultiplicationCost()\n    test.test_find_min_cost()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/max_profit_k/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/max_profit_k/max_profit_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a list of stock prices on each consecutive day, determine the max profits with k transactions.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is k the number of sell transactions?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the prices input is an array of ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* If the prices are all decreasing and there is no opportunity to make a profit, do we just return 0?\\n\",\n    \"    * Yes\\n\",\n    \"* Should the output be the max profit and days to buy and sell?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* Prices: None or k: None -> None\\n\",\n    \"* Prices: [] or k <= 0 -> []\\n\",\n    \"* Prices: [0, -1, -2, -3, -4, -5]\\n\",\n    \"    * (max profit, list of transactions)\\n\",\n    \"    * (0, [])\\n\",\n    \"* Prices: [2, 5, 7, 1, 4, 3, 1, 3] k: 3\\n\",\n    \"    * (max profit, list of transactions)\\n\",\n    \"    * (10, [Type.SELL day: 7 price: 3, \\n\",\n    \"            Type.BUY  day: 6 price: 1, \\n\",\n    \"            Type.SELL day: 4 price: 4, \\n\",\n    \"            Type.BUY  day: 3 price: 1, \\n\",\n    \"            Type.SELL day: 2 price: 7, \\n\",\n    \"            Type.BUY  day: 0 price: 2])\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"from enum import Enum  # Python 2 users: Run pip install enum34\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Type(Enum):\\n\",\n    \"    SELL = 0\\n\",\n    \"    BUY = 1\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Transaction(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, type, day, price):\\n\",\n    \"        self.type = type\\n\",\n    \"        self.day = day\\n\",\n    \"        self.price = price\\n\",\n    \"\\n\",\n    \"    def __eq__(self, other):\\n\",\n    \"        return self.type == other.type and \\\\\\n\",\n    \"            self.day == other.day and \\\\\\n\",\n    \"            self.price == other.price\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return str(self.type) + ' day: ' + \\\\\\n\",\n    \"            str(self.day) + ' price: ' + \\\\\\n\",\n    \"            str(self.price)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class StockTrader(object):\\n\",\n    \"\\n\",\n    \"    def find_max_profit(self, prices, k):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_max_profit.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMaxProfit(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_max_profit(self):\\n\",\n    \"        stock_trader = StockTrader()\\n\",\n    \"        self.assertRaises(TypeError, stock_trader.find_max_profit, None, None)\\n\",\n    \"        self.assertEqual(stock_trader.find_max_profit(prices=[], k=0), [])\\n\",\n    \"        prices = [5, 4, 3, 2, 1]\\n\",\n    \"        k = 3\\n\",\n    \"        self.assertEqual(stock_trader.find_max_profit(prices, k), (0, []))\\n\",\n    \"        prices = [2, 5, 7, 1, 4, 3, 1, 3]\\n\",\n    \"        profit, transactions = stock_trader.find_max_profit(prices, k)\\n\",\n    \"        self.assertEqual(profit, 10)\\n\",\n    \"        self.assertTrue(Transaction(Type.SELL,\\n\",\n    \"                                day=7,\\n\",\n    \"                                price=3) in transactions)\\n\",\n    \"        self.assertTrue(Transaction(Type.BUY,\\n\",\n    \"                                day=6,\\n\",\n    \"                                price=1) in transactions)\\n\",\n    \"        self.assertTrue(Transaction(Type.SELL,\\n\",\n    \"                                day=4,\\n\",\n    \"                                price=4) in transactions)\\n\",\n    \"        self.assertTrue(Transaction(Type.BUY,\\n\",\n    \"                                day=3,\\n\",\n    \"                                price=1) in transactions)\\n\",\n    \"        self.assertTrue(Transaction(Type.SELL,\\n\",\n    \"                                day=2,\\n\",\n    \"                                price=7) in transactions)\\n\",\n    \"        self.assertTrue(Transaction(Type.BUY,\\n\",\n    \"                                day=0,\\n\",\n    \"                                price=2) in transactions)\\n\",\n    \"        print('Success: test_max_profit')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMaxProfit()\\n\",\n    \"    test.test_max_profit()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/max_profit_k/max_profit_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a list of stock prices on each consecutive day, determine the max profits with k transactions.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is k the number of sell transactions?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the prices input is an array of ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* If the prices are all decreasing and there is no opportunity to make a profit, do we just return 0?\\n\",\n    \"    * Yes\\n\",\n    \"* Should the output be the max profit and days to buy and sell?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* Prices: None or k: None -> None\\n\",\n    \"* Prices: [] or k <= 0 -> []\\n\",\n    \"* Prices: [0, -1, -2, -3, -4, -5]\\n\",\n    \"    * (max profit, list of transactions)\\n\",\n    \"    * (0, [])\\n\",\n    \"* Prices: [2, 5, 7, 1, 4, 3, 1, 3] k: 3\\n\",\n    \"    * (max profit, list of transactions)\\n\",\n    \"    * (10, [Type.SELL day: 7 price: 3, \\n\",\n    \"            Type.BUY  day: 6 price: 1, \\n\",\n    \"            Type.SELL day: 4 price: 4, \\n\",\n    \"            Type.BUY  day: 3 price: 1, \\n\",\n    \"            Type.SELL day: 2 price: 7, \\n\",\n    \"            Type.BUY  day: 0 price: 2])\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use bottom up dynamic programming to build a table.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"\\n\",\n    \"The rows (i) represent the prices.\\n\",\n    \"The columns (j) represent the number of transactions (k).\\n\",\n    \"\\n\",\n    \"T[i][j] = max(T[i][j - 1],\\n\",\n    \"              prices[j] - price[m] + T[i - 1][m])\\n\",\n    \"\\n\",\n    \"m = 0...j-1\\n\",\n    \"\\n\",\n    \"      0   1   2   3   4   5   6   7\\n\",\n    \"--------------------------------------\\n\",\n    \"|   | 2 | 5 | 7 | 1 | 4 | 3 | 1 | 3  |\\n\",\n    \"--------------------------------------\\n\",\n    \"| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0  |\\n\",\n    \"| 1 | 0 | 3 | 5 | 5 | 5 | 5 | 5 | 5  |\\n\",\n    \"| 2 | 0 | 3 | 5 | 5 | 8 | 8 | 8 | 8  |\\n\",\n    \"| 3 | 0 | 3 | 5 | 5 | 8 | 8 | 8 | 10 |\\n\",\n    \"--------------------------------------\\n\",\n    \"\\n\",\n    \"Optimization:\\n\",\n    \"\\n\",\n    \"max_diff = max(max_diff,\\n\",\n    \"               T[i - 1][j - 1] - prices[j - 1])\\n\",\n    \"\\n\",\n    \"T[i][j] = max(T[i][j - 1],\\n\",\n    \"              prices[j] + max_diff)\\n\",\n    \"\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n * k)\\n\",\n    \"* Space: O(n * k)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from enum import Enum  # Python 2 users: Run pip install enum34\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Type(Enum):\\n\",\n    \"    SELL = 0\\n\",\n    \"    BUY = 1\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Transaction(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, type, day, price):\\n\",\n    \"        self.type = type\\n\",\n    \"        self.day = day\\n\",\n    \"        self.price = price\\n\",\n    \"\\n\",\n    \"    def __eq__(self, other):\\n\",\n    \"        return self.type == other.type and \\\\\\n\",\n    \"            self.day == other.day and \\\\\\n\",\n    \"            self.price == other.price\\n\",\n    \"\\n\",\n    \"    def __repr__(self):\\n\",\n    \"        return str(self.type) + ' day: ' + \\\\\\n\",\n    \"            str(self.day) + ' price: ' + \\\\\\n\",\n    \"            str(self.price)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import sys\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class StockTrader(object):\\n\",\n    \"\\n\",\n    \"    def find_max_profit(self, prices, k):\\n\",\n    \"        if prices is None or k is None:\\n\",\n    \"            raise TypeError('prices or k cannot be None')\\n\",\n    \"        if not prices or k <= 0:\\n\",\n    \"            return []\\n\",\n    \"        num_rows = k + 1  # 0th transaction for dp table\\n\",\n    \"        num_cols = len(prices)\\n\",\n    \"        T = [[None] * num_cols for _ in range(num_rows)]\\n\",\n    \"        for i in range(num_rows):\\n\",\n    \"            for j in range(num_cols):\\n\",\n    \"                if i == 0 or j == 0:\\n\",\n    \"                    T[i][j] = 0\\n\",\n    \"                    continue\\n\",\n    \"                max_profit = -sys.maxsize\\n\",\n    \"                for m in range(j):\\n\",\n    \"                    profit = prices[j] - prices[m] + T[i - 1][m]\\n\",\n    \"                    if profit > max_profit:\\n\",\n    \"                        max_profit = profit\\n\",\n    \"                T[i][j] = max(T[i][j - 1], max_profit)\\n\",\n    \"        return self._find_max_profit_transactions(T, prices)\\n\",\n    \"\\n\",\n    \"    def find_max_profit_optimized(self, prices, k):\\n\",\n    \"        if prices is None or k is None:\\n\",\n    \"            raise TypeError('prices or k cannot be None')\\n\",\n    \"        if not prices or k <= 0:\\n\",\n    \"            return []\\n\",\n    \"        num_rows = k + 1\\n\",\n    \"        num_cols = len(prices)\\n\",\n    \"        T = [[None] * num_cols for _ in range(num_rows)]\\n\",\n    \"        for i in range(num_rows):\\n\",\n    \"            max_diff = prices[0] * -1\\n\",\n    \"            for j in range(num_cols):\\n\",\n    \"                if i == 0 or j == 0:\\n\",\n    \"                    T[i][j] = 0\\n\",\n    \"                    continue\\n\",\n    \"                max_diff = max(\\n\",\n    \"                    max_diff,\\n\",\n    \"                    T[i - 1][j - 1] - prices[j - 1])\\n\",\n    \"                T[i][j] = max(\\n\",\n    \"                    T[i][j - 1],\\n\",\n    \"                    prices[j] + max_diff)\\n\",\n    \"        return self._find_max_profit_transactions(T, prices)\\n\",\n    \"\\n\",\n    \"    def _find_max_profit_transactions(self, T, prices):\\n\",\n    \"        results = []\\n\",\n    \"        i = len(T) - 1\\n\",\n    \"        j = len(T[0]) - 1\\n\",\n    \"        max_profit = T[i][j]\\n\",\n    \"        while i != 0 and j != 0:\\n\",\n    \"            if T[i][j] == T[i][j - 1]:\\n\",\n    \"                j -= 1\\n\",\n    \"            else:\\n\",\n    \"                sell_price = prices[j]\\n\",\n    \"                results.append(Transaction(Type.SELL, j, sell_price))\\n\",\n    \"                profit = T[i][j] - T[i - 1][j - 1]\\n\",\n    \"                i -= 1\\n\",\n    \"                j -= 1\\n\",\n    \"                for m in range(j + 1)[::-1]:\\n\",\n    \"                    if sell_price - prices[m] == profit:\\n\",\n    \"                        results.append(Transaction(Type.BUY, m, prices[m]))\\n\",\n    \"                        break\\n\",\n    \"        return (max_profit, results)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_max_profit.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_max_profit.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMaxProfit(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_max_profit(self):\\n\",\n    \"        stock_trader = StockTrader()\\n\",\n    \"        self.assertRaises(TypeError, stock_trader.find_max_profit, None, None)\\n\",\n    \"        self.assertEqual(stock_trader.find_max_profit(prices=[], k=0), [])\\n\",\n    \"        prices = [5, 4, 3, 2, 1]\\n\",\n    \"        k = 3\\n\",\n    \"        self.assertEqual(stock_trader.find_max_profit(prices, k), (0, []))\\n\",\n    \"        prices = [2, 5, 7, 1, 4, 3, 1, 3]\\n\",\n    \"        profit, transactions = stock_trader.find_max_profit(prices, k)\\n\",\n    \"        self.assertEqual(profit, 10)\\n\",\n    \"        self.assertTrue(Transaction(Type.SELL,\\n\",\n    \"                                day=7,\\n\",\n    \"                                price=3) in transactions)\\n\",\n    \"        self.assertTrue(Transaction(Type.BUY,\\n\",\n    \"                                day=6,\\n\",\n    \"                                price=1) in transactions)\\n\",\n    \"        self.assertTrue(Transaction(Type.SELL,\\n\",\n    \"                                day=4,\\n\",\n    \"                                price=4) in transactions)\\n\",\n    \"        self.assertTrue(Transaction(Type.BUY,\\n\",\n    \"                                day=3,\\n\",\n    \"                                price=1) in transactions)\\n\",\n    \"        self.assertTrue(Transaction(Type.SELL,\\n\",\n    \"                                day=2,\\n\",\n    \"                                price=7) in transactions)\\n\",\n    \"        self.assertTrue(Transaction(Type.BUY,\\n\",\n    \"                                day=0,\\n\",\n    \"                                price=2) in transactions)\\n\",\n    \"        print('Success: test_max_profit')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMaxProfit()\\n\",\n    \"    test.test_max_profit()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_max_profit\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_max_profit.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/max_profit_k/test_max_profit.py",
    "content": "import unittest\n\n\nclass TestMaxProfit(unittest.TestCase):\n\n    def test_max_profit(self):\n        stock_trader = StockTrader()\n        self.assertRaises(TypeError, stock_trader.find_max_profit, None, None)\n        self.assertEqual(stock_trader.find_max_profit(prices=[], k=0), [])\n        prices = [5, 4, 3, 2, 1]\n        k = 3\n        self.assertEqual(stock_trader.find_max_profit(prices, k), (0, []))\n        prices = [2, 5, 7, 1, 4, 3, 1, 3]\n        profit, transactions = stock_trader.find_max_profit(prices, k)\n        self.assertEqual(profit, 10)\n        self.assertTrue(Transaction(Type.SELL,\n                                day=7,\n                                price=3) in transactions)\n        self.assertTrue(Transaction(Type.BUY,\n                                day=6,\n                                price=1) in transactions)\n        self.assertTrue(Transaction(Type.SELL,\n                                day=4,\n                                price=4) in transactions)\n        self.assertTrue(Transaction(Type.BUY,\n                                day=3,\n                                price=1) in transactions)\n        self.assertTrue(Transaction(Type.SELL,\n                                day=2,\n                                price=7) in transactions)\n        self.assertTrue(Transaction(Type.BUY,\n                                day=0,\n                                price=2) in transactions)\n        print('Success: test_max_profit')\n\n\ndef main():\n    test = TestMaxProfit()\n    test.test_max_profit()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/n_pairs_parentheses/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find all valid combinations of n-pairs of parentheses.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input an integer representing the number of pairs?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Is the output a list of valid combinations?\\n\",\n    \"    * Yes\\n\",\n    \"* Should the output have duplicates?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None -> Exception\\n\",\n    \"* Negative -> Exception\\n\",\n    \"* 0 -> []\\n\",\n    \"* 1 -> ['()']\\n\",\n    \"* 2 -> ['(())', '()()']\\n\",\n    \"* 3 -> ['((()))', '(()())', '(())()', '()(())', '()()()']\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"class Parentheses(object):\\n\",\n    \"\\n\",\n    \"    def find_pair(self, num_pairs):\\n\",\n    \"        # TODO: implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_n_pairs_parentheses.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPairParentheses(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_pair_parentheses(self):\\n\",\n    \"        parentheses = Parentheses()\\n\",\n    \"        self.assertRaises(TypeError, parentheses.find_pair, None)\\n\",\n    \"        self.assertRaises(ValueError, parentheses.find_pair, -1)\\n\",\n    \"        self.assertEqual(parentheses.find_pair(0), [])\\n\",\n    \"        self.assertEqual(parentheses.find_pair(1), ['()'])\\n\",\n    \"        self.assertEqual(parentheses.find_pair(2), ['(())',\\n\",\n    \"                                                '()()'])\\n\",\n    \"        self.assertEqual(parentheses.find_pair(3), ['((()))',\\n\",\n    \"                                                '(()())',\\n\",\n    \"                                                '(())()',\\n\",\n    \"                                                '()(())',\\n\",\n    \"                                                '()()()'])\\n\",\n    \"        print('Success: test_pair_parentheses')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPairParentheses()\\n\",\n    \"    test.test_pair_parentheses()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/n_pairs_parentheses/n_pairs_parentheses_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find all valid combinations of n-pairs of parentheses.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input an integer representing the number of pairs?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Is the output a list of valid combinations?\\n\",\n    \"    * Yes\\n\",\n    \"* Should the output have duplicates?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None -> Exception\\n\",\n    \"* Negative -> Exception\\n\",\n    \"* 0 -> []\\n\",\n    \"* 1 -> ['()']\\n\",\n    \"* 2 -> ['(())', '()()']\\n\",\n    \"* 3 -> ['((()))', '(()())', '(())()', '()(())', '()()()']\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Algorithm\\n\",\n    \"\\n\",\n    \"Let `l` and `r` denote the number of left and right parentheses remaining at any given point. \\n\",\n    \"The algorithm makes use of the following conditions applied recursively:\\n\",\n    \"* Left braces can be inserted any time, as long as we do not exhaust them i.e. `l > 0`.\\n\",\n    \"* Right braces can be inserted, as long as the number of right braces remaining is greater than the left braces remaining i.e. `r > l`. Violation of the aforementioned condition produces an unbalanced string of parentheses.\\n\",\n    \"* If both left and right braces have been exhausted i.e. `l = 0 and r = 0`, then the resultant string produced is balanced.\\n\",\n    \"\\n\",\n    \"The algorithm can be rephrased as:\\n\",\n    \"* Base case: `l = 0 and r = 0`\\n\",\n    \"    - Add the string generated to the result set\\n\",\n    \"* Case 1: `l > 0`\\n\",\n    \"    - Add a left parenthesis to the parentheses string.\\n\",\n    \"    - Recurse (l - 1, r, new_string, result_set)\\n\",\n    \"* Case 2: `r > l`\\n\",\n    \"    - Add a right parenthesis to the parentheses string.\\n\",\n    \"    - Recurse (l, r - 1, new_string, result_set)\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: `O(4^n/n^(3/2))`, see [Catalan numbers](https://en.wikipedia.org/wiki/Catalan_number#Applications_in_combinatorics) - 1, 1, 2, 5, 14, 42, 132...\\n\",\n    \"* Space complexity: `O(n)`, due to the implicit call stack storing a maximum of 2n function calls)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Parentheses(object):\\n\",\n    \"\\n\",\n    \"    def find_pair(self, num_pairs):\\n\",\n    \"        if num_pairs is None:\\n\",\n    \"            raise TypeError('num_pairs cannot be None')\\n\",\n    \"        if num_pairs < 0:\\n\",\n    \"            raise ValueError('num_pairs cannot be < 0')\\n\",\n    \"        if not num_pairs:\\n\",\n    \"            return []\\n\",\n    \"        results = []\\n\",\n    \"        curr_results = []\\n\",\n    \"        self._find_pair(num_pairs, num_pairs, curr_results, results)\\n\",\n    \"        return results\\n\",\n    \"\\n\",\n    \"    def _find_pair(self, nleft, nright, curr_results, results):\\n\",\n    \"        if nleft == 0 and nright == 0:\\n\",\n    \"            results.append(''.join(curr_results))\\n\",\n    \"        else:\\n\",\n    \"            if nleft >= 0:\\n\",\n    \"                self._find_pair(nleft-1, nright, curr_results+['('], results)\\n\",\n    \"            if nright > nleft:\\n\",\n    \"                self._find_pair(nleft, nright-1, curr_results+[')'], results)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_n_pairs_parentheses.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_n_pairs_parentheses.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPairParentheses(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_pair_parentheses(self):\\n\",\n    \"        parentheses = Parentheses()\\n\",\n    \"        self.assertRaises(TypeError, parentheses.find_pair, None)\\n\",\n    \"        self.assertRaises(ValueError, parentheses.find_pair, -1)\\n\",\n    \"        self.assertEqual(parentheses.find_pair(0), [])\\n\",\n    \"        self.assertEqual(parentheses.find_pair(1), ['()'])\\n\",\n    \"        self.assertEqual(parentheses.find_pair(2), ['(())',\\n\",\n    \"                                                '()()'])\\n\",\n    \"        self.assertEqual(parentheses.find_pair(3), ['((()))',\\n\",\n    \"                                                '(()())',\\n\",\n    \"                                                '(())()',\\n\",\n    \"                                                '()(())',\\n\",\n    \"                                                '()()()'])\\n\",\n    \"        print('Success: test_pair_parentheses')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPairParentheses()\\n\",\n    \"    test.test_pair_parentheses()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_pair_parentheses\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_n_pairs_parentheses.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/n_pairs_parentheses/test_n_pairs_parentheses.py",
    "content": "import unittest\n\n\nclass TestPairParentheses(unittest.TestCase):\n\n    def test_pair_parentheses(self):\n        parentheses = Parentheses()\n        self.assertRaises(TypeError, parentheses.find_pair, None)\n        self.assertRaises(ValueError, parentheses.find_pair, -1)\n        self.assertEqual(parentheses.find_pair(0), [])\n        self.assertEqual(parentheses.find_pair(1), ['()'])\n        self.assertEqual(parentheses.find_pair(2), ['(())',\n                                                '()()'])\n        self.assertEqual(parentheses.find_pair(3), ['((()))',\n                                                '(()())',\n                                                '(())()',\n                                                '()(())',\n                                                '()()()'])\n        print('Success: test_pair_parentheses')\n\n\ndef main():\n    test = TestPairParentheses()\n    test.test_pair_parentheses()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/permutations/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/permutations/permutations_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find all permutations of an input string.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can the input have duplicates?\\n\",\n    \"    * Yes\\n\",\n    \"* Can the output have duplicates?\\n\",\n    \"    * No\\n\",\n    \"* Is the output a list of strings?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we have to output the results in sorted order?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None -> None\\n\",\n    \"* '' -> ''\\n\",\n    \"* 'AABC' -> ['AABC', 'AACB', 'ABAC', 'ABCA',\\n\",\n    \"             'ACAB', 'ACBA', 'BAAC', 'BACA',\\n\",\n    \"             'BCAA', 'CAAB', 'CABA', 'CBAA']\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Permutations(object):\\n\",\n    \"\\n\",\n    \"    def find_permutations(self, string):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_permutations.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPermutations(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_permutations(self):\\n\",\n    \"        permutations = Permutations()\\n\",\n    \"        self.assertEqual(permutations.find_permutations(None), None)\\n\",\n    \"        self.assertEqual(permutations.find_permutations(''), '')\\n\",\n    \"        string = 'AABC'\\n\",\n    \"        expected = [\\n\",\n    \"            'AABC', 'AACB', 'ABAC', 'ABCA',\\n\",\n    \"            'ACAB', 'ACBA', 'BAAC', 'BACA',\\n\",\n    \"            'BCAA', 'CAAB', 'CABA', 'CBAA'\\n\",\n    \"        ]\\n\",\n    \"        self.assertEqual(permutations.find_permutations(string), expected)\\n\",\n    \"        print('Success: test_permutations')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPermutations()\\n\",\n    \"    test.test_permutations()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/permutations/permutations_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find all permutations of an input string.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can the input have duplicates?\\n\",\n    \"    * Yes\\n\",\n    \"* Can the output have duplicates?\\n\",\n    \"    * No\\n\",\n    \"* Is the output a list of strings?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we have to output the results in sorted order?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None -> None\\n\",\n    \"* '' -> ''\\n\",\n    \"* 'AABC' -> ['AABC', 'AACB', 'ABAC', 'ABCA',\\n\",\n    \"             'ACAB', 'ACBA', 'BAAC', 'BACA',\\n\",\n    \"             'BCAA', 'CAAB', 'CABA', 'CBAA']\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Build a dictionary of {chars: counts} where counts is the number of times each char is found in the input\\n\",\n    \"* Loop through each item in the dictionary\\n\",\n    \"    * If the counts is 0, continue\\n\",\n    \"    * Decrement the current char's count in the dictionary\\n\",\n    \"    * Add the current char to the current results\\n\",\n    \"    * If the current result is the same length as the input, add it to the results\\n\",\n    \"    * Else, recurse\\n\",\n    \"    * Backtrack by:\\n\",\n    \"        * Removing the just added current char from the current results\\n\",\n    \"        * Incrementing the current char's count in the dictionary\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n!)\\n\",\n    \"* Space: O(n!) since we are storing the results in an array, or O(n) if we are just printing each result\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from collections import OrderedDict\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Permutations(object):\\n\",\n    \"\\n\",\n    \"    def _build_counts_map(self, string):\\n\",\n    \"        counts_map = OrderedDict()\\n\",\n    \"        for char in string:\\n\",\n    \"            if char in counts_map:\\n\",\n    \"                counts_map[char] += 1\\n\",\n    \"            else:\\n\",\n    \"                counts_map[char] = 1\\n\",\n    \"        return counts_map\\n\",\n    \"\\n\",\n    \"    def find_permutations(self, string):\\n\",\n    \"        if string is None or string == '':\\n\",\n    \"            return string\\n\",\n    \"        counts_map = self._build_counts_map(string)\\n\",\n    \"        curr_results = []\\n\",\n    \"        results = []\\n\",\n    \"        self._find_permutations(counts_map, curr_results, results, len(string))\\n\",\n    \"        return results\\n\",\n    \"\\n\",\n    \"    def _find_permutations(self, counts_map, curr_result,\\n\",\n    \"                           results, input_length):\\n\",\n    \"        for char in counts_map:\\n\",\n    \"            if counts_map[char] == 0:\\n\",\n    \"                continue\\n\",\n    \"            curr_result.append(char)\\n\",\n    \"            counts_map[char] -= 1\\n\",\n    \"            if len(curr_result) == input_length:\\n\",\n    \"                results.append(''.join(curr_result))\\n\",\n    \"            else:\\n\",\n    \"                self._find_permutations(counts_map, curr_result,\\n\",\n    \"                                        results, input_length)\\n\",\n    \"            counts_map[char] += 1\\n\",\n    \"            curr_result.pop()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_permutations.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_permutations.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPermutations(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_permutations(self):\\n\",\n    \"        permutations = Permutations()\\n\",\n    \"        self.assertEqual(permutations.find_permutations(None), None)\\n\",\n    \"        self.assertEqual(permutations.find_permutations(''), '')\\n\",\n    \"        string = 'AABC'\\n\",\n    \"        expected = [\\n\",\n    \"            'AABC', 'AACB', 'ABAC', 'ABCA',\\n\",\n    \"            'ACAB', 'ACBA', 'BAAC', 'BACA',\\n\",\n    \"            'BCAA', 'CAAB', 'CABA', 'CBAA'\\n\",\n    \"        ]\\n\",\n    \"        self.assertEqual(permutations.find_permutations(string), expected)\\n\",\n    \"        print('Success: test_permutations')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPermutations()\\n\",\n    \"    test.test_permutations()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_permutations\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_permutations.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/permutations/test_permutations.py",
    "content": "import unittest\n\n\nclass TestPermutations(unittest.TestCase):\n\n    def test_permutations(self):\n        permutations = Permutations()\n        self.assertEqual(permutations.find_permutations(None), None)\n        self.assertEqual(permutations.find_permutations(''), '')\n        string = 'AABC'\n        expected = [\n            'AABC', 'AACB', 'ABAC', 'ABCA',\n            'ACAB', 'ACBA', 'BAAC', 'BACA',\n            'BCAA', 'CAAB', 'CABA', 'CBAA'\n        ]\n        self.assertEqual(permutations.find_permutations(string), expected)\n        print('Success: test_permutations')\n\n\ndef main():\n    test = TestPermutations()\n    test.test_permutations()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/power_set/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/power_set/power_set_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Return all subsets of a set.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Should the resulting subsets be unique?\\n\",\n    \"    * Yes, treat 'ab' and 'bc' as the same\\n\",\n    \"* Is the empty set included as a subset?\\n\",\n    \"    * Yes\\n\",\n    \"* Are the inputs unique?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None -> None\\n\",\n    \"* [] -> [[]]\\n\",\n    \"* ['a'] -> [[], \\n\",\n    \"            ['a']]\\n\",\n    \"* ['a', 'b'] -> [[], \\n\",\n    \"                 ['a'], \\n\",\n    \"                 ['b'], \\n\",\n    \"                 ['a', 'b']]\\n\",\n    \"* ['a', 'b', 'c'] -> [[], \\n\",\n    \"                      ['a'], \\n\",\n    \"                      ['b'], \\n\",\n    \"                      ['c'],\\n\",\n    \"                      ['a', 'b'], \\n\",\n    \"                      ['a', 'c'], \\n\",\n    \"                      ['b', 'c'],\\n\",\n    \"                      ['a', 'b', 'c']]\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Sets(object):\\n\",\n    \"\\n\",\n    \"    def find_power_set_recursive(self, input_set):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def find_power_set_iterative(self, input_set):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_power_set.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPowerSet(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_power_set(self):\\n\",\n    \"        input_set = []\\n\",\n    \"        expected = [[]]\\n\",\n    \"        self.run_test(input_set, expected)\\n\",\n    \"        input_set = ['a']\\n\",\n    \"        expected = [['a'], []]\\n\",\n    \"        self.run_test(input_set, expected)\\n\",\n    \"        input_set = ['a', 'b']\\n\",\n    \"        expected = [['a'], ['a', 'b'], ['b'], []]\\n\",\n    \"        self.run_test(input_set, expected)\\n\",\n    \"        input_set = ['a', 'b', 'c']\\n\",\n    \"        expected = [['a'], ['a', 'b'], ['b'], ['a', 'c'], \\n\",\n    \"                    ['a', 'b', 'c'], ['b', 'c'], ['c'], []]\\n\",\n    \"        self.run_test(input_set, expected)\\n\",\n    \"        print('Success: test_power_set')\\n\",\n    \"\\n\",\n    \"    def run_test(self, input_set, expected):\\n\",\n    \"        combinatoric = Combinatoric()\\n\",\n    \"        result = combinatoric.find_power_set_recursive(input_set)\\n\",\n    \"        self.assertEqual(result, expected)\\n\",\n    \"        result = combinatoric.find_power_set_iterative(input_set)\\n\",\n    \"        self.assertEqual(result, expected)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPowerSet()\\n\",\n    \"    test.test_power_set()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/power_set/power_set_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Return all subsets of a set.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Should the resulting subsets be unique?\\n\",\n    \"    * Yes, treat 'ab' and 'bc' as the same\\n\",\n    \"* Is the empty set included as a subset?\\n\",\n    \"    * Yes\\n\",\n    \"* Are the inputs unique?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"* None -> None\\n\",\n    \"* '' -> ['']\\n\",\n    \"* 'a' -> ['a', '']\\n\",\n    \"* 'ab' -> ['a', 'ab', 'b', '']\\n\",\n    \"* 'abc' -> ['a', 'ab', 'abc', 'ac',\\n\",\n    \"            'b', 'bc', 'c', '']\\n\",\n    \"* 'aabc' -> ['a', 'aa', 'aab', 'aabc', \\n\",\n    \"             'aac', 'ab', 'abc', 'ac', \\n\",\n    \"             'b', 'bc', 'c', '']\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Build a dictionary of {chars: counts} where counts is the number of times each char is found in the input\\n\",\n    \"* Loop through each item in the dictionary\\n\",\n    \"    * Keep track of the current index (first item will have current index 0)\\n\",\n    \"    * If the char's count is 0, continue\\n\",\n    \"    * Decrement the current char's count in the dictionary\\n\",\n    \"    * Add the current char to the current results\\n\",\n    \"    * Add the current result to the results\\n\",\n    \"    * Recurse, passing in the current index as the new starting point index\\n\",\n    \"        * When we recurse, we'll check if current index < starting point index, and if so, continue\\n\",\n    \"        * This avoids duplicate results such as 'ab' and 'bc'\\n\",\n    \"    * Backtrack by:\\n\",\n    \"        * Removing the just added current char from the current results\\n\",\n    \"        * Incrementing the current char's count in the dictionary\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(2^n)\\n\",\n    \"* Space: O(2^n) if we are saving each result, or O(n) if we are just printing each result\\n\",\n    \"\\n\",\n    \"We are doubling the number of operations every time we add an element to the results: O(2^n).\\n\",\n    \"\\n\",\n    \"Note, you could also use the following method to solve this problem:\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"number binary  subset\\n\",\n    \"0      000      {}\\n\",\n    \"1      001      {c}\\n\",\n    \"2      010      {b}\\n\",\n    \"3      011      {b,c}\\n\",\n    \"4      100      {a}\\n\",\n    \"5      101      {a,c}\\n\",\n    \"6      110      {a,b}\\n\",\n    \"7      111      {a,b,c}\\n\",\n    \"</pre>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from collections import OrderedDict\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Combinatoric(object):\\n\",\n    \"\\n\",\n    \"    def _build_counts_map(self, string):\\n\",\n    \"        counts_map = OrderedDict()\\n\",\n    \"        for char in string:\\n\",\n    \"            if char in counts_map:\\n\",\n    \"                counts_map[char] += 1\\n\",\n    \"            else:\\n\",\n    \"                counts_map[char] = 1\\n\",\n    \"        return counts_map\\n\",\n    \"\\n\",\n    \"    def find_power_set(self, string):\\n\",\n    \"        if string is None:\\n\",\n    \"            return string\\n\",\n    \"        if string == '':\\n\",\n    \"            return ['']\\n\",\n    \"        counts_map = self._build_counts_map(string)\\n\",\n    \"        curr_results = []\\n\",\n    \"        results = []\\n\",\n    \"        self._find_power_set(counts_map, curr_results,\\n\",\n    \"                             results, index=0)\\n\",\n    \"        results.append('')\\n\",\n    \"        return results\\n\",\n    \"\\n\",\n    \"    def _find_power_set(self, counts_map, curr_result,\\n\",\n    \"                        results, index):\\n\",\n    \"        for curr_index, char in enumerate(counts_map):\\n\",\n    \"            if curr_index < index or counts_map[char] == 0:\\n\",\n    \"                continue\\n\",\n    \"            curr_result.append(char)\\n\",\n    \"            counts_map[char] -= 1\\n\",\n    \"            results.append(''.join(curr_result))\\n\",\n    \"            self._find_power_set(counts_map, curr_result,\\n\",\n    \"                                 results, curr_index)\\n\",\n    \"            counts_map[char] += 1\\n\",\n    \"            curr_result.pop()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_power_set.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_power_set.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestPowerSet(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_power_set(self):\\n\",\n    \"        input_set = ''\\n\",\n    \"        expected = ['']\\n\",\n    \"        self.run_test(input_set, expected)\\n\",\n    \"        input_set = 'a'\\n\",\n    \"        expected = ['a', '']\\n\",\n    \"        self.run_test(input_set, expected)\\n\",\n    \"        input_set = 'ab'\\n\",\n    \"        expected = ['a', 'ab', 'b', '']\\n\",\n    \"        self.run_test(input_set, expected)\\n\",\n    \"        input_set = 'abc'\\n\",\n    \"        expected = ['a', 'ab', 'abc', 'ac',\\n\",\n    \"                    'b', 'bc', 'c', '']\\n\",\n    \"        self.run_test(input_set, expected)\\n\",\n    \"        input_set = 'aabc'\\n\",\n    \"        expected = ['a', 'aa', 'aab', 'aabc', \\n\",\n    \"                    'aac', 'ab', 'abc', 'ac', \\n\",\n    \"                    'b', 'bc', 'c', '']\\n\",\n    \"        self.run_test(input_set, expected)\\n\",\n    \"        print('Success: test_power_set')\\n\",\n    \"\\n\",\n    \"    def run_test(self, input_set, expected):\\n\",\n    \"        combinatoric = Combinatoric()\\n\",\n    \"        result = combinatoric.find_power_set(input_set)\\n\",\n    \"        self.assertEqual(result, expected)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestPowerSet()\\n\",\n    \"    test.test_power_set()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_power_set\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_power_set.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/power_set/test_power_set.py",
    "content": "import unittest\n\n\nclass TestPowerSet(unittest.TestCase):\n\n    def test_power_set(self):\n        input_set = ''\n        expected = ['']\n        self.run_test(input_set, expected)\n        input_set = 'a'\n        expected = ['a', '']\n        self.run_test(input_set, expected)\n        input_set = 'ab'\n        expected = ['a', 'ab', 'b', '']\n        self.run_test(input_set, expected)\n        input_set = 'abc'\n        expected = ['a', 'ab', 'abc', 'ac',\n                    'b', 'bc', 'c', '']\n        self.run_test(input_set, expected)\n        input_set = 'aabc'\n        expected = ['a', 'aa', 'aab', 'aabc', \n                    'aac', 'ab', 'abc', 'ac', \n                    'b', 'bc', 'c', '']\n        self.run_test(input_set, expected)\n        print('Success: test_power_set')\n\n    def run_test(self, input_set, expected):\n        combinatoric = Combinatoric()\n        result = combinatoric.find_power_set(input_set)\n        self.assertEqual(result, expected)\n\n\ndef main():\n    test = TestPowerSet()\n    test.test_power_set()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "recursion_dynamic/steps/__init__.py",
    "content": ""
  },
  {
    "path": "recursion_dynamic/steps/steps_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: You are running up n steps.  If you can take a single, double, or triple step, how many possible ways are there to run up to the nth step?\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* If n == 0, what should the result be?\\n\",\n    \"    * Go with 1, but discuss different approaches\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None or negative input -> Exception\\n\",\n    \"* n == 0 -> 1\\n\",\n    \"* n == 1 -> 1\\n\",\n    \"* n == 2 -> 2\\n\",\n    \"* n == 3 -> 4\\n\",\n    \"* n == 4 -> 7\\n\",\n    \"* n == 10 -> 274\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Steps(object):\\n\",\n    \"\\n\",\n    \"    def count_ways(self, num_steps):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_steps.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSteps(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_steps(self):\\n\",\n    \"        steps = Steps()\\n\",\n    \"        self.assertRaises(TypeError, steps.count_ways, None)\\n\",\n    \"        self.assertRaises(TypeError, steps.count_ways, -1)\\n\",\n    \"        self.assertEqual(steps.count_ways(0), 1)\\n\",\n    \"        self.assertEqual(steps.count_ways(1), 1)\\n\",\n    \"        self.assertEqual(steps.count_ways(2), 2)\\n\",\n    \"        self.assertEqual(steps.count_ways(3), 4)\\n\",\n    \"        self.assertEqual(steps.count_ways(4), 7)\\n\",\n    \"        self.assertEqual(steps.count_ways(10), 274)\\n\",\n    \"        print('Success: test_steps')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSteps()\\n\",\n    \"    test.test_steps()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/steps/steps_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: You are running up n steps.  If you can take a single, double, or triple step, how many possible ways are there to run up to the nth step?\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* If n == 0, what should the result be?\\n\",\n    \"    * Go with 1, but discuss different approaches\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None or negative input -> Exception\\n\",\n    \"* n == 0 -> 1\\n\",\n    \"* n == 1 -> 1\\n\",\n    \"* n == 2 -> 2\\n\",\n    \"* n == 3 -> 4\\n\",\n    \"* n == 4 -> 7\\n\",\n    \"* n == 10 -> 274\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"To get to step n, we will need to have gone:\\n\",\n    \"\\n\",\n    \"* One step from n-1\\n\",\n    \"* Two steps from n-2\\n\",\n    \"* Three steps from n-3\\n\",\n    \"\\n\",\n    \"If we go the one step route above, we'll be at n-1 before taking the last step.  To get to step n-1, we will need to have gone:\\n\",\n    \"\\n\",\n    \"* One step from n-1-1\\n\",\n    \"* Two steps from n-1-2\\n\",\n    \"* Three steps from n-1-2\\n\",\n    \"\\n\",\n    \"Continue this process until we reach the start.\\n\",\n    \"\\n\",\n    \"Base case:\\n\",\n    \"\\n\",\n    \"* If n < 0: return 0\\n\",\n    \"* If n == 0: return 1\\n\",\n    \"\\n\",\n    \"Note, if we had chosen n == 0 to return 0 instead, we would need to add additional base cases.  Otherwise we'd be adding multiple 0's once we hit the base cases and not get any result > 0.\\n\",\n    \"\\n\",\n    \"Recursive case:\\n\",\n    \"\\n\",\n    \"We'll memoize the solution to improve performance.\\n\",\n    \"\\n\",\n    \"* Use the memo if we've already processed the current step.\\n\",\n    \"* Update the memo by adding the recursive calls to step(n-1), step(n-2), step(n-3)\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n), if using memoization\\n\",\n    \"* Space: O(n), where n is the recursion depth\\n\",\n    \"\\n\",\n    \"Note: The number of ways will quickly overflow the bounds of an integer.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Steps(object):\\n\",\n    \"\\n\",\n    \"    def count_ways(self, num_steps):\\n\",\n    \"        if num_steps is None or num_steps < 0:\\n\",\n    \"            raise TypeError('num_steps cannot be None or negative')\\n\",\n    \"        cache = {}\\n\",\n    \"        return self._count_ways(num_steps, cache)\\n\",\n    \"\\n\",\n    \"    def _count_ways(self, num_steps, cache):\\n\",\n    \"        if num_steps < 0:\\n\",\n    \"            return 0\\n\",\n    \"        if num_steps == 0:\\n\",\n    \"            return 1\\n\",\n    \"        if num_steps in cache:\\n\",\n    \"            return cache[num_steps]\\n\",\n    \"        cache[num_steps] = (self._count_ways(num_steps-1, cache) +\\n\",\n    \"                            self._count_ways(num_steps-2, cache) +\\n\",\n    \"                            self._count_ways(num_steps-3, cache))\\n\",\n    \"        return cache[num_steps]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_steps.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_steps.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSteps(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_steps(self):\\n\",\n    \"        steps = Steps()\\n\",\n    \"        self.assertRaises(TypeError, steps.count_ways, None)\\n\",\n    \"        self.assertRaises(TypeError, steps.count_ways, -1)\\n\",\n    \"        self.assertEqual(steps.count_ways(0), 1)\\n\",\n    \"        self.assertEqual(steps.count_ways(1), 1)\\n\",\n    \"        self.assertEqual(steps.count_ways(2), 2)\\n\",\n    \"        self.assertEqual(steps.count_ways(3), 4)\\n\",\n    \"        self.assertEqual(steps.count_ways(4), 7)\\n\",\n    \"        self.assertEqual(steps.count_ways(10), 274)\\n\",\n    \"        print('Success: test_steps')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSteps()\\n\",\n    \"    test.test_steps()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_steps\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_steps.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "recursion_dynamic/steps/test_steps.py",
    "content": "import unittest\n\n\nclass TestSteps(unittest.TestCase):\n\n    def test_steps(self):\n        steps = Steps()\n        self.assertRaises(TypeError, steps.count_ways, None)\n        self.assertRaises(TypeError, steps.count_ways, -1)\n        self.assertEqual(steps.count_ways(0), 1)\n        self.assertEqual(steps.count_ways(1), 1)\n        self.assertEqual(steps.count_ways(2), 2)\n        self.assertEqual(steps.count_ways(3), 4)\n        self.assertEqual(steps.count_ways(4), 7)\n        self.assertEqual(steps.count_ways(10), 274)\n        print('Success: test_steps')\n\n\ndef main():\n    test = TestSteps()\n    test.test_steps()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "requirements.txt",
    "content": "jupyter\nnose\n"
  },
  {
    "path": "sorting_searching/__init__.py",
    "content": ""
  },
  {
    "path": "sorting_searching/anagrams/__init__.py",
    "content": ""
  },
  {
    "path": "sorting_searching/anagrams/anagrams_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Sort an array of strings so all anagrams are next to each other.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are there any other sorting requirements other than the grouping of anagrams?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* [] -> []\\n\",\n    \"* General case\\n\",\n    \"    * Input: ['ram', 'act', 'arm', 'bat', 'cat', 'tab']\\n\",\n    \"    * Result: ['arm', 'ram', 'act', 'cat', 'bat', 'tab']\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/anagrams/anagrams_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from collections import OrderedDict\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Anagram(object):\\n\",\n    \"\\n\",\n    \"    def group_anagrams(self, items):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_anagrams.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestAnagrams(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_group_anagrams(self):\\n\",\n    \"        anagram = Anagram()\\n\",\n    \"        self.assertRaises(TypeError, anagram.group_anagrams, None)\\n\",\n    \"        data = ['ram', 'act', 'arm', 'bat', 'cat', 'tab']\\n\",\n    \"        expected = ['ram', 'arm', 'act', 'cat', 'bat', 'tab']\\n\",\n    \"        self.assertEqual(anagram.group_anagrams(data), expected)\\n\",\n    \"\\n\",\n    \"        print('Success: test_group_anagrams')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestAnagrams()\\n\",\n    \"    test.test_group_anagrams()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/anagrams/anagrams_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Sort an array of strings so all anagrams are next to each other.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are there any other sorting requirements other than the grouping of anagrams?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* [] -> []\\n\",\n    \"* General case\\n\",\n    \"    * Input: ['ram', 'act', 'arm', 'bat', 'cat', 'tab']\\n\",\n    \"    * Result: ['arm', 'ram', 'act', 'cat', 'bat', 'tab']\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"Input: ['ram', 'act', 'arm', 'bat', 'cat', 'tab']\\n\",\n    \"\\n\",\n    \"Sort the chars for each item:\\n\",\n    \"\\n\",\n    \"'ram' -> 'amr'\\n\",\n    \"'act' -> 'act'\\n\",\n    \"'arm' -> 'amr'\\n\",\n    \"'abt' -> 'bat'\\n\",\n    \"'cat' -> 'act'\\n\",\n    \"'abt' -> 'tab'\\n\",\n    \"\\n\",\n    \"Use a map of sorted chars to each item to group anagrams:\\n\",\n    \"\\n\",\n    \"{\\n\",\n    \"    'amr': ['ram', 'arm'], \\n\",\n    \"    'act': ['act', 'cat'], \\n\",\n    \"    'abt': ['bat', 'tab']\\n\",\n    \"}\\n\",\n    \"\\n\",\n    \"Result: ['arm', 'ram', 'act', 'cat', 'bat', 'tab']\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(k * n), due to the modified bucket sort\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from collections import OrderedDict\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Anagram(object):\\n\",\n    \"\\n\",\n    \"    def group_anagrams(self, items):\\n\",\n    \"        if items is None:\\n\",\n    \"            raise TypeError('items cannot be None')\\n\",\n    \"        if not items:\\n\",\n    \"            return items\\n\",\n    \"        anagram_map = OrderedDict()\\n\",\n    \"        for item in items:\\n\",\n    \"            # Use a tuple, which is hashable and\\n\",\n    \"            # serves as the key in anagram_map\\n\",\n    \"            sorted_chars = tuple(sorted(item))\\n\",\n    \"            if sorted_chars in anagram_map:\\n\",\n    \"                anagram_map[sorted_chars].append(item)\\n\",\n    \"            else:\\n\",\n    \"                anagram_map[sorted_chars] = [item]\\n\",\n    \"        result = []\\n\",\n    \"        for value in anagram_map.values():\\n\",\n    \"            result.extend(value)\\n\",\n    \"        return result\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_anagrams.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_anagrams.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestAnagrams(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_group_anagrams(self):\\n\",\n    \"        anagram = Anagram()\\n\",\n    \"        self.assertRaises(TypeError, anagram.group_anagrams, None)\\n\",\n    \"        data = ['ram', 'act', 'arm', 'bat', 'cat', 'tab']\\n\",\n    \"        expected = ['ram', 'arm', 'act', 'cat', 'bat', 'tab']\\n\",\n    \"        self.assertEqual(anagram.group_anagrams(data), expected)\\n\",\n    \"\\n\",\n    \"        print('Success: test_group_anagrams')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestAnagrams()\\n\",\n    \"    test.test_group_anagrams()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_group_anagrams\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_anagrams.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/anagrams/test_anagrams.py",
    "content": "import unittest\n\n\nclass TestAnagrams(unittest.TestCase):\n\n    def test_group_anagrams(self):\n        anagram = Anagram()\n        self.assertRaises(TypeError, anagram.group_anagrams, None)\n        data = ['ram', 'act', 'arm', 'bat', 'cat', 'tab']\n        expected = ['ram', 'arm', 'act', 'cat', 'bat', 'tab']\n        self.assertEqual(anagram.group_anagrams(data), expected)\n\n        print('Success: test_group_anagrams')\n\n\ndef main():\n    test = TestAnagrams()\n    test.test_group_anagrams()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "sorting_searching/insertion_sort/__init__.py",
    "content": ""
  },
  {
    "path": "sorting_searching/insertion_sort/insertion_sort_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement insertion sort.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is a naive solution sufficient?\\n\",\n    \"    * Yes\\n\",\n    \"* Are duplicates allowed?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input is valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* Empty input -> []\\n\",\n    \"* One element -> [element]\\n\",\n    \"* Two or more elements\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/insertion_sort/insertion_sort_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class InsertionSort(object):\\n\",\n    \"\\n\",\n    \"    def sort(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_insertion_sort.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestInsertionSort(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_insertion_sort(self):\\n\",\n    \"        insertion_sort = InsertionSort()\\n\",\n    \"\\n\",\n    \"        print('None input')\\n\",\n    \"        self.assertRaises(TypeError, insertion_sort.sort, None)\\n\",\n    \"\\n\",\n    \"        print('Empty input')\\n\",\n    \"        self.assertEqual(insertion_sort.sort([]), [])\\n\",\n    \"\\n\",\n    \"        print('One element')\\n\",\n    \"        self.assertEqual(insertion_sort.sort([5]), [5])\\n\",\n    \"\\n\",\n    \"        print('Two or more elements')\\n\",\n    \"        data = [5, 1, 7, 2, 6, -3, 5, 7, -1]\\n\",\n    \"        self.assertEqual(insertion_sort.sort(data), sorted(data))\\n\",\n    \"\\n\",\n    \"        print('Success: test_insertion_sort')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestInsertionSort()\\n\",\n    \"    test.test_insertion_sort()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/insertion_sort/insertion_sort_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/insertion_sort/insertion_sort_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement insertion sort.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is a naive solution sufficient?\\n\",\n    \"    * Yes\\n\",\n    \"* Are duplicates allowed?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input is valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* Empty input -> []\\n\",\n    \"* One element -> [element]\\n\",\n    \"* Two or more elements\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Wikipedia's animation:\\n\",\n    \"![alt text](http://upload.wikimedia.org/wikipedia/commons/0/0f/Insertion-sort-example-300px.gif)\\n\",\n    \"\\n\",\n    \"* For each value index 1 to n - 1\\n\",\n    \"    * Compare with all elements to the left of the current value to determine new insertion point\\n\",\n    \"        * Hold current value in temp variable\\n\",\n    \"        * Shift elements from new insertion point right\\n\",\n    \"        * Insert value in temp variable\\n\",\n    \"        * Break\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n^2) average, worst.  O(1) best if input is already sorted\\n\",\n    \"* Space: O(1) for the iterative solution\\n\",\n    \"\\n\",\n    \"Misc: \\n\",\n    \"\\n\",\n    \"* In-place\\n\",\n    \"* Stable\\n\",\n    \"\\n\",\n    \"Insertion sort works well for very small datasets where most of the input is already sorted.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class InsertionSort(object):\\n\",\n    \"\\n\",\n    \"    def sort(self, data):\\n\",\n    \"        if data is None:\\n\",\n    \"            raise TypeError('data cannot be None')\\n\",\n    \"        if len(data) < 2:\\n\",\n    \"            return data\\n\",\n    \"        for r in range(1, len(data)):\\n\",\n    \"            for l in range(r):\\n\",\n    \"                if data[r] < data[l]:\\n\",\n    \"                    temp = data[r]\\n\",\n    \"                    data[l+1:r+1] = data[l:r]\\n\",\n    \"                    data[l] = temp\\n\",\n    \"        return data\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_insertion_sort.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_insertion_sort.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestInsertionSort(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_insertion_sort(self):\\n\",\n    \"        insertion_sort = InsertionSort()\\n\",\n    \"\\n\",\n    \"        print('None input')\\n\",\n    \"        self.assertRaises(TypeError, insertion_sort.sort, None)\\n\",\n    \"\\n\",\n    \"        print('Empty input')\\n\",\n    \"        self.assertEqual(insertion_sort.sort([]), [])\\n\",\n    \"\\n\",\n    \"        print('One element')\\n\",\n    \"        self.assertEqual(insertion_sort.sort([5]), [5])\\n\",\n    \"\\n\",\n    \"        print('Two or more elements')\\n\",\n    \"        data = [5, 1, 7, 2, 6, -3, 5, 7, -1]\\n\",\n    \"        self.assertEqual(insertion_sort.sort(data), sorted(data))\\n\",\n    \"\\n\",\n    \"        print('Success: test_insertion_sort')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestInsertionSort()\\n\",\n    \"    test.test_insertion_sort()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"None input\\n\",\n      \"Empty input\\n\",\n      \"One element\\n\",\n      \"Two or more elements\\n\",\n      \"Success: test_insertion_sort\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_insertion_sort.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/insertion_sort/test_insertion_sort.py",
    "content": "import unittest\n\n\nclass TestInsertionSort(unittest.TestCase):\n\n    def test_insertion_sort(self):\n        insertion_sort = InsertionSort()\n\n        print('None input')\n        self.assertRaises(TypeError, insertion_sort.sort, None)\n\n        print('Empty input')\n        self.assertEqual(insertion_sort.sort([]), [])\n\n        print('One element')\n        self.assertEqual(insertion_sort.sort([5]), [5])\n\n        print('Two or more elements')\n        data = [5, 1, 7, 2, 6, -3, 5, 7, -1]\n        self.assertEqual(insertion_sort.sort(data), sorted(data))\n\n        print('Success: test_insertion_sort')\n\n\ndef main():\n    test = TestInsertionSort()\n    test.test_insertion_sort()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "sorting_searching/merge_into/__init__.py",
    "content": ""
  },
  {
    "path": "sorting_searching/merge_into/merge_into_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given sorted arrays A, B, merge B into A in sorted order.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Does A have enough space for B?\\n\",\n    \"    * Yes\\n\",\n    \"* Can the inputs have duplicate array items?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Does the inputs also include the actual size of A and B?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* A or B is None -> Exception\\n\",\n    \"* index of last A or B < 0 -> Exception\\n\",\n    \"* A or B is empty\\n\",\n    \"* General case\\n\",\n    \"    * A = [1,  3,  5,  7,  9,  None,  None,  None]\\n\",\n    \"    * B = [4,  5,  6]\\n\",\n    \"    * A = [1, 3, 4, 5, 5, 6, 7, 9]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/merge_into/merge_into_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Array(object):\\n\",\n    \"\\n\",\n    \"    def merge_into(self, source, dest, source_end_index, dest_end_index):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_merge_into.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestArray(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_merge_into(self):\\n\",\n    \"        array = Array()\\n\",\n    \"        self.assertRaises(TypeError, array.merge_into, None, None, None, None)\\n\",\n    \"        self.assertRaises(ValueError, array.merge_into, [1], [2], -1, -1)\\n\",\n    \"        a = [1, 2, 3]\\n\",\n    \"        self.assertEqual(array.merge_into(a, [], len(a), 0), [1, 2, 3])\\n\",\n    \"        a = [1, 2, 3]\\n\",\n    \"        self.assertEqual(array.merge_into(a, [], len(a), 0), [1, 2, 3])\\n\",\n    \"        a = [1,  3,  5,  7,  9,  None,  None,  None]\\n\",\n    \"        b = [4,  5,  6]\\n\",\n    \"        expected = [1, 3, 4, 5, 5, 6, 7, 9]\\n\",\n    \"        self.assertEqual(array.merge_into(a, b, 5, len(b)), expected)\\n\",\n    \"        print('Success: test_merge_into')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestArray()\\n\",\n    \"    test.test_merge_into()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/merge_into/merge_into_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given sorted arrays A, B, merge B into A in sorted order.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Does A have enough space for B?\\n\",\n    \"    * Yes\\n\",\n    \"* Can the inputs have duplicate array items?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Does the inputs also include the actual size of A and B?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* A or B is None -> Exception\\n\",\n    \"* index of last A or B < 0 -> Exception\\n\",\n    \"* A or B is empty\\n\",\n    \"* General case\\n\",\n    \"    * A = [1,  3,  5,  7,  9,  None,  None,  None]\\n\",\n    \"    * B = [4,  5,  6]\\n\",\n    \"    * A = [1, 3, 4, 5, 5, 6, 7, 9]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"                     i                 k\\n\",\n    \"A = [1,  3,  5,  7,  9,  None,  None,  None]\\n\",\n    \"             j\\n\",\n    \"B = [4,  5,  6]\\n\",\n    \"\\n\",\n    \"---\\n\",\n    \"\\n\",\n    \"A[k] = max(A[i], B[j])\\n\",\n    \"                     i                 k\\n\",\n    \"A = [1,  3,  5,  7,  9,  None,  None,  9]\\n\",\n    \"             j\\n\",\n    \"B = [4,  5,  6]\\n\",\n    \"\\n\",\n    \"---\\n\",\n    \"\\n\",\n    \"A[k] = max(A[i], B[j])\\n\",\n    \"                 i              k       \\n\",\n    \"A = [1,  3,  5,  7,  9,  None,  7,  9]\\n\",\n    \"             j\\n\",\n    \"B = [4,  5,  6]\\n\",\n    \"\\n\",\n    \"---\\n\",\n    \"\\n\",\n    \"A[k] = max(A[i], B[j])\\n\",\n    \"             i           k              \\n\",\n    \"A = [1,  3,  5,  7,  9,  6,  7,  9]\\n\",\n    \"             j\\n\",\n    \"B = [4,  5,  6]\\n\",\n    \"\\n\",\n    \"---\\n\",\n    \"\\n\",\n    \"A[k] = max(A[i], B[j])\\n\",\n    \"             i       k                  \\n\",\n    \"A = [1,  3,  5,  7,  5,  6,  7,  9]\\n\",\n    \"         j    \\n\",\n    \"B = [4,  5,  6]\\n\",\n    \"\\n\",\n    \"---\\n\",\n    \"\\n\",\n    \"A[k] = max(A[i], B[j])\\n\",\n    \"         i       k                      \\n\",\n    \"A = [1,  3,  5,  5,  5,  6,  7,  9]\\n\",\n    \"         j    \\n\",\n    \"B = [4,  5,  6]\\n\",\n    \"\\n\",\n    \"---\\n\",\n    \"\\n\",\n    \"A[k] = max(A[i], B[j])\\n\",\n    \"         i   k                          \\n\",\n    \"A = [1,  3,  4,  5,  5,  6,  7,  9]\\n\",\n    \"     j        \\n\",\n    \"B = [4,  5,  6]\\n\",\n    \"\\n\",\n    \"---\\n\",\n    \"\\n\",\n    \"A[k] = max(A[i], B[j])\\n\",\n    \"        ik                              \\n\",\n    \"A = [1,  3,  4,  5,  5,  6,  7,  9]\\n\",\n    \"             \\n\",\n    \"B = [4,  5,  6]\\n\",\n    \"\\n\",\n    \"---\\n\",\n    \"\\n\",\n    \"A = [1, 3, 4, 5, 5, 6, 7, 9]\\n\",\n    \"\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(m + n)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Array(object):\\n\",\n    \"\\n\",\n    \"    def merge_into(self, source, dest, source_end_index, dest_end_index):\\n\",\n    \"        if source is None or dest is None:\\n\",\n    \"            raise TypeError('source or dest cannot be None')\\n\",\n    \"        if source_end_index < 0 or dest_end_index < 0:\\n\",\n    \"            raise ValueError('end indices must be >= 0')\\n\",\n    \"        if not source:\\n\",\n    \"            return dest\\n\",\n    \"        if not dest:\\n\",\n    \"            return source\\n\",\n    \"        source_index = source_end_index - 1\\n\",\n    \"        dest_index = dest_end_index - 1\\n\",\n    \"        insert_index = source_end_index + dest_end_index - 1\\n\",\n    \"        while dest_index >= 0:\\n\",\n    \"            if source[source_index] > dest[dest_index]:\\n\",\n    \"                source[insert_index] = source[source_index]\\n\",\n    \"                source_index -= 1\\n\",\n    \"            else:\\n\",\n    \"                source[insert_index] = dest[dest_index]\\n\",\n    \"                dest_index -= 1\\n\",\n    \"            insert_index -= 1\\n\",\n    \"        return source\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_merge_into.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_merge_into.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestArray(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_merge_into(self):\\n\",\n    \"        array = Array()\\n\",\n    \"        self.assertRaises(TypeError, array.merge_into, None, None, None, None)\\n\",\n    \"        self.assertRaises(ValueError, array.merge_into, [1], [2], -1, -1)\\n\",\n    \"        a = [1, 2, 3]\\n\",\n    \"        self.assertEqual(array.merge_into(a, [], len(a), 0), [1, 2, 3])\\n\",\n    \"        a = [1, 2, 3]\\n\",\n    \"        self.assertEqual(array.merge_into(a, [], len(a), 0), [1, 2, 3])\\n\",\n    \"        a = [1,  3,  5,  7,  9,  None,  None,  None]\\n\",\n    \"        b = [4,  5,  6]\\n\",\n    \"        expected = [1, 3, 4, 5, 5, 6, 7, 9]\\n\",\n    \"        self.assertEqual(array.merge_into(a, b, 5, len(b)), expected)\\n\",\n    \"        print('Success: test_merge_into')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestArray()\\n\",\n    \"    test.test_merge_into()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_merge_into\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_merge_into.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/merge_into/test_merge_into.py",
    "content": "import unittest\n\n\nclass TestArray(unittest.TestCase):\n\n    def test_merge_into(self):\n        array = Array()\n        self.assertRaises(TypeError, array.merge_into, None, None, None, None)\n        self.assertRaises(ValueError, array.merge_into, [1], [2], -1, -1)\n        a = [1, 2, 3]\n        self.assertEqual(array.merge_into(a, [], len(a), 0), [1, 2, 3])\n        a = [1, 2, 3]\n        self.assertEqual(array.merge_into(a, [], len(a), 0), [1, 2, 3])\n        a = [1,  3,  5,  7,  9,  None,  None,  None]\n        b = [4,  5,  6]\n        expected = [1, 3, 4, 5, 5, 6, 7, 9]\n        self.assertEqual(array.merge_into(a, b, 5, len(b)), expected)\n        print('Success: test_merge_into')\n\n\ndef main():\n    test = TestArray()\n    test.test_merge_into()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "sorting_searching/merge_sort/__init__.py",
    "content": ""
  },
  {
    "path": "sorting_searching/merge_sort/merge_sort_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement merge sort.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is a naive solution sufficient?\\n\",\n    \"    * Yes\\n\",\n    \"* Are duplicates allowed?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input is valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* Empty input -> []\\n\",\n    \"* One element -> [element]\\n\",\n    \"* Two or more elements\\n\",\n    \"* Left and right subarrays of different lengths\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/merge_sort/merge_sort_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MergeSort(object):\\n\",\n    \"\\n\",\n    \"    def sort(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_merge_sort.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMergeSort(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_merge_sort(self):\\n\",\n    \"        merge_sort = MergeSort()\\n\",\n    \"\\n\",\n    \"        print('None input')\\n\",\n    \"        self.assertRaises(TypeError, merge_sort.sort, None)\\n\",\n    \"\\n\",\n    \"        print('Empty input')\\n\",\n    \"        self.assertEqual(merge_sort.sort([]), [])\\n\",\n    \"\\n\",\n    \"        print('One element')\\n\",\n    \"        self.assertEqual(merge_sort.sort([5]), [5])\\n\",\n    \"\\n\",\n    \"        print('Two or more elements')\\n\",\n    \"        data = [5, 1, 7, 2, 6, -3, 5, 7, -1]\\n\",\n    \"        self.assertEqual(merge_sort.sort(data), sorted(data))\\n\",\n    \"\\n\",\n    \"        print('Success: test_merge_sort')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMergeSort()\\n\",\n    \"    test.test_merge_sort()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/merge_sort/merge_sort_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/merge_sort/merge_sort_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement merge sort.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is a naive solution sufficient?\\n\",\n    \"    * Yes\\n\",\n    \"* Are duplicates allowed?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input is valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* Empty input -> []\\n\",\n    \"* One element -> [element]\\n\",\n    \"* Two or more elements\\n\",\n    \"* Left and right subarrays of different lengths\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Wikipedia's animation:\\n\",\n    \"![alt text](http://upload.wikimedia.org/wikipedia/commons/c/cc/Merge-sort-example-300px.gif)\\n\",\n    \"\\n\",\n    \"* Recursively split array into left and right halves\\n\",\n    \"* Merge split arrays\\n\",\n    \"    * Using two pointers, one for each half starting at index 0\\n\",\n    \"        * Add the smaller element to the result array\\n\",\n    \"        * Increment pointer where smaller element exists\\n\",\n    \"    * Copy remaining elements to the result array\\n\",\n    \"    * Return result array\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n log(n))\\n\",\n    \"* Space: O(n)\\n\",\n    \"\\n\",\n    \"Misc:\\n\",\n    \"\\n\",\n    \"* Not in-place\\n\",\n    \"* Most implementations are stable\\n\",\n    \"\\n\",\n    \"Merge sort can be a good choice for data sets that are too large to fit in memory, as large chunks of data can be read and written to disk.\\n\",\n    \"\\n\",\n    \"Unlike many other sorting algorithms, merge sort is not done in-place.\\n\",\n    \"\\n\",\n    \"See: [Quicksort vs merge sort](http://stackoverflow.com/questions/70402/why-is-quicksort-better-than-mergesort)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from __future__ import division\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class MergeSort(object):\\n\",\n    \"\\n\",\n    \"    def sort(self, data):\\n\",\n    \"        if data is None:\\n\",\n    \"            raise TypeError('data cannot be None')\\n\",\n    \"        return self._sort(data)\\n\",\n    \"\\n\",\n    \"    def _sort(self, data):\\n\",\n    \"        if len(data) < 2:\\n\",\n    \"            return data\\n\",\n    \"        mid = len(data) // 2\\n\",\n    \"        left = data[:mid]\\n\",\n    \"        right = data[mid:]\\n\",\n    \"        left = self._sort(left)\\n\",\n    \"        right = self._sort(right)\\n\",\n    \"        return self._merge(left, right)\\n\",\n    \"\\n\",\n    \"    def _merge(self, left, right):\\n\",\n    \"        l = 0\\n\",\n    \"        r = 0\\n\",\n    \"        result = []\\n\",\n    \"        while l < len(left) and r < len(right):\\n\",\n    \"            if left[l] < right[r]:\\n\",\n    \"                result.append(left[l])\\n\",\n    \"                l += 1\\n\",\n    \"            else:\\n\",\n    \"                result.append(right[r])\\n\",\n    \"                r += 1\\n\",\n    \"        # Copy remaining elements\\n\",\n    \"        while l < len(left):\\n\",\n    \"            result.append(left[l])\\n\",\n    \"            l += 1\\n\",\n    \"        while r < len(right):\\n\",\n    \"            result.append(right[r])\\n\",\n    \"            r += 1\\n\",\n    \"        return result\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_merge_sort.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_merge_sort.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestMergeSort(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_merge_sort(self):\\n\",\n    \"        merge_sort = MergeSort()\\n\",\n    \"\\n\",\n    \"        print('None input')\\n\",\n    \"        self.assertRaises(TypeError, merge_sort.sort, None)\\n\",\n    \"\\n\",\n    \"        print('Empty input')\\n\",\n    \"        self.assertEqual(merge_sort.sort([]), [])\\n\",\n    \"\\n\",\n    \"        print('One element')\\n\",\n    \"        self.assertEqual(merge_sort.sort([5]), [5])\\n\",\n    \"\\n\",\n    \"        print('Two or more elements')\\n\",\n    \"        data = [5, 1, 7, 2, 6, -3, 5, 7, -1]\\n\",\n    \"        self.assertEqual(merge_sort.sort(data), sorted(data))\\n\",\n    \"\\n\",\n    \"        print('Success: test_merge_sort')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestMergeSort()\\n\",\n    \"    test.test_merge_sort()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"None input\\n\",\n      \"Empty input\\n\",\n      \"One element\\n\",\n      \"Two or more elements\\n\",\n      \"Success: test_merge_sort\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_merge_sort.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/merge_sort/test_merge_sort.py",
    "content": "import unittest\n\n\nclass TestMergeSort(unittest.TestCase):\n\n    def test_merge_sort(self):\n        merge_sort = MergeSort()\n\n        print('None input')\n        self.assertRaises(TypeError, merge_sort.sort, None)\n\n        print('Empty input')\n        self.assertEqual(merge_sort.sort([]), [])\n\n        print('One element')\n        self.assertEqual(merge_sort.sort([5]), [5])\n\n        print('Two or more elements')\n        data = [5, 1, 7, 2, 6, -3, 5, 7, -1]\n        self.assertEqual(merge_sort.sort(data), sorted(data))\n\n        print('Success: test_merge_sort')\n\n\ndef main():\n    test = TestMergeSort()\n    test.test_merge_sort()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "sorting_searching/new_int/__init__.py",
    "content": ""
  },
  {
    "path": "sorting_searching/new_int/new_int_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given an array of 32 integers, find an int not in the input.  Use a minimal amount of memory.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are we working with non-negative ints?\\n\",\n    \"    * Yes\\n\",\n    \"* What is the range of the integers?\\n\",\n    \"    * Discuss the approach for 4 billion integers\\n\",\n    \"    * Implement for 32 integers\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* [] -> Exception\\n\",\n    \"* General case\\n\",\n    \"    * There is an int excluded from the input -> int\\n\",\n    \"    * There isn't an int excluded from the input -> None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/new_int/new_int_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from bitstring import BitArray  # run pip install bitstring\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Bits(object):\\n\",\n    \"\\n\",\n    \"    def new_int(self, array, max_size):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_new_int.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBits(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_new_int(self):\\n\",\n    \"        bits = Bits()\\n\",\n    \"        max_size = 32\\n\",\n    \"        self.assertRaises(TypeError, bits.new_int, None, max_size)\\n\",\n    \"        self.assertRaises(TypeError, bits.new_int, [], max_size)\\n\",\n    \"        data = [item for item in range(30)]\\n\",\n    \"        data.append(31)\\n\",\n    \"        self.assertEqual(bits.new_int(data, max_size), 30)\\n\",\n    \"        data = [item for item in range(32)]\\n\",\n    \"        self.assertEqual(bits.new_int(data, max_size), None)\\n\",\n    \"        print('Success: test_find_int_excluded_from_input')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBits()\\n\",\n    \"    test.test_new_int()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/new_int/new_int_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given an array of n integers, find an int not in the input.  Use a minimal amount of memory.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are we working with non-negative ints?\\n\",\n    \"    * Yes\\n\",\n    \"* What is the range of the integers?\\n\",\n    \"    * Discuss the approach for 4 billion integers\\n\",\n    \"    * Implement for 32 integers\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* [] -> Exception\\n\",\n    \"* General case\\n\",\n    \"    * There is an int excluded from the input -> int\\n\",\n    \"    * There isn't an int excluded from the input -> None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"The problem states to use a minimal amount of memory.  We'll use a bit vector to keep track of the inputs.\\n\",\n    \"\\n\",\n    \"Say we are given 4 billion integers, which is 2^32 integers.  The number of non-negative integers would be 2^31.  With a bit vector, we'll need 4 billion bits to map each integer to a bit.  Say we had only 1 GB of memory or 2^32 bytes.  This would leave us with 8 billion bits.\\n\",\n    \"\\n\",\n    \"To simplify this exercise, we'll work with an input of up to 32 ints that we'll map to a bit vector of 32 bits.\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"\\n\",\n    \"input = [0, 1, 2, 3, 4...28, 29, 31]\\n\",\n    \"\\n\",\n    \"bytes          [         1          ]  [          2         ] [          3          ] [          4          ]\\n\",\n    \"index       =  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31\\n\",\n    \"bit_vector  =  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  0  1\\n\",\n    \"\\n\",\n    \"result = 30\\n\",\n    \"\\n\",\n    \"* Loop through each item in the input, setting bit_vector[item] = True.\\n\",\n    \"* Loop through the bit_vector, return the first index where bit_vector[item] == False.\\n\",\n    \"\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(b), where b is the number of bits\\n\",\n    \"* Space: O(b)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from bitstring import BitArray  # Run pip install bitstring\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Bits(object):\\n\",\n    \"\\n\",\n    \"    def new_int(self, array, max_size):\\n\",\n    \"        if not array:\\n\",\n    \"            raise TypeError('array cannot be None or empty')\\n\",\n    \"        bit_vector = BitArray(max_size)\\n\",\n    \"        for item in array:\\n\",\n    \"            bit_vector[item] = True\\n\",\n    \"        for index, item in enumerate(bit_vector):\\n\",\n    \"            if not item:\\n\",\n    \"                return index\\n\",\n    \"        return None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_new_int.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_new_int.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestBits(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_new_int(self):\\n\",\n    \"        bits = Bits()\\n\",\n    \"        max_size = 32\\n\",\n    \"        self.assertRaises(TypeError, bits.new_int, None, max_size)\\n\",\n    \"        self.assertRaises(TypeError, bits.new_int, [], max_size)\\n\",\n    \"        data = [item for item in range(30)]\\n\",\n    \"        data.append(31)\\n\",\n    \"        self.assertEqual(bits.new_int(data, max_size), 30)\\n\",\n    \"        data = [item for item in range(32)]\\n\",\n    \"        self.assertEqual(bits.new_int(data, max_size), None)\\n\",\n    \"        print('Success: test_find_int_excluded_from_input')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestBits()\\n\",\n    \"    test.test_new_int()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_find_int_excluded_from_input\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_new_int.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/new_int/test_new_int.py",
    "content": "import unittest\n\n\nclass TestBits(unittest.TestCase):\n\n    def test_new_int(self):\n        bits = Bits()\n        max_size = 32\n        self.assertRaises(TypeError, bits.new_int, None, max_size)\n        self.assertRaises(TypeError, bits.new_int, [], max_size)\n        data = [item for item in range(30)]\n        data.append(31)\n        self.assertEqual(bits.new_int(data, max_size), 30)\n        data = [item for item in range(32)]\n        self.assertEqual(bits.new_int(data, max_size), None)\n        print('Success: test_find_int_excluded_from_input')\n\n\ndef main():\n    test = TestBits()\n    test.test_new_int()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "sorting_searching/quick_sort/__init__.py",
    "content": ""
  },
  {
    "path": "sorting_searching/quick_sort/quick_sort_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement quick sort.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is a naive solution sufficient (ie not in-place)?\\n\",\n    \"    * Yes\\n\",\n    \"* Are duplicates allowed?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input is valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* Empty input -> []\\n\",\n    \"* One element -> [element]\\n\",\n    \"* Two or more elements\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/quick_sort/quick_sort_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class QuickSort(object):\\n\",\n    \"\\n\",\n    \"    def sort(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_quick_sort.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestQuickSort(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_quick_sort(self):\\n\",\n    \"        quick_sort = QuickSort()\\n\",\n    \"\\n\",\n    \"        print('None input')\\n\",\n    \"        self.assertRaises(TypeError, quick_sort.sort, None)\\n\",\n    \"\\n\",\n    \"        print('Empty input')\\n\",\n    \"        self.assertEqual(quick_sort.sort([]), [])\\n\",\n    \"\\n\",\n    \"        print('One element')\\n\",\n    \"        self.assertEqual(quick_sort.sort([5]), [5])\\n\",\n    \"\\n\",\n    \"        print('Two or more elements')\\n\",\n    \"        data = [5, 1, 7, 2, 6, -3, 5, 7, -1]\\n\",\n    \"        self.assertEqual(quick_sort.sort(data), sorted(data))\\n\",\n    \"\\n\",\n    \"        print('Success: test_quick_sort\\\\n')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestQuickSort()\\n\",\n    \"    test.test_quick_sort()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/quick_sort/quick_sort_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/quick_sort/quick_sort_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement quick sort.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Pythonic-Code](#Pythonic-Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is a naive solution sufficient (ie not in-place)?\\n\",\n    \"    * Yes\\n\",\n    \"* Are duplicates allowed?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input is valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* Empty input -> []\\n\",\n    \"* One element -> [element]\\n\",\n    \"* Two or more elements\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Wikipedia's animation:\\n\",\n    \"![alt text](http://upload.wikimedia.org/wikipedia/commons/6/6a/Sorting_quicksort_anim.gif)\\n\",\n    \"\\n\",\n    \"* Set pivot to the middle element in the data\\n\",\n    \"* For each element:\\n\",\n    \"    * If current element is the pivot, continue\\n\",\n    \"    * If the element is less than the pivot, add to left array\\n\",\n    \"    * Else, add to right array\\n\",\n    \"* Recursively apply quicksort to the left array\\n\",\n    \"* Recursively apply quicksort to the right array\\n\",\n    \"* Merge the left array + pivot + right array\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n log(n)) average, best, O(n^2) worst\\n\",\n    \"* Space: O(n)\\n\",\n    \"\\n\",\n    \"Misc:\\n\",\n    \"\\n\",\n    \"* More sophisticated implementations are in-place, although they still take up recursion depth space\\n\",\n    \"* Most implementations are not stable\\n\",\n    \"\\n\",\n    \"See [Quicksort on wikipedia](https://en.wikipedia.org/wiki/Quicksort):\\n\",\n    \"\\n\",\n    \"Typically, quicksort is significantly faster in practice than other Θ(nlogn) algorithms, because its inner loop can be efficiently implemented on most architectures [presumably because it has good cache locality], and in most real-world data, it is possible to make design choices which minimize the probability of requiring quadratic time.\\n\",\n    \"\\n\",\n    \"See: [Quicksort vs merge sort](http://stackoverflow.com/questions/70402/why-is-quicksort-better-than-mergesort)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from __future__ import division\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class QuickSort(object):\\n\",\n    \"\\n\",\n    \"    def sort(self, data):\\n\",\n    \"        if data is None:\\n\",\n    \"            raise TypeError('data cannot be None')\\n\",\n    \"        return self._sort(data)\\n\",\n    \"\\n\",\n    \"    def _sort(self, data):\\n\",\n    \"        if len(data) < 2:\\n\",\n    \"            return data\\n\",\n    \"        equal = []\\n\",\n    \"        left = []\\n\",\n    \"        right = []\\n\",\n    \"        pivot_index = len(data) // 2\\n\",\n    \"        pivot_value = data[pivot_index]\\n\",\n    \"        # Build the left and right partitions\\n\",\n    \"        for item in data:\\n\",\n    \"            if item == pivot_value:\\n\",\n    \"                equal.append(item)\\n\",\n    \"            elif item < pivot_value:\\n\",\n    \"                left.append(item)\\n\",\n    \"            else:\\n\",\n    \"                right.append(item)\\n\",\n    \"        # Recursively apply quick_sort\\n\",\n    \"        left_ = self._sort(left)\\n\",\n    \"        right_ = self._sort(right)\\n\",\n    \"        return left_ + equal + right_\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_quick_sort.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_quick_sort.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestQuickSort(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_quick_sort(self):\\n\",\n    \"        quick_sort = QuickSort()\\n\",\n    \"\\n\",\n    \"        print('None input')\\n\",\n    \"        self.assertRaises(TypeError, quick_sort.sort, None)\\n\",\n    \"\\n\",\n    \"        print('Empty input')\\n\",\n    \"        self.assertEqual(quick_sort.sort([]), [])\\n\",\n    \"\\n\",\n    \"        print('One element')\\n\",\n    \"        self.assertEqual(quick_sort.sort([5]), [5])\\n\",\n    \"\\n\",\n    \"        print('Two or more elements')\\n\",\n    \"        data = [5, 1, 7, 2, 6, -3, 5, 7, -1]\\n\",\n    \"        self.assertEqual(quick_sort.sort(data), sorted(data))\\n\",\n    \"\\n\",\n    \"        print('Success: test_quick_sort\\\\n')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestQuickSort()\\n\",\n    \"    test.test_quick_sort()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"None input\\n\",\n      \"Empty input\\n\",\n      \"One element\\n\",\n      \"Two or more elements\\n\",\n      \"Success: test_quick_sort\\n\",\n      \"\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_quick_sort.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/quick_sort/test_quick_sort.py",
    "content": "import unittest\n\n\nclass TestQuickSort(unittest.TestCase):\n\n    def test_quick_sort(self):\n        quick_sort = QuickSort()\n\n        print('None input')\n        self.assertRaises(TypeError, quick_sort.sort, None)\n\n        print('Empty input')\n        self.assertEqual(quick_sort.sort([]), [])\n\n        print('One element')\n        self.assertEqual(quick_sort.sort([5]), [5])\n\n        print('Two or more elements')\n        data = [5, 1, 7, 2, 6, -3, 5, 7, -1]\n        self.assertEqual(quick_sort.sort(data), sorted(data))\n\n        print('Success: test_quick_sort\\n')\n\n\ndef main():\n    test = TestQuickSort()\n    test.test_quick_sort()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "sorting_searching/radix_sort/__init__.py",
    "content": ""
  },
  {
    "path": "sorting_searching/radix_sort/radix_sort_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement radix sort.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input a list?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Check for None in place of an array\\n\",\n    \"    * Assume array elements are ints\\n\",\n    \"* Do we know the max digits to handle?\\n\",\n    \"    * No\\n\",\n    \"* Are the digits base 10?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* [] -> []\\n\",\n    \"* [128, 256, 164, 8, 2, 148, 212, 242, 244] -> [2, 8, 128, 148, 164, 212, 242, 244, 256]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/radix_sort/radix_sort_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class RadixSort(object):\\n\",\n    \"\\n\",\n    \"    def sort(self, array, base=10):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_radix_sort.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestRadixSort(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_sort(self):\\n\",\n    \"        radix_sort = RadixSort()\\n\",\n    \"        self.assertRaises(TypeError, radix_sort.sort, None)\\n\",\n    \"        self.assertEqual(radix_sort.sort([]), [])\\n\",\n    \"        array = [128, 256, 164, 8, 2, 148, 212, 242, 244]\\n\",\n    \"        expected = [2, 8, 128, 148, 164, 212, 242, 244, 256]\\n\",\n    \"        self.assertEqual(radix_sort.sort(array), expected)\\n\",\n    \"        print('Success: test_sort')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestRadixSort()\\n\",\n    \"    test.test_sort()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/radix_sort/radix_sort_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement radix sort.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input a list?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * Check for None in place of an array\\n\",\n    \"    * Assume array elements are ints\\n\",\n    \"* Do we know the max digits to handle?\\n\",\n    \"    * No\\n\",\n    \"* Are the digits base 10?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* [] -> []\\n\",\n    \"* [128, 256, 164, 8, 2, 148, 212, 242, 244] -> [2, 8, 128, 148, 164, 212, 242, 244, 256]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Sample input: [1, 220, 122, 112]\\n\",\n    \"\\n\",\n    \"* We'll evaluate each digit starting with the ones position\\n\",\n    \"    * [**1**, 22**0**, 12**2**, 11**2**]\\n\",\n    \"        * Bucket 0: 220\\n\",\n    \"        * Bucket 1: 1\\n\",\n    \"        * Bucket 2: 122, 112\\n\",\n    \"        * Result: [220, 1, 122, 112]\\n\",\n    \"    * [2**2**0, 1, 1**2**2, 1**1**2]\\n\",\n    \"        * Bucket 0: 1\\n\",\n    \"        * Bucket 1: 112\\n\",\n    \"        * Bucket 2: 220, 122\\n\",\n    \"        * Result: [1, 112, 220, 122]\\n\",\n    \"    * [1, **1**12, **2**20, **1**22]\\n\",\n    \"        * Bucket 0: 1\\n\",\n    \"        * Bucket 1: 112, 122\\n\",\n    \"        * Bucket 2: 220\\n\",\n    \"        * Result: [1, 112, 122, 220]\\n\",\n    \"\\n\",\n    \"Bucketing example: 123\\n\",\n    \"\\n\",\n    \"* Ones\\n\",\n    \"    * 12**3** // 10^0 = 123\\n\",\n    \"    * 123 % 10 = 3\\n\",\n    \"* Tens\\n\",\n    \"    * 1**2**3 // 10^1 = 12\\n\",\n    \"    * 12 % 10 = 2\\n\",\n    \"* Hundreds\\n\",\n    \"    * **1**23 // 10^2 = 1\\n\",\n    \"    * 1 % 10 = 1\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(k*n), where n is the number of items and k is the number of digits in the largest item\\n\",\n    \"* Space: O(k+n)\\n\",\n    \"\\n\",\n    \"Misc:\\n\",\n    \"* Not in-place\\n\",\n    \"* Most implementations are stable\\n\",\n    \"\\n\",\n    \"If k (the number of digits) is less than log(n), radix sort can be faster than algorithms such as quicksort.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class RadixSort(object):\\n\",\n    \"\\n\",\n    \"    def sort(self, array, base=10):\\n\",\n    \"        if array is None:\\n\",\n    \"            raise TypeError('array cannot be None')\\n\",\n    \"        if not array:\\n\",\n    \"            return []\\n\",\n    \"        max_element = max(array)\\n\",\n    \"        max_digits = len(str(abs(max_element)))\\n\",\n    \"        curr_array = array\\n\",\n    \"        for digit in range(max_digits):\\n\",\n    \"            buckets = [[] for _ in range(base)]\\n\",\n    \"            for item in curr_array:\\n\",\n    \"                buckets[(item//(base**digit))%base].append(item)\\n\",\n    \"            curr_array = []\\n\",\n    \"            for bucket in buckets:\\n\",\n    \"                curr_array.extend(bucket)\\n\",\n    \"        return curr_array\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_radix_sort.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_radix_sort.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestRadixSort(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_sort(self):\\n\",\n    \"        radix_sort = RadixSort()\\n\",\n    \"        self.assertRaises(TypeError, radix_sort.sort, None)\\n\",\n    \"        self.assertEqual(radix_sort.sort([]), [])\\n\",\n    \"        array = [128, 256, 164, 8, 2, 148, 212, 242, 244]\\n\",\n    \"        expected = [2, 8, 128, 148, 164, 212, 242, 244, 256]\\n\",\n    \"        self.assertEqual(radix_sort.sort(array), expected)\\n\",\n    \"        print('Success: test_sort')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestRadixSort()\\n\",\n    \"    test.test_sort()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_sort\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_radix_sort.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/radix_sort/test_radix_sort.py",
    "content": "import unittest\n\n\nclass TestRadixSort(unittest.TestCase):\n\n    def test_sort(self):\n        radix_sort = RadixSort()\n        self.assertRaises(TypeError, radix_sort.sort, None)\n        self.assertEqual(radix_sort.sort([]), [])\n        array = [128, 256, 164, 8, 2, 148, 212, 242, 244]\n        expected = [2, 8, 128, 148, 164, 212, 242, 244, 256]\n        self.assertEqual(radix_sort.sort(array), expected)\n        print('Success: test_sort')\n\n\ndef main():\n    test = TestRadixSort()\n    test.test_sort()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "sorting_searching/rotated_array_search/__init__.py",
    "content": ""
  },
  {
    "path": "sorting_searching/rotated_array_search/rotated_array_search_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find an element in a sorted array that has been rotated a number of times.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input an array of ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we know how many times the array was rotated?\\n\",\n    \"    * No\\n\",\n    \"* Was the array originally sorted in increasing or decreasing order?\\n\",\n    \"    * Increasing\\n\",\n    \"* For the output, do we return the index?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* [] -> None\\n\",\n    \"* Not found -> None\\n\",\n    \"* General case with duplicates\\n\",\n    \"* General case without duplicates\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/rotated_array_search/rotated_array_search_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Array(object):\\n\",\n    \"\\n\",\n    \"    def search_sorted_array(self, array, val):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_search_sorted_array.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestArray(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_search_sorted_array(self):\\n\",\n    \"        array = Array()\\n\",\n    \"        self.assertRaises(TypeError, array.search_sorted_array, None)\\n\",\n    \"        self.assertEqual(array.search_sorted_array([3, 1, 2], 0), None)\\n\",\n    \"        self.assertEqual(array.search_sorted_array([3, 1, 2], 0), None)\\n\",\n    \"        data = [10, 12, 14,  1,  3,  5,  6,  7,  8,  9]\\n\",\n    \"        self.assertEqual(array.search_sorted_array(data, val=1), 3)\\n\",\n    \"        data = [ 1,  1,  2,  1,  1,  1,  1,  1,  1,  1]\\n\",\n    \"        self.assertEqual(array.search_sorted_array(data, val=2), 2)\\n\",\n    \"        print('Success: test_search_sorted_array')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestArray()\\n\",\n    \"    test.test_search_sorted_array()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/rotated_array_search/rotated_array_search_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Find an element in a sorted array that has been rotated a number of times.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is the input an array of ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Can the input have duplicates?\\n\",\n    \"    * Yes\\n\",\n    \"* Do we know how many times the array was rotated?\\n\",\n    \"    * No\\n\",\n    \"* Was the array originally sorted in increasing or decreasing order?\\n\",\n    \"    * Increasing\\n\",\n    \"* For the output, do we return the index?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* [] -> None\\n\",\n    \"* Not found -> None\\n\",\n    \"* General case with duplicates\\n\",\n    \"* General case without duplicates\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### General case without dupes\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"\\n\",\n    \"index                   0   1   2   3   4   5   6   7   8   9\\n\",\n    \"input                 [ 1,  3,  5,  6,  7,  8,  9, 10, 12, 14]\\n\",\n    \"input rotated 1x      [10, 12, 14,  1,  3,  5,  6,  7,  8,  9]\\n\",\n    \"input rotated 2x      [ 5,  6,  7,  8,  9, 10, 12, 14,  1,  3]\\n\",\n    \"input rotated 3x      [10, 12, 14,  1,  3,  5,  6,  7,  8,  9]\\n\",\n    \"\\n\",\n    \"find 1\\n\",\n    \"len = 10\\n\",\n    \"mid = 10 // 2 = 5\\n\",\n    \"                        s                   m               e\\n\",\n    \"index                   0   1   2   3   4   5   6   7   8   9\\n\",\n    \"input                 [10, 12, 14,  1,  3,  5,  6,  7,  8,  9]\\n\",\n    \"\\n\",\n    \"input[start] > input[mid]: Left half is rotated\\n\",\n    \"input[end] >= input[mid]: Right half is sorted\\n\",\n    \"1 is not within input[mid+1] to input[end] on the right side, go left\\n\",\n    \"\\n\",\n    \"                        s       m       e\\n\",\n    \"index                   0   1   2   3   4   5   6   7   8   9\\n\",\n    \"input                 [10, 12, 14,  1,  3,  5,  6,  7,  8,  9]\\n\",\n    \"\\n\",\n    \"input[start] <= input[mid]: Right half is rotated\\n\",\n    \"input[end] >= input[mid]: Left half is sorted\\n\",\n    \"1 is not within input[left] to input[mid-1] on the left side, go right\\n\",\n    \"\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"### General case with dupes\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"\\n\",\n    \"                        s                   m               e\\n\",\n    \"index                   0   1   2   3   4   5   6   7   8   9\\n\",\n    \"input                 [ 1,  1,  1,  1,  1,  1,  1,  1,  1,  2]\\n\",\n    \"\\n\",\n    \"input[start] == input[mid], input[mid] != input[end], go right\\n\",\n    \"\\n\",\n    \"input rotated 1x      [ 1,  1,  2,  1,  1,  1,  1,  1,  1,  1]\\n\",\n    \"\\n\",\n    \"input[start] == input[mid] == input[end], search both sides\\n\",\n    \"\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(log n) if there are no duplicates, else O(n)\\n\",\n    \"* Space: O(m), where m is the recursion depth\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Array(object):\\n\",\n    \"\\n\",\n    \"    def search_sorted_array(self, array, val):\\n\",\n    \"        if array is None or val is None:\\n\",\n    \"            raise TypeError('array or val cannot be None')\\n\",\n    \"        if not array:\\n\",\n    \"            return None\\n\",\n    \"        return self._search_sorted_array(array, val, start=0, end=len(array) - 1)\\n\",\n    \"\\n\",\n    \"    def _search_sorted_array(self, array, val, start, end):\\n\",\n    \"        if end < start:\\n\",\n    \"            return None\\n\",\n    \"        mid = (start + end) // 2\\n\",\n    \"        if array[mid] == val:\\n\",\n    \"            return mid\\n\",\n    \"        # Left side is sorted\\n\",\n    \"        if array[start] < array[mid]:\\n\",\n    \"            if array[start] <= val < array[mid]:\\n\",\n    \"                return self._search_sorted_array(array, val, start, mid - 1)\\n\",\n    \"            else:\\n\",\n    \"                return self._search_sorted_array(array, val, mid + 1, end)\\n\",\n    \"        # Right side is sorted\\n\",\n    \"        elif array[start] > array[mid]:\\n\",\n    \"            if array[mid] < val <= array[end]:\\n\",\n    \"                return self._search_sorted_array(array, val, mid + 1, end)\\n\",\n    \"            else:\\n\",\n    \"                return self._search_sorted_array(array, val, start, mid - 1)\\n\",\n    \"        # Duplicates\\n\",\n    \"        else:\\n\",\n    \"            if array[mid] != array[end]:\\n\",\n    \"                return self._search_sorted_array(array, val, mid + 1, end)\\n\",\n    \"            else:\\n\",\n    \"                result = self._search_sorted_array(array, val, start, mid - 1)\\n\",\n    \"                if result != None:\\n\",\n    \"                    return result\\n\",\n    \"                else:\\n\",\n    \"                    return self._search_sorted_array(array, val, mid + 1, end)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_search_sorted_array.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_search_sorted_array.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestArray(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_search_sorted_array(self):\\n\",\n    \"        array = Array()\\n\",\n    \"        self.assertRaises(TypeError, array.search_sorted_array, None)\\n\",\n    \"        self.assertEqual(array.search_sorted_array([3, 1, 2], 0), None)\\n\",\n    \"        self.assertEqual(array.search_sorted_array([3, 1, 2], 0), None)\\n\",\n    \"        data = [10, 12, 14,  1,  3,  5,  6,  7,  8,  9]\\n\",\n    \"        self.assertEqual(array.search_sorted_array(data, val=1), 3)\\n\",\n    \"        data = [ 1,  1,  2,  1,  1,  1,  1,  1,  1,  1]\\n\",\n    \"        self.assertEqual(array.search_sorted_array(data, val=2), 2)\\n\",\n    \"        print('Success: test_search_sorted_array')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestArray()\\n\",\n    \"    test.test_search_sorted_array()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_search_sorted_array\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_search_sorted_array.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/rotated_array_search/test_search_sorted_array.py",
    "content": "import unittest\n\n\nclass TestArray(unittest.TestCase):\n\n    def test_search_sorted_array(self):\n        array = Array()\n        self.assertRaises(TypeError, array.search_sorted_array, None)\n        self.assertEqual(array.search_sorted_array([3, 1, 2], 0), None)\n        self.assertEqual(array.search_sorted_array([3, 1, 2], 0), None)\n        data = [10, 12, 14,  1,  3,  5,  6,  7,  8,  9]\n        self.assertEqual(array.search_sorted_array(data, val=1), 3)\n        data = [ 1,  1,  2,  1,  1,  1,  1,  1,  1,  1]\n        self.assertEqual(array.search_sorted_array(data, val=2), 2)\n        print('Success: test_search_sorted_array')\n\n\ndef main():\n    test = TestArray()\n    test.test_search_sorted_array()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "sorting_searching/search_sorted_matrix/__init__.py",
    "content": ""
  },
  {
    "path": "sorting_searching/search_sorted_matrix/search_sorted_matrix_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Search a sorted matrix for an item.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are items in each row sorted?\\n\",\n    \"    * Yes\\n\",\n    \"* Are items in each column sorted?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the sorting in ascending or descending order?\\n\",\n    \"    * Ascending\\n\",\n    \"* Is the matrix a rectangle?  Not jagged?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the matrix square?\\n\",\n    \"    * Not necessarily\\n\",\n    \"* Is the output a tuple (row, col)?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the item you are searching for always in the matrix?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* General case\\n\",\n    \"    * Item found -> (row, col)\\n\",\n    \"    * Item not found -> None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.jupyter.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/search_sorted_matrix/search_sorted_matrix_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class SortedMatrix(object):\\n\",\n    \"\\n\",\n    \"    def find_val(self, matrix, val):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_search_sorted_matrix.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSortedMatrix(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_find_val(self):\\n\",\n    \"        matrix = [[20, 40, 63, 80],\\n\",\n    \"                  [30, 50, 80, 90],\\n\",\n    \"                  [40, 60, 110, 110],\\n\",\n    \"                  [50, 65, 105, 150]]\\n\",\n    \"        sorted_matrix = SortedMatrix()\\n\",\n    \"        self.assertRaises(TypeError, sorted_matrix.find_val, None, None)\\n\",\n    \"        self.assertEqual(sorted_matrix.find_val(matrix, 1000), None)\\n\",\n    \"        self.assertEqual(sorted_matrix.find_val(matrix, 60), (2, 1))\\n\",\n    \"        print('Success: test_find_val')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSortedMatrix()\\n\",\n    \"    test.test_find_val()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/search_sorted_matrix/search_sorted_matrix_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"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).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Search a sorted matrix for an item.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are items in each row sorted?\\n\",\n    \"    * Yes\\n\",\n    \"* Are items in each column sorted?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the sorting in ascending or descending order?\\n\",\n    \"    * Ascending\\n\",\n    \"* Is the matrix a rectangle?  Not jagged?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the matrix square?\\n\",\n    \"    * Not necessarily\\n\",\n    \"* Is the output a tuple (row, col)?\\n\",\n    \"    * Yes\\n\",\n    \"* Is the item you are searching for always in the matrix?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume the inputs are valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* General case\\n\",\n    \"    * Item found -> (row, col)\\n\",\n    \"    * Item not found -> None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"<pre>\\n\",\n    \"\\n\",\n    \"Find 60 (val = 60)\\n\",\n    \"\\n\",\n    \" 20  40  63   80\\n\",\n    \" 30  50  80   90\\n\",\n    \" 40  60  100 110\\n\",\n    \" 50  65  105 150\\n\",\n    \"\\n\",\n    \"* If the start of a col > val, look left\\n\",\n    \"* If the end of a col < val, look right\\n\",\n    \"* If the start of row > val, look up\\n\",\n    \"* If the end of a row < val, look down\\n\",\n    \"\\n\",\n    \"If we start at the upper right corner, we just need to use these cases:\\n\",\n    \"\\n\",\n    \"* If the start of a col > val, look left\\n\",\n    \"* If the end of a row < val, look down\\n\",\n    \"\\n\",\n    \"</pre>\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n + m), where n and m are the matrix dimensions\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class SortedMatrix(object):\\n\",\n    \"\\n\",\n    \"    def find_val(self, matrix, val):\\n\",\n    \"        if matrix is None or val is None:\\n\",\n    \"            raise TypeError('matrix and val cannot be None')\\n\",\n    \"        row = 0\\n\",\n    \"        col = len(matrix[0]) - 1\\n\",\n    \"        while row < len(matrix) and col >= 0:\\n\",\n    \"            if matrix[row][col] == val:\\n\",\n    \"                return (row, col)\\n\",\n    \"            elif matrix[row][col] > val:\\n\",\n    \"                col -= 1\\n\",\n    \"            else:\\n\",\n    \"                row += 1\\n\",\n    \"        return None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_search_sorted_matrix.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_search_sorted_matrix.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSortedMatrix(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_find_val(self):\\n\",\n    \"        matrix = [[20, 40, 63, 80],\\n\",\n    \"                  [30, 50, 80, 90],\\n\",\n    \"                  [40, 60, 110, 110],\\n\",\n    \"                  [50, 65, 105, 150]]\\n\",\n    \"        sorted_matrix = SortedMatrix()\\n\",\n    \"        self.assertRaises(TypeError, sorted_matrix.find_val, None, None)\\n\",\n    \"        self.assertEqual(sorted_matrix.find_val(matrix, 1000), None)\\n\",\n    \"        self.assertEqual(sorted_matrix.find_val(matrix, 60), (2, 1))\\n\",\n    \"        print('Success: test_find_val')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSortedMatrix()\\n\",\n    \"    test.test_find_val()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_find_val\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_search_sorted_matrix.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/search_sorted_matrix/test_search_sorted_matrix.py",
    "content": "import unittest\n\n\nclass TestSortedMatrix(unittest.TestCase):\n\n    def test_find_val(self):\n        matrix = [[20, 40, 63, 80],\n                  [30, 50, 80, 90],\n                  [40, 60, 110, 110],\n                  [50, 65, 105, 150]]\n        sorted_matrix = SortedMatrix()\n        self.assertRaises(TypeError, sorted_matrix.find_val, None, None)\n        self.assertEqual(sorted_matrix.find_val(matrix, 1000), None)\n        self.assertEqual(sorted_matrix.find_val(matrix, 60), (2, 1))\n        print('Success: test_find_val')\n\n\ndef main():\n    test = TestSortedMatrix()\n    test.test_find_val()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "sorting_searching/selection_sort/__init__.py",
    "content": ""
  },
  {
    "path": "sorting_searching/selection_sort/selection_sort_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement selection sort.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is a naive solution sufficient (ie not stable, not based on a heap)?\\n\",\n    \"    * Yes\\n\",\n    \"* Are duplicates allowed?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input is valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* Empty input -> []\\n\",\n    \"* One element -> [element]\\n\",\n    \"* Two or more elements\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/selection_sort/selection_sort_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class SelectionSort(object):\\n\",\n    \"\\n\",\n    \"    def sort(self, data):\\n\",\n    \"        # TODO: Implement me (recursive)\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_selection_sort.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSelectionSort(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_selection_sort(self, func):\\n\",\n    \"        print('None input')\\n\",\n    \"        self.assertRaises(TypeError, func, None)\\n\",\n    \"\\n\",\n    \"        print('Empty input')\\n\",\n    \"        self.assertEqual(func([]), [])\\n\",\n    \"\\n\",\n    \"        print('One element')\\n\",\n    \"        self.assertEqual(func([5]), [5])\\n\",\n    \"\\n\",\n    \"        print('Two or more elements')\\n\",\n    \"        data = [5, 1, 7, 2, 6, -3, 5, 7, -10]\\n\",\n    \"        self.assertEqual(func(data), sorted(data))\\n\",\n    \"\\n\",\n    \"        print('Success: test_selection_sort\\\\n')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSelectionSort()\\n\",\n    \"    selection_sort = SelectionSort()\\n\",\n    \"    test.test_selection_sort(selection_sort.sort)\\n\",\n    \"    try:\\n\",\n    \"        test.test_selection_sort(selection_sort.sort_recursive)\\n\",\n    \"        test.test_selection_sort(selection_sort.sor_iterative_alt)\\n\",\n    \"    except NameError:\\n\",\n    \"        # Alternate solutions are only defined\\n\",\n    \"        # in the solutions file\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/sorting_searching/selection_sort/selection_sort_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/selection_sort/selection_sort_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement selection sort.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Is a naive solution sufficient (ie not stable, not based on a heap)?\\n\",\n    \"    * Yes\\n\",\n    \"* Are duplicates allowed?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input is valid?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* None -> Exception\\n\",\n    \"* [] -> []\\n\",\n    \"* One element -> [element]\\n\",\n    \"* Two or more elements\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Wikipedia's animation:\\n\",\n    \"![alt text](http://upload.wikimedia.org/wikipedia/commons/9/94/Selection-Sort-Animation.gif)\\n\",\n    \"\\n\",\n    \"We can do this recursively or iteratively.  Iteratively will be more efficient as it doesn't require the extra space overhead with the recursive calls.\\n\",\n    \"\\n\",\n    \"* For each element\\n\",\n    \"    * Check every element to the right to find the min\\n\",\n    \"    * If min < current element, swap\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n^2) average, worst, best\\n\",\n    \"* Space: O(1) iterative, O(m) recursive where m is the recursion depth (unless tail-call elimination is available, then O(1))\\n\",\n    \"    * Note: Tail call elimination is not inherently available in Python, see the following [StackOverflow post](http://stackoverflow.com/a/13592002).\\n\",\n    \"\\n\",\n    \"Misc: \\n\",\n    \"\\n\",\n    \"* In-place\\n\",\n    \"* Most implementations are not stable, due to swapping of values\\n\",\n    \"\\n\",\n    \"Selection sort might be a good option if moving elements is more expensive than comparing them, as it requires at most n-1 swaps.\\n\",\n    \"\\n\",\n    \"The finding of a minimum element can be done with a min heap, which would change the worst-case run time to O(n log(n)) and increase the space to O(n).  This is called a heap sort.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class SelectionSort(object):\\n\",\n    \"\\n\",\n    \"    def sort(self, data):\\n\",\n    \"        if data is None:\\n\",\n    \"            raise TypeError('data cannot be None')\\n\",\n    \"        if len(data) < 2:\\n\",\n    \"            return data\\n\",\n    \"        for i in range(len(data) - 1):\\n\",\n    \"            min_index = i\\n\",\n    \"            for j in range(i + 1, len(data)):\\n\",\n    \"                if data[j] < data[min_index]:\\n\",\n    \"                    min_index = j\\n\",\n    \"            if data[min_index] < data[i]:\\n\",\n    \"                data[i], data[min_index] = data[min_index], data[i]\\n\",\n    \"        return data\\n\",\n    \"\\n\",\n    \"    def sort_iterative_alt(self, data):\\n\",\n    \"        if data is None:\\n\",\n    \"            raise TypeError('data cannot be None')\\n\",\n    \"        if len(data) < 2:\\n\",\n    \"            return data\\n\",\n    \"        for i in range(len(data) - 1):\\n\",\n    \"            self._swap(data, i, self._find_min_index(data, i))\\n\",\n    \"        return data\\n\",\n    \"\\n\",\n    \"    def sort_recursive(self, data):\\n\",\n    \"        if data is None:\\n\",\n    \"            raise TypeError('data cannot be None')\\n\",\n    \"        if len(data) < 2:\\n\",\n    \"            return data\\n\",\n    \"        return self._sort_recursive(data, start=0)\\n\",\n    \"\\n\",\n    \"    def _sort_recursive(self, data, start):\\n\",\n    \"        if data is None:\\n\",\n    \"            return\\n\",\n    \"        if start < len(data) - 1:\\n\",\n    \"            swap(data, start, self._find_min_index(data, start))\\n\",\n    \"            self._sort_recursive(data, start + 1)\\n\",\n    \"        return data\\n\",\n    \"\\n\",\n    \"    def _find_min_index(self, data, start):\\n\",\n    \"        min_index = start\\n\",\n    \"        for i in range(start + 1, len(data)):\\n\",\n    \"            if data[i] < data[min_index]:\\n\",\n    \"                min_index = i\\n\",\n    \"        return min_index\\n\",\n    \"\\n\",\n    \"    def _swap(self, data, i, j):\\n\",\n    \"        if i != j:\\n\",\n    \"            data[i], data[j] = data[j], data[i]\\n\",\n    \"        return data\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_selection_sort.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_selection_sort.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSelectionSort(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_selection_sort(self, func):\\n\",\n    \"        print('None input')\\n\",\n    \"        self.assertRaises(TypeError, func, None)\\n\",\n    \"\\n\",\n    \"        print('Empty input')\\n\",\n    \"        self.assertEqual(func([]), [])\\n\",\n    \"\\n\",\n    \"        print('One element')\\n\",\n    \"        self.assertEqual(func([5]), [5])\\n\",\n    \"\\n\",\n    \"        print('Two or more elements')\\n\",\n    \"        data = [5, 1, 7, 2, 6, -3, 5, 7, -10]\\n\",\n    \"        self.assertEqual(func(data), sorted(data))\\n\",\n    \"\\n\",\n    \"        print('Success: test_selection_sort\\\\n')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSelectionSort()\\n\",\n    \"    selection_sort = SelectionSort()\\n\",\n    \"    test.test_selection_sort(selection_sort.sort)\\n\",\n    \"    try:\\n\",\n    \"        test.test_selection_sort(selection_sort.sort_recursive)\\n\",\n    \"        test.test_selection_sort(selection_sort.sor_iterative_alt)\\n\",\n    \"    except NameError:\\n\",\n    \"        # Alternate solutions are only defined\\n\",\n    \"        # in the solutions file\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"None input\\n\",\n      \"Empty input\\n\",\n      \"One element\\n\",\n      \"Two or more elements\\n\",\n      \"Success: test_selection_sort\\n\",\n      \"\\n\",\n      \"None input\\n\",\n      \"Empty input\\n\",\n      \"One element\\n\",\n      \"Two or more elements\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_selection_sort.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "sorting_searching/selection_sort/test_selection_sort.py",
    "content": "import unittest\n\n\nclass TestSelectionSort(unittest.TestCase):\n\n    def test_selection_sort(self, func):\n        print('None input')\n        self.assertRaises(TypeError, func, None)\n\n        print('Empty input')\n        self.assertEqual(func([]), [])\n\n        print('One element')\n        self.assertEqual(func([5]), [5])\n\n        print('Two or more elements')\n        data = [5, 1, 7, 2, 6, -3, 5, 7, -10]\n        self.assertEqual(func(data), sorted(data))\n\n        print('Success: test_selection_sort\\n')\n\n\ndef main():\n    test = TestSelectionSort()\n    selection_sort = SelectionSort()\n    test.test_selection_sort(selection_sort.sort)\n    try:\n        test.test_selection_sort(selection_sort.sort_recursive)\n        test.test_selection_sort(selection_sort.sor_iterative_alt)\n    except NameError:\n        # Alternate solutions are only defined\n        # in the solutions file\n        pass\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "stacks_queues/__init__.py",
    "content": ""
  },
  {
    "path": "stacks_queues/n_stacks/__init__.py",
    "content": ""
  },
  {
    "path": "stacks_queues/n_stacks/n_stacks_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement n stacks using a single array.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are the stacks and array a fixed size?\\n\",\n    \"    * Yes\\n\",\n    \"* Are the stacks equally sized?\\n\",\n    \"    * Yes\\n\",\n    \"* Does pushing to a full stack result in an exception?\\n\",\n    \"    * Yes\\n\",\n    \"* Does popping from an empty stack result in an exception?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the user passed in stack index is valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Test the following on the three stacks:\\n\",\n    \"    * Push to full stack -> Exception\\n\",\n    \"    * Push to non-full stack\\n\",\n    \"    * Pop on empty stack -> Exception\\n\",\n    \"    * Pop on non-empty stack\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/n_stacks/n_stacks_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Stacks(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, num_stacks, stack_size):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def abs_index(self, stack_index):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def push(self, stack_index, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def pop(self, stack_index):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_n_stacks.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestStacks(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_pop_on_empty(self, num_stacks, stack_size):\\n\",\n    \"        print('Test: Pop on empty stack')\\n\",\n    \"        stacks = Stacks(num_stacks, stack_size)\\n\",\n    \"        stacks.pop(0)\\n\",\n    \"\\n\",\n    \"    def test_push_on_full(self, num_stacks, stack_size):\\n\",\n    \"        print('Test: Push to full stack')\\n\",\n    \"        stacks = Stacks(num_stacks, stack_size)\\n\",\n    \"        for i in range(0, stack_size):\\n\",\n    \"            stacks.push(2, i)\\n\",\n    \"        stacks.push(2, stack_size)\\n\",\n    \"\\n\",\n    \"    def test_stacks(self, num_stacks, stack_size):\\n\",\n    \"        print('Test: Push to non-full stack')\\n\",\n    \"        stacks = Stacks(num_stacks, stack_size)\\n\",\n    \"        stacks.push(0, 1)\\n\",\n    \"        stacks.push(0, 2)\\n\",\n    \"        stacks.push(1, 3)\\n\",\n    \"        stacks.push(2, 4)\\n\",\n    \"\\n\",\n    \"        print('Test: Pop on non-empty stack')\\n\",\n    \"        self.assertEqual(stacks.pop(0), 2)\\n\",\n    \"        self.assertEqual(stacks.pop(0), 1)\\n\",\n    \"        self.assertEqual(stacks.pop(1), 3)\\n\",\n    \"        self.assertEqual(stacks.pop(2), 4)\\n\",\n    \"\\n\",\n    \"        print('Success: test_stacks\\\\n')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    num_stacks = 3\\n\",\n    \"    stack_size = 100\\n\",\n    \"    test = TestStacks()\\n\",\n    \"    test.assertRaises(Exception, test.test_pop_on_empty, num_stacks,\\n\",\n    \"                      stack_size)\\n\",\n    \"    test.assertRaises(Exception, test.test_push_on_full, num_stacks,\\n\",\n    \"                      stack_size)\\n\",\n    \"    test.test_stacks(num_stacks, stack_size)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/n_stacks/n_stacks_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "stacks_queues/n_stacks/n_stacks_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement n stacks using a single array.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Are the stacks and array a fixed size?\\n\",\n    \"    * Yes\\n\",\n    \"* Are the stacks equally sized?\\n\",\n    \"    * Yes\\n\",\n    \"* Does pushing to a full stack result in an exception?\\n\",\n    \"    * Yes\\n\",\n    \"* Does popping from an empty stack result in an exception?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the user passed in stack index is valid?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Test the following on the three stacks:\\n\",\n    \"    * Push to full stack -> Exception\\n\",\n    \"    * Push to non-full stack\\n\",\n    \"    * Pop on empty stack -> Exception\\n\",\n    \"    * Pop on non-empty stack\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### Absolute Index\\n\",\n    \"\\n\",\n    \"* return stack size * stack index + stack pointer\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Push\\n\",\n    \"\\n\",\n    \"* If stack is full, throw exception\\n\",\n    \"* Else\\n\",\n    \"    * Increment stack pointer\\n\",\n    \"    * Get the absolute array index\\n\",\n    \"    * Insert the value to this index\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Pop\\n\",\n    \"\\n\",\n    \"* If stack is empty, throw exception\\n\",\n    \"* Else\\n\",\n    \"    * Store the value contained in the absolute array index\\n\",\n    \"    * Set the value in the absolute array index to None\\n\",\n    \"    * Decrement stack pointer\\n\",\n    \"    * return value\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Stacks(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, num_stacks, stack_size):\\n\",\n    \"        self.num_stacks = num_stacks\\n\",\n    \"        self.stack_size = stack_size\\n\",\n    \"        self.stack_pointers = [-1] * self.num_stacks\\n\",\n    \"        self.stack_array = [None] * self.num_stacks * self.stack_size\\n\",\n    \"\\n\",\n    \"    def abs_index(self, stack_index):\\n\",\n    \"        return stack_index * self.stack_size + self.stack_pointers[stack_index]\\n\",\n    \"\\n\",\n    \"    def push(self, stack_index, data):\\n\",\n    \"        if self.stack_pointers[stack_index] == self.stack_size - 1:\\n\",\n    \"            raise Exception('Stack is full')\\n\",\n    \"        self.stack_pointers[stack_index] += 1\\n\",\n    \"        array_index = self.abs_index(stack_index)\\n\",\n    \"        self.stack_array[array_index] = data\\n\",\n    \"\\n\",\n    \"    def pop(self, stack_index):\\n\",\n    \"        if self.stack_pointers[stack_index] == -1:\\n\",\n    \"            raise Exception('Stack is empty')\\n\",\n    \"        array_index = self.abs_index(stack_index)\\n\",\n    \"        data = self.stack_array[array_index]\\n\",\n    \"        self.stack_array[array_index] = None\\n\",\n    \"        self.stack_pointers[stack_index] -= 1\\n\",\n    \"        return data\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_n_stacks.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_n_stacks.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestStacks(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_pop_on_empty(self, num_stacks, stack_size):\\n\",\n    \"        print('Test: Pop on empty stack')\\n\",\n    \"        stacks = Stacks(num_stacks, stack_size)\\n\",\n    \"        stacks.pop(0)\\n\",\n    \"\\n\",\n    \"    def test_push_on_full(self, num_stacks, stack_size):\\n\",\n    \"        print('Test: Push to full stack')\\n\",\n    \"        stacks = Stacks(num_stacks, stack_size)\\n\",\n    \"        for i in range(0, stack_size):\\n\",\n    \"            stacks.push(2, i)\\n\",\n    \"        stacks.push(2, stack_size)\\n\",\n    \"\\n\",\n    \"    def test_stacks(self, num_stacks, stack_size):\\n\",\n    \"        print('Test: Push to non-full stack')\\n\",\n    \"        stacks = Stacks(num_stacks, stack_size)\\n\",\n    \"        stacks.push(0, 1)\\n\",\n    \"        stacks.push(0, 2)\\n\",\n    \"        stacks.push(1, 3)\\n\",\n    \"        stacks.push(2, 4)\\n\",\n    \"\\n\",\n    \"        print('Test: Pop on non-empty stack')\\n\",\n    \"        self.assertEqual(stacks.pop(0), 2)\\n\",\n    \"        self.assertEqual(stacks.pop(0), 1)\\n\",\n    \"        self.assertEqual(stacks.pop(1), 3)\\n\",\n    \"        self.assertEqual(stacks.pop(2), 4)\\n\",\n    \"\\n\",\n    \"        print('Success: test_stacks\\\\n')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    num_stacks = 3\\n\",\n    \"    stack_size = 100\\n\",\n    \"    test = TestStacks()\\n\",\n    \"    test.assertRaises(Exception, test.test_pop_on_empty, num_stacks,\\n\",\n    \"                      stack_size)\\n\",\n    \"    test.assertRaises(Exception, test.test_push_on_full, num_stacks,\\n\",\n    \"                      stack_size)\\n\",\n    \"    test.test_stacks(num_stacks, stack_size)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Pop on empty stack\\n\",\n      \"Test: Push to full stack\\n\",\n      \"Test: Push to non-full stack\\n\",\n      \"Test: Pop on non-empty stack\\n\",\n      \"Success: test_stacks\\n\",\n      \"\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"run -i test_n_stacks.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": []\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "stacks_queues/n_stacks/test_n_stacks.py",
    "content": "import unittest\n\n\nclass TestStacks(unittest.TestCase):\n\n    def test_pop_on_empty(self, num_stacks, stack_size):\n        print('Test: Pop on empty stack')\n        stacks = Stacks(num_stacks, stack_size)\n        stacks.pop(0)\n\n    def test_push_on_full(self, num_stacks, stack_size):\n        print('Test: Push to full stack')\n        stacks = Stacks(num_stacks, stack_size)\n        for i in range(0, stack_size):\n            stacks.push(2, i)\n        stacks.push(2, stack_size)\n\n    def test_stacks(self, num_stacks, stack_size):\n        print('Test: Push to non-full stack')\n        stacks = Stacks(num_stacks, stack_size)\n        stacks.push(0, 1)\n        stacks.push(0, 2)\n        stacks.push(1, 3)\n        stacks.push(2, 4)\n\n        print('Test: Pop on non-empty stack')\n        self.assertEqual(stacks.pop(0), 2)\n        self.assertEqual(stacks.pop(0), 1)\n        self.assertEqual(stacks.pop(1), 3)\n        self.assertEqual(stacks.pop(2), 4)\n\n        print('Success: test_stacks\\n')\n\n\ndef main():\n    num_stacks = 3\n    stack_size = 100\n    test = TestStacks()\n    test.assertRaises(Exception, test.test_pop_on_empty, num_stacks,\n                      stack_size)\n    test.assertRaises(Exception, test.test_push_on_full, num_stacks,\n                      stack_size)\n    test.test_stacks(num_stacks, stack_size)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "stacks_queues/queue_from_stacks/__init__.py",
    "content": ""
  },
  {
    "path": "stacks_queues/queue_from_stacks/queue_from_stacks_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a queue using two stacks.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Do we expect the methods to be enqueue and dequeue?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a stack class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we push a None value to the Stack?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Enqueue and dequeue on empty stack\\n\",\n    \"* Enqueue and dequeue on non-empty stack\\n\",\n    \"* Multiple enqueue in a row\\n\",\n    \"* Multiple dequeue in a row\\n\",\n    \"* Enqueue after a dequeue\\n\",\n    \"* Dequeue after an enqueue\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/queue_from_stacks/queue_from_stacks_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../stack/stack.py\\n\",\n    \"%load ../stack/stack.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class QueueFromStacks(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def shift_stacks(self, source, destination):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def enqueue(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def dequeue(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_queue_from_stacks.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestQueueFromStacks(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_queue_from_stacks(self):\\n\",\n    \"        print('Test: Dequeue on empty stack')\\n\",\n    \"        queue = QueueFromStacks()\\n\",\n    \"        self.assertEqual(queue.dequeue(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: Enqueue on empty stack')\\n\",\n    \"        print('Test: Enqueue on non-empty stack')\\n\",\n    \"        print('Test: Multiple enqueue in a row')\\n\",\n    \"        num_items = 3\\n\",\n    \"        for i in range(0, num_items):\\n\",\n    \"            queue.enqueue(i)\\n\",\n    \"\\n\",\n    \"        print('Test: Dequeue on non-empty stack')\\n\",\n    \"        print('Test: Dequeue after an enqueue')\\n\",\n    \"        self.assertEqual(queue.dequeue(), 0)\\n\",\n    \"\\n\",\n    \"        print('Test: Multiple dequeue in a row')\\n\",\n    \"        self.assertEqual(queue.dequeue(), 1)\\n\",\n    \"        self.assertEqual(queue.dequeue(), 2)\\n\",\n    \"\\n\",\n    \"        print('Test: Enqueue after a dequeue')\\n\",\n    \"        queue.enqueue(5)\\n\",\n    \"        self.assertEqual(queue.dequeue(), 5)\\n\",\n    \"\\n\",\n    \"        print('Success: test_queue_from_stacks')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestQueueFromStacks()\\n\",\n    \"    test.test_queue_from_stacks()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/queue_from_stacks/queue_from_stacks_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "stacks_queues/queue_from_stacks/queue_from_stacks_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a queue using two stacks.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Do we expect the methods to be enqueue and dequeue?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a stack class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we push a None value to the Stack?\\n\",\n    \"    * No\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Enqueue and dequeue on empty stack\\n\",\n    \"* Enqueue and dequeue on non-empty stack\\n\",\n    \"* Multiple enqueue in a row\\n\",\n    \"* Multiple dequeue in a row\\n\",\n    \"* Enqueue after a dequeue\\n\",\n    \"* Dequeue after an enqueue\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use two stacks (left and right) to implement the queue.  The left stack will be used for enqueue and the right stack will be used for dequeue.\\n\",\n    \"\\n\",\n    \"To prevent multiple dequeue calls from needlessly shifting elements around between the stacks, we'll shift elements in a lazy manner.\\n\",\n    \"\\n\",\n    \"### Enqueue\\n\",\n    \"\\n\",\n    \"* If right stack is not empty\\n\",\n    \"    * Shift the elements of the right stack to the left stack\\n\",\n    \"* Push the data to the left stack\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\\n\",\n    \"\\n\",\n    \"### Dequeue\\n\",\n    \"\\n\",\n    \"* If the left stack is not empty\\n\",\n    \"    * Shift the elements of the left stack to the right stack\\n\",\n    \"* Pop from the right stack and return the data\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\\n\",\n    \"\\n\",\n    \"### Shift Stacks\\n\",\n    \"\\n\",\n    \"* While the source stack has elements:\\n\",\n    \"    * Pop from the source stack and push the data to the destination stack\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../stack/stack.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class QueueFromStacks(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self):\\n\",\n    \"        self.left_stack = Stack()\\n\",\n    \"        self.right_stack = Stack()\\n\",\n    \"\\n\",\n    \"    def shift_stacks(self, source, destination):\\n\",\n    \"        while source.peek() is not None:\\n\",\n    \"            destination.push(source.pop())\\n\",\n    \"\\n\",\n    \"    def enqueue(self, data):\\n\",\n    \"        self.shift_stacks(self.right_stack, self.left_stack)\\n\",\n    \"        self.left_stack.push(data)\\n\",\n    \"\\n\",\n    \"    def dequeue(self):\\n\",\n    \"        self.shift_stacks(self.left_stack, self.right_stack)\\n\",\n    \"        return self.right_stack.pop()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_queue_from_stacks.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_queue_from_stacks.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestQueueFromStacks(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_queue_from_stacks(self):\\n\",\n    \"        print('Test: Dequeue on empty stack')\\n\",\n    \"        queue = QueueFromStacks()\\n\",\n    \"        self.assertEqual(queue.dequeue(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: Enqueue on empty stack')\\n\",\n    \"        print('Test: Enqueue on non-empty stack')\\n\",\n    \"        print('Test: Multiple enqueue in a row')\\n\",\n    \"        num_items = 3\\n\",\n    \"        for i in range(0, num_items):\\n\",\n    \"            queue.enqueue(i)\\n\",\n    \"\\n\",\n    \"        print('Test: Dequeue on non-empty stack')\\n\",\n    \"        print('Test: Dequeue after an enqueue')\\n\",\n    \"        self.assertEqual(queue.dequeue(), 0)\\n\",\n    \"\\n\",\n    \"        print('Test: Multiple dequeue in a row')\\n\",\n    \"        self.assertEqual(queue.dequeue(), 1)\\n\",\n    \"        self.assertEqual(queue.dequeue(), 2)\\n\",\n    \"\\n\",\n    \"        print('Test: Enqueue after a dequeue')\\n\",\n    \"        queue.enqueue(5)\\n\",\n    \"        self.assertEqual(queue.dequeue(), 5)\\n\",\n    \"\\n\",\n    \"        print('Success: test_queue_from_stacks')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestQueueFromStacks()\\n\",\n    \"    test.test_queue_from_stacks()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Dequeue on empty stack\\n\",\n      \"Test: Enqueue on empty stack\\n\",\n      \"Test: Enqueue on non-empty stack\\n\",\n      \"Test: Multiple enqueue in a row\\n\",\n      \"Test: Dequeue on non-empty stack\\n\",\n      \"Test: Dequeue after an enqueue\\n\",\n      \"Test: Multiple dequeue in a row\\n\",\n      \"Test: Enqueue after a dequeue\\n\",\n      \"Success: test_queue_from_stacks\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_queue_from_stacks.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "stacks_queues/queue_from_stacks/test_queue_from_stacks.py",
    "content": "import unittest\n\n\nclass TestQueueFromStacks(unittest.TestCase):\n\n    def test_queue_from_stacks(self):\n        print('Test: Dequeue on empty stack')\n        queue = QueueFromStacks()\n        self.assertEqual(queue.dequeue(), None)\n\n        print('Test: Enqueue on empty stack')\n        print('Test: Enqueue on non-empty stack')\n        print('Test: Multiple enqueue in a row')\n        num_items = 3\n        for i in range(0, num_items):\n            queue.enqueue(i)\n\n        print('Test: Dequeue on non-empty stack')\n        print('Test: Dequeue after an enqueue')\n        self.assertEqual(queue.dequeue(), 0)\n\n        print('Test: Multiple dequeue in a row')\n        self.assertEqual(queue.dequeue(), 1)\n        self.assertEqual(queue.dequeue(), 2)\n\n        print('Test: Enqueue after a dequeue')\n        queue.enqueue(5)\n        self.assertEqual(queue.dequeue(), 5)\n\n        print('Success: test_queue_from_stacks')\n\n\ndef main():\n    test = TestQueueFromStacks()\n    test.test_queue_from_stacks()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "stacks_queues/queue_list/__init__.py",
    "content": ""
  },
  {
    "path": "stacks_queues/queue_list/queue_list.py",
    "content": "class Node(object):\n\n    def __init__(self, data):\n        self.data = data\n        self.next = None\n\n\nclass Queue(object):\n\n    def __init__(self):\n        self.head = None\n        self.tail = None\n\n    def enqueue(self, data):\n        node = Node(data)\n        # Empty list\n        if self.head is None and self.tail is None:\n            self.head = node\n            self.tail = node\n        else:\n            self.tail.next = node\n            self.tail = node\n\n    def dequeue(self):\n        # Empty list\n        if self.head is None and self.tail is None:\n            return None\n        data = self.head.data\n        # Remove only element from a one element list\n        if self.head == self.tail:\n            self.head = None\n            self.tail = None\n        else:\n            self.head = self.head.next\n        return data\n"
  },
  {
    "path": "stacks_queues/queue_list/queue_list_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a queue with enqueue and dequeue methods using a linked list.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Pythonic-Code](#Pythonic-Code)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* If there is one item in the list, do you expect the first and last pointers to both point to it?\\n\",\n    \"    * Yes\\n\",\n    \"* If there are no items on the list, do you expect the first and last pointers to be None?\\n\",\n    \"    * Yes\\n\",\n    \"* If you dequeue on an empty queue, does that return None?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### Enqueue\\n\",\n    \"\\n\",\n    \"* Enqueue to an empty queue\\n\",\n    \"* Enqueue to a non-empty queue\\n\",\n    \"\\n\",\n    \"### Dequeue\\n\",\n    \"\\n\",\n    \"* Dequeue an empty queue -> None\\n\",\n    \"* Dequeue a queue with one element\\n\",\n    \"* Dequeue a queue with more than one element\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/queue_list/queue_list_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Node(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Queue(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def enqueue(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def dequeue(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_queue_list.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestQueue(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    # TODO: It would be better if we had unit tests for each\\n\",\n    \"    # method in addition to the following end-to-end test\\n\",\n    \"    def test_end_to_end(self):\\n\",\n    \"        print('Test: Dequeue an empty queue')\\n\",\n    \"        queue = Queue()\\n\",\n    \"        self.assertEqual(queue.dequeue(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: Enqueue to an empty queue')\\n\",\n    \"        queue.enqueue(1)\\n\",\n    \"\\n\",\n    \"        print('Test: Dequeue a queue with one element')\\n\",\n    \"        self.assertEqual(queue.dequeue(), 1)\\n\",\n    \"\\n\",\n    \"        print('Test: Enqueue to a non-empty queue')\\n\",\n    \"        queue.enqueue(2)\\n\",\n    \"        queue.enqueue(3)\\n\",\n    \"        queue.enqueue(4)\\n\",\n    \"\\n\",\n    \"        print('Test: Dequeue a queue with more than one element')\\n\",\n    \"        self.assertEqual(queue.dequeue(), 2)\\n\",\n    \"        self.assertEqual(queue.dequeue(), 3)\\n\",\n    \"        self.assertEqual(queue.dequeue(), 4)\\n\",\n    \"\\n\",\n    \"        print('Success: test_end_to_end')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestQueue()\\n\",\n    \"    test.test_end_to_end()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/queue_list/queue_list_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "stacks_queues/queue_list/queue_list_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a queue with enqueue and dequeue methods using a linked list.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Pythonic-Code](#Pythonic-Code)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* If there is one item in the list, do you expect the head and tail pointers to both point to it?\\n\",\n    \"    * Yes\\n\",\n    \"* If there are no items on the list, do you expect the head and tail pointers to be None?\\n\",\n    \"    * Yes\\n\",\n    \"* If you dequeue on an empty queue, does that return None?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### Enqueue\\n\",\n    \"\\n\",\n    \"* Enqueue to an empty queue\\n\",\n    \"* Enqueue to a non-empty queue\\n\",\n    \"\\n\",\n    \"### Dequeue\\n\",\n    \"\\n\",\n    \"* Dequeue an empty queue -> None\\n\",\n    \"* Dequeue a queue with one element\\n\",\n    \"* Dequeue a queue with more than one element\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### Enqueue\\n\",\n    \"\\n\",\n    \"* If the list is empty, set head and tail to node\\n\",\n    \"* Else, set tail to node\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Dequeue\\n\",\n    \"\\n\",\n    \"* If the list is empty, return None\\n\",\n    \"* If the list has one node\\n\",\n    \"    * Save the head node's value\\n\",\n    \"    * Set head and tail to None\\n\",\n    \"    * Return the saved value\\n\",\n    \"* Else\\n\",\n    \"    * Save the head node's value\\n\",\n    \"    * Set head to its next node\\n\",\n    \"    * Return the saved value\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting queue_list.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile queue_list.py\\n\",\n    \"class Node(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, data):\\n\",\n    \"        self.data = data\\n\",\n    \"        self.next = None\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Queue(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self):\\n\",\n    \"        self.head = None\\n\",\n    \"        self.tail = None\\n\",\n    \"\\n\",\n    \"    def enqueue(self, data):\\n\",\n    \"        node = Node(data)\\n\",\n    \"        # Empty list\\n\",\n    \"        if self.head is None and self.tail is None:\\n\",\n    \"            self.head = node\\n\",\n    \"            self.tail = node\\n\",\n    \"        else:\\n\",\n    \"            self.tail.next = node\\n\",\n    \"            self.tail = node\\n\",\n    \"\\n\",\n    \"    def dequeue(self):\\n\",\n    \"        # Empty list\\n\",\n    \"        if self.head is None and self.tail is None:\\n\",\n    \"            return None\\n\",\n    \"        data = self.head.data\\n\",\n    \"        # Remove only element from a one element list\\n\",\n    \"        if self.head == self.tail:\\n\",\n    \"            self.head = None\\n\",\n    \"            self.tail = None\\n\",\n    \"        else:\\n\",\n    \"            self.head = self.head.next\\n\",\n    \"        return data\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run queue_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_queue_list.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_queue_list.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestQueue(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    # TODO: It would be better if we had unit tests for each\\n\",\n    \"    # method in addition to the following end-to-end test\\n\",\n    \"    def test_end_to_end(self):\\n\",\n    \"        print('Test: Dequeue an empty queue')\\n\",\n    \"        queue = Queue()\\n\",\n    \"        self.assertEqual(queue.dequeue(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: Enqueue to an empty queue')\\n\",\n    \"        queue.enqueue(1)\\n\",\n    \"\\n\",\n    \"        print('Test: Dequeue a queue with one element')\\n\",\n    \"        self.assertEqual(queue.dequeue(), 1)\\n\",\n    \"\\n\",\n    \"        print('Test: Enqueue to a non-empty queue')\\n\",\n    \"        queue.enqueue(2)\\n\",\n    \"        queue.enqueue(3)\\n\",\n    \"        queue.enqueue(4)\\n\",\n    \"\\n\",\n    \"        print('Test: Dequeue a queue with more than one element')\\n\",\n    \"        self.assertEqual(queue.dequeue(), 2)\\n\",\n    \"        self.assertEqual(queue.dequeue(), 3)\\n\",\n    \"        self.assertEqual(queue.dequeue(), 4)\\n\",\n    \"\\n\",\n    \"        print('Success: test_end_to_end')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestQueue()\\n\",\n    \"    test.test_end_to_end()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Dequeue an empty queue\\n\",\n      \"Test: Enqueue to an empty queue\\n\",\n      \"Test: Dequeue a queue with one element\\n\",\n      \"Test: Enqueue to a non-empty queue\\n\",\n      \"Test: Dequeue a queue with more than one element\\n\",\n      \"Success: test_end_to_end\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_queue_list.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Pythonic-Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Source: https://docs.python.org/2/tutorial/datastructures.html#using-lists-as-queues\\n\",\n    \"<pre>\\n\",\n    \"It is possible to use a list as a queue, where the first element added is the first element retrieved (“first-in, first-out”); however, lists are not efficient for this purpose. While appends and pops from the end of list are fast, doing inserts or pops from the beginning of a list is slow (because all of the other elements have to be shifted by one).\\n\",\n    \"\\n\",\n    \"To implement a queue, use collections.deque which was designed to have fast appends and pops from both ends. For example:\\n\",\n    \"\\n\",\n    \">>>\\n\",\n    \">>> from collections import deque\\n\",\n    \">>> queue = deque([\\\"Eric\\\", \\\"John\\\", \\\"Michael\\\"])\\n\",\n    \">>> queue.append(\\\"Terry\\\")           # Terry arrives\\n\",\n    \">>> queue.append(\\\"Graham\\\")          # Graham arrives\\n\",\n    \">>> queue.popleft()                 # The first to arrive now leaves\\n\",\n    \"'Eric'\\n\",\n    \">>> queue.popleft()                 # The second to arrive now leaves\\n\",\n    \"'John'\\n\",\n    \">>> queue                           # Remaining queue in order of arrival\\n\",\n    \"deque(['Michael', 'Terry', 'Graham'])\\n\",\n    \"</pre>\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "stacks_queues/queue_list/test_queue_list.py",
    "content": "import unittest\n\n\nclass TestQueue(unittest.TestCase):\n\n    # TODO: It would be better if we had unit tests for each\n    # method in addition to the following end-to-end test\n    def test_end_to_end(self):\n        print('Test: Dequeue an empty queue')\n        queue = Queue()\n        self.assertEqual(queue.dequeue(), None)\n\n        print('Test: Enqueue to an empty queue')\n        queue.enqueue(1)\n\n        print('Test: Dequeue a queue with one element')\n        self.assertEqual(queue.dequeue(), 1)\n\n        print('Test: Enqueue to a non-empty queue')\n        queue.enqueue(2)\n        queue.enqueue(3)\n        queue.enqueue(4)\n\n        print('Test: Dequeue a queue with more than one element')\n        self.assertEqual(queue.dequeue(), 2)\n        self.assertEqual(queue.dequeue(), 3)\n        self.assertEqual(queue.dequeue(), 4)\n\n        print('Success: test_end_to_end')\n\n\ndef main():\n    test = TestQueue()\n    test.test_end_to_end()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "stacks_queues/set_of_stacks/__init__.py",
    "content": ""
  },
  {
    "path": "stacks_queues/set_of_stacks/set_of_stacks_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement SetOfStacks that wraps a list of stacks, where each stack is bound by a capacity.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume we already have a stack class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Are all stack bound by the same capacity?\\n\",\n    \"    * Yes\\n\",\n    \"* If a stack becomes full, should automatically create one?\\n\",\n    \"    * Yes\\n\",\n    \"* If a stack becomes empty, should we delete it?\\n\",\n    \"    * Yes\\n\",\n    \"* If we pop on an empty stack, should we return None?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Push and pop on an empty stack\\n\",\n    \"* Push and pop on a non-empty stack\\n\",\n    \"* Push on a capacity stack to create a new one\\n\",\n    \"* Pop on a stack to destroy it\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/set_of_stacks/set_of_stacks_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../stack/stack.py\\n\",\n    \"%load ../stack/stack.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class StackWithCapacity(Stack):\\n\",\n    \"\\n\",\n    \"    def __init__(self, top=None, capacity=10):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def push(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def pop(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def is_full(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class SetOfStacks(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, indiv_stack_capacity):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def push(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def pop(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_set_of_stacks.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSetOfStacks(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_set_of_stacks(self):\\n\",\n    \"        print('Test: Push on an empty stack')\\n\",\n    \"        stacks = SetOfStacks(indiv_stack_capacity=2)\\n\",\n    \"        stacks.push(3)\\n\",\n    \"\\n\",\n    \"        print('Test: Push on a non-empty stack')\\n\",\n    \"        stacks.push(5)\\n\",\n    \"\\n\",\n    \"        print('Test: Push on a capacity stack to create a new one')\\n\",\n    \"        stacks.push('a')\\n\",\n    \"\\n\",\n    \"        print('Test: Pop on a stack to destroy it')\\n\",\n    \"        self.assertEqual(stacks.pop(), 'a')\\n\",\n    \"\\n\",\n    \"        print('Test: Pop general case')\\n\",\n    \"        self.assertEqual(stacks.pop(), 5)\\n\",\n    \"        self.assertEqual(stacks.pop(), 3)\\n\",\n    \"\\n\",\n    \"        print('Test: Pop on no elements')\\n\",\n    \"        self.assertEqual(stacks.pop(), None)\\n\",\n    \"\\n\",\n    \"        print('Success: test_set_of_stacks')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSetOfStacks()\\n\",\n    \"    test.test_set_of_stacks()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/set_of_stacks/set_of_stacks_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "stacks_queues/set_of_stacks/set_of_stacks_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement SetOfStacks that wraps a list of stacks, where each stack is bound by a capacity.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume we already have a stack class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Are all stack bound by the same capacity?\\n\",\n    \"    * Yes\\n\",\n    \"* If a stack becomes full, should automatically create one?\\n\",\n    \"    * Yes\\n\",\n    \"* If a stack becomes empty, should we delete it?\\n\",\n    \"    * Yes\\n\",\n    \"* If we pop on an empty stack, should we return None?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Push and pop on an empty stack\\n\",\n    \"* Push and pop on a non-empty stack\\n\",\n    \"* Push on a capacity stack to create a new one\\n\",\n    \"* Pop on a stack to destroy it\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### Push\\n\",\n    \"\\n\",\n    \"* If there are no stacks or the last stack is full\\n\",\n    \"    * Create a new stack\\n\",\n    \"* Push to the new stack\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(m), where m is the size of the new stack if the last stack is full\\n\",\n    \"\\n\",\n    \"### Pop\\n\",\n    \"\\n\",\n    \"* If there are no stacks, return None\\n\",\n    \"* Else if the last stack has one element\\n\",\n    \"    * Pop the last element's data\\n\",\n    \"    * Delete the now empty stack\\n\",\n    \"    * Update the last stack pointer\\n\",\n    \"* Else Pop the last element's data\\n\",\n    \"* Return the last element's data\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../stack/stack.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class StackWithCapacity(Stack):\\n\",\n    \"\\n\",\n    \"    def __init__(self, top=None, capacity=10):\\n\",\n    \"        super(StackWithCapacity, self).__init__(top)\\n\",\n    \"        self.capacity = capacity\\n\",\n    \"        self.num_items = 0\\n\",\n    \"\\n\",\n    \"    def push(self, data):\\n\",\n    \"        if self.is_full():\\n\",\n    \"            raise Exception('Stack full')\\n\",\n    \"        super(StackWithCapacity, self).push(data)\\n\",\n    \"        self.num_items += 1\\n\",\n    \"\\n\",\n    \"    def pop(self):\\n\",\n    \"        self.num_items -= 1\\n\",\n    \"        return super(StackWithCapacity, self).pop()\\n\",\n    \"\\n\",\n    \"    def is_full(self):\\n\",\n    \"        return self.num_items == self.capacity\\n\",\n    \"\\n\",\n    \"    def is_empty(self):\\n\",\n    \"        return self.num_items == 0\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class SetOfStacks(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, indiv_stack_capacity):\\n\",\n    \"        self.indiv_stack_capacity = indiv_stack_capacity\\n\",\n    \"        self.stacks = []\\n\",\n    \"        self.last_stack = None\\n\",\n    \"\\n\",\n    \"    def push(self, data):\\n\",\n    \"        if self.last_stack is None or self.last_stack.is_full():\\n\",\n    \"            self.last_stack = StackWithCapacity(None, self.indiv_stack_capacity)\\n\",\n    \"            self.stacks.append(self.last_stack)\\n\",\n    \"        self.last_stack.push(data)\\n\",\n    \"\\n\",\n    \"    def pop(self):\\n\",\n    \"        if self.last_stack is None:\\n\",\n    \"            return None\\n\",\n    \"        data = self.last_stack.pop()\\n\",\n    \"        if self.last_stack.is_empty():\\n\",\n    \"            self.stacks.pop()\\n\",\n    \"            self.last_stack = self.stacks[-1] if self.stacks else None\\n\",\n    \"        return data\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_set_of_stacks.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_set_of_stacks.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSetOfStacks(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_set_of_stacks(self):\\n\",\n    \"        print('Test: Push on an empty stack')\\n\",\n    \"        stacks = SetOfStacks(indiv_stack_capacity=2)\\n\",\n    \"        stacks.push(3)\\n\",\n    \"\\n\",\n    \"        print('Test: Push on a non-empty stack')\\n\",\n    \"        stacks.push(5)\\n\",\n    \"\\n\",\n    \"        print('Test: Push on a capacity stack to create a new one')\\n\",\n    \"        stacks.push('a')\\n\",\n    \"\\n\",\n    \"        print('Test: Pop on a stack to destroy it')\\n\",\n    \"        self.assertEqual(stacks.pop(), 'a')\\n\",\n    \"\\n\",\n    \"        print('Test: Pop general case')\\n\",\n    \"        self.assertEqual(stacks.pop(), 5)\\n\",\n    \"        self.assertEqual(stacks.pop(), 3)\\n\",\n    \"\\n\",\n    \"        print('Test: Pop on no elements')\\n\",\n    \"        self.assertEqual(stacks.pop(), None)\\n\",\n    \"\\n\",\n    \"        print('Success: test_set_of_stacks')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSetOfStacks()\\n\",\n    \"    test.test_set_of_stacks()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Push on an empty stack\\n\",\n      \"Test: Push on a non-empty stack\\n\",\n      \"Test: Push on a capacity stack to create a new one\\n\",\n      \"Test: Pop on a stack to destroy it\\n\",\n      \"Test: Pop general case\\n\",\n      \"Test: Pop on no elements\\n\",\n      \"Success: test_set_of_stacks\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_set_of_stacks.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "stacks_queues/set_of_stacks/test_set_of_stacks.py",
    "content": "import unittest\n\n\nclass TestSetOfStacks(unittest.TestCase):\n\n    def test_set_of_stacks(self):\n        print('Test: Push on an empty stack')\n        stacks = SetOfStacks(indiv_stack_capacity=2)\n        stacks.push(3)\n\n        print('Test: Push on a non-empty stack')\n        stacks.push(5)\n\n        print('Test: Push on a capacity stack to create a new one')\n        stacks.push('a')\n\n        print('Test: Pop on a stack to destroy it')\n        self.assertEqual(stacks.pop(), 'a')\n\n        print('Test: Pop general case')\n        self.assertEqual(stacks.pop(), 5)\n        self.assertEqual(stacks.pop(), 3)\n\n        print('Test: Pop on no elements')\n        self.assertEqual(stacks.pop(), None)\n\n        print('Success: test_set_of_stacks')\n\n\ndef main():\n    test = TestSetOfStacks()\n    test.test_set_of_stacks()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "stacks_queues/sort_stack/__init__.py",
    "content": ""
  },
  {
    "path": "stacks_queues/sort_stack/sort_stack_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Sort a stack.  You can use another stack as a buffer.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* When sorted, should the largest element be at the top or bottom?\\n\",\n    \"    * Top\\n\",\n    \"* Can you have duplicate values like 5, 5?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a stack class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Empty stack -> None\\n\",\n    \"* One element stack\\n\",\n    \"* Two or more element stack (general case)\\n\",\n    \"* Already sorted stack\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/sort_stack/sort_stack_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../stack/stack.py\\n\",\n    \"%load ../stack/stack.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyStack(Stack):\\n\",\n    \"\\n\",\n    \"    def sort(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_sort_stack.py\\n\",\n    \"from random import randint\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSortStack(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def get_sorted_stack(self, stack, numbers):\\n\",\n    \"        for x in numbers:\\n\",\n    \"            stack.push(x)\\n\",\n    \"        sorted_stack = stack.sort()\\n\",\n    \"        return sorted_stack\\n\",\n    \"\\n\",\n    \"    def test_sort_stack(self, stack):\\n\",\n    \"        print('Test: Empty stack')\\n\",\n    \"        sorted_stack = self.get_sorted_stack(stack, [])\\n\",\n    \"        self.assertEqual(sorted_stack.pop(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: One element stack')\\n\",\n    \"        sorted_stack = self.get_sorted_stack(stack, [1])\\n\",\n    \"        self.assertEqual(sorted_stack.pop(), 1)\\n\",\n    \"\\n\",\n    \"        print('Test: Two or more element stack (general case)')\\n\",\n    \"        num_items = 10\\n\",\n    \"        numbers = [randint(0, 10) for x in range(num_items)]\\n\",\n    \"        sorted_stack = self.get_sorted_stack(stack, numbers)\\n\",\n    \"        sorted_numbers = []\\n\",\n    \"        for _ in range(num_items):\\n\",\n    \"            sorted_numbers.append(sorted_stack.pop())\\n\",\n    \"        self.assertEqual(sorted_numbers, sorted(numbers, reverse=True))\\n\",\n    \"\\n\",\n    \"        print('Success: test_sort_stack')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSortStack()\\n\",\n    \"    test.test_sort_stack(MyStack())\\n\",\n    \"    try:\\n\",\n    \"        test.test_sort_stack(MyStackSimplified())\\n\",\n    \"    except NameError:\\n\",\n    \"        # Alternate solutions are only defined\\n\",\n    \"        # in the solutions file\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/sort_stack/sort_stack_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "stacks_queues/sort_stack/sort_stack_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Sort a stack.  You can use another stack as a buffer.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* When sorted, should the largest element be at the top or bottom?\\n\",\n    \"    * Top\\n\",\n    \"* Can you have duplicate values like 5, 5?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a stack class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Empty stack -> None\\n\",\n    \"* One element stack\\n\",\n    \"* Two or more element stack (general case)\\n\",\n    \"* Already sorted stack\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"* Our buffer will hold elements in reverse sorted order, smallest at the top\\n\",\n    \"* Store the current top element in a temp variable\\n\",\n    \"* While stack is not empty\\n\",\n    \"    * While buffer is not empty or buffer top is > than temp\\n\",\n    \"        * Move buffer top to stack\\n\",\n    \"    * Move temp to top of buffer\\n\",\n    \"* Return buffer\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n^2)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../stack/stack.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyStack(Stack):\\n\",\n    \"\\n\",\n    \"    def sort(self):\\n\",\n    \"        buff = MyStack()\\n\",\n    \"        while not self.is_empty():\\n\",\n    \"            temp = self.pop()\\n\",\n    \"            if buff.is_empty() or temp >= buff.peek():\\n\",\n    \"                buff.push(temp)\\n\",\n    \"            else:\\n\",\n    \"                while not buff.is_empty() and temp < buff.peek():\\n\",\n    \"                    self.push(buff.pop())\\n\",\n    \"                buff.push(temp)\\n\",\n    \"        return buff\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"The solution can be further simplified:\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class MyStackSimplified(Stack):\\n\",\n    \"\\n\",\n    \"    def sort(self):\\n\",\n    \"        buff = MyStack()\\n\",\n    \"        while not self.is_empty():\\n\",\n    \"            temp = self.pop()\\n\",\n    \"            while not buff.is_empty() and temp < buff.peek():\\n\",\n    \"                self.push(buff.pop())\\n\",\n    \"            buff.push(temp)\\n\",\n    \"        return buff\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_sort_stack.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_sort_stack.py\\n\",\n    \"from random import randint\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestSortStack(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def get_sorted_stack(self, stack, numbers):\\n\",\n    \"        for x in numbers:\\n\",\n    \"            stack.push(x)\\n\",\n    \"        sorted_stack = stack.sort()\\n\",\n    \"        return sorted_stack\\n\",\n    \"\\n\",\n    \"    def test_sort_stack(self, stack):\\n\",\n    \"        print('Test: Empty stack')\\n\",\n    \"        sorted_stack = self.get_sorted_stack(stack, [])\\n\",\n    \"        self.assertEqual(sorted_stack.pop(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: One element stack')\\n\",\n    \"        sorted_stack = self.get_sorted_stack(stack, [1])\\n\",\n    \"        self.assertEqual(sorted_stack.pop(), 1)\\n\",\n    \"\\n\",\n    \"        print('Test: Two or more element stack (general case)')\\n\",\n    \"        num_items = 10\\n\",\n    \"        numbers = [randint(0, 10) for x in range(num_items)]\\n\",\n    \"        sorted_stack = self.get_sorted_stack(stack, numbers)\\n\",\n    \"        sorted_numbers = []\\n\",\n    \"        for _ in range(num_items):\\n\",\n    \"            sorted_numbers.append(sorted_stack.pop())\\n\",\n    \"        self.assertEqual(sorted_numbers, sorted(numbers, reverse=True))\\n\",\n    \"\\n\",\n    \"        print('Success: test_sort_stack')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestSortStack()\\n\",\n    \"    test.test_sort_stack(MyStack())\\n\",\n    \"    test.test_sort_stack(MyStackSimplified())\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Empty stack\\n\",\n      \"Test: One element stack\\n\",\n      \"Test: Two or more element stack (general case)\\n\",\n      \"Success: test_sort_stack\\n\",\n      \"Test: Empty stack\\n\",\n      \"Test: One element stack\\n\",\n      \"Test: Two or more element stack (general case)\\n\",\n      \"Success: test_sort_stack\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_sort_stack.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "stacks_queues/sort_stack/test_sort_stack.py",
    "content": "from random import randint\nimport unittest\n\n\nclass TestSortStack(unittest.TestCase):\n\n    def get_sorted_stack(self, stack, numbers):\n        for x in numbers:\n            stack.push(x)\n        sorted_stack = stack.sort()\n        return sorted_stack\n\n    def test_sort_stack(self, stack):\n        print('Test: Empty stack')\n        sorted_stack = self.get_sorted_stack(stack, [])\n        self.assertEqual(sorted_stack.pop(), None)\n\n        print('Test: One element stack')\n        sorted_stack = self.get_sorted_stack(stack, [1])\n        self.assertEqual(sorted_stack.pop(), 1)\n\n        print('Test: Two or more element stack (general case)')\n        num_items = 10\n        numbers = [randint(0, 10) for x in range(num_items)]\n        sorted_stack = self.get_sorted_stack(stack, numbers)\n        sorted_numbers = []\n        for _ in range(num_items):\n            sorted_numbers.append(sorted_stack.pop())\n        self.assertEqual(sorted_numbers, sorted(numbers, reverse=True))\n\n        print('Success: test_sort_stack')\n\n\ndef main():\n    test = TestSortStack()\n    test.test_sort_stack(MyStack())\n    test.test_sort_stack(MyStackSimplified())\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "stacks_queues/stack/__init__.py",
    "content": ""
  },
  {
    "path": "stacks_queues/stack/stack.py",
    "content": "class Node(object):\n\n    def __init__(self, data, next=None):\n        self.data = data\n        self.next = next\n\n\nclass Stack(object):\n\n    def __init__(self, top=None):\n        self.top = top\n\n    def push(self, data):\n        self.top = Node(data, self.top)\n\n    def pop(self):\n        if self.top is None:\n            return None\n        data = self.top.data\n        self.top = self.top.next\n        return data\n\n    def peek(self):\n        return self.top.data if self.top is not None else None\n\n    def is_empty(self):\n        return self.peek() is None\n"
  },
  {
    "path": "stacks_queues/stack/stack_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a stack with push, pop, peek, and is_empty methods using a linked list.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Pythonic-Code](#Pythonic-Code)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* If we pop on an empty stack, do we return None?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### Push\\n\",\n    \"\\n\",\n    \"* Push to empty stack\\n\",\n    \"* Push to non-empty stack\\n\",\n    \"\\n\",\n    \"### Pop\\n\",\n    \"\\n\",\n    \"* Pop on empty stack\\n\",\n    \"* Pop on single element stack\\n\",\n    \"* Pop on multiple element stack\\n\",\n    \"\\n\",\n    \"### Peek\\n\",\n    \"\\n\",\n    \"* Peek on empty stack\\n\",\n    \"* Peek on one or more element stack\\n\",\n    \"\\n\",\n    \"### Is Empty\\n\",\n    \"\\n\",\n    \"* Is empty on empty stack\\n\",\n    \"* Is empty on one or more element stack\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/stack/stack_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Node(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Stack(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, top=None):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def push(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def pop(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def peek(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def is_empty(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_stack.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestStack(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    # TODO: It would be better if we had unit tests for each\\n\",\n    \"    # method in addition to the following end-to-end test\\n\",\n    \"    def test_end_to_end(self):\\n\",\n    \"        print('Test: Empty stack')\\n\",\n    \"        stack = Stack()\\n\",\n    \"        self.assertEqual(stack.peek(), None)\\n\",\n    \"        self.assertEqual(stack.pop(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: One element')\\n\",\n    \"        top = Node(5)\\n\",\n    \"        stack = Stack(top)\\n\",\n    \"        self.assertEqual(stack.pop(), 5)\\n\",\n    \"        self.assertEqual(stack.peek(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: More than one element')\\n\",\n    \"        stack = Stack()\\n\",\n    \"        stack.push(1)\\n\",\n    \"        stack.push(2)\\n\",\n    \"        stack.push(3)\\n\",\n    \"        self.assertEqual(stack.pop(), 3)\\n\",\n    \"        self.assertEqual(stack.peek(), 2)\\n\",\n    \"        self.assertEqual(stack.pop(), 2)\\n\",\n    \"        self.assertEqual(stack.peek(), 1)\\n\",\n    \"        self.assertEqual(stack.is_empty(), False)\\n\",\n    \"        self.assertEqual(stack.pop(), 1)\\n\",\n    \"        self.assertEqual(stack.peek(), None)\\n\",\n    \"        self.assertEqual(stack.is_empty(), True)\\n\",\n    \"\\n\",\n    \"        print('Success: test_end_to_end')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestStack()\\n\",\n    \"    test.test_end_to_end()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/stack/stack_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "stacks_queues/stack/stack_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a stack with push, pop, peek, and is_empty methods using a linked list.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Pythonic-Code](#Pythonic-Code)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* If we pop on an empty stack, do we return None?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### Push\\n\",\n    \"\\n\",\n    \"* Push to empty stack\\n\",\n    \"* Push to non-empty stack\\n\",\n    \"\\n\",\n    \"### Pop\\n\",\n    \"\\n\",\n    \"* Pop on empty stack\\n\",\n    \"* Pop on single element stack\\n\",\n    \"* Pop on multiple element stack\\n\",\n    \"\\n\",\n    \"### Peek\\n\",\n    \"\\n\",\n    \"* Peek on empty stack\\n\",\n    \"* Peek on one or more element stack\\n\",\n    \"\\n\",\n    \"### Is Empty\\n\",\n    \"\\n\",\n    \"* Is empty on empty stack\\n\",\n    \"* Is empty on one or more element stack\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### Push\\n\",\n    \"\\n\",\n    \"* Create new node with value\\n\",\n    \"* Set node's next to top\\n\",\n    \"* Set top to node\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Pop\\n\",\n    \"\\n\",\n    \"* If stack is empty, return None\\n\",\n    \"* Else \\n\",\n    \"    * Save top's value\\n\",\n    \"    * Set top to top.next\\n\",\n    \"    * Return saved value\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Peek\\n\",\n    \"\\n\",\n    \"* If stack is empty, return None\\n\",\n    \"* Else return top's value\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Is Empty\\n\",\n    \"* If peek has a value, return False\\n\",\n    \"* Else return True\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting stack.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile stack.py\\n\",\n    \"class Node(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, data, next=None):\\n\",\n    \"        self.data = data\\n\",\n    \"        self.next = next\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class Stack(object):\\n\",\n    \"\\n\",\n    \"    def __init__(self, top=None):\\n\",\n    \"        self.top = top\\n\",\n    \"\\n\",\n    \"    def push(self, data):\\n\",\n    \"        self.top = Node(data, self.top)\\n\",\n    \"\\n\",\n    \"    def pop(self):\\n\",\n    \"        if self.top is None:\\n\",\n    \"            return None\\n\",\n    \"        data = self.top.data\\n\",\n    \"        self.top = self.top.next\\n\",\n    \"        return data\\n\",\n    \"\\n\",\n    \"    def peek(self):\\n\",\n    \"        return self.top.data if self.top is not None else None\\n\",\n    \"\\n\",\n    \"    def is_empty(self):\\n\",\n    \"        return self.peek() is None\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run stack.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_stack.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_stack.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestStack(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    # TODO: It would be better if we had unit tests for each\\n\",\n    \"    # method in addition to the following end-to-end test\\n\",\n    \"    def test_end_to_end(self):\\n\",\n    \"        print('Test: Empty stack')\\n\",\n    \"        stack = Stack()\\n\",\n    \"        self.assertEqual(stack.peek(), None)\\n\",\n    \"        self.assertEqual(stack.pop(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: One element')\\n\",\n    \"        top = Node(5)\\n\",\n    \"        stack = Stack(top)\\n\",\n    \"        self.assertEqual(stack.pop(), 5)\\n\",\n    \"        self.assertEqual(stack.peek(), None)\\n\",\n    \"\\n\",\n    \"        print('Test: More than one element')\\n\",\n    \"        stack = Stack()\\n\",\n    \"        stack.push(1)\\n\",\n    \"        stack.push(2)\\n\",\n    \"        stack.push(3)\\n\",\n    \"        self.assertEqual(stack.pop(), 3)\\n\",\n    \"        self.assertEqual(stack.peek(), 2)\\n\",\n    \"        self.assertEqual(stack.pop(), 2)\\n\",\n    \"        self.assertEqual(stack.peek(), 1)\\n\",\n    \"        self.assertEqual(stack.is_empty(), False)\\n\",\n    \"        self.assertEqual(stack.pop(), 1)\\n\",\n    \"        self.assertEqual(stack.peek(), None)\\n\",\n    \"        self.assertEqual(stack.is_empty(), True)\\n\",\n    \"\\n\",\n    \"        print('Success: test_end_to_end')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestStack()\\n\",\n    \"    test.test_end_to_end()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Empty stack\\n\",\n      \"Test: One element\\n\",\n      \"Test: More than one element\\n\",\n      \"Success: test_end_to_end\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_stack.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Pythonic-Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Source: https://docs.python.org/2/tutorial/datastructures.html#using-lists-as-stacks\\n\",\n    \"<pre>\\n\",\n    \"5.1.1. Using Lists as Stacks\\n\",\n    \"The list methods make it very easy to use a list as a stack, where the last element added is the first element retrieved (“last-in, first-out”). To add an item to the top of the stack, use append(). To retrieve an item from the top of the stack, use pop() without an explicit index. For example:\\n\",\n    \"\\n\",\n    \">>> stack = [3, 4, 5]\\n\",\n    \">>> stack.append(6)\\n\",\n    \">>> stack.append(7)\\n\",\n    \">>> stack\\n\",\n    \"[3, 4, 5, 6, 7]\\n\",\n    \">>> stack.pop()\\n\",\n    \"7\\n\",\n    \">>> stack\\n\",\n    \"[3, 4, 5, 6]\\n\",\n    \">>> stack.pop()\\n\",\n    \"6\\n\",\n    \">>> stack.pop()\\n\",\n    \"5\\n\",\n    \">>> stack\\n\",\n    \"[3, 4]\\n\",\n    \"</pre>\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "stacks_queues/stack/test_stack.py",
    "content": "import unittest\n\n\nclass TestStack(unittest.TestCase):\n\n    # TODO: It would be better if we had unit tests for each\n    # method in addition to the following end-to-end test\n    def test_end_to_end(self):\n        print('Test: Empty stack')\n        stack = Stack()\n        self.assertEqual(stack.peek(), None)\n        self.assertEqual(stack.pop(), None)\n\n        print('Test: One element')\n        top = Node(5)\n        stack = Stack(top)\n        self.assertEqual(stack.pop(), 5)\n        self.assertEqual(stack.peek(), None)\n\n        print('Test: More than one element')\n        stack = Stack()\n        stack.push(1)\n        stack.push(2)\n        stack.push(3)\n        self.assertEqual(stack.pop(), 3)\n        self.assertEqual(stack.peek(), 2)\n        self.assertEqual(stack.pop(), 2)\n        self.assertEqual(stack.peek(), 1)\n        self.assertEqual(stack.is_empty(), False)\n        self.assertEqual(stack.pop(), 1)\n        self.assertEqual(stack.peek(), None)\n        self.assertEqual(stack.is_empty(), True)\n\n        print('Success: test_end_to_end')\n\n\ndef main():\n    test = TestStack()\n    test.test_end_to_end()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "stacks_queues/stack_min/__init__.py",
    "content": ""
  },
  {
    "path": "stacks_queues/stack_min/stack_min_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a stack with push, pop, and min methods running O(1) time.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a stack of ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input values for push are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* If we call this function on an empty stack, can we return sys.maxsize?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a stack class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Push/pop on empty stack\\n\",\n    \"* Push/pop on non-empty stack\\n\",\n    \"* Min on empty stack\\n\",\n    \"* Min on non-empty stack\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/stack_min/stack_min_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../stack/stack.py\\n\",\n    \"%load ../stack/stack.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"import sys\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class StackMin(Stack):\\n\",\n    \"\\n\",\n    \"    def __init__(self, top=None):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def minimum(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def push(self, data):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"    def pop(self):\\n\",\n    \"        # TODO: Implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_stack_min.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestStackMin(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_stack_min(self):\\n\",\n    \"        print('Test: Push on empty stack, non-empty stack')\\n\",\n    \"        stack = StackMin()\\n\",\n    \"        stack.push(5)\\n\",\n    \"        self.assertEqual(stack.peek(), 5)\\n\",\n    \"        self.assertEqual(stack.minimum(), 5)\\n\",\n    \"        stack.push(1)\\n\",\n    \"        self.assertEqual(stack.peek(), 1)\\n\",\n    \"        self.assertEqual(stack.minimum(), 1)\\n\",\n    \"        stack.push(3)\\n\",\n    \"        self.assertEqual(stack.peek(), 3)\\n\",\n    \"        self.assertEqual(stack.minimum(), 1)\\n\",\n    \"        stack.push(0)\\n\",\n    \"        self.assertEqual(stack.peek(), 0)\\n\",\n    \"        self.assertEqual(stack.minimum(), 0)\\n\",\n    \"\\n\",\n    \"        print('Test: Pop on non-empty stack')\\n\",\n    \"        self.assertEqual(stack.pop(), 0)\\n\",\n    \"        self.assertEqual(stack.minimum(), 1)\\n\",\n    \"        self.assertEqual(stack.pop(), 3)\\n\",\n    \"        self.assertEqual(stack.minimum(), 1)\\n\",\n    \"        self.assertEqual(stack.pop(), 1)\\n\",\n    \"        self.assertEqual(stack.minimum(), 5)\\n\",\n    \"        self.assertEqual(stack.pop(), 5)\\n\",\n    \"        self.assertEqual(stack.minimum(), sys.maxsize)\\n\",\n    \"\\n\",\n    \"        print('Test: Pop empty stack')\\n\",\n    \"        self.assertEqual(stack.pop(), None)\\n\",\n    \"\\n\",\n    \"        print('Success: test_stack_min')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestStackMin()\\n\",\n    \"    test.test_stack_min()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/stacks_queues/stack_min/stack_min_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "stacks_queues/stack_min/stack_min_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Donne Martin](http://donnemartin.com). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a stack with push, pop, and min methods running O(1) time.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we assume this is a stack of ints?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume the input values for push are valid?\\n\",\n    \"    * Yes\\n\",\n    \"* If we call this function on an empty stack, can we return sys.maxsize?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume we already have a stack class that can be used for this problem?\\n\",\n    \"    * Yes\\n\",\n    \"* Can we assume this fits memory?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* Push/pop on empty stack\\n\",\n    \"* Push/pop on non-empty stack\\n\",\n    \"* Min on empty stack\\n\",\n    \"* Min on non-empty stack\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"We'll use a second stack to keep track of the minimum values.\\n\",\n    \"\\n\",\n    \"### Min\\n\",\n    \"\\n\",\n    \"* If the second stack is empty, return an error code (max int value)\\n\",\n    \"* Else, return the top of the stack, without popping it\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Push\\n\",\n    \"\\n\",\n    \"* Push the data\\n\",\n    \"* If the data is less than min\\n\",\n    \"    * Push data to second stack\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\\n\",\n    \"\\n\",\n    \"### Pop\\n\",\n    \"\\n\",\n    \"* Pop the data\\n\",\n    \"* If the data is equal to min\\n\",\n    \"    * Pop the top of the second stack\\n\",\n    \"* Return the data\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run ../stack/stack.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import sys\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class StackMin(Stack):\\n\",\n    \"\\n\",\n    \"    def __init__(self, top=None):\\n\",\n    \"        super(StackMin, self).__init__(top)\\n\",\n    \"        self.stack_of_mins = Stack()\\n\",\n    \"\\n\",\n    \"    def minimum(self):\\n\",\n    \"        if self.stack_of_mins.top is None:\\n\",\n    \"            return sys.maxsize\\n\",\n    \"        else:\\n\",\n    \"            return self.stack_of_mins.peek()\\n\",\n    \"\\n\",\n    \"    def push(self, data):\\n\",\n    \"        super(StackMin, self).push(data)\\n\",\n    \"        if data < self.minimum():\\n\",\n    \"            self.stack_of_mins.push(data)\\n\",\n    \"\\n\",\n    \"    def pop(self):\\n\",\n    \"        data = super(StackMin, self).pop()\\n\",\n    \"        if data == self.minimum():\\n\",\n    \"            self.stack_of_mins.pop()\\n\",\n    \"        return data\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_stack_min.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_stack_min.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestStackMin(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_stack_min(self):\\n\",\n    \"        print('Test: Push on empty stack, non-empty stack')\\n\",\n    \"        stack = StackMin()\\n\",\n    \"        stack.push(5)\\n\",\n    \"        self.assertEqual(stack.peek(), 5)\\n\",\n    \"        self.assertEqual(stack.minimum(), 5)\\n\",\n    \"        stack.push(1)\\n\",\n    \"        self.assertEqual(stack.peek(), 1)\\n\",\n    \"        self.assertEqual(stack.minimum(), 1)\\n\",\n    \"        stack.push(3)\\n\",\n    \"        self.assertEqual(stack.peek(), 3)\\n\",\n    \"        self.assertEqual(stack.minimum(), 1)\\n\",\n    \"        stack.push(0)\\n\",\n    \"        self.assertEqual(stack.peek(), 0)\\n\",\n    \"        self.assertEqual(stack.minimum(), 0)\\n\",\n    \"\\n\",\n    \"        print('Test: Pop on non-empty stack')\\n\",\n    \"        self.assertEqual(stack.pop(), 0)\\n\",\n    \"        self.assertEqual(stack.minimum(), 1)\\n\",\n    \"        self.assertEqual(stack.pop(), 3)\\n\",\n    \"        self.assertEqual(stack.minimum(), 1)\\n\",\n    \"        self.assertEqual(stack.pop(), 1)\\n\",\n    \"        self.assertEqual(stack.minimum(), 5)\\n\",\n    \"        self.assertEqual(stack.pop(), 5)\\n\",\n    \"        self.assertEqual(stack.minimum(), sys.maxsize)\\n\",\n    \"\\n\",\n    \"        print('Test: Pop empty stack')\\n\",\n    \"        self.assertEqual(stack.pop(), None)\\n\",\n    \"\\n\",\n    \"        print('Success: test_stack_min')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestStackMin()\\n\",\n    \"    test.test_stack_min()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: Push on empty stack, non-empty stack\\n\",\n      \"Test: Pop on non-empty stack\\n\",\n      \"Test: Pop empty stack\\n\",\n      \"Success: test_stack_min\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"run -i test_stack_min.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "stacks_queues/stack_min/test_stack_min.py",
    "content": "import unittest\n\n\nclass TestStackMin(unittest.TestCase):\n\n    def test_stack_min(self):\n        print('Test: Push on empty stack, non-empty stack')\n        stack = StackMin()\n        stack.push(5)\n        self.assertEqual(stack.peek(), 5)\n        self.assertEqual(stack.minimum(), 5)\n        stack.push(1)\n        self.assertEqual(stack.peek(), 1)\n        self.assertEqual(stack.minimum(), 1)\n        stack.push(3)\n        self.assertEqual(stack.peek(), 3)\n        self.assertEqual(stack.minimum(), 1)\n        stack.push(0)\n        self.assertEqual(stack.peek(), 0)\n        self.assertEqual(stack.minimum(), 0)\n\n        print('Test: Pop on non-empty stack')\n        self.assertEqual(stack.pop(), 0)\n        self.assertEqual(stack.minimum(), 1)\n        self.assertEqual(stack.pop(), 3)\n        self.assertEqual(stack.minimum(), 1)\n        self.assertEqual(stack.pop(), 1)\n        self.assertEqual(stack.minimum(), 5)\n        self.assertEqual(stack.pop(), 5)\n        self.assertEqual(stack.minimum(), sys.maxsize)\n\n        print('Test: Pop empty stack')\n        self.assertEqual(stack.pop(), None)\n\n        print('Success: test_stack_min')\n\n\ndef main():\n    test = TestStackMin()\n    test.test_stack_min()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "staging/README.md",
    "content": "staging\n============\n\nThis folder contains challenges that are still under development.  These challenges might need some minor tweaks or polishing before being placed in the general repository."
  },
  {
    "path": "staging/__init__.py",
    "content": ""
  },
  {
    "path": "staging/arrays_strings/__init__.py",
    "content": ""
  },
  {
    "path": "staging/arrays_strings/reverse_words/__init__.py",
    "content": ""
  },
  {
    "path": "staging/arrays_strings/reverse_words/reverse_words_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"<small> <i> This notebook was prepared by Marco Guajardo. For license visit [github](https://github.com/donnemartin/interactive-coding-challenges) </i> </small>\\n\",\n    \".\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Given a string of words, return a string with the words in reverse\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"* Can we assume the string is ASCII?\\n\",\n    \"  * Yes\\n\",\n    \"* Is whitespace important?\\n\",\n    \"  * no the whitespace does not change\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"  * yes\\n\",\n    \"* What if the string is empty?\\n\",\n    \"  * return None\\n\",\n    \"* Is the order of words important?\\n\",\n    \"  * yes\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"* Empty string -> None\\n\",\n    \"* \\\"the sun is very hot\\\" -> \\\"eht nus si yrev toh\\\"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"* Refer to the [Solution](https://github.com/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/reverse_words/reverse_words_solution.ipynb) if you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code \"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 21,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def reverse_words (S):\\n\",\n    \"    #TODO: implement me\\n\",\n    \"    pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"<b> The following unit test is expected to fail until you solve challenge </b>\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class UnitTest(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def testReverseWords(self, func):\\n\",\n    \"            self.assertEqual(func('the sun is hot'), 'eht nus si toh')\\n\",\n    \"            self.assertEqual(func(''), None)\\n\",\n    \"            self.assertEqual(func('123 456 789'), '321 654 987')\\n\",\n    \"            self.assertEqual(func('magic'), 'cigam')\\n\",\n    \"            print('Success: reverse_words')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = UnitTest()\\n\",\n    \"    test.testReverseWords(reverse_words)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__==\\\"__main__\\\":\\n\",\n    \"  main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"* Review the [Solution Notebook](https://github.com/donnemartin/interactive-coding-challenges/blob/master/arrays_strings/reverse_words/reverse_words_solution.ipynb) for discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "staging/arrays_strings/reverse_words/reverse_words_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"<small> <i> This notebook was prepared by Marco Guajardo. For license visit [github](https://github.com/donnemartin/interactive-coding-challenges) </i> </small>\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution notebook\\n\",\n    \"## Problem: Given a string of words, return a string with the words in reverse\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"* Can we assume the string is ASCII?\\n\",\n    \"  * Yes\\n\",\n    \"* Is whitespace important?\\n\",\n    \"  * no the whitespace does not change\\n\",\n    \"* Is this case sensitive?\\n\",\n    \"  * yes\\n\",\n    \"* What if the string is empty?\\n\",\n    \"  * return None\\n\",\n    \"* Is the order of words important?\\n\",\n    \"  * yes\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm: Split words into a list and reverse each word individually\\n\",\n    \"Steps:\\n\",\n    \"\\n\",\n    \"* Check if string is empty\\n\",\n    \"* If not empty, split the string into a list of words \\n\",\n    \"* For each word on the list\\n\",\n    \"  * reverse the word\\n\",\n    \"* Return the string representation of the list\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"\\n\",\n    \"* Time complexity is O(n) where n is the number of chars.\\n\",\n    \"* Space complexity is O(n) where n is the number of chars. \"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def reverse_words(S):\\n\",\n    \"    if len(S) is 0:\\n\",\n    \"        return None\\n\",\n    \"\\n\",\n    \"    words = S.split()\\n\",\n    \"    for i in range (len(words)):\\n\",\n    \"        words[i] = words[i][::-1]\\n\",\n    \"\\n\",\n    \"    return \\\" \\\".join(words)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting reverse_words_solution.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile reverse_words_solution.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestReverseWords(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def testReverseWords(self, func):\\n\",\n    \"            self.assertEqual(func('the sun is hot'), 'eht nus si toh')\\n\",\n    \"            self.assertEqual(func(''), None)\\n\",\n    \"            self.assertEqual(func('123 456 789'), '321 654 987')\\n\",\n    \"            self.assertEqual(func('magic'), 'cigam')\\n\",\n    \"            print('Success: reverse_words')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestReverseWords()\\n\",\n    \"    test.testReverseWords(reverse_words)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__==\\\"__main__\\\":\\n\",\n    \"  main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: reverse_words\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"run -i reverse_words_solution.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "staging/arrays_strings/reverse_words/reverse_words_solution.py",
    "content": "import unittest\n\n\nclass TestReverseWords(unittest.TestCase):\n\n    def testReverseWords(self, func):\n            self.assertEqual(func('the sun is hot'), 'eht nus si toh')\n            self.assertEqual(func(''), None)\n            self.assertEqual(func('123 456 789'), '321 654 987')\n            self.assertEqual(func('magic'), 'cigam')\n            print('Success: reverse_words')\n\n\ndef main():\n    test = TestReverseWords()\n    test.testReverseWords(reverse_words)\n\n\nif __name__==\"__main__\":\n  main()\n"
  },
  {
    "path": "staging/graphs_trees/__init__.py",
    "content": ""
  },
  {
    "path": "staging/graphs_trees/binary_tree/__init__.py",
    "content": ""
  },
  {
    "path": "staging/graphs_trees/binary_tree/binary_search_tree.py",
    "content": "\nclass Node (object):\n\tdef __init__ (self, data):\n\t\tself.data = data\n\t\tself.rightChild = None\n\t\tself.leftChild = None\n\nclass BinaryTree (object):\n\tdef __init__ (self):\n\t\tself.root = None\n\n\tdef insert (self, newData):\n\t\tleaf = Node(newData)\n\n\t\tif self.root is None:\n\t\t\tself.root = leaf\n\t\telse:\n\t\t\tcurrent = self.root\n\t\t\tparent = self.root\n\t\t\twhile current is not None:\n\t\t\t\tparent = current\n\t\t\t\tif newData < current.data:\n\t\t\t\t\tcurrent = current.leftChild\n\t\t\t\telse:\n\t\t\t\t\tcurrent = current.rightChild\n\n\t\t\tif newData < parent.data:\n\t\t\t\tparent.leftChild = leaf\n\t\t\telse:\n\t\t\t\tparent.rightChild = leaf\n\n\t# returns false if the item to be deleted is not on the tree\n\tdef delete (self, data):\n\t\tcurrent = self.root\n\t\tparent = self.root\n\t\tisLeft = False\n\n\t\tif current is None:\n\t\t\treturn False\n\n\t\twhile current is not None and current.data is not data:\n\t\t\tparent = current\n\t\t\tif data < current.data:\n\t\t\t\tcurrent = current.leftChild\n\t\t\t\tisLeft = True \n\t\t\telse:\n\t\t\t\tcurrent = current.rightChild\n\t\t\t\tisLeft = False\n\n\t\tif current is None:\n\t\t\treturn False\n\n\t\tif current.leftChild is None and current.rightChild is None:\n\t\t\tif current is self.root:\n\t\t\t\tself.root = None\n\t\t\telif isLeft:\n\t\t\t\tparent.leftChild = None\n\t\t\telse:\n\t\t\t\tparent.rightChild = None\n\n\t\telif current.rightChild is None:\n\t\t\tif current is self.root:\n\t\t\t\tself.root = current.leftChild\n\t\t\telif isLeft:\n\t\t\t\tparent.leftChild = current.leftChild\n\t\t\telse:\n\t\t\t\tparent.rightChild = current.leftChild\n\n\t\telif current.rightChild is None:\n\t\t\tif current is self.root:\n\t\t\t\tself.root = current.rightChild\n\t\t\telif isLeft:\n\t\t\t\tparent.lChild = current.rightChild\n\t\t\telse:\n\t\t\t\tparent.rightChild = current.rightChild\n\n\t\telse:\n\t\t\tsuccessor = current.rightChild\n\t\t\tsuccessorParent = current\n\n\t\t\twhile successor.leftChild is not None:\n\t\t\t\tsuccessorParent = successor\n\t\t\t\tsuccessor = successor.leftChild\n\n\t\t\tif current is self.root:\n\t\t\t\tself.root = successor\n\t\t\telif isLeft:\n\t\t\t\tparent.leftChild = successor\n\t\t\telse:\n\t\t\t\tparent.rightChild = successor\n\n\t\t\tsuccessor.leftChild = current.leftChild\n\n\t\t\tif successor is not current.rightChild:\n\t\t\t\tsuccessorParent.leftChild = successor.rightChild\n\t\t\t\tsuccessor.rightChild = current.rightChild\n\n\t\treturn True \n\n\n\tdef minNode (self):\n\t\tcurrent = self.root\n\t\twhile current.leftChild is not None:\n\t\t\tcurrent = current.leftChild\n\n\t\treturn current.data\n\n\tdef maxNode (self):\n\t\tcurrent = self.root\n\t\twhile current.rightChild is not None:\n\t\t\tcurrent = current.rightChild\n\n\t\treturn current.data\n\n\tdef printPostOrder (self):\n\t\tglobal postOrder\n\t\tpostOrder = []\n\n\t\tdef PostOrder(node):\n\t\t\tif node is not None:\n\t\t\t\tPostOrder(node.leftChild)\n\t\t\t\tPostOrder(node.rightChild)\n\t\t\t\tpostOrder.append(node.data)\n\n\t\tPostOrder(self.root)\n\t\treturn postOrder\n\n\tdef printInOrder (self):\n\t\tglobal inOrder \n\t\tinOrder = []\n\n\t\tdef InOrder (node):\n\t\t\tif node is not None:\n\t\t\t\tInOrder(node.leftChild)\n\t\t\t\tinOrder.append(node.data)\n\t\t\t\tInOrder(node.rightChild)\n\n\t\tInOrder(self.root)\n\t\treturn inOrder\n\n\tdef printPreOrder (self):\n\t\tglobal preOrder\n\t\tpreOrder = []\n\n\t\tdef PreOrder (node):\n\t\t\tif node is not None:\n\t\t\t\tpreOrder.append(node.data)\n\t\t\t\tPreOrder(node.leftChild)\n\t\t\t\tPreOrder(node.rightChild)\n\n\t\tPreOrder(self.root)\n\t\treturn preOrder\n\n\tdef treeIsEmpty (self):\n\t\treturn self.root is None\n"
  },
  {
    "path": "staging/graphs_trees/binary_tree/binary_tree_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by Marco Guajardo. Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a binary search tree with insert, delete, different traversals & max/min node values\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"* Is this a binary tree?\\n\",\n    \"  * Yes\\n\",\n    \"* Is the root set to None initially?\\n\",\n    \"  * Yes\\n\",\n    \"* Do we care if the tree is balanced?\\n\",\n    \"  * No\\n\",\n    \"* What do we return for the traversals?\\n\",\n    \"  * Return a list of the data in the desired order\\n\",\n    \"* What type of data can the tree hold?\\n\",\n    \"  * Assume the tree only takes ints. In a realistic example, we'd use a hash table to convert other types to ints.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### Insert \\n\",\n    \"\\n\",\n    \"* Always start with the root\\n\",\n    \"* If value is less than the root, go to the left child\\n\",\n    \"* if value is more than the root, go to the right child\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"### Delete\\n\",\n    \"\\n\",\n    \"* Deleting a node from a binary tree is tricky. Make sure you arrange the tree correctly when deleting a node.\\n\",\n    \"* Here are some basic [instructions](http://www.algolist.net/Data_structures/Binary_search_tree/Removal)\\n\",\n    \"* If the value to delete isn't on the tree return False\\n\",\n    \"\\n\",\n    \"### Traversals \\n\",\n    \"\\n\",\n    \"* In order traversal - left, center, right\\n\",\n    \"* Pre order traversal - center, left, right\\n\",\n    \"* Post order traversal - left, right, center\\n\",\n    \"* Return list for all traversals \\n\",\n    \"\\n\",\n    \"### Max & Min\\n\",\n    \"* Find the max node in the binary search tree\\n\",\n    \"* Find the min node in the binary search tree\\n\",\n    \"\\n\",\n    \"### treeIsEmpty\\n\",\n    \"* check if the tree is empty\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/binary_tree_implementation/binary_tree_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class Node (object):\\n\",\n    \"    def __init__ (self, data=None):\\n\",\n    \"        #TODO:implement me\\n\",\n    \"        pass\\n\",\n    \"    \\n\",\n    \"    def __str__ (self):\\n\",\n    \"        #TODO:implement me\\n\",\n    \"        pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"class BinaryTree (object):\\n\",\n    \"    def __init__ (self):\\n\",\n    \"        #TODO:implement me\\n\",\n    \"        pass\\n\",\n    \"    \\n\",\n    \"    def insert (self, newData):\\n\",\n    \"        #TODO:implement me\\n\",\n    \"        pass\\n\",\n    \"    \\n\",\n    \"    def delete (self, key):\\n\",\n    \"        #TODO:implement me\\n\",\n    \"        pass\\n\",\n    \"    \\n\",\n    \"    def maxNode (self):\\n\",\n    \"        #TODO:implement me\\n\",\n    \"        pass\\n\",\n    \"    \\n\",\n    \"    def minNode (self):\\n\",\n    \"        #TODO:implement me\\n\",\n    \"        pass\\n\",\n    \"    \\n\",\n    \"    def printPostOrder (self):\\n\",\n    \"        #TODO:implement me\\n\",\n    \"        pass\\n\",\n    \"    \\n\",\n    \"    def printPreOrder (self):\\n\",\n    \"        #TODO:implement me\\n\",\n    \"        pass\\n\",\n    \"    \\n\",\n    \"    def printInOrder (self):\\n\",\n    \"        #TODO:implement me\\n\",\n    \"        pass\\n\",\n    \"    \\n\",\n    \"    def treeIsEmpty (self):\\n\",\n    \"        #TODO: implement me\\n\",\n    \"        pass\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"import unittest\\n\",\n    \"\\n\",\n    \"class TestBinaryTree(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"\\tdef test_insert_traversals (self):\\n\",\n    \"\\t\\tmyTree = BinaryTree()\\n\",\n    \"\\t\\tmyTree2 = BinaryTree()\\n\",\n    \"\\t\\tfor num in [50, 30, 70, 10, 40, 60, 80, 7, 25, 38]:\\n\",\n    \"\\t\\t\\tmyTree.insert(num)\\n\",\n    \"\\t\\t[myTree2.insert(num) for num in range (1, 100, 10)]\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Test: insert checking with in order traversal\\\")\\n\",\n    \"\\t\\texpectVal = [7, 10, 25, 30, 38, 40, 50, 60, 70, 80]\\n\",\n    \"\\t\\tself.assertEqual(myTree.printInOrder(), expectVal)\\n\",\n    \"\\t\\texpectVal = [1, 11, 21, 31, 41, 51, 61, 71, 81, 91]\\n\",\n    \"\\t\\tself.assertEqual(myTree2.printInOrder(), expectVal)\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Test: insert checking with post order traversal\\\")\\n\",\n    \"\\t\\texpectVal = [7, 25, 10, 38, 40, 30, 60, 80, 70, 50]\\n\",\n    \"\\t\\tself.assertEqual(myTree.printPostOrder(), expectVal)\\n\",\n    \"\\t\\texpectVal = [91, 81, 71, 61, 51, 41, 31, 21, 11, 1]\\n\",\n    \"\\t\\tself.assertEqual(myTree2.printPostOrder(), expectVal)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Test: insert checking with pre order traversal\\\")\\n\",\n    \"\\t\\texpectVal = [50, 30, 10, 7, 25, 40, 38, 70, 60, 80]\\n\",\n    \"\\t\\tself.assertEqual(myTree.printPreOrder(), expectVal)\\n\",\n    \"\\t\\texpectVal = [1, 11, 21, 31, 41, 51, 61, 71, 81, 91]\\n\",\n    \"\\t\\tself.assertEqual(myTree2.printPreOrder(), expectVal)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Success: test_insert_traversals\\\")\\n\",\n    \"\\n\",\n    \"\\tdef test_max_min_nodes (self):\\n\",\n    \"\\t\\tmyTree = BinaryTree()\\n\",\n    \"\\t\\tmyTree.insert(5)\\n\",\n    \"\\t\\tmyTree.insert(1)\\n\",\n    \"\\t\\tmyTree.insert(21)\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Test: max node\\\")\\n\",\n    \"\\t\\tself.assertEqual(myTree.maxNode(), 21)\\n\",\n    \"\\t\\tmyTree.insert(32)\\n\",\n    \"\\t\\tself.assertEqual(myTree.maxNode(), 32)\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Test: min node\\\")\\n\",\n    \"\\t\\tself.assertEqual(myTree.minNode(), 1)\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Test: min node inserting negative number\\\")\\n\",\n    \"\\t\\tmyTree.insert(-10)\\n\",\n    \"\\t\\tself.assertEqual(myTree.minNode(), -10)\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Success: test_max_min_nodes\\\")\\n\",\n    \"\\n\",\n    \"\\tdef test_delete (self):\\n\",\n    \"\\t\\tmyTree = BinaryTree()\\n\",\n    \"\\t\\tmyTree.insert(5)\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Test: delete\\\")\\n\",\n    \"\\t\\tmyTree.delete(5)\\n\",\n    \"\\t\\tself.assertEqual(myTree.treeIsEmpty(), True)\\n\",\n    \"\\t\\t\\n\",\n    \"\\t\\tprint(\\\"Test: more complex deletions\\\")\\n\",\n    \"\\t\\t[myTree.insert(x) for x in range(1, 5)]\\n\",\n    \"\\t\\tmyTree.delete(2)\\n\",\n    \"\\t\\tself.assertEqual(myTree.root.rightChild.data, 3)\\n\",\n    \"        \\n\",\n    \"\\t\\tprint(\\\"Test: delete invalid value\\\")\\n\",\n    \"\\t\\tself.assertEqual(myTree.delete(100), False)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Success: test_delete\\\")\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    testing = TestBinaryTree()\\n\",\n    \"    testing.test_insert_traversals()\\n\",\n    \"    testing.test_max_min_nodes()\\n\",\n    \"    testing.test_delete()\\n\",\n    \"    \\n\",\n    \"if __name__=='__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution NoteBook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/binary_tree_implementation/binary_tree_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "staging/graphs_trees/binary_tree/binary_tree_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by Marco Guajardo. Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a binary search tree with insert, delete, different traversals & max/min node values\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"* Is this a binary tree?\\n\",\n    \"  * Yes\\n\",\n    \"* Is the root set to None initially?\\n\",\n    \"  * Yes\\n\",\n    \"* Do we care if the tree is balanced?\\n\",\n    \"  * No\\n\",\n    \"* What do we return for the traversals?\\n\",\n    \"  * Return a list of the data in the desired order\\n\",\n    \"* What type of data can the tree hold?\\n\",\n    \"  * Assume the tree only takes ints. In a realistic example, we'd use a hash table to convert other types to ints.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"### Insert \\n\",\n    \"\\n\",\n    \"* Always start with the root\\n\",\n    \"* If value is less than the root, go to the left child\\n\",\n    \"* if value is more than the root, go to the right child\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"### Delete\\n\",\n    \"\\n\",\n    \"* Deleting a node from a binary tree is tricky. Make sure you arrange the tree correctly when deleting a node.\\n\",\n    \"* Here are some basic [instructions](http://www.algolist.net/Data_structures/Binary_search_tree/Removal)\\n\",\n    \"* If the value to delete isn't on the tree return False\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"### Traversals \\n\",\n    \"\\n\",\n    \"* In order traversal - left, center, right\\n\",\n    \"* Pre order traversal - center, left, right\\n\",\n    \"* Post order traversal - left, right, center\\n\",\n    \"* Return list for all traversals \\n\",\n    \"\\n\",\n    \"### Max & Min\\n\",\n    \"* Find the max node in the binary search tree\\n\",\n    \"* Find the min node in the binary search tree\\n\",\n    \"\\n\",\n    \"### treeIsEmpty\\n\",\n    \"* check if the tree is empty\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook](http://nbviewer.ipython.org/github/donnemartin/interactive-coding-challenges/blob/master/graphs_trees/binary_tree_implementation/binary_tree_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"### Insert\\n\",\n    \"\\n\",\n    \"* If root is none, insert at root\\n\",\n    \"* Else\\n\",\n    \"  * While node is not None\\n\",\n    \"      * if value is less go left child\\n\",\n    \"      * If value is more go right child\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"* Time complexity: O(log(n))\\n\",\n    \"* Space complexity: O(n)\\n\",\n    \"\\n\",\n    \"### Min Node\\n\",\n    \"\\n\",\n    \"* Keep going to the left child until you reach None and return the value\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"* Time complexity: O(log(n))\\n\",\n    \"* Space complexity: O(n)\\n\",\n    \"\\n\",\n    \"### Max Node\\n\",\n    \"\\n\",\n    \"* Keep going to the right child until you reach None and return the value\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"* Time complexity: O(log(n))\\n\",\n    \"* Space complexity: O(n)\\n\",\n    \"\\n\",\n    \"### Traversals\\n\",\n    \"\\n\",\n    \"* In order\\n\",\n    \"  * While the node is not None\\n\",\n    \"      * Call left child recursively\\n\",\n    \"      * Append data\\n\",\n    \"      * Call right child recursively \\n\",\n    \"   \\n\",\n    \"* Post order\\n\",\n    \"  * While the node is not None\\n\",\n    \"      * Call left child recursively\\n\",\n    \"      * Call right child recursively \\n\",\n    \"      * Append data\\n\",\n    \" \\n\",\n    \"* Pre order\\n\",\n    \"  * While the node is not None\\n\",\n    \"      * Append data\\n\",\n    \"      * Call left child recursively\\n\",\n    \"      * Call right child recursively \\n\",\n    \"\\n\",\n    \"\\n\",\n    \"* Time complexity: O(n) for all traversals\\n\",\n    \"* Space complexity: O(n)\\n\",\n    \"\\n\",\n    \"### Delete\\n\",\n    \"\\n\",\n    \"* First, find value to delete\\n\",\n    \"* If value is not in tree \\n\",\n    \"  * Return False\\n\",\n    \"* If value found\\n\",\n    \"  * Check if the node is a left child or right child\\n\",\n    \"    * If node is left child\\n\",\n    \"      * Find the biggest value in all the node's children and replace it with it\\n\",\n    \"    * If node is right child\\n\",\n    \"      * Find the smallest value in all the node's children and replace it with it\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"* Time complexity: O(log(n))\\n\",\n    \"* Space complexity: O(n)\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting binary_search_tree.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile binary_search_tree.py\\n\",\n    \"\\n\",\n    \"class Node (object):\\n\",\n    \"\\tdef __init__ (self, data):\\n\",\n    \"\\t\\tself.data = data\\n\",\n    \"\\t\\tself.rightChild = None\\n\",\n    \"\\t\\tself.leftChild = None\\n\",\n    \"\\n\",\n    \"class BinaryTree (object):\\n\",\n    \"\\tdef __init__ (self):\\n\",\n    \"\\t\\tself.root = None\\n\",\n    \"\\n\",\n    \"\\tdef insert (self, newData):\\n\",\n    \"\\t\\tleaf = Node(newData)\\n\",\n    \"\\n\",\n    \"\\t\\tif self.root is None:\\n\",\n    \"\\t\\t\\tself.root = leaf\\n\",\n    \"\\t\\telse:\\n\",\n    \"\\t\\t\\tcurrent = self.root\\n\",\n    \"\\t\\t\\tparent = self.root\\n\",\n    \"\\t\\t\\twhile current is not None:\\n\",\n    \"\\t\\t\\t\\tparent = current\\n\",\n    \"\\t\\t\\t\\tif newData < current.data:\\n\",\n    \"\\t\\t\\t\\t\\tcurrent = current.leftChild\\n\",\n    \"\\t\\t\\t\\telse:\\n\",\n    \"\\t\\t\\t\\t\\tcurrent = current.rightChild\\n\",\n    \"\\n\",\n    \"\\t\\t\\tif newData < parent.data:\\n\",\n    \"\\t\\t\\t\\tparent.leftChild = leaf\\n\",\n    \"\\t\\t\\telse:\\n\",\n    \"\\t\\t\\t\\tparent.rightChild = leaf\\n\",\n    \"\\n\",\n    \"\\t# returns false if the item to be deleted is not on the tree\\n\",\n    \"\\tdef delete (self, data):\\n\",\n    \"\\t\\tcurrent = self.root\\n\",\n    \"\\t\\tparent = self.root\\n\",\n    \"\\t\\tisLeft = False\\n\",\n    \"\\n\",\n    \"\\t\\tif current is None:\\n\",\n    \"\\t\\t\\treturn False\\n\",\n    \"\\n\",\n    \"\\t\\twhile current is not None and current.data is not data:\\n\",\n    \"\\t\\t\\tparent = current\\n\",\n    \"\\t\\t\\tif data < current.data:\\n\",\n    \"\\t\\t\\t\\tcurrent = current.leftChild\\n\",\n    \"\\t\\t\\t\\tisLeft = True \\n\",\n    \"\\t\\t\\telse:\\n\",\n    \"\\t\\t\\t\\tcurrent = current.rightChild\\n\",\n    \"\\t\\t\\t\\tisLeft = False\\n\",\n    \"\\n\",\n    \"\\t\\tif current is None:\\n\",\n    \"\\t\\t\\treturn False\\n\",\n    \"\\n\",\n    \"\\t\\tif current.leftChild is None and current.rightChild is None:\\n\",\n    \"\\t\\t\\tif current is self.root:\\n\",\n    \"\\t\\t\\t\\tself.root = None\\n\",\n    \"\\t\\t\\telif isLeft:\\n\",\n    \"\\t\\t\\t\\tparent.leftChild = None\\n\",\n    \"\\t\\t\\telse:\\n\",\n    \"\\t\\t\\t\\tparent.rightChild = None\\n\",\n    \"\\n\",\n    \"\\t\\telif current.rightChild is None:\\n\",\n    \"\\t\\t\\tif current is self.root:\\n\",\n    \"\\t\\t\\t\\tself.root = current.leftChild\\n\",\n    \"\\t\\t\\telif isLeft:\\n\",\n    \"\\t\\t\\t\\tparent.leftChild = current.leftChild\\n\",\n    \"\\t\\t\\telse:\\n\",\n    \"\\t\\t\\t\\tparent.rightChild = current.leftChild\\n\",\n    \"\\n\",\n    \"\\t\\telif current.rightChild is None:\\n\",\n    \"\\t\\t\\tif current is self.root:\\n\",\n    \"\\t\\t\\t\\tself.root = current.rightChild\\n\",\n    \"\\t\\t\\telif isLeft:\\n\",\n    \"\\t\\t\\t\\tparent.lChild = current.rightChild\\n\",\n    \"\\t\\t\\telse:\\n\",\n    \"\\t\\t\\t\\tparent.rightChild = current.rightChild\\n\",\n    \"\\n\",\n    \"\\t\\telse:\\n\",\n    \"\\t\\t\\tsuccessor = current.rightChild\\n\",\n    \"\\t\\t\\tsuccessorParent = current\\n\",\n    \"\\n\",\n    \"\\t\\t\\twhile successor.leftChild is not None:\\n\",\n    \"\\t\\t\\t\\tsuccessorParent = successor\\n\",\n    \"\\t\\t\\t\\tsuccessor = successor.leftChild\\n\",\n    \"\\n\",\n    \"\\t\\t\\tif current is self.root:\\n\",\n    \"\\t\\t\\t\\tself.root = successor\\n\",\n    \"\\t\\t\\telif isLeft:\\n\",\n    \"\\t\\t\\t\\tparent.leftChild = successor\\n\",\n    \"\\t\\t\\telse:\\n\",\n    \"\\t\\t\\t\\tparent.rightChild = successor\\n\",\n    \"\\n\",\n    \"\\t\\t\\tsuccessor.leftChild = current.leftChild\\n\",\n    \"\\n\",\n    \"\\t\\t\\tif successor is not current.rightChild:\\n\",\n    \"\\t\\t\\t\\tsuccessorParent.leftChild = successor.rightChild\\n\",\n    \"\\t\\t\\t\\tsuccessor.rightChild = current.rightChild\\n\",\n    \"\\n\",\n    \"\\t\\treturn True \\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\tdef minNode (self):\\n\",\n    \"\\t\\tcurrent = self.root\\n\",\n    \"\\t\\twhile current.leftChild is not None:\\n\",\n    \"\\t\\t\\tcurrent = current.leftChild\\n\",\n    \"\\n\",\n    \"\\t\\treturn current.data\\n\",\n    \"\\n\",\n    \"\\tdef maxNode (self):\\n\",\n    \"\\t\\tcurrent = self.root\\n\",\n    \"\\t\\twhile current.rightChild is not None:\\n\",\n    \"\\t\\t\\tcurrent = current.rightChild\\n\",\n    \"\\n\",\n    \"\\t\\treturn current.data\\n\",\n    \"\\n\",\n    \"\\tdef printPostOrder (self):\\n\",\n    \"\\t\\tglobal postOrder\\n\",\n    \"\\t\\tpostOrder = []\\n\",\n    \"\\n\",\n    \"\\t\\tdef PostOrder(node):\\n\",\n    \"\\t\\t\\tif node is not None:\\n\",\n    \"\\t\\t\\t\\tPostOrder(node.leftChild)\\n\",\n    \"\\t\\t\\t\\tPostOrder(node.rightChild)\\n\",\n    \"\\t\\t\\t\\tpostOrder.append(node.data)\\n\",\n    \"\\n\",\n    \"\\t\\tPostOrder(self.root)\\n\",\n    \"\\t\\treturn postOrder\\n\",\n    \"\\n\",\n    \"\\tdef printInOrder (self):\\n\",\n    \"\\t\\tglobal inOrder \\n\",\n    \"\\t\\tinOrder = []\\n\",\n    \"\\n\",\n    \"\\t\\tdef InOrder (node):\\n\",\n    \"\\t\\t\\tif node is not None:\\n\",\n    \"\\t\\t\\t\\tInOrder(node.leftChild)\\n\",\n    \"\\t\\t\\t\\tinOrder.append(node.data)\\n\",\n    \"\\t\\t\\t\\tInOrder(node.rightChild)\\n\",\n    \"\\n\",\n    \"\\t\\tInOrder(self.root)\\n\",\n    \"\\t\\treturn inOrder\\n\",\n    \"\\n\",\n    \"\\tdef printPreOrder (self):\\n\",\n    \"\\t\\tglobal preOrder\\n\",\n    \"\\t\\tpreOrder = []\\n\",\n    \"\\n\",\n    \"\\t\\tdef PreOrder (node):\\n\",\n    \"\\t\\t\\tif node is not None:\\n\",\n    \"\\t\\t\\t\\tpreOrder.append(node.data)\\n\",\n    \"\\t\\t\\t\\tPreOrder(node.leftChild)\\n\",\n    \"\\t\\t\\t\\tPreOrder(node.rightChild)\\n\",\n    \"\\n\",\n    \"\\t\\tPreOrder(self.root)\\n\",\n    \"\\t\\treturn preOrder\\n\",\n    \"\\n\",\n    \"\\tdef treeIsEmpty (self):\\n\",\n    \"\\t\\treturn self.root is None\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%run binary_search_tree.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_binary_search_tree.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_binary_search_tree.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"class TestBinaryTree(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"\\tdef test_insert_traversals (self):\\n\",\n    \"\\t\\tmyTree = BinaryTree()\\n\",\n    \"\\t\\tmyTree2 = BinaryTree()\\n\",\n    \"\\t\\tfor num in [50, 30, 70, 10, 40, 60, 80, 7, 25, 38]:\\n\",\n    \"\\t\\t\\tmyTree.insert(num)\\n\",\n    \"\\t\\t[myTree2.insert(num) for num in range (1, 100, 10)]\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Test: insert checking with in order traversal\\\")\\n\",\n    \"\\t\\texpectVal = [7, 10, 25, 30, 38, 40, 50, 60, 70, 80]\\n\",\n    \"\\t\\tself.assertEqual(myTree.printInOrder(), expectVal)\\n\",\n    \"\\t\\texpectVal = [1, 11, 21, 31, 41, 51, 61, 71, 81, 91]\\n\",\n    \"\\t\\tself.assertEqual(myTree2.printInOrder(), expectVal)\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Test: insert checking with post order traversal\\\")\\n\",\n    \"\\t\\texpectVal = [7, 25, 10, 38, 40, 30, 60, 80, 70, 50]\\n\",\n    \"\\t\\tself.assertEqual(myTree.printPostOrder(), expectVal)\\n\",\n    \"\\t\\texpectVal = [91, 81, 71, 61, 51, 41, 31, 21, 11, 1]\\n\",\n    \"\\t\\tself.assertEqual(myTree2.printPostOrder(), expectVal)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Test: insert checking with pre order traversal\\\")\\n\",\n    \"\\t\\texpectVal = [50, 30, 10, 7, 25, 40, 38, 70, 60, 80]\\n\",\n    \"\\t\\tself.assertEqual(myTree.printPreOrder(), expectVal)\\n\",\n    \"\\t\\texpectVal = [1, 11, 21, 31, 41, 51, 61, 71, 81, 91]\\n\",\n    \"\\t\\tself.assertEqual(myTree2.printPreOrder(), expectVal)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Success: test_insert_traversals\\\")\\n\",\n    \"\\n\",\n    \"\\tdef test_max_min_nodes (self):\\n\",\n    \"\\t\\tmyTree = BinaryTree()\\n\",\n    \"\\t\\tmyTree.insert(5)\\n\",\n    \"\\t\\tmyTree.insert(1)\\n\",\n    \"\\t\\tmyTree.insert(21)\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Test: max node\\\")\\n\",\n    \"\\t\\tself.assertEqual(myTree.maxNode(), 21)\\n\",\n    \"\\t\\tmyTree.insert(32)\\n\",\n    \"\\t\\tself.assertEqual(myTree.maxNode(), 32)\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Test: min node\\\")\\n\",\n    \"\\t\\tself.assertEqual(myTree.minNode(), 1)\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Test: min node inserting negative number\\\")\\n\",\n    \"\\t\\tmyTree.insert(-10)\\n\",\n    \"\\t\\tself.assertEqual(myTree.minNode(), -10)\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Success: test_max_min_nodes\\\")\\n\",\n    \"\\n\",\n    \"\\tdef test_delete (self):\\n\",\n    \"\\t\\tmyTree = BinaryTree()\\n\",\n    \"\\t\\tmyTree.insert(5)\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Test: delete\\\")\\n\",\n    \"\\t\\tmyTree.delete(5)\\n\",\n    \"\\t\\tself.assertEqual(myTree.treeIsEmpty(), True)\\n\",\n    \"\\t\\t\\n\",\n    \"\\t\\tprint(\\\"Test: more complex deletions\\\")\\n\",\n    \"\\t\\t[myTree.insert(x) for x in range(1, 5)]\\n\",\n    \"\\t\\tmyTree.delete(2)\\n\",\n    \"\\t\\tself.assertEqual(myTree.root.rightChild.data, 3)\\n\",\n    \"        \\n\",\n    \"\\t\\tprint(\\\"Test: delete invalid value\\\")\\n\",\n    \"\\t\\tself.assertEqual(myTree.delete(100), False)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"\\t\\tprint(\\\"Success: test_delete\\\")\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    testing = TestBinaryTree()\\n\",\n    \"    testing.test_insert_traversals()\\n\",\n    \"    testing.test_max_min_nodes()\\n\",\n    \"    testing.test_delete()\\n\",\n    \"    \\n\",\n    \"if __name__=='__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Test: insert checking with in order traversal\\n\",\n      \"Test: insert checking with post order traversal\\n\",\n      \"Test: insert checking with pre order traversal\\n\",\n      \"Success: test_insert_traversals\\n\",\n      \"Test: max node\\n\",\n      \"Test: min node\\n\",\n      \"Test: min node inserting negative number\\n\",\n      \"Success: test_max_min_nodes\\n\",\n      \"Test: delete\\n\",\n      \"Test: more complex deletions\\n\",\n      \"Test: delete invalid value\\n\",\n      \"Success: test_delete\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_binary_search_tree.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "staging/graphs_trees/binary_tree/test_binary_search_tree.py",
    "content": "import unittest\n\nclass TestBinaryTree(unittest.TestCase):\n\n\tdef test_insert_traversals (self):\n\t\tmyTree = BinaryTree()\n\t\tmyTree2 = BinaryTree()\n\t\tfor num in [50, 30, 70, 10, 40, 60, 80, 7, 25, 38]:\n\t\t\tmyTree.insert(num)\n\t\t[myTree2.insert(num) for num in range (1, 100, 10)]\n\n\t\tprint(\"Test: insert checking with in order traversal\")\n\t\texpectVal = [7, 10, 25, 30, 38, 40, 50, 60, 70, 80]\n\t\tself.assertEqual(myTree.printInOrder(), expectVal)\n\t\texpectVal = [1, 11, 21, 31, 41, 51, 61, 71, 81, 91]\n\t\tself.assertEqual(myTree2.printInOrder(), expectVal)\n\n\t\tprint(\"Test: insert checking with post order traversal\")\n\t\texpectVal = [7, 25, 10, 38, 40, 30, 60, 80, 70, 50]\n\t\tself.assertEqual(myTree.printPostOrder(), expectVal)\n\t\texpectVal = [91, 81, 71, 61, 51, 41, 31, 21, 11, 1]\n\t\tself.assertEqual(myTree2.printPostOrder(), expectVal)\n\n\n\t\tprint(\"Test: insert checking with pre order traversal\")\n\t\texpectVal = [50, 30, 10, 7, 25, 40, 38, 70, 60, 80]\n\t\tself.assertEqual(myTree.printPreOrder(), expectVal)\n\t\texpectVal = [1, 11, 21, 31, 41, 51, 61, 71, 81, 91]\n\t\tself.assertEqual(myTree2.printPreOrder(), expectVal)\n\n\n\t\tprint(\"Success: test_insert_traversals\")\n\n\tdef test_max_min_nodes (self):\n\t\tmyTree = BinaryTree()\n\t\tmyTree.insert(5)\n\t\tmyTree.insert(1)\n\t\tmyTree.insert(21)\n\n\t\tprint(\"Test: max node\")\n\t\tself.assertEqual(myTree.maxNode(), 21)\n\t\tmyTree.insert(32)\n\t\tself.assertEqual(myTree.maxNode(), 32)\n\n\t\tprint(\"Test: min node\")\n\t\tself.assertEqual(myTree.minNode(), 1)\n\n\t\tprint(\"Test: min node inserting negative number\")\n\t\tmyTree.insert(-10)\n\t\tself.assertEqual(myTree.minNode(), -10)\n\n\t\tprint(\"Success: test_max_min_nodes\")\n\n\tdef test_delete (self):\n\t\tmyTree = BinaryTree()\n\t\tmyTree.insert(5)\n\n\t\tprint(\"Test: delete\")\n\t\tmyTree.delete(5)\n\t\tself.assertEqual(myTree.treeIsEmpty(), True)\n\t\t\n\t\tprint(\"Test: more complex deletions\")\n\t\t[myTree.insert(x) for x in range(1, 5)]\n\t\tmyTree.delete(2)\n\t\tself.assertEqual(myTree.root.rightChild.data, 3)\n        \n\t\tprint(\"Test: delete invalid value\")\n\t\tself.assertEqual(myTree.delete(100), False)\n\n\n\t\tprint(\"Success: test_delete\")\n\ndef main():\n    testing = TestBinaryTree()\n    testing.test_insert_traversals()\n    testing.test_max_min_nodes()\n    testing.test_delete()\n    \nif __name__=='__main__':\n    main()\n"
  },
  {
    "path": "staging/linked_lists/__init__.py",
    "content": ""
  },
  {
    "path": "staging/online_judges/__init__.py",
    "content": ""
  },
  {
    "path": "staging/recursion_dynamic/__init__.py",
    "content": ""
  },
  {
    "path": "staging/sorting_searching/__init__.py",
    "content": ""
  },
  {
    "path": "staging/sorting_searching/group_ordered/__init__.py",
    "content": ""
  },
  {
    "path": "staging/sorting_searching/group_ordered/group_ordered_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [wdonahoe](https://github.com/wdonahoe). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a function that groups identical items based on their order in the list.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we use extra data structures?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* group_ordered([1,2,1,3,2])     ->     [1,1,2,2,3]\\n\",\n    \"* group_ordered(['a','b','a')    ->     ['a','a','b']\\n\",\n    \"* group_ordered([1,1,2,3,4,5,2,1]->     [1,1,1,2,2,3,4,5]\\n\",\n    \"* group_ordered([])              ->     []\\n\",\n    \"* group_ordered([1])             ->     [1]\\n\",\n    \"* group_ordered(None)            ->     None\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [solution notebook](https://github.com/donnemartin/interactive-coding-challenges/templates/foo_solution.ipynb).  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def group_ordered(list_in):\\n\",\n    \"    # TODO: Implement me\\n\",\n    \"    pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"# %load test_group_ordered.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestGroupOrdered(unittest.TestCase):\\n\",\n    \"    def test_group_ordered(self, func):\\n\",\n    \"\\n\",\n    \"        self.assertEqual(func(None), None)\\n\",\n    \"        print('Success: ' + func.__name__ + \\\" None case.\\\")\\n\",\n    \"        self.assertEqual(func([]), [])\\n\",\n    \"        print('Success: ' + func.__name__ + \\\" Empty case.\\\")\\n\",\n    \"        self.assertEqual(func([1]), [1])\\n\",\n    \"        print('Success: ' + func.__name__ + \\\" Single element case.\\\")\\n\",\n    \"        self.assertEqual(func([1, 2, 1, 3, 2]), [1, 1, 2, 2, 3])\\n\",\n    \"        self.assertEqual(func(['a', 'b', 'a']), ['a', 'a', 'b'])\\n\",\n    \"        self.assertEqual(func([1, 1, 2, 3, 4, 5, 2, 1]), [1, 1, 1, 2, 2, 3, 4, 5])\\n\",\n    \"        self.assertEqual(func([1, 2, 3, 4, 3, 4]), [1, 2, 3, 3, 4, 4])\\n\",\n    \"        print('Success: ' + func.__name__)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestGroupOrdered()\\n\",\n    \"    test.test_group_ordered(group_ordered)\\n\",\n    \"    try:\\n\",\n    \"        test.test_group_ordered(group_ordered_alt)\\n\",\n    \"    except NameError:\\n\",\n    \"        # Alternate solutions are only defined\\n\",\n    \"        # in the solutions file\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [solution notebook](https://github.com/donnemartin/interactive-coding-challenges/sorting_searching/group_ordered/group_ordered_solution.ipynb) for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "staging/sorting_searching/group_ordered/group_ordered_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [wdonahoe](https://github.com/wdonahoe). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement a function that groups identical items based on their order in the list.\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm: Modified Selection Sort](#Algorithm: Modified Selection Sort)\\n\",\n    \"* [Code: Modified Selection Sort](#Code: Modified Selection Sort)\\n\",\n    \"* [Algorithm: Ordered Dict](#Algorithm: Ordered Dict)\\n\",\n    \"* [Code: Ordered Dict](#Code:-Ordered-Dict)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Can we use extra data structures?\\n\",\n    \"    * Yes\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* group_ordered([1,2,1,3,2]) -> [1,1,2,2,3]\\n\",\n    \"* group_ordered(['a','b','a') -> ['a','a','b']\\n\",\n    \"* group_ordered([1,1,2,3,4,5,2,1]-> [1,1,1,2,2,3,4,5]\\n\",\n    \"* group_ordered([]) -> []\\n\",\n    \"* group_ordered([1]) -> [1]\\n\",\n    \"* group_ordered(None) -> None\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm: Modified Selection Sort\\n\",\n    \"\\n\",\n    \"* Save the relative position of the first-occurrence of each item in a list.\\n\",\n    \"* Iterate through list of unique items.\\n\",\n    \"    * Keep an outer index; scan rest of list, swapping matching items with outer index and incrementing outer index each time. \\n\",\n    \"    \\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(n^2)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Code: Modified Selection Sort\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def make_order_list(list_in):\\n\",\n    \"    order_list = []\\n\",\n    \"    for item in list_in:\\n\",\n    \"        if item not in order_list:\\n\",\n    \"            order_list.append(item)\\n\",\n    \"    return order_list\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def group_ordered(list_in):\\n\",\n    \"    if list_in is None:\\n\",\n    \"        return None\\n\",\n    \"    order_list = make_order_list(list_in)\\n\",\n    \"    current = 0\\n\",\n    \"    for item in order_list:\\n\",\n    \"        search = current + 1\\n\",\n    \"        while True:\\n\",\n    \"            try:\\n\",\n    \"                if list_in[search] != item:\\n\",\n    \"                    search += 1\\n\",\n    \"                else:\\n\",\n    \"                    current += 1\\n\",\n    \"                    list_in[current], list_in[search] = list_in[search], list_in[current]\\n\",\n    \"                    search += 1\\n\",\n    \"            except IndexError:\\n\",\n    \"                break\\n\",\n    \"    return list_in\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm: Ordered Dict.\\n\",\n    \"\\n\",\n    \"* Use an ordered dict to track insertion order of each key\\n\",\n    \"* Flatten list of values.\\n\",\n    \"\\n\",\n    \"Complexity:\\n\",\n    \"\\n\",\n    \"* Time: O(n)\\n\",\n    \"* Space: O(n)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code: Ordered Dict\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"from collections import OrderedDict\\n\",\n    \"\\n\",\n    \"def group_ordered_alt(list_in):\\n\",\n    \"    if list_in is None:\\n\",\n    \"        return None\\n\",\n    \"    result = OrderedDict()\\n\",\n    \"    for value in list_in:\\n\",\n    \"        result.setdefault(value, []).append(value)\\n\",\n    \"    return [v for group in result.values() for v in group]\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\\n\",\n    \"\\n\",\n    \"#### The following unit test is expected to fail until you solve the challenge.\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_group_ordered.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_group_ordered.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestGroupOrdered(unittest.TestCase):\\n\",\n    \"    def test_group_ordered(self, func):\\n\",\n    \"\\n\",\n    \"        self.assertEqual(func(None), None)\\n\",\n    \"        print('Success: ' + func.__name__ + \\\" None case.\\\")\\n\",\n    \"        self.assertEqual(func([]), [])\\n\",\n    \"        print('Success: ' + func.__name__ + \\\" Empty case.\\\")\\n\",\n    \"        self.assertEqual(func([1]), [1])\\n\",\n    \"        print('Success: ' + func.__name__ + \\\" Single element case.\\\")\\n\",\n    \"        self.assertEqual(func([1, 2, 1, 3, 2]), [1, 1, 2, 2, 3])\\n\",\n    \"        self.assertEqual(func(['a', 'b', 'a']), ['a', 'a', 'b'])\\n\",\n    \"        self.assertEqual(func([1, 1, 2, 3, 4, 5, 2, 1]), [1, 1, 1, 2, 2, 3, 4, 5])\\n\",\n    \"        self.assertEqual(func([1, 2, 3, 4, 3, 4]), [1, 2, 3, 3, 4, 4])\\n\",\n    \"        print('Success: ' + func.__name__)\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestGroupOrdered()\\n\",\n    \"    test.test_group_ordered(group_ordered)\\n\",\n    \"    try:\\n\",\n    \"        test.test_group_ordered(group_ordered_alt)\\n\",\n    \"    except NameError:\\n\",\n    \"        # Alternate solutions are only defined\\n\",\n    \"        # in the solutions file\\n\",\n    \"        pass\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: group_ordered None case.\\n\",\n      \"Success: group_ordered Empty case.\\n\",\n      \"Success: group_ordered Single element case.\\n\",\n      \"Success: group_ordered\\n\",\n      \"Success: group_ordered_alt None case.\\n\",\n      \"Success: group_ordered_alt Empty case.\\n\",\n      \"Success: group_ordered_alt Single element case.\\n\",\n      \"Success: group_ordered_alt\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_group_ordered.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "staging/sorting_searching/group_ordered/test_group_ordered.py",
    "content": "import unittest\n\n\nclass TestGroupOrdered(unittest.TestCase):\n    def test_group_ordered(self, func):\n\n        self.assertEqual(func(None), None)\n        print('Success: ' + func.__name__ + \" None case.\")\n        self.assertEqual(func([]), [])\n        print('Success: ' + func.__name__ + \" Empty case.\")\n        self.assertEqual(func([1]), [1])\n        print('Success: ' + func.__name__ + \" Single element case.\")\n        self.assertEqual(func([1, 2, 1, 3, 2]), [1, 1, 2, 2, 3])\n        self.assertEqual(func(['a', 'b', 'a']), ['a', 'a', 'b'])\n        self.assertEqual(func([1, 1, 2, 3, 4, 5, 2, 1]), [1, 1, 1, 2, 2, 3, 4, 5])\n        self.assertEqual(func([1, 2, 3, 4, 3, 4]), [1, 2, 3, 3, 4, 4])\n        print('Success: ' + func.__name__)\n\n\ndef main():\n    test = TestGroupOrdered()\n    test.test_group_ordered(group_ordered)\n    try:\n        test.test_group_ordered(group_ordered_alt)\n    except NameError:\n        # Alternate solutions are only defined\n        # in the solutions file\n        pass\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "staging/stacks_queues/__init__.py",
    "content": ""
  },
  {
    "path": "templates/__init__.py",
    "content": ""
  },
  {
    "path": "templates/foo_challenge.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Author](https://github.com/). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Challenge Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement foo(val), which returns val\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\\n\",\n    \"* [Solution Notebook](#Solution-Notebook)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Does foo do anything else?\\n\",\n    \"    * No\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* foo(val) -> val\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Refer to the [Solution Notebook]().  If you are stuck and need a hint, the solution notebook's algorithm discussion might be a good place to start.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def foo(val):\\n\",\n    \"    # TODO: Implement me\\n\",\n    \"    pass\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"**The following unit test is expected to fail until you solve the challenge.**\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"%load test_foo.py\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Solution Notebook\\n\",\n    \"\\n\",\n    \"Review the [Solution Notebook]() for a discussion on algorithms and code solutions.\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "templates/foo_solution.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This notebook was prepared by [Author](https://github.com/). Source and license info is on [GitHub](https://github.com/donnemartin/interactive-coding-challenges).\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Solution Notebook\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Problem: Implement foo(val), which returns val\\n\",\n    \"\\n\",\n    \"* [Constraints](#Constraints)\\n\",\n    \"* [Test Cases](#Test-Cases)\\n\",\n    \"* [Algorithm](#Algorithm)\\n\",\n    \"* [Code](#Code)\\n\",\n    \"* [Unit Test](#Unit-Test)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Constraints\\n\",\n    \"\\n\",\n    \"* Does foo do anything else?\\n\",\n    \"    * No\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Test Cases\\n\",\n    \"\\n\",\n    \"* foo(val) -> val\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Algorithm\\n\",\n    \"\\n\",\n    \"Return the input, val\\n\",\n    \"    \\n\",\n    \"Complexity:\\n\",\n    \"* Time: O(1)\\n\",\n    \"* Space: O(1)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Code\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": [\n    \"def foo(val):\\n\",\n    \"    return val\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Unit Test\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Overwriting test_foo.py\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%%writefile test_foo.py\\n\",\n    \"import unittest\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"class TestFoo(unittest.TestCase):\\n\",\n    \"\\n\",\n    \"    def test_foo(self):\\n\",\n    \"        self.assertEqual(foo(None), None)\\n\",\n    \"        self.assertEqual(foo(0), 0)\\n\",\n    \"        self.assertEqual(foo('bar'), 'bar')\\n\",\n    \"        print('Success: test_foo')\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"def main():\\n\",\n    \"    test = TestFoo()\\n\",\n    \"    test.test_foo()\\n\",\n    \"\\n\",\n    \"\\n\",\n    \"if __name__ == '__main__':\\n\",\n    \"    main()\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {},\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"Success: test_foo\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"%run -i test_foo.py\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.7.2\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n"
  },
  {
    "path": "templates/test_foo.py",
    "content": "import unittest\n\n\nclass TestFoo(unittest.TestCase):\n\n    def test_foo(self):\n        self.assertEqual(foo(None), None)\n        self.assertEqual(foo(0), 0)\n        self.assertEqual(foo('bar'), 'bar')\n        print('Success: test_foo')\n\n\ndef main():\n    test = TestFoo()\n    test.test_foo()\n\n\nif __name__ == '__main__':\n    main()\n"
  }
]