From 0e1bac0c10dfe263f784ede822737276d80d922b Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Sun, 17 Mar 2019 00:20:41 -0700 Subject: [PATCH 01/20] modified folder names to show order correctly. --- .../11. Container With Most Water.ipynb | 0 .../12. Integer to Roman.ipynb | 0 .../242. Valid Anagram.ipynb | 0 .../303. Range Sum Query - Immutable.ipynb | 0 .../304. Range Sum Query 2D - Immutable.ipynb | 0 .../4_median_twosortedarrays.py | 0 .../5. Longest Palindromic Substring.ipynb | 0 .../6. ZigZag Conversion.ipynb | 0 .../.ipynb_checkpoints/debug_testing-checkpoint.ipynb | 0 {7.Reverse_integer => 7. Reverse_integer}/README.md | 0 {7.Reverse_integer => 7. Reverse_integer}/Reverse_Integer.py | 0 {7.Reverse_integer => 7. Reverse_integer}/__init__.py | 0 {7.Reverse_integer => 7. Reverse_integer}/debug_testing.ipynb | 0 {7.Reverse_integer => 7. Reverse_integer}/test_Reverse_integer.py | 0 .../.ipynb_checkpoints/8. String to Integer-checkpoint.ipynb | 0 .../8. String to Integer.ipynb | 0 {8.String2Integer => 8. String2Integer}/README.md | 0 {824.Goat_Latin => 824. Goat_Latin}/824. Goat Latin.ipynb | 0 18 files changed, 0 insertions(+), 0 deletions(-) rename {11.Container_with_most_water => 11. Container_with_most_water}/11. Container With Most Water.ipynb (100%) rename {12.Integer_to_Roman => 12. Integer_to_Roman}/12. Integer to Roman.ipynb (100%) rename {242.Valid_Anagram => 242. Valid_Anagram}/242. Valid Anagram.ipynb (100%) rename {303.Range_Sum_Query => 303. Range_Sum_Query}/303. Range Sum Query - Immutable.ipynb (100%) rename {304.Range_Sum_Query_2D => 304. Range_Sum_Query_2D}/304. Range Sum Query 2D - Immutable.ipynb (100%) rename {4.Median_TwoSortedArrays => 4. Median_TwoSortedArrays}/4_median_twosortedarrays.py (100%) rename {5.Longest_Palindromic_Substring => 5. Longest_Palindromic_Substring}/5. Longest Palindromic Substring.ipynb (100%) rename {6.ZigZag_Conversion => 6. ZigZag_Conversion}/6. ZigZag Conversion.ipynb (100%) rename {7.Reverse_integer => 7. Reverse_integer}/.ipynb_checkpoints/debug_testing-checkpoint.ipynb (100%) rename {7.Reverse_integer => 7. Reverse_integer}/README.md (100%) rename {7.Reverse_integer => 7. Reverse_integer}/Reverse_Integer.py (100%) rename {7.Reverse_integer => 7. Reverse_integer}/__init__.py (100%) rename {7.Reverse_integer => 7. Reverse_integer}/debug_testing.ipynb (100%) rename {7.Reverse_integer => 7. Reverse_integer}/test_Reverse_integer.py (100%) rename {8.String2Integer => 8. String2Integer}/.ipynb_checkpoints/8. String to Integer-checkpoint.ipynb (100%) rename {8.String2Integer => 8. String2Integer}/8. String to Integer.ipynb (100%) rename {8.String2Integer => 8. String2Integer}/README.md (100%) rename {824.Goat_Latin => 824. Goat_Latin}/824. Goat Latin.ipynb (100%) diff --git a/11.Container_with_most_water/11. Container With Most Water.ipynb b/11. Container_with_most_water/11. Container With Most Water.ipynb similarity index 100% rename from 11.Container_with_most_water/11. Container With Most Water.ipynb rename to 11. Container_with_most_water/11. Container With Most Water.ipynb diff --git a/12.Integer_to_Roman/12. Integer to Roman.ipynb b/12. Integer_to_Roman/12. Integer to Roman.ipynb similarity index 100% rename from 12.Integer_to_Roman/12. Integer to Roman.ipynb rename to 12. Integer_to_Roman/12. Integer to Roman.ipynb diff --git a/242.Valid_Anagram/242. Valid Anagram.ipynb b/242. Valid_Anagram/242. Valid Anagram.ipynb similarity index 100% rename from 242.Valid_Anagram/242. Valid Anagram.ipynb rename to 242. Valid_Anagram/242. Valid Anagram.ipynb diff --git a/303.Range_Sum_Query/303. Range Sum Query - Immutable.ipynb b/303. Range_Sum_Query/303. Range Sum Query - Immutable.ipynb similarity index 100% rename from 303.Range_Sum_Query/303. Range Sum Query - Immutable.ipynb rename to 303. Range_Sum_Query/303. Range Sum Query - Immutable.ipynb diff --git a/304.Range_Sum_Query_2D/304. Range Sum Query 2D - Immutable.ipynb b/304. Range_Sum_Query_2D/304. Range Sum Query 2D - Immutable.ipynb similarity index 100% rename from 304.Range_Sum_Query_2D/304. Range Sum Query 2D - Immutable.ipynb rename to 304. Range_Sum_Query_2D/304. Range Sum Query 2D - Immutable.ipynb diff --git a/4.Median_TwoSortedArrays/4_median_twosortedarrays.py b/4. Median_TwoSortedArrays/4_median_twosortedarrays.py similarity index 100% rename from 4.Median_TwoSortedArrays/4_median_twosortedarrays.py rename to 4. Median_TwoSortedArrays/4_median_twosortedarrays.py diff --git a/5.Longest_Palindromic_Substring/5. Longest Palindromic Substring.ipynb b/5. Longest_Palindromic_Substring/5. Longest Palindromic Substring.ipynb similarity index 100% rename from 5.Longest_Palindromic_Substring/5. Longest Palindromic Substring.ipynb rename to 5. Longest_Palindromic_Substring/5. Longest Palindromic Substring.ipynb diff --git a/6.ZigZag_Conversion/6. ZigZag Conversion.ipynb b/6. ZigZag_Conversion/6. ZigZag Conversion.ipynb similarity index 100% rename from 6.ZigZag_Conversion/6. ZigZag Conversion.ipynb rename to 6. ZigZag_Conversion/6. ZigZag Conversion.ipynb diff --git a/7.Reverse_integer/.ipynb_checkpoints/debug_testing-checkpoint.ipynb b/7. Reverse_integer/.ipynb_checkpoints/debug_testing-checkpoint.ipynb similarity index 100% rename from 7.Reverse_integer/.ipynb_checkpoints/debug_testing-checkpoint.ipynb rename to 7. Reverse_integer/.ipynb_checkpoints/debug_testing-checkpoint.ipynb diff --git a/7.Reverse_integer/README.md b/7. Reverse_integer/README.md similarity index 100% rename from 7.Reverse_integer/README.md rename to 7. Reverse_integer/README.md diff --git a/7.Reverse_integer/Reverse_Integer.py b/7. Reverse_integer/Reverse_Integer.py similarity index 100% rename from 7.Reverse_integer/Reverse_Integer.py rename to 7. Reverse_integer/Reverse_Integer.py diff --git a/7.Reverse_integer/__init__.py b/7. Reverse_integer/__init__.py similarity index 100% rename from 7.Reverse_integer/__init__.py rename to 7. Reverse_integer/__init__.py diff --git a/7.Reverse_integer/debug_testing.ipynb b/7. Reverse_integer/debug_testing.ipynb similarity index 100% rename from 7.Reverse_integer/debug_testing.ipynb rename to 7. Reverse_integer/debug_testing.ipynb diff --git a/7.Reverse_integer/test_Reverse_integer.py b/7. Reverse_integer/test_Reverse_integer.py similarity index 100% rename from 7.Reverse_integer/test_Reverse_integer.py rename to 7. Reverse_integer/test_Reverse_integer.py diff --git a/8.String2Integer/.ipynb_checkpoints/8. String to Integer-checkpoint.ipynb b/8. String2Integer/.ipynb_checkpoints/8. String to Integer-checkpoint.ipynb similarity index 100% rename from 8.String2Integer/.ipynb_checkpoints/8. String to Integer-checkpoint.ipynb rename to 8. String2Integer/.ipynb_checkpoints/8. String to Integer-checkpoint.ipynb diff --git a/8.String2Integer/8. String to Integer.ipynb b/8. String2Integer/8. String to Integer.ipynb similarity index 100% rename from 8.String2Integer/8. String to Integer.ipynb rename to 8. String2Integer/8. String to Integer.ipynb diff --git a/8.String2Integer/README.md b/8. String2Integer/README.md similarity index 100% rename from 8.String2Integer/README.md rename to 8. String2Integer/README.md diff --git a/824.Goat_Latin/824. Goat Latin.ipynb b/824. Goat_Latin/824. Goat Latin.ipynb similarity index 100% rename from 824.Goat_Latin/824. Goat Latin.ipynb rename to 824. Goat_Latin/824. Goat Latin.ipynb From bdd8013e69f00b9bcb851e7d5aa172c68bd2142b Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Fri, 26 Apr 2019 23:39:43 -0700 Subject: [PATCH 02/20] two methods in python for leetcode question number 807. --- ...ease_to_Keep_City_Skyline-checkpoint.ipynb | 396 ++++++++++++++++++ .../Max_Increase_to_Keep_City_Skyline.ipynb | 396 ++++++++++++++++++ 2 files changed, 792 insertions(+) create mode 100644 807. Max Increase to Keep City Skyline/.ipynb_checkpoints/Max_Increase_to_Keep_City_Skyline-checkpoint.ipynb create mode 100644 807. Max Increase to Keep City Skyline/Max_Increase_to_Keep_City_Skyline.ipynb diff --git a/807. Max Increase to Keep City Skyline/.ipynb_checkpoints/Max_Increase_to_Keep_City_Skyline-checkpoint.ipynb b/807. Max Increase to Keep City Skyline/.ipynb_checkpoints/Max_Increase_to_Keep_City_Skyline-checkpoint.ipynb new file mode 100644 index 0000000..379d235 --- /dev/null +++ b/807. Max Increase to Keep City Skyline/.ipynb_checkpoints/Max_Increase_to_Keep_City_Skyline-checkpoint.ipynb @@ -0,0 +1,396 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Python 3.7.1\r\n" + ] + } + ], + "source": [ + "!python --version" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\nIn a 2 dimensional array grid, each value grid[i][j] represents the \\nheight of a building located there. We are allowed to increase the \\nheight of any number of buildings, by any amount (the amounts can be \\ndifferent for different buildings). Height 0 is considered to be a \\nbuilding as well. \\n\\nAt the end, the \"skyline\" when viewed from all four directions of \\nthe grid, i.e. top, bottom, left, and right, must be the same as \\nthe skyline of the original grid. A city\\'s skyline is the outer \\ncontour of the rectangles formed by all the buildings when viewed \\nfrom a distance. See the following example.\\n\\nWhat is the maximum total sum that the height of the buildings can \\nbe increased?\\n\\n\\nExample:\\nInput: grid = [[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]]\\nOutput: 35\\nExplanation: \\nThe grid is:\\n[ [3, 0, 8, 4], \\n [2, 4, 5, 7],\\n [9, 2, 6, 3],\\n [0, 3, 1, 0] ]\\n\\nThe skyline viewed from top or bottom is: [9, 4, 8, 7]\\nThe skyline viewed from left or right is: [8, 7, 9, 3]\\n\\nThe grid after increasing the height of buildings without affecting skylines is:\\n\\ngridNew = [ [8, 4, 8, 7],\\n [7, 4, 7, 7],\\n [9, 4, 8, 7],\\n [3, 3, 3, 3] ]\\n\\nlink:\\nhttps://leetcode.com/problems/max-increase-to-keep-city-skyline/\\n'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"\"\"\n", + "In a 2 dimensional array grid, each value grid[i][j] represents the \n", + "height of a building located there. We are allowed to increase the \n", + "height of any number of buildings, by any amount (the amounts can be \n", + "different for different buildings). Height 0 is considered to be a \n", + "building as well. \n", + "\n", + "At the end, the \"skyline\" when viewed from all four directions of \n", + "the grid, i.e. top, bottom, left, and right, must be the same as \n", + "the skyline of the original grid. A city's skyline is the outer \n", + "contour of the rectangles formed by all the buildings when viewed \n", + "from a distance. See the following example.\n", + "\n", + "What is the maximum total sum that the height of the buildings can \n", + "be increased?\n", + "\n", + "\n", + "Example:\n", + "Input: grid = [[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]]\n", + "Output: 35\n", + "Explanation: \n", + "The grid is:\n", + "[ [3, 0, 8, 4], \n", + " [2, 4, 5, 7],\n", + " [9, 2, 6, 3],\n", + " [0, 3, 1, 0] ]\n", + "\n", + "The skyline viewed from top or bottom is: [9, 4, 8, 7]\n", + "The skyline viewed from left or right is: [8, 7, 9, 3]\n", + "\n", + "The grid after increasing the height of buildings without affecting skylines is:\n", + "\n", + "gridNew = [ [8, 4, 8, 7],\n", + " [7, 4, 7, 7],\n", + " [9, 4, 8, 7],\n", + " [3, 3, 3, 3] ]\n", + "\n", + "link:\n", + "https://leetcode.com/problems/max-increase-to-keep-city-skyline/\n", + "\"\"\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Solution 1\n", + "The idea is straight forward, height of each cell is bounded by two conditions: (max in the row, max in the col). \n", + "The challenge will be, how to find and fill it efficiently. \n", + "The first solution here, we use brutal force to begin with." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[9, 4, 8, 7]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# def maxIncreaseKeepingSkyline(grid):\n", + "grid = [ [3, 0, 8, 4], \n", + " [2, 4, 5, 7],\n", + " [9, 2, 6, 3],\n", + " [0, 3, 1, 0] ]\n", + "total_init = sum([sum(content) for content in grid])\n", + "max_col = [0] * len(grid)\n", + "# iterate through colum, bcz max(list) is easy to call\n", + "for col in range(len(grid)):\n", + " for row in range(len(grid)):\n", + " if grid[row][col] > max_col[col]:\n", + " max_col[col] = grid[row][col]\n", + "\n", + "max_col" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "gridNew = grid[:]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[3, 0, 8, 4], [2, 4, 5, 7], [9, 2, 6, 3], [0, 3, 1, 0]]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gridNew2 = grid.copy() # notice that [[0]*4]*4 will give error at the end\n", + "gridNew2" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 0 9 8 8\n", + "0 1 4 8 4\n", + "0 2 8 8 8\n", + "0 3 7 8 7\n", + "1 0 9 7 7\n", + "1 1 4 7 4\n", + "1 2 8 7 7\n", + "1 3 7 7 7\n", + "2 0 9 9 9\n", + "2 1 4 9 4\n", + "2 2 8 9 8\n", + "2 3 7 9 7\n", + "3 0 9 3 3\n", + "3 1 4 3 3\n", + "3 2 8 3 3\n", + "3 3 7 3 3\n" + ] + }, + { + "data": { + "text/plain": [ + "[[8, 4, 8, 7], [7, 4, 7, 7], [9, 4, 8, 7], [3, 3, 3, 3]]" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "for row in range(len(grid)):\n", + " for col in range(len(grid)):\n", + " # new grid is bounded by max in col and max in row\n", + " gridNew[row][col] = min(max_col[col], max(grid[row]))\n", + " print(row, col, max_col[col], max(grid[row]), gridNew[row][col]) \n", + " \n", + "gridNew" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[8, 4, 8, 7], [7, 4, 7, 7], [9, 4, 8, 7], [3, 3, 3, 3]]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "grid # well.. due to the python copy problem..you will need deepcopy to \n", + " # generate a new copy with brand new pointer...\n", + " # ref: https://stackoverflow.com/questions/13783315/sum-of-list-of-lists-returns-sum-list\n", + " # a easier way here is to calculate total_init at the begining." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "57 92\n" + ] + }, + { + "data": { + "text/plain": [ + "35" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "total_new = sum([sum(content) for content in gridNew])\n", + "print(total_init, total_new)\n", + "total_increase = total_new - total_init\n", + "total_increase" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# put into a function:\n", + "class Solution(object):\n", + " def maxIncreaseKeepingSkyline(self, grid):\n", + " \"\"\"\n", + " :type grid: List[List[int]]\n", + " :rtype: int\n", + " \"\"\"\n", + " total_init = sum([sum(content) for content in grid])\n", + " max_col = [0] * len(grid)\n", + " # iterate through colum, bcz max(list) is easy to call\n", + " for col in range(len(grid)):\n", + " for row in range(len(grid)):\n", + " if grid[row][col] > max_col[col]:\n", + " max_col[col] = grid[row][col]\n", + " \n", + " gridNew = grid[:]\n", + " for row in range(len(grid)):\n", + " for col in range(len(grid)):\n", + " # new grid is bounded by max in col and max in row\n", + " gridNew[row][col] = min(max_col[col], max(grid[row]))\n", + " \n", + " total_new = sum([sum(content) for content in gridNew])\n", + " total_increase = total_new - total_init \n", + " return total_increase\n", + " \n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "35" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "grid = [ [3, 0, 8, 4], \n", + " [2, 4, 5, 7],\n", + " [9, 2, 6, 3],\n", + " [0, 3, 1, 0] ]\n", + "\n", + "Solution().maxIncreaseKeepingSkyline(grid)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "35" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# note:\n", + "# there are many place we can improve from this brutal approach,\n", + "# for example, we don't really need to create the girdNew, but \n", + "# instead, we only need to accumulate the difference between\n", + "# (height at current cell, possible max height). \n", + "# e.g. we know the possible max height at cell(0,0) is \n", + "# min(9, 8) = 8. So the difference = 8-3 = 5\n", + "# this will save both time and space, and it won't modify the original\n", + "# grid input.\n", + "\n", + "class Solution2(object):\n", + " def maxIncreaseKeepingSkyline(self, grid):\n", + " \"\"\"\n", + " :type grid: List[List[int]]\n", + " :rtype: int\n", + " \"\"\"\n", + " total_init = sum([sum(content) for content in grid])\n", + " max_col = [0] * len(grid)\n", + " # iterate through colum, bcz max(list) is easy to call\n", + " for col in range(len(grid)):\n", + " for row in range(len(grid)):\n", + " if grid[row][col] > max_col[col]:\n", + " max_col[col] = grid[row][col]\n", + " \n", + " output = 0\n", + " for row in range(len(grid)):\n", + " for col in range(len(grid)):\n", + " possible_local_max = min(max_col[col], max(grid[row]))\n", + " output += possible_local_max - grid[row][col]\n", + " \n", + " return output\n", + " \n", + "grid = [ [3, 0, 8, 4], \n", + " [2, 4, 5, 7],\n", + " [9, 2, 6, 3],\n", + " [0, 3, 1, 0] ]\n", + "Solution2().maxIncreaseKeepingSkyline(grid)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/807. Max Increase to Keep City Skyline/Max_Increase_to_Keep_City_Skyline.ipynb b/807. Max Increase to Keep City Skyline/Max_Increase_to_Keep_City_Skyline.ipynb new file mode 100644 index 0000000..379d235 --- /dev/null +++ b/807. Max Increase to Keep City Skyline/Max_Increase_to_Keep_City_Skyline.ipynb @@ -0,0 +1,396 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Python 3.7.1\r\n" + ] + } + ], + "source": [ + "!python --version" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'\\nIn a 2 dimensional array grid, each value grid[i][j] represents the \\nheight of a building located there. We are allowed to increase the \\nheight of any number of buildings, by any amount (the amounts can be \\ndifferent for different buildings). Height 0 is considered to be a \\nbuilding as well. \\n\\nAt the end, the \"skyline\" when viewed from all four directions of \\nthe grid, i.e. top, bottom, left, and right, must be the same as \\nthe skyline of the original grid. A city\\'s skyline is the outer \\ncontour of the rectangles formed by all the buildings when viewed \\nfrom a distance. See the following example.\\n\\nWhat is the maximum total sum that the height of the buildings can \\nbe increased?\\n\\n\\nExample:\\nInput: grid = [[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]]\\nOutput: 35\\nExplanation: \\nThe grid is:\\n[ [3, 0, 8, 4], \\n [2, 4, 5, 7],\\n [9, 2, 6, 3],\\n [0, 3, 1, 0] ]\\n\\nThe skyline viewed from top or bottom is: [9, 4, 8, 7]\\nThe skyline viewed from left or right is: [8, 7, 9, 3]\\n\\nThe grid after increasing the height of buildings without affecting skylines is:\\n\\ngridNew = [ [8, 4, 8, 7],\\n [7, 4, 7, 7],\\n [9, 4, 8, 7],\\n [3, 3, 3, 3] ]\\n\\nlink:\\nhttps://leetcode.com/problems/max-increase-to-keep-city-skyline/\\n'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"\"\"\n", + "In a 2 dimensional array grid, each value grid[i][j] represents the \n", + "height of a building located there. We are allowed to increase the \n", + "height of any number of buildings, by any amount (the amounts can be \n", + "different for different buildings). Height 0 is considered to be a \n", + "building as well. \n", + "\n", + "At the end, the \"skyline\" when viewed from all four directions of \n", + "the grid, i.e. top, bottom, left, and right, must be the same as \n", + "the skyline of the original grid. A city's skyline is the outer \n", + "contour of the rectangles formed by all the buildings when viewed \n", + "from a distance. See the following example.\n", + "\n", + "What is the maximum total sum that the height of the buildings can \n", + "be increased?\n", + "\n", + "\n", + "Example:\n", + "Input: grid = [[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]]\n", + "Output: 35\n", + "Explanation: \n", + "The grid is:\n", + "[ [3, 0, 8, 4], \n", + " [2, 4, 5, 7],\n", + " [9, 2, 6, 3],\n", + " [0, 3, 1, 0] ]\n", + "\n", + "The skyline viewed from top or bottom is: [9, 4, 8, 7]\n", + "The skyline viewed from left or right is: [8, 7, 9, 3]\n", + "\n", + "The grid after increasing the height of buildings without affecting skylines is:\n", + "\n", + "gridNew = [ [8, 4, 8, 7],\n", + " [7, 4, 7, 7],\n", + " [9, 4, 8, 7],\n", + " [3, 3, 3, 3] ]\n", + "\n", + "link:\n", + "https://leetcode.com/problems/max-increase-to-keep-city-skyline/\n", + "\"\"\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Solution 1\n", + "The idea is straight forward, height of each cell is bounded by two conditions: (max in the row, max in the col). \n", + "The challenge will be, how to find and fill it efficiently. \n", + "The first solution here, we use brutal force to begin with." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[9, 4, 8, 7]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# def maxIncreaseKeepingSkyline(grid):\n", + "grid = [ [3, 0, 8, 4], \n", + " [2, 4, 5, 7],\n", + " [9, 2, 6, 3],\n", + " [0, 3, 1, 0] ]\n", + "total_init = sum([sum(content) for content in grid])\n", + "max_col = [0] * len(grid)\n", + "# iterate through colum, bcz max(list) is easy to call\n", + "for col in range(len(grid)):\n", + " for row in range(len(grid)):\n", + " if grid[row][col] > max_col[col]:\n", + " max_col[col] = grid[row][col]\n", + "\n", + "max_col" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "gridNew = grid[:]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[3, 0, 8, 4], [2, 4, 5, 7], [9, 2, 6, 3], [0, 3, 1, 0]]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "gridNew2 = grid.copy() # notice that [[0]*4]*4 will give error at the end\n", + "gridNew2" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 0 9 8 8\n", + "0 1 4 8 4\n", + "0 2 8 8 8\n", + "0 3 7 8 7\n", + "1 0 9 7 7\n", + "1 1 4 7 4\n", + "1 2 8 7 7\n", + "1 3 7 7 7\n", + "2 0 9 9 9\n", + "2 1 4 9 4\n", + "2 2 8 9 8\n", + "2 3 7 9 7\n", + "3 0 9 3 3\n", + "3 1 4 3 3\n", + "3 2 8 3 3\n", + "3 3 7 3 3\n" + ] + }, + { + "data": { + "text/plain": [ + "[[8, 4, 8, 7], [7, 4, 7, 7], [9, 4, 8, 7], [3, 3, 3, 3]]" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "for row in range(len(grid)):\n", + " for col in range(len(grid)):\n", + " # new grid is bounded by max in col and max in row\n", + " gridNew[row][col] = min(max_col[col], max(grid[row]))\n", + " print(row, col, max_col[col], max(grid[row]), gridNew[row][col]) \n", + " \n", + "gridNew" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[8, 4, 8, 7], [7, 4, 7, 7], [9, 4, 8, 7], [3, 3, 3, 3]]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "grid # well.. due to the python copy problem..you will need deepcopy to \n", + " # generate a new copy with brand new pointer...\n", + " # ref: https://stackoverflow.com/questions/13783315/sum-of-list-of-lists-returns-sum-list\n", + " # a easier way here is to calculate total_init at the begining." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "57 92\n" + ] + }, + { + "data": { + "text/plain": [ + "35" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "total_new = sum([sum(content) for content in gridNew])\n", + "print(total_init, total_new)\n", + "total_increase = total_new - total_init\n", + "total_increase" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "# put into a function:\n", + "class Solution(object):\n", + " def maxIncreaseKeepingSkyline(self, grid):\n", + " \"\"\"\n", + " :type grid: List[List[int]]\n", + " :rtype: int\n", + " \"\"\"\n", + " total_init = sum([sum(content) for content in grid])\n", + " max_col = [0] * len(grid)\n", + " # iterate through colum, bcz max(list) is easy to call\n", + " for col in range(len(grid)):\n", + " for row in range(len(grid)):\n", + " if grid[row][col] > max_col[col]:\n", + " max_col[col] = grid[row][col]\n", + " \n", + " gridNew = grid[:]\n", + " for row in range(len(grid)):\n", + " for col in range(len(grid)):\n", + " # new grid is bounded by max in col and max in row\n", + " gridNew[row][col] = min(max_col[col], max(grid[row]))\n", + " \n", + " total_new = sum([sum(content) for content in gridNew])\n", + " total_increase = total_new - total_init \n", + " return total_increase\n", + " \n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "35" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "grid = [ [3, 0, 8, 4], \n", + " [2, 4, 5, 7],\n", + " [9, 2, 6, 3],\n", + " [0, 3, 1, 0] ]\n", + "\n", + "Solution().maxIncreaseKeepingSkyline(grid)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "35" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# note:\n", + "# there are many place we can improve from this brutal approach,\n", + "# for example, we don't really need to create the girdNew, but \n", + "# instead, we only need to accumulate the difference between\n", + "# (height at current cell, possible max height). \n", + "# e.g. we know the possible max height at cell(0,0) is \n", + "# min(9, 8) = 8. So the difference = 8-3 = 5\n", + "# this will save both time and space, and it won't modify the original\n", + "# grid input.\n", + "\n", + "class Solution2(object):\n", + " def maxIncreaseKeepingSkyline(self, grid):\n", + " \"\"\"\n", + " :type grid: List[List[int]]\n", + " :rtype: int\n", + " \"\"\"\n", + " total_init = sum([sum(content) for content in grid])\n", + " max_col = [0] * len(grid)\n", + " # iterate through colum, bcz max(list) is easy to call\n", + " for col in range(len(grid)):\n", + " for row in range(len(grid)):\n", + " if grid[row][col] > max_col[col]:\n", + " max_col[col] = grid[row][col]\n", + " \n", + " output = 0\n", + " for row in range(len(grid)):\n", + " for col in range(len(grid)):\n", + " possible_local_max = min(max_col[col], max(grid[row]))\n", + " output += possible_local_max - grid[row][col]\n", + " \n", + " return output\n", + " \n", + "grid = [ [3, 0, 8, 4], \n", + " [2, 4, 5, 7],\n", + " [9, 2, 6, 3],\n", + " [0, 3, 1, 0] ]\n", + "Solution2().maxIncreaseKeepingSkyline(grid)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 81fb098803befab01666855e06bcf0705e5f6fa3 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Wed, 28 Sep 2022 17:35:05 -0700 Subject: [PATCH 03/20] update all the code. --- .gitignore | 1 + .../139. Word Break-checkpoint.ipynb | 6 + ...1. Merge Two Sorted Lists-checkpoint.ipynb | 6 + .../402. Remove K Digits-checkpoint.ipynb | 151 ++ ...Element in a Sorted Array-checkpoint.ipynb | 6 + ...Reorder Data in Log Files-checkpoint.ipynb | 6 + .../Linked_list_related-checkpoint.ipynb | 206 +++ .ipynb_checkpoints/Untitled1-checkpoint.ipynb | 6 + .ipynb_checkpoints/Untitled2-checkpoint.ipynb | 6 + 1109-Corporate-flight-booking/main.py | 23 + .../Solution.cs | 71 + .../CSharpSoultions.cs | 41 + .../README.md | 1 + 139. Word Break.ipynb | 175 +++ 152.MaximumProductSubarray/Solution.cs | 31 + 198.HouseRobber/Solution.py | 13 + 206.Reverse_Linked_List.py | 51 + 21. Merge Two Sorted Lists.ipynb | 208 +++ 22.GeneratePyarentheses.py | 23 + 290.WordPattern/Solution.py | 23 + 402. Remove K Digits.ipynb | 298 ++++ 472.ConcatenatedWords.py | 94 ++ 540. Single Element in a Sorted Array.ipynb | 105 ++ 57.InsertInterval/Solution.cs | 41 + 57.InsertInterval/Solution.py | 29 + 83. Remove Duplicates from Sorted List.py | 37 + 835.ImageOverlap/Solution.py | 29 + 876_Middle_of_the_Linked_List.py | 20 + 937. Reorder Data in Log Files.ipynb | 210 +++ ...zzle_BFS_and_Jigsaw-Copy1-checkpoint.ipynb | 606 ++++++++ ...dingPuzzle_BFS_and_Jigsaw-checkpoint.ipynb | 1224 +++++++++++++++++ ...3_SlidingPuzzle_BFS_and_Jigsaw-Copy1.ipynb | 762 ++++++++++ .../773_SlidingPuzzle_BFS_and_Jigsaw.ipynb | 1224 +++++++++++++++++ BasicCsharp_List.cs | 47 + BasicCsharp_functions.cs | 15 + LinkedList.py | 40 + Linked_list_related.ipynb | 582 ++++++++ Untitled1.ipynb | 125 ++ Untitled2.ipynb | 290 ++++ __pycache__/LinkedList.cpython-36.pyc | Bin 0 -> 1539 bytes akuna.py | 1 + tmp.py | 58 + 42 files changed, 6891 insertions(+) create mode 100644 .gitignore create mode 100644 .ipynb_checkpoints/139. Word Break-checkpoint.ipynb create mode 100644 .ipynb_checkpoints/21. Merge Two Sorted Lists-checkpoint.ipynb create mode 100644 .ipynb_checkpoints/402. Remove K Digits-checkpoint.ipynb create mode 100644 .ipynb_checkpoints/540. Single Element in a Sorted Array-checkpoint.ipynb create mode 100644 .ipynb_checkpoints/937. Reorder Data in Log Files-checkpoint.ipynb create mode 100644 .ipynb_checkpoints/Linked_list_related-checkpoint.ipynb create mode 100644 .ipynb_checkpoints/Untitled1-checkpoint.ipynb create mode 100644 .ipynb_checkpoints/Untitled2-checkpoint.ipynb create mode 100644 1109-Corporate-flight-booking/main.py create mode 100644 1305.AllElementsInTwoBinarySearchTrees/Solution.cs create mode 100644 1365.HowManyNumbersAreSmallerThanTheCurrentNumber/CSharpSoultions.cs create mode 100644 1365.HowManyNumbersAreSmallerThanTheCurrentNumber/README.md create mode 100644 139. Word Break.ipynb create mode 100644 152.MaximumProductSubarray/Solution.cs create mode 100644 198.HouseRobber/Solution.py create mode 100644 206.Reverse_Linked_List.py create mode 100644 21. Merge Two Sorted Lists.ipynb create mode 100644 22.GeneratePyarentheses.py create mode 100644 290.WordPattern/Solution.py create mode 100644 402. Remove K Digits.ipynb create mode 100644 472.ConcatenatedWords.py create mode 100644 540. Single Element in a Sorted Array.ipynb create mode 100644 57.InsertInterval/Solution.cs create mode 100644 57.InsertInterval/Solution.py create mode 100644 83. Remove Duplicates from Sorted List.py create mode 100644 835.ImageOverlap/Solution.py create mode 100644 876_Middle_of_the_Linked_List.py create mode 100644 937. Reorder Data in Log Files.ipynb create mode 100644 BFS_jigsaw/.ipynb_checkpoints/773_SlidingPuzzle_BFS_and_Jigsaw-Copy1-checkpoint.ipynb create mode 100644 BFS_jigsaw/.ipynb_checkpoints/773_SlidingPuzzle_BFS_and_Jigsaw-checkpoint.ipynb create mode 100644 BFS_jigsaw/773_SlidingPuzzle_BFS_and_Jigsaw-Copy1.ipynb create mode 100644 BFS_jigsaw/773_SlidingPuzzle_BFS_and_Jigsaw.ipynb create mode 100644 BasicCsharp_List.cs create mode 100644 BasicCsharp_functions.cs create mode 100644 LinkedList.py create mode 100644 Linked_list_related.ipynb create mode 100644 Untitled1.ipynb create mode 100644 Untitled2.ipynb create mode 100644 __pycache__/LinkedList.cpython-36.pyc create mode 100644 tmp.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/.ipynb_checkpoints/139. Word Break-checkpoint.ipynb b/.ipynb_checkpoints/139. Word Break-checkpoint.ipynb new file mode 100644 index 0000000..2fd6442 --- /dev/null +++ b/.ipynb_checkpoints/139. Word Break-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/.ipynb_checkpoints/21. Merge Two Sorted Lists-checkpoint.ipynb b/.ipynb_checkpoints/21. Merge Two Sorted Lists-checkpoint.ipynb new file mode 100644 index 0000000..2fd6442 --- /dev/null +++ b/.ipynb_checkpoints/21. Merge Two Sorted Lists-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/.ipynb_checkpoints/402. Remove K Digits-checkpoint.ipynb b/.ipynb_checkpoints/402. Remove K Digits-checkpoint.ipynb new file mode 100644 index 0000000..3aff7bb --- /dev/null +++ b/.ipynb_checkpoints/402. Remove K Digits-checkpoint.ipynb @@ -0,0 +1,151 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Problem description\n", + "Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible.\n", + "\n", + "Note:\n", + "The length of num is less than 10002 and will be ≥ k.\n", + "The given num does not contain any leading zero.\n", + "\n", + "Example 1:\n", + "Input: num = \"1432219\", k = 3 \n", + "Output: \"1219\" \n", + "Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest. \n", + "\n", + "Example 2: \n", + "Input: num = \"10200\", k = 1 \n", + "Output: \"200\" \n", + "Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes. \n", + "\n", + "Example 3: \n", + "Input: num = \"10\", k = 2 \n", + "Output: \"0\" \n", + "Explanation: Remove all the digits from the number and it is left with nothing which is 0." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class Solution(object):\n", + " def removeKdigits(self, num, k):\n", + " \"\"\"\n", + " :type num: str\n", + " :type k: int\n", + " :rtype: str\n", + " \"\"\"\n", + " if k == len(num):\n", + " return \"0\"\n", + " if k == 0:\n", + " return min(num)\n", + " candidate = [int(num[:i]+num[i+1:]) for i in range(len(num))]\n", + " return removeKdigits(_, candidate, k-1)\n", + " \n", + " \n", + "\n", + "num = \"1432219\"\n", + "k = 3\n", + "Solution.removeKdigits(_, num, k)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['1', '0', '0', '0', '2', '0']" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(\"100020\")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[432219, 132219, 142219, 143219, 143219, 143229, 143221]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "num = \"1432219\"\n", + "candidate = [int(num[:i]+num[i+1:]) for i in range(len(num))]\n", + "candidate" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/.ipynb_checkpoints/540. Single Element in a Sorted Array-checkpoint.ipynb b/.ipynb_checkpoints/540. Single Element in a Sorted Array-checkpoint.ipynb new file mode 100644 index 0000000..2fd6442 --- /dev/null +++ b/.ipynb_checkpoints/540. Single Element in a Sorted Array-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/.ipynb_checkpoints/937. Reorder Data in Log Files-checkpoint.ipynb b/.ipynb_checkpoints/937. Reorder Data in Log Files-checkpoint.ipynb new file mode 100644 index 0000000..2fd6442 --- /dev/null +++ b/.ipynb_checkpoints/937. Reorder Data in Log Files-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/.ipynb_checkpoints/Linked_list_related-checkpoint.ipynb b/.ipynb_checkpoints/Linked_list_related-checkpoint.ipynb new file mode 100644 index 0000000..240f936 --- /dev/null +++ b/.ipynb_checkpoints/Linked_list_related-checkpoint.ipynb @@ -0,0 +1,206 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "class ListNode(object):\n", + " def __init__(self, val=0, next=None):\n", + " self.val = val\n", + " self.next = next" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "LN1 = ListNode(2, ListNode(4, ListNode(3)))\n", + "LN2 = ListNode(5, ListNode(6, ListNode(4)))\n", + "LN3 = ListNode(5, ListNode(6, ListNode(4, ListNode(1))))" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "num1=2, num2=5, tmp_num=7, total_num=7\n", + "num1=4, num2=6, tmp_num=100, total_num=107\n", + "num1=3, num2=4, tmp_num=700, total_num=807\n" + ] + }, + { + "data": { + "text/plain": [ + "807" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def addTwoNumbers(l1, l2):\n", + " \"\"\"\n", + " :type l1: ListNode\n", + " :type l2: ListNode\n", + " :rtype: ListNode\n", + " \"\"\"\n", + " digit = 0\n", + " total_num = 0\n", + " while l1 and l2:\n", + " num1 = l1.val\n", + " num2 = l2.val\n", + " tmp_num = (num1+num2)*(10**digit)\n", + " total_num += tmp_num\n", + " print(f\"num1={num1}, num2={num2}, tmp_num={tmp_num}, total_num={total_num}\")\n", + " l1 = l1.next\n", + " l2 = l2.next\n", + " digit += 1\n", + "\n", + " while l1: #l2 exhausted\n", + " num1 = l1.val\n", + " tmp_num = num1 * (10**digit)\n", + " total_num += tmp_num\n", + " print(f\"num1={num1}, num2={num2}, tmp_num={tmp_num}, total_num={total_num}\")\n", + " l1 = l1.next\n", + " digit += 1\n", + "\n", + " while l2:\n", + " num2 = l2.val\n", + " tmp_num = num2 * (10**digit)\n", + " total_num += tmp_num\n", + " print(f\"num1={num1}, num2={num2}, tmp_num={tmp_num}, total_num={total_num}\")\n", + " l2 = l2.next\n", + " digit += 1\n", + " \n", + " out = ListNode(0,ListNode())\n", + " tmp = out.next\n", + " for i in list(str(total_num))[::-1]:\n", + "# print(i)\n", + " tmp.val = int(i)\n", + " tmp.next = ListNode()\n", + " tmp = tmp.next\n", + " return out.next\n", + "\n", + "\n", + "addTwoNumbers(LN1, LN2) #807" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "num1=2, num2=5, tmp_num=7, total_num=7\n", + "num1=4, num2=6, tmp_num=100, total_num=107\n", + "num1=3, num2=4, tmp_num=700, total_num=807\n", + "num1=3, num2=1, tmp_num=1000, total_num=1807\n" + ] + }, + { + "data": { + "text/plain": [ + "1807" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "addTwoNumbers(LN1, LN3) #1807" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "7\n", + "0\n", + "8\n" + ] + } + ], + "source": [ + "out = ListNode(0,ListNode())\n", + "tmp = out.next\n", + "for i in list(str(807))[::-1]:\n", + " print(i)\n", + "\n", + " tmp.val = i\n", + " tmp.next = ListNode()\n", + " tmp = tmp.next\n", + " \n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'8'" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "out.next.next.next.val" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/.ipynb_checkpoints/Untitled1-checkpoint.ipynb b/.ipynb_checkpoints/Untitled1-checkpoint.ipynb new file mode 100644 index 0000000..2fd6442 --- /dev/null +++ b/.ipynb_checkpoints/Untitled1-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/.ipynb_checkpoints/Untitled2-checkpoint.ipynb b/.ipynb_checkpoints/Untitled2-checkpoint.ipynb new file mode 100644 index 0000000..2fd6442 --- /dev/null +++ b/.ipynb_checkpoints/Untitled2-checkpoint.ipynb @@ -0,0 +1,6 @@ +{ + "cells": [], + "metadata": {}, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/1109-Corporate-flight-booking/main.py b/1109-Corporate-flight-booking/main.py new file mode 100644 index 0000000..9895762 --- /dev/null +++ b/1109-Corporate-flight-booking/main.py @@ -0,0 +1,23 @@ +DEBUG = True + + +def corpFlightBookings(bookings, n): + print("Bookings = ", bookings) + myList = [0] * (n + 2) + for start, end, val in bookings: + myList[start] += val + myList[end + 1] -= val + if DEBUG: + print(f"start = {start}, end = {end}, val = {val}.") + print("myList = ", myList) + if DEBUG: print("finish first stage.") + for i in range(1, n + 2): + myList[i] += myList[i - 1] + if DEBUG: + print("myList = ", myList, end="\n") + return myList[1:-1] + + +# corpFlightBookings([[1, 2, 10], [2, 3, 20], [2, 5, 25]], 5) + +corpFlightBookings([[3, 3, 5], [1, 3, 20], [1, 2, 15]], 3) diff --git a/1305.AllElementsInTwoBinarySearchTrees/Solution.cs b/1305.AllElementsInTwoBinarySearchTrees/Solution.cs new file mode 100644 index 0000000..2b3aace --- /dev/null +++ b/1305.AllElementsInTwoBinarySearchTrees/Solution.cs @@ -0,0 +1,71 @@ +/** +2020-09-07 TAKE AWAY: +Queue doesn't support index; +List kind of doesn't support pop, but there's a way to hack it +(get value and then RemoveAt(0)) + +public void for functions without a return (in place change) +*/ + +/** + * Definition for a binary tree node. + * public class TreeNode { + * public int val; + * public TreeNode left; + * public TreeNode right; + * public TreeNode(int val=0, TreeNode left=null, TreeNode right=null) { + * this.val = val; + * this.left = left; + * this.right = right; + * } + * } + */ +public class Solution { + public List list1 = new List(); + public List list2 = new List(); + // public Queue list1 = new Queue(); + // public Queue list2 = new Queue(); + public List output = new List(); + + public void inOrder(TreeNode node, List list){ + if (node != null) + { + inOrder(node.left, list); + list.Add(node.val); + inOrder(node.right, list); + } + } + + public IList GetAllElements(TreeNode root1, TreeNode root2) { + inOrder(root1, list1); + inOrder(root2, list2); + + while (list1.Count > 0 && list2.Count > 0) + { + if (list1[0] < list2[0]) + { + output.Add(list1[0]); + list1.RemoveAt(0); + } + else + { + output.Add(list2[0]); + list2.RemoveAt(0); + } + } + + while (list1.Count > 0) + { + output.Add(list1[0]); + list1.RemoveAt(0); + } + while (list2.Count > 0) + { + output.Add(list2[0]); + list2.RemoveAt(0); + } + + return output; + + } +} \ No newline at end of file diff --git a/1365.HowManyNumbersAreSmallerThanTheCurrentNumber/CSharpSoultions.cs b/1365.HowManyNumbersAreSmallerThanTheCurrentNumber/CSharpSoultions.cs new file mode 100644 index 0000000..3123c5c --- /dev/null +++ b/1365.HowManyNumbersAreSmallerThanTheCurrentNumber/CSharpSoultions.cs @@ -0,0 +1,41 @@ +// Merhod 1: Brutal Force +public class Solution { + public int[] SmallerNumbersThanCurrent(int[] nums) { + int[] aaa = new int[nums.Length]; + + for (int i = 0; i < nums.Length; i++) + { + int tmp_count = 0; + foreach (int val in nums.ToList().FindAll(e=>(e < nums[i])).ToList()) + { + tmp_count += 1; + } + aaa[i] = tmp_count; + } + return aaa; + } +} + +// Method 2: sort and use a cache +public class Solution { + public int[] SmallerNumbersThanCurrent(int[] nums) { + int[] aaa = new int[nums.Length]; + Array.Copy(nums, 0, aaa, 0, nums.Length); + Array.Sort(aaa); + + Dictionary store = new Dictionary (); + for (int i = 0; i < aaa.Length; i++) + { + if (store.ContainsKey(aaa[i]) == false) + { + store[aaa[i]] = i; + } + } + + for (int i = 0; i < nums.Length; i++) + { + aaa[i] = store[nums[i]]; + } + return aaa; + } +} \ No newline at end of file diff --git a/1365.HowManyNumbersAreSmallerThanTheCurrentNumber/README.md b/1365.HowManyNumbersAreSmallerThanTheCurrentNumber/README.md new file mode 100644 index 0000000..30b6af4 --- /dev/null +++ b/1365.HowManyNumbersAreSmallerThanTheCurrentNumber/README.md @@ -0,0 +1 @@ +https://leetcode.com/problems/how-many-numbers-are-smaller-than-the-current-number/ diff --git a/139. Word Break.ipynb b/139. Word Break.ipynb new file mode 100644 index 0000000..7540d6f --- /dev/null +++ b/139. Word Break.ipynb @@ -0,0 +1,175 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "i=1; \n", + "dp=[True, False, False, False, False, False, False, False, False]\n", + "w = leet\n", + "len(w)=4, dp[i-len(w)]=False, s[i-len(w):i]=\n", + "w = code\n", + "len(w)=4, dp[i-len(w)]=False, s[i-len(w):i]=\n", + "\n", + "\n", + "i=2; \n", + "dp=[True, False, False, False, False, False, False, False, False]\n", + "w = leet\n", + "len(w)=4, dp[i-len(w)]=False, s[i-len(w):i]=\n", + "w = code\n", + "len(w)=4, dp[i-len(w)]=False, s[i-len(w):i]=\n", + "\n", + "\n", + "i=3; \n", + "dp=[True, False, False, False, False, False, False, False, False]\n", + "w = leet\n", + "len(w)=4, dp[i-len(w)]=False, s[i-len(w):i]=\n", + "w = code\n", + "len(w)=4, dp[i-len(w)]=False, s[i-len(w):i]=\n", + "\n", + "\n", + "i=4; \n", + "dp=[True, False, False, False, False, False, False, False, False]\n", + "w = leet\n", + "len(w)=4, dp[i-len(w)]=True, s[i-len(w):i]=leet\n", + "if triggered, dp = [True, False, False, False, True, False, False, False, False]\n", + "w = code\n", + "len(w)=4, dp[i-len(w)]=True, s[i-len(w):i]=leet\n", + "\n", + "\n", + "i=5; \n", + "dp=[True, False, False, False, True, False, False, False, False]\n", + "w = leet\n", + "len(w)=4, dp[i-len(w)]=False, s[i-len(w):i]=eetc\n", + "w = code\n", + "len(w)=4, dp[i-len(w)]=False, s[i-len(w):i]=eetc\n", + "\n", + "\n", + "i=6; \n", + "dp=[True, False, False, False, True, False, False, False, False]\n", + "w = leet\n", + "len(w)=4, dp[i-len(w)]=False, s[i-len(w):i]=etco\n", + "w = code\n", + "len(w)=4, dp[i-len(w)]=False, s[i-len(w):i]=etco\n", + "\n", + "\n", + "i=7; \n", + "dp=[True, False, False, False, True, False, False, False, False]\n", + "w = leet\n", + "len(w)=4, dp[i-len(w)]=False, s[i-len(w):i]=tcod\n", + "w = code\n", + "len(w)=4, dp[i-len(w)]=False, s[i-len(w):i]=tcod\n", + "\n", + "\n", + "i=8; \n", + "dp=[True, False, False, False, True, False, False, False, False]\n", + "w = leet\n", + "len(w)=4, dp[i-len(w)]=True, s[i-len(w):i]=code\n", + "w = code\n", + "len(w)=4, dp[i-len(w)]=True, s[i-len(w):i]=code\n", + "if triggered, dp = [True, False, False, False, True, False, False, False, True]\n", + "\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def wordBreak(s, wordDict):\n", + " n = len(s)\n", + " dp = [False for i in range(n+1)]\n", + " dp[0] = True\n", + " for i in range(1,n+1):\n", + " print(f\"i={i}; \\ndp={dp}\")\n", + " for w in wordDict:\n", + " print(f\"w = {w}\")\n", + " print(f\"len(w)={len(w)}, dp[i-len(w)]={dp[i-len(w)]}, s[i-len(w):i]={s[i-len(w):i]}\")\n", + " if dp[i-len(w)] and s[i-len(w):i]==w:\n", + " dp[i]=True\n", + " print(f\"if triggered, dp = {dp}\")\n", + " print(\"\\n\")\n", + " return dp[-1]\n", + "\n", + "s = \"leetcode\"\n", + "wordDict = [\"leet\", \"code\"]\n", + "wordBreak(s, wordDict)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'leet'" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "s[0:4]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/152.MaximumProductSubarray/Solution.cs b/152.MaximumProductSubarray/Solution.cs new file mode 100644 index 0000000..eaca030 --- /dev/null +++ b/152.MaximumProductSubarray/Solution.cs @@ -0,0 +1,31 @@ +public class Solution { + public int MaxProduct(int[] nums) + { + if (nums.Length == 0){ + return 0; + } + List max_so_far = new List() {nums[0]}; + List min_so_far = new List() {nums[0]}; + + int maximum = nums[0]; + + for (int i = 1; i < nums.Length; i++) + { + int n = nums[i]; + // Console.WriteLine("i = {0}, n = {1}", i, n); + int local_max = new [] {n, n*max_so_far[i-1], n*min_so_far[i-1]}.Max(); + int local_min = new [] {n, n*max_so_far[i-1], n*min_so_far[i-1]}.Min(); + + max_so_far.Add(local_max); + min_so_far.Add(local_min); + + if (local_max > maximum) + { + maximum = local_max; + } + } + + + return maximum; + } +} \ No newline at end of file diff --git a/198.HouseRobber/Solution.py b/198.HouseRobber/Solution.py new file mode 100644 index 0000000..4c32b6c --- /dev/null +++ b/198.HouseRobber/Solution.py @@ -0,0 +1,13 @@ +class Solution: + + def recurssive_rob(self, i, nums): + if i < 0: + return 0 + if i not in self.cache: + self.cache[i] = max(self.recurssive_rob(i-1,nums), self.recurssive_rob(i-2, nums) + nums[i]) + return self.cache[i] + + + def rob(self, nums: List[int]) -> int: + self.cache = {} + return self.recurssive_rob(len(nums)-1, nums) \ No newline at end of file diff --git a/206.Reverse_Linked_List.py b/206.Reverse_Linked_List.py new file mode 100644 index 0000000..4d19121 --- /dev/null +++ b/206.Reverse_Linked_List.py @@ -0,0 +1,51 @@ +# Definition for singly-linked list. +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + + +# Solution 1, iterate with stack +class Solution: + # time: O(2n) -> O(n) + # space: O(n) for stack + def reverseList(self, head: ListNode) -> ListNode: + stack = [] + cur = head + while cur: + stack.append(cur) + cur = cur.next + + out = cur = ListNode() + while stack: + cur.next = stack.pop(-1) + cur = cur.next + cur.next = None + return out.next + +# Solution 2, read once and change along the way +class Solution: + # time: O(n) + # space: O(1) + def reverseList(self, head: ListNode) -> ListNode: + prev = None + cur = head + while cur: + nxt = cur.next + cur.next = prev + prev = cur + cur = nxt + return prev + +# Solution 3, recursive +class Solution: + # time: O(n) + # space: O(n) due to recursive stack, which can go n levels deep + def reverseList(self, head: ListNode) -> ListNode: + if not head or not head.next: + return head # bottom + p = reverseList(head.next) # reverse all the parts after head + head.next.next = head + head.next = None # need it for the last recurisve call to remove the loop + return p + \ No newline at end of file diff --git a/21. Merge Two Sorted Lists.ipynb b/21. Merge Two Sorted Lists.ipynb new file mode 100644 index 0000000..6381aa2 --- /dev/null +++ b/21. Merge Two Sorted Lists.ipynb @@ -0,0 +1,208 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "# Definition for singly-linked list.\n", + "class ListNode(object):\n", + " def __init__(self, val=0, next=None):\n", + " self.val = val\n", + " self.next = next\n", + " \n", + " def __str__(self):\n", + " out = \"Linked List: \"\n", + " cur = self\n", + " while cur.val:\n", + " out += str(cur.val) + \"-> \"\n", + " if cur.next:\n", + " cur = cur.next\n", + " else:\n", + " break\n", + " return out[:-3]\n", + " \n", + " def __repr__(self):\n", + " out = \"Linked List: \"\n", + " cur = self\n", + " while cur.val:\n", + " out += str(cur.val) + \"-> \"\n", + " if cur.next:\n", + " cur = cur.next\n", + " else:\n", + " break\n", + " return out[:-3]" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Linked List: 1-> 2-> 4\n" + ] + } + ], + "source": [ + "l1 = ListNode(1)\n", + "l1.next = ListNode(2, ListNode(4))\n", + "print(l1)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Linked List: 1-> 3-> 4\n" + ] + } + ], + "source": [ + "l2 = ListNode(1, ListNode(3, ListNode(4)))\n", + "print(l2)" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 Linked List: 1\n", + "case2 Linked List: 1-> 1\n", + "case1 Linked List: 1-> 1-> 2\n", + "case2 Linked List: 1-> 1-> 2-> 3\n", + "case1 Linked List: 1-> 1-> 2-> 3-> 4\n", + "l2 long Linked List: 1-> 1-> 2-> 3-> 4-> 4\n" + ] + }, + { + "data": { + "text/plain": [ + "Linked List: 1-> 1-> 2-> 3-> 4-> 4" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def mergeTwoLists(l1, l2):\n", + " \"\"\"\n", + " :type l1: ListNode\n", + " :type l2: ListNode\n", + " :rtype: ListNode\n", + " \"\"\"\n", + " out = ListNode()\n", + " if l1.val <= l2.val:\n", + " out.val = l1.val\n", + " l1 = l1.next\n", + " else:\n", + " out.val = l2.val\n", + " l2 = l2.next\n", + " print(\"1\", out)\n", + " cur = out\n", + " while l1 and l2:\n", + " if l1.val <= l2.val:\n", + " cur.next = ListNode(l1.val)\n", + " l1 = l1.next\n", + " cur = cur.next\n", + " print(\"case1\", out)\n", + " else:\n", + " cur.next = ListNode(l2.val)\n", + " l2 = l2.next\n", + " cur = cur.next\n", + " print(\"case2\", out)\n", + " if l1:\n", + " cur.next = l1\n", + " print(\"l1 long\", out)\n", + " else:\n", + " cur.next = l2\n", + " print(\"l2 long\", out)\n", + " return out\n", + "mergeTwoLists(l1,l2)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 Linked List: 1\n" + ] + }, + { + "data": { + "text/plain": [ + "Linked List: 2-> 4" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/22.GeneratePyarentheses.py b/22.GeneratePyarentheses.py new file mode 100644 index 0000000..862b8b3 --- /dev/null +++ b/22.GeneratePyarentheses.py @@ -0,0 +1,23 @@ +def generateParenthesis(n): + res, stack = [], [] + + def backtrack(openN, closeN): + if openN == closeN == n: + res.append("".join(stack)) + return + + if openN < n: + stack.append("(") + backtrack(openN + 1, closeN) + stack.pop() + + if closeN < openN: + stack.append(")") + backtrack(openN, closeN + 1) + stack.pop() + + backtrack(0, 0) + return res + + +generateParenthesis(3) diff --git a/290.WordPattern/Solution.py b/290.WordPattern/Solution.py new file mode 100644 index 0000000..daf1301 --- /dev/null +++ b/290.WordPattern/Solution.py @@ -0,0 +1,23 @@ +class Solution: + def wordPattern(self, pattern: str, string: str) -> bool: + # idea: translate both of them into same dictionary mapping + + pattern = list(pattern) + dict1, dict2 = {}, {} + count1, count2 = 0, 0 + trans1, trans2 = "", "" + + for letter in pattern: + if letter not in dict1: + dict1[letter] = count1 + count1 += 1 + trans1 += " " + str(dict1[letter]) + + string = string.split(" ") + for w in string: + if w not in dict2: + dict2[w] = count2 + count2 += 1 + trans2 += " " + str(dict2[w]) + + return trans1 == trans2 \ No newline at end of file diff --git a/402. Remove K Digits.ipynb b/402. Remove K Digits.ipynb new file mode 100644 index 0000000..e3de56d --- /dev/null +++ b/402. Remove K Digits.ipynb @@ -0,0 +1,298 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Problem description\n", + "Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible.\n", + "\n", + "Note:\n", + "The length of num is less than 10002 and will be ≥ k.\n", + "The given num does not contain any leading zero.\n", + "\n", + "Example 1:\n", + "Input: num = \"1432219\", k = 3 \n", + "Output: \"1219\" \n", + "Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest. \n", + "\n", + "Example 2: \n", + "Input: num = \"10200\", k = 1 \n", + "Output: \"200\" \n", + "Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes. \n", + "\n", + "Example 3: \n", + "Input: num = \"10\", k = 2 \n", + "Output: \"0\" \n", + "Explanation: Remove all the digits from the number and it is left with nothing which is 0." + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'1219'" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "class Solution(object):\n", + " def removeKdigits(self, num, k):\n", + " \"\"\"\n", + " :type num: str\n", + " :type k: int\n", + " :rtype: str\n", + " \"\"\"\n", + " def remove_1_digit(num):\n", + " nums = list(num)\n", + " for current_index in range(1, len(nums)):\n", + " left_index = current_index - 1\n", + " if nums[left_index] > nums[current_index]:\n", + " return num[:left_index] + num[current_index:]\n", + " return num[:-1]\n", + " for _ in range(k):\n", + " num = remove_1_digit(num)\n", + " return num\n", + " \n", + "\n", + " \n", + "num = \"1432219\"\n", + "k = 3\n", + "Solution.removeKdigits(_, num, k)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'143221'" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "num = \"1432219\"\n", + "num[:-1]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[432219, 132219, 142219, 143219, 143219, 143229, 143221]\n", + "132219 2\n", + "[32219, 12219, 13219, 13219, 13229, 13221]\n", + "12219 1\n", + "[2219, 1219, 1219, 1229, 1221]\n", + "1219 0\n" + ] + }, + { + "data": { + "text/plain": [ + "'1219'" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# approach 1, time out brutal.\n", + "\n", + "class Solution(object):\n", + " def removeKdigits(self, num, k):\n", + " \"\"\"\n", + " :type num: str\n", + " :type k: int\n", + " :rtype: str\n", + " \"\"\"\n", + " if k == len(num):\n", + " return \"0\"\n", + " if k == 0:\n", + " return num\n", + " candidate = [int(num[:i]+num[i+1:]) for i in range(len(num))]\n", + " print(candidate)\n", + " print(str(min(candidate)), k-1)\n", + " return Solution.removeKdigits(_, str(min(candidate)), k-1)\n", + " \n", + "num = \"1432219\"\n", + "k = 3\n", + "Solution.removeKdigits(_, num, k)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[200, 1200, 1000, 1020, 1020]\n", + "200 0\n" + ] + }, + { + "data": { + "text/plain": [ + "'200'" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "num = \"10200\"\n", + "k = 1\n", + "Solution.removeKdigits(_, num, k)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'0'" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "num = \"10\"\n", + "k = 2\n", + "Solution.removeKdigits(_, num, k)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[432219, 132219, 142219, 143219, 143219, 143229, 143221]\n" + ] + }, + { + "data": { + "text/plain": [ + "'132219'" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "num = \"1432219\"\n", + "candidate = [int(num[:i]+num[i+1:]) for i in range(len(num))]\n", + "print(candidate)\n", + "str(min(candidate))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "could not convert string to float: ", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfloat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mValueError\u001b[0m: could not convert string to float: " + ] + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/472.ConcatenatedWords.py b/472.ConcatenatedWords.py new file mode 100644 index 0000000..d1f40fb --- /dev/null +++ b/472.ConcatenatedWords.py @@ -0,0 +1,94 @@ +# class Solution: +# # 1 - need to fix the cache. +# # 2 - lru_cache decorator can only be used on hashable objects (i.e. can't be applied on dict) +# def findAllConcatenatedWordsInADict(self, words: List[str]) -> List[str]: +# def isValid(word, lookup): +# # print(f"word = {word}") +# # print("cache = ", cache) +# # print() + +# # if word in cache: +# # return cache[word] +# if word in res: +# return True + +# if len(word) == 0: +# return True +# first_letter = word[0] +# for candidate in lookup[first_letter]: +# if candidate == word[: len(candidate)] and isValid( +# word[len(candidate) :], lookup +# ): +# cache[word] = True +# return True +# # cache[word] = False +# return False + +# cache = {} +# from collections import defaultdict + +# lookup = defaultdict(set) +# # form +# for word in words: +# if len(word) == 0: +# continue +# lookup[word[0]].add(word) # key: first letter, value: word + +# res = [] +# for word in words: +# if len(word) == 0: +# continue +# lookup[word[0]].remove(word) +# if isValid(word, lookup): +# res.append(word) +# lookup[word[0]].add(word) +# return res + + +class Solution: + def findAllConcatenatedWordsInADict(self, words: List[str]) -> List[str]: + cache = {} + from collections import defaultdict + + lookup = defaultdict(set) + + # form + for word in words: + if len(word) == 0: + continue + + if word[0] not in lookup: + lookup[word[0]] = set() + lookup[word[0]].add(word) # key: first letter, value: word + + def isValid(word, lookup): + nonlocal cache + if word in cache: + return cache[word] + + if len(word) == 0: + return True + first_letter = word[0] + for candidate in lookup[first_letter]: + if candidate == word[: len(candidate)] and isValid( + word[len(candidate) :], lookup + ): + cache[word] = True + return True + return False + + res = [] + for word in words: + if len(word) == 0: + continue + lookup[word[0]].remove(word) + if isValid(word, lookup): + res.append(word) + print(f"word = {word}") + print("res = ", res) + print("cache = ", cache) + print() + + lookup[word[0]].add(word) + + return res diff --git a/540. Single Element in a Sorted Array.ipynb b/540. Single Element in a Sorted Array.ipynb new file mode 100644 index 0000000..d692f4e --- /dev/null +++ b/540. Single Element in a Sorted Array.ipynb @@ -0,0 +1,105 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Problem Description\n", + "You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once. Find this single element that appears only once.\n", + "\n", + " \n", + "\n", + "Example 1: \n", + "Input: [1,1,2,3,3,4,4,8,8] \n", + "Output: 2 \n", + "\n", + "Example 2: \n", + "Input: [3,3,7,7,10,11,11] \n", + "Output: 10 \n", + " \n", + "\n", + "Note: Your solution should run in O(log n) time and O(1) space." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "10" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# approach 1, works but not good enough\n", + "class Solution(object):\n", + " def singleNonDuplicate(self, nums):\n", + " \"\"\"\n", + " :type nums: List[int]\n", + " :rtype: int\n", + " \"\"\"\n", + " for index in range(0, len(nums)-1, 2):\n", + " left = nums[index]\n", + " right = nums[index+1]\n", + " if left != right:\n", + " return left\n", + " return nums[-1]\n", + " \n", + "Solution.singleNonDuplicate(_, [3,3,7,7,10,11,11])" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/57.InsertInterval/Solution.cs b/57.InsertInterval/Solution.cs new file mode 100644 index 0000000..264eb36 --- /dev/null +++ b/57.InsertInterval/Solution.cs @@ -0,0 +1,41 @@ +public class Solution { + // Notice this is not the best practical solution + // Shall come back later for better coding + // e.g. use linkedlist + public int[][] Insert(int[][] intervals, int[] newInterval) { + int head = newInterval[0]; + int end = newInterval[1]; + List output = new List(); + + int i = 0; + while (i < intervals.Count()) + { + int cur_head = intervals[i][0], cur_end = intervals[i][1]; + if (head <= cur_end) + { + if (end < cur_head) + { + break; + } + else + { + head = Math.Min(head, cur_head); + end = Math.Max(end, cur_end); + } + } + else + { + output.Add(intervals[i]); + } + i += 1; + } + output.Add(new int[2] {head, end}); + + while (i < intervals.Count()) + { + output.Add(intervals[i]); + i++; + } + return output.ToArray(); + } +} \ No newline at end of file diff --git a/57.InsertInterval/Solution.py b/57.InsertInterval/Solution.py new file mode 100644 index 0000000..2a9c0c3 --- /dev/null +++ b/57.InsertInterval/Solution.py @@ -0,0 +1,29 @@ +class Solution: + def insert(self, intervals: List[List[int]], newInterval: List[int]) -> List[List[int]]: + i = 0 + head, end = newInterval + output = [] + + while i < len(intervals): + cur_head, cur_end = intervals[i] + # we only need to insert one interval + # and the first task is to find where to start + if head <= cur_end: + if end < cur_head: + # easy case, new interval shall be at position 0 + break + else: + # start merging, we will keep doing this + # until the updated end < cur_head + head = min(head, cur_head) + end = max(end, cur_end) + # merge not start yet, append + else: + output.append(intervals[i]) + i += 1 + output.append([head,end]) + output.extend(intervals[i:]) + return output + + + \ No newline at end of file diff --git a/83. Remove Duplicates from Sorted List.py b/83. Remove Duplicates from Sorted List.py new file mode 100644 index 0000000..dd4c53f --- /dev/null +++ b/83. Remove Duplicates from Sorted List.py @@ -0,0 +1,37 @@ +# Definition for singly-linked list. +class ListNode: + def __init__(self, val=0, next=None): + self.val = val + self.next = next + +class Solution: + # time: O(n) + # space: O(n) + def deleteDuplicates(self, head: ListNode) -> ListNode: + if not head: + return head + seen = [head.val] + cur = head + while cur.next: + if cur.next.val in seen: + cur.next = cur.next.next + else: + seen.append(cur.next.val) + cur = cur.next + + + return head +# comment: since the input ListNode is sorted, so we don't actually need a cache to save seen nodes. + + +class Solution: + # time: O(n) + # space: O(1) + def deleteDuplicates(self, head: ListNode) -> ListNode: + cur = head + while cur and cur.next: + if cur.val == cur.next.val: + cur.next = cur.next.next + else: + cur = cur.next + return head \ No newline at end of file diff --git a/835.ImageOverlap/Solution.py b/835.ImageOverlap/Solution.py new file mode 100644 index 0000000..ae5a630 --- /dev/null +++ b/835.ImageOverlap/Solution.py @@ -0,0 +1,29 @@ +class Solution: + def find_all_ones(self, grid): + # given a list of list of int, return the locations where + # element == 1 + tmp_out = [] + if grid: + for i in range(len(grid[0])): + for j in range(len(grid)): + if grid[i][j] == 1: + tmp_out.append((i,j)) + return tmp_out + + def largestOverlap(self, A: List[List[int]], B: List[List[int]]) -> int: + + onesA = self.find_all_ones(A) + onesB = self.find_all_ones(B) + cache = defaultdict(int) + max_count = 0 + + for (x_a, y_a) in onesA: + for (x_b, y_b) in onesB: + vector = (x_b - x_a, y_b - y_a) + cache[vector] += 1 + max_count = max(max_count, cache[vector]) + # print(x_a, y_a, x_b, y_b) + # break + return max_count + + \ No newline at end of file diff --git a/876_Middle_of_the_Linked_List.py b/876_Middle_of_the_Linked_List.py new file mode 100644 index 0000000..d3a60b3 --- /dev/null +++ b/876_Middle_of_the_Linked_List.py @@ -0,0 +1,20 @@ +# 876. Middle of the Linked List + +# Definition for singly-linked list. +# class ListNode: +# def __init__(self, x): +# self.val = x +# self.next = None + +class Solution: + def middleNode(self, head: ListNode) -> ListNode: + mid_finder, end_finder = head, head + # while end_finder.next and end_finder.next.next: + # mid_finder = mid_finder.next + # end_finder = end_finder.next.next + # if end_finder.next: + # mid_finder = mid_finder.next + while end_finder and end_finder.next: + mid_finder = mid_finder.next + end_finder = end_finder.next.next + return mid_finder \ No newline at end of file diff --git a/937. Reorder Data in Log Files.ipynb b/937. Reorder Data in Log Files.ipynb new file mode 100644 index 0000000..796af2c --- /dev/null +++ b/937. Reorder Data in Log Files.ipynb @@ -0,0 +1,210 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "a = \"a\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a.isdigit()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "def is_digitlog(string):\n", + " strs = string.split(\" \")\n", + " for word in strs[1:]:\n", + " if not word.isdigit():\n", + " return False\n", + " return True" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['let1 art can',\n", + " 'let3 art zero',\n", + " 'let2 own kit dig',\n", + " 'dig1 8 1 5 1',\n", + " 'dig2 3 6']" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def reorderLogFiles(logs):\n", + " \"\"\"\n", + " :type logs: List[str]\n", + " :rtype: List[str]\n", + " \"\"\"\n", + " digit_logs = []\n", + " word_logs = []\n", + " for log in logs:\n", + " if is_digitlog(log):\n", + " digit_logs.append(log)\n", + " else:\n", + " # move identifier to the end for sorting\n", + " words_in_log = log.split(\" \")\n", + " log = \" \".join(words_in_log[1:])\n", + " log += \" \" + words_in_log[0]\n", + " word_logs.append(log)\n", + " word_logs = sorted(word_logs)\n", + " # move identifier back to the front\n", + " converted_back_word_logs = []\n", + " for word in word_logs:\n", + " tmp_words = word.split(\" \")\n", + " words = \" \".join(tmp_words[:-1])\n", + " words = tmp_words[-1] + \" \" + words\n", + " converted_back_word_logs.append(words)\n", + " \n", + " return converted_back_word_logs + digit_logs\n", + "\n", + "logs = [\"dig1 8 1 5 1\",\"let1 art can\",\"dig2 3 6\",\"let2 own kit dig\",\"let3 art zero\"]\n", + "reorderLogFiles(logs)" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['let1 art can',\n", + " 'let3 art zero',\n", + " 'let2 own kit dig',\n", + " 'dig1 8 1 5 1',\n", + " 'dig2 3 6']" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# better version: use configs in .sort() function:\n", + "def reorderLogFiles(logs):\n", + " \"\"\"\n", + " :type logs: List[str]\n", + " :rtype: List[str]\n", + " \"\"\"\n", + " digit_logs = []\n", + " word_logs = []\n", + " for log in logs:\n", + " if is_digitlog(log):\n", + " digit_logs.append(log)\n", + " else:\n", + " word_logs.append(log)\n", + " \n", + " # sort by identifier first\n", + " word_logs.sort(key=lambda x: x.split()[0])\n", + " word_logs.sort(key=lambda x: x.split()[1:])\n", + " return word_logs + digit_logs\n", + "\n", + "logs = [\"dig1 8 1 5 1\",\"let1 art can\",\"dig2 3 6\",\"let2 own kit dig\",\"let3 art zero\"]\n", + "reorderLogFiles(logs)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['dig1 8 1 5 1',\n", + " 'dig2 3 6',\n", + " 'let1 art can',\n", + " 'let2 own kit dig',\n", + " 'let3 art zero']" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "logs.sort(key=lambda x: x.split(\" \")[0])\n", + "logs" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/BFS_jigsaw/.ipynb_checkpoints/773_SlidingPuzzle_BFS_and_Jigsaw-Copy1-checkpoint.ipynb b/BFS_jigsaw/.ipynb_checkpoints/773_SlidingPuzzle_BFS_and_Jigsaw-Copy1-checkpoint.ipynb new file mode 100644 index 0000000..87a44db --- /dev/null +++ b/BFS_jigsaw/.ipynb_checkpoints/773_SlidingPuzzle_BFS_and_Jigsaw-Copy1-checkpoint.ipynb @@ -0,0 +1,606 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. We implement 773. Sliding Puzzle as a warmup\n", + "On a 2x3 board, there are 5 tiles represented by the integers 1 through 5, and an empty square represented by 0. \n", + "\n", + "A move consists of choosing 0 and a 4-directionally adjacent number and swapping it. \n", + "\n", + "The state of the board is solved if and only if the board is [[1,2,3],[4,5,0]]. \n", + "\n", + "Given a puzzle board, return the least number of moves required so that the state of the board is solved. If it is impossible for the state of the board to be solved, return -1." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import copy\n", + "import math" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# def slidingPuzzle(board: List[List[int]]) -> int:\n", + "# pass\n", + "len_x = 1\n", + "len_y = 2\n", + "def search_board(board, start_pos):\n", + " \"\"\"Given a board and starting position and moving direction,\n", + " make the move and return a new board.\n", + " e.g. [[1,2,3], [4,5,0]], start_pos=1, 2 (which is 0), dir=left,\n", + " return [[1,2,3], [4,0,5]]\"\"\"\n", + " x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + " out_boards = []\n", + " if y > 0:\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x][y-1] = new_board[x][y-1], new_board[x][y]\n", + " out_boards.append((new_board, x, y-1))\n", + " if y <= (len_y-1):\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x][y+1] = new_board[x][y+1], new_board[x][y]\n", + " out_boards.append((new_board, x, y+1))\n", + " if x >0:\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x-1][y] = new_board[x-1][y], new_board[x][y]\n", + " out_boards.append((new_board, x-1, y))\n", + " if x <= (len_x-1):\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x+1][y] = new_board[x+1][y], new_board[x][y]\n", + " out_boards.append((new_board, x+1, y))\n", + " return out_boards\n", + "\n", + "def slidingPuzzle(board, x, y):\n", + " step = 0\n", + " Q = [(board, x, y, step)]\n", + " seen = []\n", + " while len(Q)>0:\n", + "# import pdb; pdb.set_trace()\n", + " to_explore, x, y, step = Q.pop(0)\n", + " print(to_explore, step)\n", + " if to_explore == [[1,2,3], [4,5,0]]:\n", + " print(\"Found! at step: \",step)\n", + " return step\n", + " \n", + " if to_explore in seen:\n", + " continue\n", + " else:\n", + " seen.append(to_explore)\n", + " if 0 in to_explore[0]:\n", + " x = 0\n", + " else:\n", + " x = 1\n", + " y = to_explore[x].index(0)\n", + " \n", + " new_possibilities = search_board(board=to_explore, start_pos=(x,y))\n", + " for index, new in enumerate(new_possibilities):\n", + " new_board, new_x, new_y = new\n", + " Q.append([new_board, new_x, new_y, step+1])\n", + " return -1\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# tests:\n", + "# print(slidingPuzzle([[1,2,3], [4,5,0]]))\n", + "board = [[1,2,3],[4,0,5]]\n", + "print(slidingPuzzle(board, 1, 1)) # 1\n", + "board = [[4,1,2],[5,0,3]]\n", + "print(slidingPuzzle(board, 1, 1)) # 5" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = [[3,2,4],[1,5,0]]\n", + "print(slidingPuzzle(board, 1, 2)) # 14" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = [[1,2,3], [4,5,0]]\n", + "# tmp[1].index(0)\n", + "# if 0 in tmp[0]: x = 0, \n", + "# else: x = 1\n", + "# new_tmp = tmp.copy()\n", + "import copy\n", + "new_tmp = copy.deepcopy(tmp)\n", + "print(tmp, new_tmp)\n", + "tmp[0][0], tmp[0][1] = tmp[0][1], tmp[0][0]\n", + "print(tmp, new_tmp)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = [[[[1,2,3], [4,5,0]], 0, 0, 1]]\n", + "tmp.append([[[[1,2,6], [4,5,0]], 1, 0, 2]])\n", + "tmp" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.1 A tree version\n", + "Well. We did solve the 773 above. However, we also want a road map to the min solution. \n", + "And it seems only possible with a tree structure (that way you get a hold of the last node, find the parent, then the parent's parent, etc.)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from anytree import Node, RenderTree" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# def slidingPuzzle(board: List[List[int]]) -> int:\n", + "# pass\n", + "len_x = 1\n", + "len_y = 2\n", + "def search_board(board, start_pos):\n", + " \"\"\"Given a board and starting position and moving direction,\n", + " make the move and return a new board.\n", + " e.g. [[1,2,3], [4,5,0]], start_pos=1, 2 (which is 0), dir=left,\n", + " return [[1,2,3], [4,0,5]]\"\"\"\n", + " x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + " out_boards = []\n", + " if y > 0:\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y-1] = new_board[x][y-1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y-1))\n", + " if y <= (len_y-1):\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y+1] = new_board[x][y+1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y+1))\n", + " if x >0:\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x-1][y] = new_board[x-1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x-1, y))\n", + " if x <= (len_x-1):\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x+1][y] = new_board[x+1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x+1, y))\n", + " return out_boards\n", + "\n", + "def slidingPuzzle(board, x, y):\n", + " step = 0\n", + " Q = [(board, x, y, step)]\n", + " seen = []\n", + " while len(Q)>0:\n", + " to_explore, x, y, step = Q.pop(0)\n", + " if to_explore.name == [[1,2,3], [4,5,0]]:\n", + " return to_explore.depth\n", + " \n", + " if to_explore.name in seen:\n", + " continue\n", + " else:\n", + " seen.append(to_explore.name)\n", + " if 0 in to_explore.name[0]:\n", + " x = 0\n", + " else:\n", + " x = 1\n", + " y = to_explore.name[x].index(0)\n", + " \n", + " new_possibilities = search_board(board=to_explore, start_pos=(x,y))\n", + " for index, new in enumerate(new_possibilities):\n", + " new_board, new_x, new_y = new\n", + " Q.append([new_board, new_x, new_y, step+1])\n", + " return -1\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[1,2,3],[4,0,5]])\n", + "print(slidingPuzzle(board, 1, 1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[4,1,2],[5,0,3]])\n", + "print(slidingPuzzle(board, 1, 1))\n", + "for pre, fill, node in RenderTree(board):\n", + " print(\"%s%s\" % (pre, node.name))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[3,2,4],[1,5,0]])\n", + "print(slidingPuzzle(board, 1, 2)) # 14" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# dir(board)\n", + "# ??Node" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. We use BFS to solve the jigsaw problem.\n", + "Problem: Given a 3x3 list with non repeating numbers, \n", + "(e.g. [[5, 0, 3], [1, 2, 6], [8, 7, 9]]) \n", + "each time you can swap two adjacent numbers (up, down, left, right.) \n", + "search through the possible space to find the minimum steps required to sort it, \n", + "and print out the road map.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "len_x = 2\n", + "len_y = 2\n", + "def search_board(board, start_pos):\n", + " \"\"\"Given a board and starting position and moving direction,\n", + " make the move and return a new board.\n", + " e.g. [[1,2,3], [4,5,0]], start_pos=1, 2 (which is 0), dir=left,\n", + " return [[1,2,3], [4,0,5]]\"\"\"\n", + " x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + " out_boards = []\n", + " if y > 0: # left\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y-1] = new_board[x][y-1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y-1))\n", + " if y <= (len_y-1): #right\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y+1] = new_board[x][y+1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y+1))\n", + " if x >0: # up\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x-1][y] = new_board[x-1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x-1, y))\n", + " if x <= (len_x-1): # down\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x+1][y] = new_board[x+1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x+1, y))\n", + " return out_boards\n", + "\n", + "def slidingPuzzle(board):\n", + " Q = []\n", + " for x in range(3):\n", + " for y in range(3):\n", + " Q.append(board)\n", + "# Q.append((board, x, y))\n", + " seen = []\n", + " while len(Q)>0:\n", + "# import pdb; pdb.set_trace()\n", + "# to_explore, x, y = Q.pop(0)\n", + "# print(to_explore.name, to_explore.depth)\n", + " to_explore = Q.pop(0)\n", + " if len(seen)%100 == 0:\n", + " print(len(seen), to_explore.depth)\n", + " if to_explore.name == [[1,2,3], [4,5,6], [7,8,9]]:\n", + " return to_explore.depth, to_explore\n", + " for x in range(3):\n", + " for y in range(3):\n", + " new_possibilities = search_board(board=to_explore, start_pos=(x,y))\n", + " for index, new in enumerate(new_possibilities):\n", + " new_board, _, _ = new\n", + " if new_board.name not in seen:\n", + " seen.append(new_board.name)\n", + " Q.append(new_board)\n", + " return -1, None" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# test\n", + "board = Node([[1,2,3],[4,5,6], [7,8,9]])\n", + "%time print(slidingPuzzle(board)) # 0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "board = Node([[1,2,3],[4,5,6], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "board = Node([[1,2,3],[4,6,5], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[1,2,3],[6,4,5], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[1,6,3],[4,2,5], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[4,6,3],[7,2,5], [1,9,8]])\n", + "%time tmp = slidingPuzzle(board)\n", + "print(tmp) # 5" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[5,4,6],[9,7,2], [8,1,3]])\n", + "%time tmp = slidingPuzzle(board)\n", + "print(tmp) # ghost examiner" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "ERROR:root:Internal Python error in the inspect module.\n", + "Below is the traceback from this internal error.\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Traceback (most recent call last):\n", + " File \"/Users/toby/.local/lib/python3.6/site-packages/IPython/core/magics/execution.py\", line 1310, in time\n", + " exec(code, glob, local_ns)\n", + " File \"\", line 1, in \n", + " File \"\", line 52, in slidingPuzzle\n", + " if new_board.name not in seen:\n", + "KeyboardInterrupt\n", + "\n", + "During handling of the above exception, another exception occurred:\n", + "\n", + "Traceback (most recent call last):\n", + " File \"/Users/toby/.local/lib/python3.6/site-packages/IPython/core/interactiveshell.py\", line 2039, in showtraceback\n", + " stb = value._render_traceback_()\n", + "AttributeError: 'KeyboardInterrupt' object has no attribute '_render_traceback_'\n", + "\n", + "During handling of the above exception, another exception occurred:\n", + "\n", + "Traceback (most recent call last):\n", + " File \"/Users/toby/.local/lib/python3.6/site-packages/IPython/core/ultratb.py\", line 1101, in get_records\n", + " return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset)\n", + " File \"/Users/toby/.local/lib/python3.6/site-packages/IPython/core/ultratb.py\", line 319, in wrapped\n", + " return f(*args, **kwargs)\n", + " File \"/Users/toby/.local/lib/python3.6/site-packages/IPython/core/ultratb.py\", line 353, in _fixed_getinnerframes\n", + " records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))\n", + " File \"/Users/toby/anaconda3/envs/py36/lib/python3.6/inspect.py\", line 1490, in getinnerframes\n", + " frameinfo = (tb.tb_frame,) + getframeinfo(tb, context)\n", + " File \"/Users/toby/anaconda3/envs/py36/lib/python3.6/inspect.py\", line 1452, in getframeinfo\n", + " lines, lnum = findsource(frame)\n", + " File \"/Users/toby/.local/lib/python3.6/site-packages/IPython/core/ultratb.py\", line 185, in findsource\n", + " lines = linecache.getlines(file, globals_dict)\n", + " File \"/Users/toby/anaconda3/envs/py36/lib/python3.6/linecache.py\", line 47, in getlines\n", + " return updatecache(filename, module_globals)\n", + " File \"/Users/toby/anaconda3/envs/py36/lib/python3.6/linecache.py\", line 137, in updatecache\n", + " lines = fp.readlines()\n", + " File \"/Users/toby/anaconda3/envs/py36/lib/python3.6/codecs.py\", line 318, in decode\n", + " def decode(self, input, final=False):\n", + "KeyboardInterrupt\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n", + "KeyboardInterrupt\n", + "\n" + ] + } + ], + "source": [ + "board = Node([[6,7,9],[2,3,8], [4,1,5]])\n", + "%time tmp = slidingPuzzle(board)\n", + "print(tmp) # human examiner" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[7,5,1],[6,2,9], [4,3,8]])\n", + "%time tmp2 = slidingPuzzle(board)\n", + "print(tmp2) # fairy examiner" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + "# if direction=='left' and y > 0:\n", + "# board[x][y], board[x][y-1] = board[x][y-1], board[x][y]\n", + "# if direction=='right' and to_explore.name, x, yy <= (len_y-1):\n", + "# board[x][y], board[x][y+1] = board[x][y+1], board[x][y]\n", + "# if direction=='up' and x >0:\n", + "# board[x][y], board[x-1][y] = board[x-1][y], board[x][y]\n", + "# if direction=='down' and x <= (len_x-1):\n", + "# board[x][y], board[x+1][y] = board[x+1][y], board[x][y]\n", + "# return board\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# from anytree import Node, RenderTree\n", + "\n", + "# udo = Node(\"Udo\")\n", + "# marc = Node(\"Marc\", parent=udo)\n", + "# lian = Node(\"Lian\", parent=marc)\n", + "# dan = Node(\"Dan\", parent=udo)\n", + "# jet = Node(\"Jet\", parent=dan)\n", + "# jan = Node(\"Jan\", parent=dan)\n", + "# joe = Node(\"Joe\", parent=dan)\n", + "\n", + "# print(udo)\n", + "# Node('/Udo')\n", + "# print(joe)\n", + "# Node('/Udo/Dan/Joe')\n", + "\n", + "# for pre, fill, node in RenderTree(udo):\n", + "# print(\"%s%s\" % (pre, node.name))\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/BFS_jigsaw/.ipynb_checkpoints/773_SlidingPuzzle_BFS_and_Jigsaw-checkpoint.ipynb b/BFS_jigsaw/.ipynb_checkpoints/773_SlidingPuzzle_BFS_and_Jigsaw-checkpoint.ipynb new file mode 100644 index 0000000..108aad3 --- /dev/null +++ b/BFS_jigsaw/.ipynb_checkpoints/773_SlidingPuzzle_BFS_and_Jigsaw-checkpoint.ipynb @@ -0,0 +1,1224 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. We implement 773. Sliding Puzzle as a warmup\n", + "On a 2x3 board, there are 5 tiles represented by the integers 1 through 5, and an empty square represented by 0. \n", + "\n", + "A move consists of choosing 0 and a 4-directionally adjacent number and swapping it. \n", + "\n", + "The state of the board is solved if and only if the board is [[1,2,3],[4,5,0]]. \n", + "\n", + "Given a puzzle board, return the least number of moves required so that the state of the board is solved. If it is impossible for the state of the board to be solved, return -1." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import copy\n", + "import math\n", + "\n", + "from anytree import Node, RenderTree" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": {}, + "outputs": [], + "source": [ + "# def slidingPuzzle(board: List[List[int]]) -> int:\n", + "# pass\n", + "len_x = 1\n", + "len_y = 2\n", + "def search_board(board, start_pos):\n", + " \"\"\"Given a board and starting position and moving direction,\n", + " make the move and return a new board.\n", + " e.g. [[1,2,3], [4,5,0]], start_pos=1, 2 (which is 0), dir=left,\n", + " return [[1,2,3], [4,0,5]]\"\"\"\n", + " x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + " out_boards = []\n", + " if y > 0:\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x][y-1] = new_board[x][y-1], new_board[x][y]\n", + " out_boards.append((new_board, x, y-1))\n", + " if y <= (len_y-1):\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x][y+1] = new_board[x][y+1], new_board[x][y]\n", + " out_boards.append((new_board, x, y+1))\n", + " if x >0:\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x-1][y] = new_board[x-1][y], new_board[x][y]\n", + " out_boards.append((new_board, x-1, y))\n", + " if x <= (len_x-1):\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x+1][y] = new_board[x+1][y], new_board[x][y]\n", + " out_boards.append((new_board, x+1, y))\n", + " return out_boards\n", + "\n", + "def slidingPuzzle(board, x, y):\n", + " step = 0\n", + " Q = [(board, x, y, step)]\n", + " seen = []\n", + " while len(Q)>0:\n", + "# import pdb; pdb.set_trace()\n", + " to_explore, x, y, step = Q.pop(0)\n", + " print(to_explore, step)\n", + " if to_explore == [[1,2,3], [4,5,0]]:\n", + " print(\"Found! at step: \",step)\n", + " return step\n", + " \n", + " if to_explore in seen:\n", + " continue\n", + " else:\n", + " seen.append(to_explore)\n", + " if 0 in to_explore[0]:\n", + " x = 0\n", + " else:\n", + " x = 1\n", + " y = to_explore[x].index(0)\n", + " \n", + " new_possibilities = search_board(board=to_explore, start_pos=(x,y))\n", + " for index, new in enumerate(new_possibilities):\n", + " new_board, new_x, new_y = new\n", + " Q.append([new_board, new_x, new_y, step+1])\n", + " return -1\n" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1, 2, 3], [4, 0, 5]] 0\n", + "[[1, 2, 3], [0, 4, 5]] 1\n", + "[[1, 2, 3], [4, 5, 0]] 1\n", + "Found! at step: 1\n", + "1\n", + "[[4, 1, 2], [5, 0, 3]] 0\n", + "[[4, 1, 2], [0, 5, 3]] 1\n", + "[[4, 1, 2], [5, 3, 0]] 1\n", + "[[4, 0, 2], [5, 1, 3]] 1\n", + "[[4, 1, 2], [5, 0, 3]] 2\n", + "[[0, 1, 2], [4, 5, 3]] 2\n", + "[[4, 1, 2], [5, 0, 3]] 2\n", + "[[4, 1, 0], [5, 3, 2]] 2\n", + "[[0, 4, 2], [5, 1, 3]] 2\n", + "[[4, 2, 0], [5, 1, 3]] 2\n", + "[[4, 1, 2], [5, 0, 3]] 2\n", + "[[1, 0, 2], [4, 5, 3]] 3\n", + "[[4, 1, 2], [0, 5, 3]] 3\n", + "[[4, 0, 1], [5, 3, 2]] 3\n", + "[[4, 1, 2], [5, 3, 0]] 3\n", + "[[4, 0, 2], [5, 1, 3]] 3\n", + "[[5, 4, 2], [0, 1, 3]] 3\n", + "[[4, 0, 2], [5, 1, 3]] 3\n", + "[[4, 2, 3], [5, 1, 0]] 3\n", + "[[0, 1, 2], [4, 5, 3]] 4\n", + "[[1, 2, 0], [4, 5, 3]] 4\n", + "[[1, 5, 2], [4, 0, 3]] 4\n", + "[[0, 4, 1], [5, 3, 2]] 4\n", + "[[4, 1, 0], [5, 3, 2]] 4\n", + "[[4, 3, 1], [5, 0, 2]] 4\n", + "[[5, 4, 2], [1, 0, 3]] 4\n", + "[[0, 4, 2], [5, 1, 3]] 4\n", + "[[4, 2, 3], [5, 0, 1]] 4\n", + "[[4, 2, 0], [5, 1, 3]] 4\n", + "[[1, 0, 2], [4, 5, 3]] 5\n", + "[[1, 2, 3], [4, 5, 0]] 5\n", + "Found! at step: 5\n", + "5\n" + ] + } + ], + "source": [ + "# tests:\n", + "# print(slidingPuzzle([[1,2,3], [4,5,0]]))\n", + "board = [[1,2,3],[4,0,5]]\n", + "print(slidingPuzzle(board, 1, 1)) # 1\n", + "board = [[4,1,2],[5,0,3]]\n", + "print(slidingPuzzle(board, 1, 1)) # 5" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[3, 2, 4], [1, 5, 0]] 0\n", + "[[3, 2, 4], [1, 0, 5]] 1\n", + "[[3, 2, 0], [1, 5, 4]] 1\n", + "[[3, 2, 4], [0, 1, 5]] 2\n", + "[[3, 2, 4], [1, 5, 0]] 2\n", + "[[3, 0, 4], [1, 2, 5]] 2\n", + "[[3, 0, 2], [1, 5, 4]] 2\n", + "[[3, 2, 4], [1, 5, 0]] 2\n", + "[[3, 2, 4], [1, 0, 5]] 3\n", + "[[0, 2, 4], [3, 1, 5]] 3\n", + "[[0, 3, 4], [1, 2, 5]] 3\n", + "[[3, 4, 0], [1, 2, 5]] 3\n", + "[[3, 2, 4], [1, 0, 5]] 3\n", + "[[0, 3, 2], [1, 5, 4]] 3\n", + "[[3, 2, 0], [1, 5, 4]] 3\n", + "[[3, 5, 2], [1, 0, 4]] 3\n", + "[[2, 0, 4], [3, 1, 5]] 4\n", + "[[3, 2, 4], [0, 1, 5]] 4\n", + "[[3, 0, 4], [1, 2, 5]] 4\n", + "[[1, 3, 4], [0, 2, 5]] 4\n", + "[[3, 0, 4], [1, 2, 5]] 4\n", + "[[3, 4, 5], [1, 2, 0]] 4\n", + "[[3, 0, 2], [1, 5, 4]] 4\n", + "[[1, 3, 2], [0, 5, 4]] 4\n", + "[[3, 5, 2], [0, 1, 4]] 4\n", + "[[3, 5, 2], [1, 4, 0]] 4\n", + "[[3, 0, 2], [1, 5, 4]] 4\n", + "[[0, 2, 4], [3, 1, 5]] 5\n", + "[[2, 4, 0], [3, 1, 5]] 5\n", + "[[2, 1, 4], [3, 0, 5]] 5\n", + "[[1, 3, 4], [2, 0, 5]] 5\n", + "[[0, 3, 4], [1, 2, 5]] 5\n", + "[[3, 4, 5], [1, 0, 2]] 5\n", + "[[3, 4, 0], [1, 2, 5]] 5\n", + "[[1, 3, 2], [5, 0, 4]] 5\n", + "[[0, 3, 2], [1, 5, 4]] 5\n", + "[[3, 5, 2], [1, 0, 4]] 5\n", + "[[0, 5, 2], [3, 1, 4]] 5\n", + "[[3, 5, 2], [1, 0, 4]] 5\n", + "[[3, 5, 0], [1, 4, 2]] 5\n", + "[[2, 0, 4], [3, 1, 5]] 6\n", + "[[2, 4, 5], [3, 1, 0]] 6\n", + "[[2, 1, 4], [0, 3, 5]] 6\n", + "[[2, 1, 4], [3, 5, 0]] 6\n", + "[[2, 0, 4], [3, 1, 5]] 6\n", + "[[1, 3, 4], [0, 2, 5]] 6\n", + "[[1, 3, 4], [2, 5, 0]] 6\n", + "[[1, 0, 4], [2, 3, 5]] 6\n", + "[[3, 4, 5], [0, 1, 2]] 6\n", + "[[3, 4, 5], [1, 2, 0]] 6\n", + "[[3, 0, 5], [1, 4, 2]] 6\n", + "[[1, 3, 2], [0, 5, 4]] 6\n", + "[[1, 3, 2], [5, 4, 0]] 6\n", + "[[1, 0, 2], [5, 3, 4]] 6\n", + "[[5, 0, 2], [3, 1, 4]] 6\n", + "[[3, 5, 2], [0, 1, 4]] 6\n", + "[[3, 0, 5], [1, 4, 2]] 6\n", + "[[3, 5, 2], [1, 4, 0]] 6\n", + "[[2, 4, 5], [3, 0, 1]] 7\n", + "[[2, 4, 0], [3, 1, 5]] 7\n", + "[[2, 1, 4], [3, 0, 5]] 7\n", + "[[0, 1, 4], [2, 3, 5]] 7\n", + "[[2, 1, 4], [3, 0, 5]] 7\n", + "[[2, 1, 0], [3, 5, 4]] 7\n", + "[[1, 3, 4], [2, 0, 5]] 7\n", + "[[1, 3, 0], [2, 5, 4]] 7\n", + "[[0, 1, 4], [2, 3, 5]] 7\n", + "[[1, 4, 0], [2, 3, 5]] 7\n", + "[[1, 3, 4], [2, 0, 5]] 7\n", + "[[3, 4, 5], [1, 0, 2]] 7\n", + "[[0, 4, 5], [3, 1, 2]] 7\n", + "[[0, 3, 5], [1, 4, 2]] 7\n", + "[[3, 5, 0], [1, 4, 2]] 7\n", + "[[3, 4, 5], [1, 0, 2]] 7\n", + "[[1, 3, 2], [5, 0, 4]] 7\n", + "[[1, 3, 0], [5, 4, 2]] 7\n", + "[[0, 1, 2], [5, 3, 4]] 7\n", + "[[1, 2, 0], [5, 3, 4]] 7\n", + "[[1, 3, 2], [5, 0, 4]] 7\n", + "[[0, 5, 2], [3, 1, 4]] 7\n", + "[[5, 2, 0], [3, 1, 4]] 7\n", + "[[5, 1, 2], [3, 0, 4]] 7\n", + "[[2, 4, 5], [0, 3, 1]] 8\n", + "[[2, 4, 5], [3, 1, 0]] 8\n", + "[[2, 0, 5], [3, 4, 1]] 8\n", + "[[1, 0, 4], [2, 3, 5]] 8\n", + "[[2, 1, 4], [0, 3, 5]] 8\n", + "[[2, 0, 1], [3, 5, 4]] 8\n", + "[[2, 1, 4], [3, 5, 0]] 8\n", + "[[1, 0, 3], [2, 5, 4]] 8\n", + "[[1, 3, 4], [2, 5, 0]] 8\n", + "[[1, 0, 4], [2, 3, 5]] 8\n", + "[[1, 4, 5], [2, 3, 0]] 8\n", + "[[4, 0, 5], [3, 1, 2]] 8\n", + "[[3, 4, 5], [0, 1, 2]] 8\n", + "[[3, 0, 5], [1, 4, 2]] 8\n", + "[[1, 3, 5], [0, 4, 2]] 8\n", + "[[1, 0, 3], [5, 4, 2]] 8\n", + "[[1, 3, 2], [5, 4, 0]] 8\n", + "[[1, 0, 2], [5, 3, 4]] 8\n", + "[[5, 1, 2], [0, 3, 4]] 8\n", + "[[1, 0, 2], [5, 3, 4]] 8\n", + "[[1, 2, 4], [5, 3, 0]] 8\n", + "[[5, 0, 2], [3, 1, 4]] 8\n", + "[[5, 2, 4], [3, 1, 0]] 8\n", + "[[5, 1, 2], [0, 3, 4]] 8\n", + "[[5, 1, 2], [3, 4, 0]] 8\n", + "[[5, 0, 2], [3, 1, 4]] 8\n", + "[[2, 4, 5], [3, 0, 1]] 9\n", + "[[0, 4, 5], [2, 3, 1]] 9\n", + "[[0, 2, 5], [3, 4, 1]] 9\n", + "[[2, 5, 0], [3, 4, 1]] 9\n", + "[[2, 4, 5], [3, 0, 1]] 9\n", + "[[0, 2, 1], [3, 5, 4]] 9\n", + "[[2, 1, 0], [3, 5, 4]] 9\n", + "[[2, 5, 1], [3, 0, 4]] 9\n", + "[[0, 1, 3], [2, 5, 4]] 9\n", + "[[1, 3, 0], [2, 5, 4]] 9\n", + "[[1, 5, 3], [2, 0, 4]] 9\n", + "[[1, 4, 5], [2, 0, 3]] 9\n", + "[[1, 4, 0], [2, 3, 5]] 9\n", + "[[0, 4, 5], [3, 1, 2]] 9\n", + "[[4, 5, 0], [3, 1, 2]] 9\n", + "[[4, 1, 5], [3, 0, 2]] 9\n", + "[[1, 3, 5], [4, 0, 2]] 9\n", + "[[0, 3, 5], [1, 4, 2]] 9\n", + "[[0, 1, 3], [5, 4, 2]] 9\n", + "[[1, 3, 0], [5, 4, 2]] 9\n", + "[[1, 4, 3], [5, 0, 2]] 9\n", + "[[5, 1, 2], [3, 0, 4]] 9\n", + "[[0, 1, 2], [5, 3, 4]] 9\n", + "[[1, 2, 4], [5, 0, 3]] 9\n", + "[[1, 2, 0], [5, 3, 4]] 9\n", + "[[5, 2, 4], [3, 0, 1]] 9\n", + "[[5, 2, 0], [3, 1, 4]] 9\n", + "[[5, 1, 2], [3, 0, 4]] 9\n", + "[[5, 1, 0], [3, 4, 2]] 9\n", + "[[4, 0, 5], [2, 3, 1]] 10\n", + "[[2, 4, 5], [0, 3, 1]] 10\n", + "[[2, 0, 5], [3, 4, 1]] 10\n", + "[[3, 2, 5], [0, 4, 1]] 10\n", + "[[2, 0, 5], [3, 4, 1]] 10\n", + "[[2, 5, 1], [3, 4, 0]] 10\n", + "[[2, 0, 1], [3, 5, 4]] 10\n", + "[[3, 2, 1], [0, 5, 4]] 10\n", + "[[2, 5, 1], [0, 3, 4]] 10\n", + "[[2, 5, 1], [3, 4, 0]] 10\n", + "[[2, 0, 1], [3, 5, 4]] 10\n", + "[[1, 0, 3], [2, 5, 4]] 10\n", + "[[2, 1, 3], [0, 5, 4]] 10\n", + "[[1, 5, 3], [0, 2, 4]] 10\n", + "[[1, 5, 3], [2, 4, 0]] 10\n", + "[[1, 0, 3], [2, 5, 4]] 10\n", + "[[1, 4, 5], [0, 2, 3]] 10\n", + "[[1, 4, 5], [2, 3, 0]] 10\n", + "[[1, 0, 5], [2, 4, 3]] 10\n", + "[[4, 0, 5], [3, 1, 2]] 10\n", + "[[4, 5, 2], [3, 1, 0]] 10\n", + "[[4, 1, 5], [0, 3, 2]] 10\n", + "[[4, 1, 5], [3, 2, 0]] 10\n", + "[[4, 0, 5], [3, 1, 2]] 10\n", + "[[1, 3, 5], [0, 4, 2]] 10\n", + "[[1, 3, 5], [4, 2, 0]] 10\n", + "[[1, 0, 5], [4, 3, 2]] 10\n", + "[[1, 0, 3], [5, 4, 2]] 10\n", + "[[5, 1, 3], [0, 4, 2]] 10\n", + "[[1, 4, 3], [0, 5, 2]] 10\n", + "[[1, 4, 3], [5, 2, 0]] 10\n", + "[[1, 0, 3], [5, 4, 2]] 10\n", + "[[1, 2, 4], [0, 5, 3]] 10\n", + "[[1, 2, 4], [5, 3, 0]] 10\n", + "[[1, 0, 4], [5, 2, 3]] 10\n", + "[[5, 2, 4], [0, 3, 1]] 10\n", + "[[5, 2, 4], [3, 1, 0]] 10\n", + "[[5, 0, 4], [3, 2, 1]] 10\n", + "[[5, 0, 1], [3, 4, 2]] 10\n", + "[[5, 1, 2], [3, 4, 0]] 10\n", + "[[0, 4, 5], [2, 3, 1]] 11\n", + "[[4, 5, 0], [2, 3, 1]] 11\n", + "[[4, 3, 5], [2, 0, 1]] 11\n", + "[[3, 2, 5], [4, 0, 1]] 11\n", + "[[0, 2, 5], [3, 4, 1]] 11\n", + "[[2, 5, 1], [3, 0, 4]] 11\n", + "[[2, 5, 0], [3, 4, 1]] 11\n", + "[[3, 2, 1], [5, 0, 4]] 11\n", + "[[0, 2, 1], [3, 5, 4]] 11\n", + "[[2, 5, 1], [3, 0, 4]] 11\n", + "[[0, 5, 1], [2, 3, 4]] 11\n", + "[[2, 1, 3], [5, 0, 4]] 11\n", + "[[0, 1, 3], [2, 5, 4]] 11\n", + "[[1, 5, 3], [2, 0, 4]] 11\n", + "[[0, 5, 3], [1, 2, 4]] 11\n", + "[[1, 5, 3], [2, 0, 4]] 11\n", + "[[1, 5, 0], [2, 4, 3]] 11\n", + "[[1, 4, 5], [2, 0, 3]] 11\n", + "[[0, 4, 5], [1, 2, 3]] 11\n", + "[[0, 1, 5], [2, 4, 3]] 11\n", + "[[1, 5, 0], [2, 4, 3]] 11\n", + "[[1, 4, 5], [2, 0, 3]] 11\n", + "[[4, 5, 2], [3, 0, 1]] 11\n", + "[[4, 5, 0], [3, 1, 2]] 11\n", + "[[4, 1, 5], [3, 0, 2]] 11\n", + "[[0, 1, 5], [4, 3, 2]] 11\n", + "[[4, 1, 5], [3, 0, 2]] 11\n", + "[[4, 1, 0], [3, 2, 5]] 11\n", + "[[1, 3, 5], [4, 0, 2]] 11\n", + "[[1, 3, 0], [4, 2, 5]] 11\n", + "[[0, 1, 5], [4, 3, 2]] 11\n", + "[[1, 5, 0], [4, 3, 2]] 11\n", + "[[1, 3, 5], [4, 0, 2]] 11\n", + "[[5, 1, 3], [4, 0, 2]] 11\n", + "[[0, 1, 3], [5, 4, 2]] 11\n", + "[[1, 4, 3], [5, 0, 2]] 11\n", + "[[0, 4, 3], [1, 5, 2]] 11\n", + "[[1, 4, 3], [5, 0, 2]] 11\n", + "[[1, 4, 0], [5, 2, 3]] 11\n", + "[[1, 2, 4], [5, 0, 3]] 11\n", + "[[0, 2, 4], [1, 5, 3]] 11\n", + "[[0, 1, 4], [5, 2, 3]] 11\n", + "[[1, 4, 0], [5, 2, 3]] 11\n", + "[[1, 2, 4], [5, 0, 3]] 11\n", + "[[5, 2, 4], [3, 0, 1]] 11\n", + "[[0, 2, 4], [5, 3, 1]] 11\n", + "[[0, 5, 4], [3, 2, 1]] 11\n", + "[[5, 4, 0], [3, 2, 1]] 11\n", + "[[5, 2, 4], [3, 0, 1]] 11\n", + "[[0, 5, 1], [3, 4, 2]] 11\n", + "[[5, 1, 0], [3, 4, 2]] 11\n", + "[[5, 4, 1], [3, 0, 2]] 11\n", + "[[4, 0, 5], [2, 3, 1]] 12\n", + "[[4, 5, 1], [2, 3, 0]] 12\n", + "[[4, 3, 5], [0, 2, 1]] 12\n", + "[[4, 3, 5], [2, 1, 0]] 12\n", + "[[4, 0, 5], [2, 3, 1]] 12\n", + "[[3, 2, 5], [0, 4, 1]] 12\n", + "[[3, 2, 5], [4, 1, 0]] 12\n", + "[[3, 0, 5], [4, 2, 1]] 12\n", + "[[3, 2, 1], [0, 5, 4]] 12\n", + "[[3, 2, 1], [5, 4, 0]] 12\n", + "[[3, 0, 1], [5, 2, 4]] 12\n", + "[[5, 0, 1], [2, 3, 4]] 12\n", + "[[2, 5, 1], [0, 3, 4]] 12\n", + "[[2, 1, 3], [0, 5, 4]] 12\n", + "[[2, 1, 3], [5, 4, 0]] 12\n", + "[[2, 0, 3], [5, 1, 4]] 12\n", + "[[5, 0, 3], [1, 2, 4]] 12\n", + "[[1, 5, 3], [0, 2, 4]] 12\n", + "[[1, 0, 5], [2, 4, 3]] 12\n", + "[[1, 5, 3], [2, 4, 0]] 12\n", + "[[4, 0, 5], [1, 2, 3]] 12\n", + "[[1, 4, 5], [0, 2, 3]] 12\n", + "[[1, 0, 5], [2, 4, 3]] 12\n", + "[[2, 1, 5], [0, 4, 3]] 12\n", + "[[4, 5, 2], [0, 3, 1]] 12\n", + "[[4, 5, 2], [3, 1, 0]] 12\n", + "[[4, 0, 2], [3, 5, 1]] 12\n", + "[[1, 0, 5], [4, 3, 2]] 12\n", + "[[4, 1, 5], [0, 3, 2]] 12\n", + "[[4, 0, 1], [3, 2, 5]] 12\n", + "[[4, 1, 5], [3, 2, 0]] 12\n", + "[[1, 0, 3], [4, 2, 5]] 12\n", + "[[1, 3, 5], [4, 2, 0]] 12\n", + "[[1, 0, 5], [4, 3, 2]] 12\n", + "[[1, 5, 2], [4, 3, 0]] 12\n", + "[[5, 1, 3], [0, 4, 2]] 12\n", + "[[5, 1, 3], [4, 2, 0]] 12\n", + "[[5, 0, 3], [4, 1, 2]] 12\n", + "[[4, 0, 3], [1, 5, 2]] 12\n", + "[[1, 4, 3], [0, 5, 2]] 12\n", + "[[1, 0, 4], [5, 2, 3]] 12\n", + "[[1, 4, 3], [5, 2, 0]] 12\n", + "[[2, 0, 4], [1, 5, 3]] 12\n", + "[[1, 2, 4], [0, 5, 3]] 12\n", + "[[1, 0, 4], [5, 2, 3]] 12\n", + "[[5, 1, 4], [0, 2, 3]] 12\n", + "[[2, 0, 4], [5, 3, 1]] 12\n", + "[[5, 2, 4], [0, 3, 1]] 12\n", + "[[5, 0, 4], [3, 2, 1]] 12\n", + "[[3, 5, 4], [0, 2, 1]] 12\n", + "[[5, 0, 4], [3, 2, 1]] 12\n", + "[[5, 4, 1], [3, 2, 0]] 12\n", + "[[5, 0, 1], [3, 4, 2]] 12\n", + "[[3, 5, 1], [0, 4, 2]] 12\n", + "[[5, 4, 1], [0, 3, 2]] 12\n", + "[[5, 4, 1], [3, 2, 0]] 12\n", + "[[5, 0, 1], [3, 4, 2]] 12\n", + "[[4, 5, 1], [2, 0, 3]] 13\n", + "[[4, 5, 0], [2, 3, 1]] 13\n", + "[[4, 3, 5], [2, 0, 1]] 13\n", + "[[0, 3, 5], [4, 2, 1]] 13\n", + "[[4, 3, 5], [2, 0, 1]] 13\n", + "[[4, 3, 0], [2, 1, 5]] 13\n", + "[[3, 2, 5], [4, 0, 1]] 13\n", + "[[3, 2, 0], [4, 1, 5]] 13\n", + "[[0, 3, 5], [4, 2, 1]] 13\n", + "[[3, 5, 0], [4, 2, 1]] 13\n", + "[[3, 2, 5], [4, 0, 1]] 13\n", + "[[3, 2, 1], [5, 0, 4]] 13\n", + "[[3, 2, 0], [5, 4, 1]] 13\n", + "[[0, 3, 1], [5, 2, 4]] 13\n", + "[[3, 1, 0], [5, 2, 4]] 13\n", + "[[3, 2, 1], [5, 0, 4]] 13\n", + "[[0, 5, 1], [2, 3, 4]] 13\n", + "[[5, 1, 0], [2, 3, 4]] 13\n", + "[[5, 3, 1], [2, 0, 4]] 13\n", + "[[2, 1, 3], [5, 0, 4]] 13\n", + "[[2, 1, 0], [5, 4, 3]] 13\n", + "[[0, 2, 3], [5, 1, 4]] 13\n", + "[[2, 3, 0], [5, 1, 4]] 13\n", + "[[2, 1, 3], [5, 0, 4]] 13\n", + "[[0, 5, 3], [1, 2, 4]] 13\n", + "[[5, 3, 0], [1, 2, 4]] 13\n", + "[[5, 2, 3], [1, 0, 4]] 13\n", + "[[0, 4, 5], [1, 2, 3]] 13\n", + "[[4, 5, 0], [1, 2, 3]] 13\n", + "[[4, 2, 5], [1, 0, 3]] 13\n", + "[[2, 1, 5], [4, 0, 3]] 13\n", + "[[0, 1, 5], [2, 4, 3]] 13\n", + "[[4, 5, 2], [3, 0, 1]] 13\n", + "[[0, 5, 2], [4, 3, 1]] 13\n", + "[[0, 4, 2], [3, 5, 1]] 13\n", + "[[4, 2, 0], [3, 5, 1]] 13\n", + "[[4, 5, 2], [3, 0, 1]] 13\n", + "[[0, 4, 1], [3, 2, 5]] 13\n", + "[[4, 1, 0], [3, 2, 5]] 13\n", + "[[4, 2, 1], [3, 0, 5]] 13\n", + "[[0, 1, 3], [4, 2, 5]] 13\n", + "[[1, 3, 0], [4, 2, 5]] 13\n", + "[[1, 2, 3], [4, 0, 5]] 13\n", + "[[1, 5, 2], [4, 0, 3]] 13\n", + "[[1, 5, 0], [4, 3, 2]] 13\n", + "[[5, 1, 3], [4, 0, 2]] 13\n", + "[[5, 1, 0], [4, 2, 3]] 13\n", + "[[0, 5, 3], [4, 1, 2]] 13\n", + "[[5, 3, 0], [4, 1, 2]] 13\n", + "[[5, 1, 3], [4, 0, 2]] 13\n", + "[[0, 4, 3], [1, 5, 2]] 13\n", + "[[4, 3, 0], [1, 5, 2]] 13\n", + "[[4, 5, 3], [1, 0, 2]] 13\n", + "[[0, 2, 4], [1, 5, 3]] 13\n", + "[[2, 4, 0], [1, 5, 3]] 13\n", + "[[2, 5, 4], [1, 0, 3]] 13\n", + "[[5, 1, 4], [2, 0, 3]] 13\n", + "[[0, 1, 4], [5, 2, 3]] 13\n", + "[[0, 2, 4], [5, 3, 1]] 13\n", + "[[2, 4, 0], [5, 3, 1]] 13\n", + "[[2, 3, 4], [5, 0, 1]] 13\n", + "[[3, 5, 4], [2, 0, 1]] 13\n", + "[[0, 5, 4], [3, 2, 1]] 13\n", + "[[5, 4, 1], [3, 0, 2]] 13\n", + "[[5, 4, 0], [3, 2, 1]] 13\n", + "[[3, 5, 1], [4, 0, 2]] 13\n", + "[[0, 5, 1], [3, 4, 2]] 13\n", + "[[5, 4, 1], [3, 0, 2]] 13\n", + "[[0, 4, 1], [5, 3, 2]] 13\n", + "[[4, 5, 1], [0, 2, 3]] 14\n", + "[[4, 5, 1], [2, 3, 0]] 14\n", + "[[4, 0, 1], [2, 5, 3]] 14\n", + "[[3, 0, 5], [4, 2, 1]] 14\n", + "[[4, 3, 5], [0, 2, 1]] 14\n", + "[[4, 0, 3], [2, 1, 5]] 14\n", + "[[4, 3, 5], [2, 1, 0]] 14\n", + "[[3, 0, 2], [4, 1, 5]] 14\n", + "[[3, 2, 5], [4, 1, 0]] 14\n", + "[[3, 0, 5], [4, 2, 1]] 14\n", + "[[3, 5, 1], [4, 2, 0]] 14\n", + "[[3, 0, 2], [5, 4, 1]] 14\n", + "[[3, 2, 1], [5, 4, 0]] 14\n", + "[[3, 0, 1], [5, 2, 4]] 14\n", + "[[5, 3, 1], [0, 2, 4]] 14\n", + "[[3, 0, 1], [5, 2, 4]] 14\n", + "[[3, 1, 4], [5, 2, 0]] 14\n", + "[[5, 0, 1], [2, 3, 4]] 14\n", + "[[5, 1, 4], [2, 3, 0]] 14\n", + "[[5, 3, 1], [0, 2, 4]] 14\n", + "[[5, 3, 1], [2, 4, 0]] 14\n", + "[[5, 0, 1], [2, 3, 4]] 14\n", + "[[2, 0, 1], [5, 4, 3]] 14\n", + "[[2, 1, 3], [5, 4, 0]] 14\n", + "[[2, 0, 3], [5, 1, 4]] 14\n", + "[[5, 2, 3], [0, 1, 4]] 14\n", + "[[2, 0, 3], [5, 1, 4]] 14\n", + "[[2, 3, 4], [5, 1, 0]] 14\n", + "[[5, 0, 3], [1, 2, 4]] 14\n", + "[[5, 3, 4], [1, 2, 0]] 14\n", + "[[5, 2, 3], [0, 1, 4]] 14\n", + "[[5, 2, 3], [1, 4, 0]] 14\n", + "[[5, 0, 3], [1, 2, 4]] 14\n", + "[[4, 0, 5], [1, 2, 3]] 14\n", + "[[4, 5, 3], [1, 2, 0]] 14\n", + "[[4, 2, 5], [0, 1, 3]] 14\n", + "[[4, 2, 5], [1, 3, 0]] 14\n", + "[[4, 0, 5], [1, 2, 3]] 14\n", + "[[2, 1, 5], [0, 4, 3]] 14\n", + "[[2, 1, 5], [4, 3, 0]] 14\n", + "[[2, 0, 5], [4, 1, 3]] 14\n", + "[[5, 0, 2], [4, 3, 1]] 14\n", + "[[4, 5, 2], [0, 3, 1]] 14\n", + "[[4, 0, 2], [3, 5, 1]] 14\n", + "[[3, 4, 2], [0, 5, 1]] 14\n", + "[[4, 0, 2], [3, 5, 1]] 14\n", + "[[4, 2, 1], [3, 5, 0]] 14\n", + "[[4, 0, 1], [3, 2, 5]] 14\n", + "[[3, 4, 1], [0, 2, 5]] 14\n", + "[[4, 2, 1], [0, 3, 5]] 14\n", + "[[4, 2, 1], [3, 5, 0]] 14\n", + "[[4, 0, 1], [3, 2, 5]] 14\n", + "[[1, 0, 3], [4, 2, 5]] 14\n", + "[[4, 1, 3], [0, 2, 5]] 14\n", + "[[1, 2, 3], [0, 4, 5]] 14\n", + "[[1, 2, 3], [4, 5, 0]] 14\n", + "Found! at step: 14\n", + "14\n" + ] + } + ], + "source": [ + "board = [[3,2,4],[1,5,0]]\n", + "print(slidingPuzzle(board, 1, 2)) # 14" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1, 2, 3], [4, 5, 0]] [[1, 2, 3], [4, 5, 0]]\n", + "[[2, 1, 3], [4, 5, 0]] [[1, 2, 3], [4, 5, 0]]\n" + ] + } + ], + "source": [ + "tmp = [[1,2,3], [4,5,0]]\n", + "# tmp[1].index(0)\n", + "# if 0 in tmp[0]: x = 0, \n", + "# else: x = 1\n", + "# new_tmp = tmp.copy()\n", + "import copy\n", + "new_tmp = copy.deepcopy(tmp)\n", + "print(tmp, new_tmp)\n", + "tmp[0][0], tmp[0][1] = tmp[0][1], tmp[0][0]\n", + "print(tmp, new_tmp)" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[[[1, 2, 3], [4, 5, 0]], 0, 0, 1], [[[[1, 2, 6], [4, 5, 0]], 1, 0, 2]]]" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tmp = [[[[1,2,3], [4,5,0]], 0, 0, 1]]\n", + "tmp.append([[[[1,2,6], [4,5,0]], 1, 0, 2]])\n", + "tmp" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.1 A tree version\n", + "Well. We did solve the 773 above. However, we also want a road map to the min solution. \n", + "And it seems only possible with a tree structure (that way you get a hold of the last node, find the parent, then the parent's parent, etc.)" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": {}, + "outputs": [], + "source": [ + "# def slidingPuzzle(board: List[List[int]]) -> int:\n", + "# pass\n", + "len_x = 1\n", + "len_y = 2\n", + "def search_board(board, start_pos):\n", + " \"\"\"Given a board and starting position and moving direction,\n", + " make the move and return a new board.\n", + " e.g. [[1,2,3], [4,5,0]], start_pos=1, 2 (which is 0), dir=left,\n", + " return [[1,2,3], [4,0,5]]\"\"\"\n", + " x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + " out_boards = []\n", + " if y > 0:\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y-1] = new_board[x][y-1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y-1))\n", + " if y <= (len_y-1):\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y+1] = new_board[x][y+1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y+1))\n", + " if x >0:\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x-1][y] = new_board[x-1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x-1, y))\n", + " if x <= (len_x-1):\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x+1][y] = new_board[x+1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x+1, y))\n", + " return out_boards\n", + "\n", + "def slidingPuzzle(board, x, y):\n", + " step = 0\n", + " Q = [(board, x, y, step)]\n", + " seen = []\n", + " while len(Q)>0:\n", + " to_explore, x, y, step = Q.pop(0)\n", + " if to_explore.name == [[1,2,3], [4,5,0]]:\n", + " return to_explore.depth\n", + " \n", + " if to_explore.name in seen:\n", + " continue\n", + " else:\n", + " seen.append(to_explore.name)\n", + " if 0 in to_explore.name[0]:\n", + " x = 0\n", + " else:\n", + " x = 1\n", + " y = to_explore.name[x].index(0)\n", + " \n", + " new_possibilities = search_board(board=to_explore, start_pos=(x,y))\n", + " for index, new in enumerate(new_possibilities):\n", + " new_board, new_x, new_y = new\n", + " Q.append([new_board, new_x, new_y, step+1])\n", + " return -1\n" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + } + ], + "source": [ + "board = Node([[1,2,3],[4,0,5]])\n", + "print(slidingPuzzle(board, 1, 1))" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n", + "[[4, 1, 2], [5, 0, 3]]\n", + "├── [[4, 1, 2], [0, 5, 3]]\n", + "│ ├── [[4, 1, 2], [5, 0, 3]]\n", + "│ └── [[0, 1, 2], [4, 5, 3]]\n", + "│ ├── [[1, 0, 2], [4, 5, 3]]\n", + "│ │ ├── [[0, 1, 2], [4, 5, 3]]\n", + "│ │ ├── [[1, 2, 0], [4, 5, 3]]\n", + "│ │ │ ├── [[1, 0, 2], [4, 5, 3]]\n", + "│ │ │ └── [[1, 2, 3], [4, 5, 0]]\n", + "│ │ └── [[1, 5, 2], [4, 0, 3]]\n", + "│ │ ├── [[1, 5, 2], [0, 4, 3]]\n", + "│ │ ├── [[1, 5, 2], [4, 3, 0]]\n", + "│ │ └── [[1, 0, 2], [4, 5, 3]]\n", + "│ └── [[4, 1, 2], [0, 5, 3]]\n", + "├── [[4, 1, 2], [5, 3, 0]]\n", + "│ ├── [[4, 1, 2], [5, 0, 3]]\n", + "│ └── [[4, 1, 0], [5, 3, 2]]\n", + "│ ├── [[4, 0, 1], [5, 3, 2]]\n", + "│ │ ├── [[0, 4, 1], [5, 3, 2]]\n", + "│ │ │ ├── [[4, 0, 1], [5, 3, 2]]\n", + "│ │ │ └── [[5, 4, 1], [0, 3, 2]]\n", + "│ │ ├── [[4, 1, 0], [5, 3, 2]]\n", + "│ │ └── [[4, 3, 1], [5, 0, 2]]\n", + "│ │ ├── [[4, 3, 1], [0, 5, 2]]\n", + "│ │ ├── [[4, 3, 1], [5, 2, 0]]\n", + "│ │ └── [[4, 0, 1], [5, 3, 2]]\n", + "│ └── [[4, 1, 2], [5, 3, 0]]\n", + "└── [[4, 0, 2], [5, 1, 3]]\n", + " ├── [[0, 4, 2], [5, 1, 3]]\n", + " │ ├── [[4, 0, 2], [5, 1, 3]]\n", + " │ └── [[5, 4, 2], [0, 1, 3]]\n", + " │ ├── [[5, 4, 2], [1, 0, 3]]\n", + " │ │ ├── [[5, 4, 2], [0, 1, 3]]\n", + " │ │ ├── [[5, 4, 2], [1, 3, 0]]\n", + " │ │ └── [[5, 0, 2], [1, 4, 3]]\n", + " │ └── [[0, 4, 2], [5, 1, 3]]\n", + " ├── [[4, 2, 0], [5, 1, 3]]\n", + " │ ├── [[4, 0, 2], [5, 1, 3]]\n", + " │ └── [[4, 2, 3], [5, 1, 0]]\n", + " │ ├── [[4, 2, 3], [5, 0, 1]]\n", + " │ │ ├── [[4, 2, 3], [0, 5, 1]]\n", + " │ │ ├── [[4, 2, 3], [5, 1, 0]]\n", + " │ │ └── [[4, 0, 3], [5, 2, 1]]\n", + " │ └── [[4, 2, 0], [5, 1, 3]]\n", + " └── [[4, 1, 2], [5, 0, 3]]\n" + ] + } + ], + "source": [ + "board = Node([[4,1,2],[5,0,3]])\n", + "print(slidingPuzzle(board, 1, 1))\n", + "for pre, fill, node in RenderTree(board):\n", + " print(\"%s%s\" % (pre, node.name))" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "14\n" + ] + } + ], + "source": [ + "board = Node([[3,2,4],[1,5,0]])\n", + "print(slidingPuzzle(board, 1, 2)) # 14" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 103, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# dir(board)\n", + "# ??Node" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. We use BFS to solve the jigsaw problem.\n", + "Problem: Given a 3x3 list with non repeating numbers, \n", + "(e.g. [[5, 0, 3], [1, 2, 6], [8, 7, 9]]) \n", + "each time you can swap two adjacent numbers (up, down, left, right.) \n", + "search through the possible space to find the minimum steps required to sort it, \n", + "and print out the road map.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 230, + "metadata": {}, + "outputs": [], + "source": [ + "len_x = 2\n", + "len_y = 2\n", + "def search_board(board, start_pos):\n", + " \"\"\"Given a board and starting position and moving direction,\n", + " make the move and return a new board.\n", + " e.g. [[1,2,3], [4,5,0]], start_pos=1, 2 (which is 0), dir=left,\n", + " return [[1,2,3], [4,0,5]]\"\"\"\n", + " x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + " out_boards = []\n", + " if y > 0: # left\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y-1] = new_board[x][y-1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y-1))\n", + " if y <= (len_y-1): #right\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y+1] = new_board[x][y+1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y+1))\n", + " if x >0: # up\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x-1][y] = new_board[x-1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x-1, y))\n", + " if x <= (len_x-1): # down\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x+1][y] = new_board[x+1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x+1, y))\n", + " return out_boards\n", + "\n", + "def slidingPuzzle(board):\n", + " Q = []\n", + " for x in range(3):\n", + " for y in range(3):\n", + " Q.append(board)\n", + "# Q.append((board, x, y))\n", + " seen = []\n", + " while len(Q)>0:\n", + "# import pdb; pdb.set_trace()\n", + "# to_explore, x, y = Q.pop(0)\n", + "# print(to_explore.name, to_explore.depth)\n", + " to_explore = Q.pop(0)\n", + " if len(seen)%100 == 0:\n", + " print(len(seen), to_explore.depth)\n", + " if to_explore.name == [[1,2,3], [4,5,6], [7,8,9]]:\n", + " return to_explore.depth, to_explore\n", + " for x in range(3):\n", + " for y in range(3):\n", + " new_possibilities = search_board(board=to_explore, start_pos=(x,y))\n", + " for index, new in enumerate(new_possibilities):\n", + " new_board, _, _ = new\n", + " if new_board.name not in seen:\n", + " seen.append(new_board.name)\n", + " Q.append(new_board)\n", + " return -1, None" + ] + }, + { + "cell_type": "code", + "execution_count": 224, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(0, Node('/[[1, 2, 3], [4, 5, 6], [7, 8, 9]]'))\n", + "CPU times: user 108 µs, sys: 29 µs, total: 137 µs\n", + "Wall time: 125 µs\n" + ] + } + ], + "source": [ + "# test\n", + "board = Node([[1,2,3],[4,5,6], [7,8,9]])\n", + "%time print(slidingPuzzle(board)) # 0" + ] + }, + { + "cell_type": "code", + "execution_count": 222, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1, Node('/[[1, 2, 3], [4, 5, 6], [7, 9, 8]]/[[1, 2, 3], [4, 5, 6], [7, 8, 9]]'))\n", + "CPU times: user 11 ms, sys: 935 µs, total: 11.9 ms\n", + "Wall time: 11.1 ms\n" + ] + } + ], + "source": [ + "board = Node([[1,2,3],[4,5,6], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 1" + ] + }, + { + "cell_type": "code", + "execution_count": 223, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(2, Node('/[[1, 2, 3], [4, 6, 5], [7, 9, 8]]/[[1, 2, 3], [4, 5, 6], [7, 9, 8]]/[[1, 2, 3], [4, 5, 6], [7, 8, 9]]'))\n", + "CPU times: user 405 ms, sys: 16.3 ms, total: 421 ms\n", + "Wall time: 421 ms\n" + ] + } + ], + "source": [ + "board = Node([[1,2,3],[4,6,5], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 2" + ] + }, + { + "cell_type": "code", + "execution_count": 225, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(3, Node('/[[1, 2, 3], [6, 4, 5], [7, 9, 8]]/[[1, 2, 3], [4, 6, 5], [7, 9, 8]]/[[1, 2, 3], [4, 5, 6], [7, 9, 8]]/[[1, 2, 3], [4, 5, 6], [7, 8, 9]]'))\n", + "CPU times: user 758 ms, sys: 4.87 ms, total: 763 ms\n", + "Wall time: 766 ms\n" + ] + } + ], + "source": [ + "board = Node([[1,2,3],[6,4,5], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 3" + ] + }, + { + "cell_type": "code", + "execution_count": 226, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(3, Node('/[[1, 6, 3], [4, 2, 5], [7, 9, 8]]/[[1, 2, 3], [4, 6, 5], [7, 9, 8]]/[[1, 2, 3], [4, 5, 6], [7, 9, 8]]/[[1, 2, 3], [4, 5, 6], [7, 8, 9]]'))\n", + "CPU times: user 586 ms, sys: 4.77 ms, total: 591 ms\n", + "Wall time: 592 ms\n" + ] + } + ], + "source": [ + "board = Node([[1,6,3],[4,2,5], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 3" + ] + }, + { + "cell_type": "code", + "execution_count": 228, + "metadata": { + "collapsed": true + }, + "outputs": [ + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mslidingPuzzle\u001b[0;34m(board)\u001b[0m\n\u001b[1;32m 50\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnew\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_possibilities\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 51\u001b[0m \u001b[0mnew_board\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnew\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 52\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mnew_board\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mseen\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 53\u001b[0m \u001b[0mseen\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_board\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 54\u001b[0m \u001b[0mQ\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_board\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[[1, 2, 3], [4, 5, 0]], 0, 0, 1], [[[[1, 2, 6], [4, 5, 0]], 1, 0, 2]]]\n" + ] + } + ], + "source": [ + "board = Node([[4,6,3],[7,2,5], [1,9,8]])\n", + "%time tmp = slidingPuzzle(board)\n", + "print(tmp) # 5" + ] + }, + { + "cell_type": "code", + "execution_count": 229, + "metadata": {}, + "outputs": [ + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mslidingPuzzle\u001b[0;34m(board)\u001b[0m\n\u001b[1;32m 50\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnew\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_possibilities\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 51\u001b[0m \u001b[0mnew_board\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnew\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 52\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mnew_board\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mseen\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 53\u001b[0m \u001b[0mseen\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_board\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 54\u001b[0m \u001b[0mQ\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_board\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[[1, 2, 3], [4, 5, 0]], 0, 0, 1], [[[[1, 2, 6], [4, 5, 0]], 1, 0, 2]]]\n" + ] + } + ], + "source": [ + "board = Node([[5,4,6],[9,7,2], [8,1,3]])\n", + "%time tmp = slidingPuzzle(board)\n", + "print(tmp) # ghost examiner" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 231, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 0\n", + "500 2\n", + "900 3\n", + "1000 3\n", + "1800 3\n", + "2400 3\n", + "2500 3\n", + "3600 4\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mslidingPuzzle\u001b[0;34m(board)\u001b[0m\n\u001b[1;32m 51\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnew\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_possibilities\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 52\u001b[0m \u001b[0mnew_board\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnew\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 53\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mnew_board\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mseen\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 54\u001b[0m \u001b[0mseen\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_board\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 55\u001b[0m \u001b[0mQ\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_board\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[[1, 2, 3], [4, 5, 0]], 0, 0, 1], [[[[1, 2, 6], [4, 5, 0]], 1, 0, 2]]]\n" + ] + } + ], + "source": [ + "board = Node([[9,5,8],[2,4,1], [3,6,7]])\n", + "%time tmp = slidingPuzzle(board)\n", + "print(tmp) # monster examiner" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + "# if direction=='left' and y > 0:\n", + "# board[x][y], board[x][y-1] = board[x][y-1], board[x][y]\n", + "# if direction=='right' and to_explore.name, x, yy <= (len_y-1):\n", + "# board[x][y], board[x][y+1] = board[x][y+1], board[x][y]\n", + "# if direction=='up' and x >0:\n", + "# board[x][y], board[x-1][y] = board[x-1][y], board[x][y]\n", + "# if direction=='down' and x <= (len_x-1):\n", + "# board[x][y], board[x+1][y] = board[x+1][y], board[x][y]\n", + "# return board\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# from anytree import Node, RenderTree\n", + "\n", + "# udo = Node(\"Udo\")\n", + "# marc = Node(\"Marc\", parent=udo)\n", + "# lian = Node(\"Lian\", parent=marc)\n", + "# dan = Node(\"Dan\", parent=udo)\n", + "# jet = Node(\"Jet\", parent=dan)\n", + "# jan = Node(\"Jan\", parent=dan)\n", + "# joe = Node(\"Joe\", parent=dan)\n", + "\n", + "# print(udo)\n", + "# Node('/Udo')\n", + "# print(joe)\n", + "# Node('/Udo/Dan/Joe')\n", + "\n", + "# for pre, fill, node in RenderTree(udo):\n", + "# print(\"%s%s\" % (pre, node.name))\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/BFS_jigsaw/773_SlidingPuzzle_BFS_and_Jigsaw-Copy1.ipynb b/BFS_jigsaw/773_SlidingPuzzle_BFS_and_Jigsaw-Copy1.ipynb new file mode 100644 index 0000000..a5219a9 --- /dev/null +++ b/BFS_jigsaw/773_SlidingPuzzle_BFS_and_Jigsaw-Copy1.ipynb @@ -0,0 +1,762 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. We implement 773. Sliding Puzzle as a warmup\n", + "On a 2x3 board, there are 5 tiles represented by the integers 1 through 5, and an empty square represented by 0. \n", + "\n", + "A move consists of choosing 0 and a 4-directionally adjacent number and swapping it. \n", + "\n", + "The state of the board is solved if and only if the board is [[1,2,3],[4,5,0]]. \n", + "\n", + "Given a puzzle board, return the least number of moves required so that the state of the board is solved. If it is impossible for the state of the board to be solved, return -1." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import copy\n", + "import math" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# def slidingPuzzle(board: List[List[int]]) -> int:\n", + "# pass\n", + "len_x = 1\n", + "len_y = 2\n", + "def search_board(board, start_pos):\n", + " \"\"\"Given a board and starting position and moving direction,\n", + " make the move and return a new board.\n", + " e.g. [[1,2,3], [4,5,0]], start_pos=1, 2 (which is 0), dir=left,\n", + " return [[1,2,3], [4,0,5]]\"\"\"\n", + " x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + " out_boards = []\n", + " if y > 0:\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x][y-1] = new_board[x][y-1], new_board[x][y]\n", + " out_boards.append((new_board, x, y-1))\n", + " if y <= (len_y-1):\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x][y+1] = new_board[x][y+1], new_board[x][y]\n", + " out_boards.append((new_board, x, y+1))\n", + " if x >0:\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x-1][y] = new_board[x-1][y], new_board[x][y]\n", + " out_boards.append((new_board, x-1, y))\n", + " if x <= (len_x-1):\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x+1][y] = new_board[x+1][y], new_board[x][y]\n", + " out_boards.append((new_board, x+1, y))\n", + " return out_boards\n", + "\n", + "def slidingPuzzle(board, x, y):\n", + " step = 0\n", + " Q = [(board, x, y, step)]\n", + " seen = []\n", + " while len(Q)>0:\n", + "# import pdb; pdb.set_trace()\n", + " to_explore, x, y, step = Q.pop(0)\n", + " print(to_explore, step)\n", + " if to_explore == [[1,2,3], [4,5,0]]:\n", + " print(\"Found! at step: \",step)\n", + " return step\n", + " \n", + " if to_explore in seen:\n", + " continue\n", + " else:\n", + " seen.append(to_explore)\n", + " if 0 in to_explore[0]:\n", + " x = 0\n", + " else:\n", + " x = 1\n", + " y = to_explore[x].index(0)\n", + " \n", + " new_possibilities = search_board(board=to_explore, start_pos=(x,y))\n", + " for index, new in enumerate(new_possibilities):\n", + " new_board, new_x, new_y = new\n", + " Q.append([new_board, new_x, new_y, step+1])\n", + " return -1\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# tests:\n", + "# print(slidingPuzzle([[1,2,3], [4,5,0]]))\n", + "board = [[1,2,3],[4,0,5]]\n", + "print(slidingPuzzle(board, 1, 1)) # 1\n", + "board = [[4,1,2],[5,0,3]]\n", + "print(slidingPuzzle(board, 1, 1)) # 5" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = [[3,2,4],[1,5,0]]\n", + "print(slidingPuzzle(board, 1, 2)) # 14" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = [[1,2,3], [4,5,0]]\n", + "# tmp[1].index(0)\n", + "# if 0 in tmp[0]: x = 0, \n", + "# else: x = 1\n", + "# new_tmp = tmp.copy()\n", + "import copy\n", + "new_tmp = copy.deepcopy(tmp)\n", + "print(tmp, new_tmp)\n", + "tmp[0][0], tmp[0][1] = tmp[0][1], tmp[0][0]\n", + "print(tmp, new_tmp)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = [[[[1,2,3], [4,5,0]], 0, 0, 1]]\n", + "tmp.append([[[[1,2,6], [4,5,0]], 1, 0, 2]])\n", + "tmp" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.1 A tree version\n", + "Well. We did solve the 773 above. However, we also want a road map to the min solution. \n", + "And it seems only possible with a tree structure (that way you get a hold of the last node, find the parent, then the parent's parent, etc.)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from anytree import Node, RenderTree" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# def slidingPuzzle(board: List[List[int]]) -> int:\n", + "# pass\n", + "len_x = 1\n", + "len_y = 2\n", + "def search_board(board, start_pos):\n", + " \"\"\"Given a board and starting position and moving direction,\n", + " make the move and return a new board.\n", + " e.g. [[1,2,3], [4,5,0]], start_pos=1, 2 (which is 0), dir=left,\n", + " return [[1,2,3], [4,0,5]]\"\"\"\n", + " x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + " out_boards = []\n", + " if y > 0:\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y-1] = new_board[x][y-1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y-1))\n", + " if y <= (len_y-1):\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y+1] = new_board[x][y+1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y+1))\n", + " if x >0:\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x-1][y] = new_board[x-1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x-1, y))\n", + " if x <= (len_x-1):\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x+1][y] = new_board[x+1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x+1, y))\n", + " return out_boards\n", + "\n", + "def slidingPuzzle(board, x, y):\n", + " step = 0\n", + " Q = [(board, x, y, step)]\n", + " seen = []\n", + " while len(Q)>0:\n", + " to_explore, x, y, step = Q.pop(0)\n", + " if to_explore.name == [[1,2,3], [4,5,0]]:\n", + " return to_explore.depth\n", + " \n", + " if to_explore.name in seen:\n", + " continue\n", + " else:\n", + " seen.append(to_explore.name)\n", + " if 0 in to_explore.name[0]:\n", + " x = 0\n", + " else:\n", + " x = 1\n", + " y = to_explore.name[x].index(0)\n", + " \n", + " new_possibilities = search_board(board=to_explore, start_pos=(x,y))\n", + " for index, new in enumerate(new_possibilities):\n", + " new_board, new_x, new_y = new\n", + " Q.append([new_board, new_x, new_y, step+1])\n", + " return -1\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[1,2,3],[4,0,5]])\n", + "print(slidingPuzzle(board, 1, 1))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[4,1,2],[5,0,3]])\n", + "print(slidingPuzzle(board, 1, 1))\n", + "for pre, fill, node in RenderTree(board):\n", + " print(\"%s%s\" % (pre, node.name))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[3,2,4],[1,5,0]])\n", + "print(slidingPuzzle(board, 1, 2)) # 14" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# dir(board)\n", + "# ??Node" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. We use BFS to solve the jigsaw problem.\n", + "Problem: Given a 3x3 list with non repeating numbers, \n", + "(e.g. [[5, 0, 3], [1, 2, 6], [8, 7, 9]]) \n", + "each time you can swap two adjacent numbers (up, down, left, right.) \n", + "search through the possible space to find the minimum steps required to sort it, \n", + "and print out the road map.\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "len_x = 2\n", + "len_y = 2\n", + "def search_board(board, start_pos):\n", + " \"\"\"Given a board and starting position and moving direction,\n", + " make the move and return a new board.\n", + " e.g. [[1,2,3], [4,5,0]], start_pos=1, 2 (which is 0), dir=left,\n", + " return [[1,2,3], [4,0,5]]\"\"\"\n", + " x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + " out_boards = []\n", + " if y > 0: # left\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y-1] = new_board[x][y-1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y-1))\n", + " if y <= (len_y-1): #right\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y+1] = new_board[x][y+1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y+1))\n", + " if x >0: # up\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x-1][y] = new_board[x-1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x-1, y))\n", + " if x <= (len_x-1): # down\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x+1][y] = new_board[x+1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x+1, y))\n", + " return out_boards\n", + "\n", + "def slidingPuzzle(board):\n", + " Q = []\n", + " for x in range(3):\n", + " for y in range(3):\n", + " Q.append(board)\n", + "# Q.append((board, x, y))\n", + " seen = []\n", + " while len(Q)>0:\n", + "# import pdb; pdb.set_trace()\n", + "# to_explore, x, y = Q.pop(0)\n", + "# print(to_explore.name, to_explore.depth)\n", + " to_explore = Q.pop(0)\n", + " if len(seen)%100 == 0:\n", + " print(len(seen), to_explore.depth)\n", + " if to_explore.name == [[1,2,3], [4,5,6], [7,8,9]]:\n", + " return to_explore.depth, to_explore\n", + " for x in range(3):\n", + " for y in range(3):\n", + " new_possibilities = search_board(board=to_explore, start_pos=(x,y))\n", + " for index, new in enumerate(new_possibilities):\n", + " new_board, _, _ = new\n", + " if new_board.name not in seen:\n", + " seen.append(new_board.name)\n", + " Q.append(new_board)\n", + " return -1, None" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# test\n", + "board = Node([[1,2,3],[4,5,6], [7,8,9]])\n", + "%time print(slidingPuzzle(board)) # 0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "board = Node([[1,2,3],[4,5,6], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "board = Node([[1,2,3],[4,6,5], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 2" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[1,2,3],[6,4,5], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[1,6,3],[4,2,5], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 3" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[4,6,3],[7,2,5], [1,9,8]])\n", + "%time tmp = slidingPuzzle(board)\n", + "print(tmp) # 5" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[5,4,6],[9,7,2], [8,1,3]])\n", + "%time tmp = slidingPuzzle(board)\n", + "print(tmp) # ghost examiner" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "ERROR:root:Internal Python error in the inspect module.\n", + "Below is the traceback from this internal error.\n", + "\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Traceback (most recent call last):\n", + " File \"/Users/toby/.local/lib/python3.6/site-packages/IPython/core/magics/execution.py\", line 1310, in time\n", + " exec(code, glob, local_ns)\n", + " File \"\", line 1, in \n", + " File \"\", line 52, in slidingPuzzle\n", + " if new_board.name not in seen:\n", + "KeyboardInterrupt\n", + "\n", + "During handling of the above exception, another exception occurred:\n", + "\n", + "Traceback (most recent call last):\n", + " File \"/Users/toby/.local/lib/python3.6/site-packages/IPython/core/interactiveshell.py\", line 2039, in showtraceback\n", + " stb = value._render_traceback_()\n", + "AttributeError: 'KeyboardInterrupt' object has no attribute '_render_traceback_'\n", + "\n", + "During handling of the above exception, another exception occurred:\n", + "\n", + "Traceback (most recent call last):\n", + " File \"/Users/toby/.local/lib/python3.6/site-packages/IPython/core/ultratb.py\", line 1101, in get_records\n", + " return _fixed_getinnerframes(etb, number_of_lines_of_context, tb_offset)\n", + " File \"/Users/toby/.local/lib/python3.6/site-packages/IPython/core/ultratb.py\", line 319, in wrapped\n", + " return f(*args, **kwargs)\n", + " File \"/Users/toby/.local/lib/python3.6/site-packages/IPython/core/ultratb.py\", line 353, in _fixed_getinnerframes\n", + " records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))\n", + " File \"/Users/toby/anaconda3/envs/py36/lib/python3.6/inspect.py\", line 1490, in getinnerframes\n", + " frameinfo = (tb.tb_frame,) + getframeinfo(tb, context)\n", + " File \"/Users/toby/anaconda3/envs/py36/lib/python3.6/inspect.py\", line 1452, in getframeinfo\n", + " lines, lnum = findsource(frame)\n", + " File \"/Users/toby/.local/lib/python3.6/site-packages/IPython/core/ultratb.py\", line 185, in findsource\n", + " lines = linecache.getlines(file, globals_dict)\n", + " File \"/Users/toby/anaconda3/envs/py36/lib/python3.6/linecache.py\", line 47, in getlines\n", + " return updatecache(filename, module_globals)\n", + " File \"/Users/toby/anaconda3/envs/py36/lib/python3.6/linecache.py\", line 137, in updatecache\n", + " lines = fp.readlines()\n", + " File \"/Users/toby/anaconda3/envs/py36/lib/python3.6/codecs.py\", line 318, in decode\n", + " def decode(self, input, final=False):\n", + "KeyboardInterrupt\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n", + "KeyboardInterrupt\n", + "\n" + ] + } + ], + "source": [ + "board = Node([[6,7,9],[2,3,8], [4,1,5]])\n", + "%time tmp = slidingPuzzle(board)\n", + "print(tmp) # human examiner" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "board = Node([[7,5,1],[6,2,9], [4,3,8]])\n", + "%time tmp2 = slidingPuzzle(board)\n", + "print(tmp2) # fairy examiner" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + "# if direction=='left' and y > 0:\n", + "# board[x][y], board[x][y-1] = board[x][y-1], board[x][y]\n", + "# if direction=='right' and to_explore.name, x, yy <= (len_y-1):\n", + "# board[x][y], board[x][y+1] = board[x][y+1], board[x][y]\n", + "# if direction=='up' and x >0:\n", + "# board[x][y], board[x-1][y] = board[x-1][y], board[x][y]\n", + "# if direction=='down' and x <= (len_x-1):\n", + "# board[x][y], board[x+1][y] = board[x+1][y], board[x][y]\n", + "# return board\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# from anytree import Node, RenderTree\n", + "\n", + "# udo = Node(\"Udo\")\n", + "# marc = Node(\"Marc\", parent=udo)\n", + "# lian = Node(\"Lian\", parent=marc)\n", + "# dan = Node(\"Dan\", parent=udo)\n", + "# jet = Node(\"Jet\", parent=dan)\n", + "# jan = Node(\"Jan\", parent=dan)\n", + "# joe = Node(\"Joe\", parent=dan)\n", + "\n", + "# print(udo)\n", + "# Node('/Udo')\n", + "# print(joe)\n", + "# Node('/Udo/Dan/Joe')\n", + "\n", + "# for pre, fill, node in RenderTree(udo):\n", + "# print(\"%s%s\" % (pre, node.name))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Using TensorFlow backend.\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "import pandas as pd\n", + "from keras.preprocessing.text import Tokenizer\n", + "from keras.preprocessing.sequence import pad_sequences\n", + "\n", + "from keras.layers import Input, Embedding, Activation, Flatten, Dense\n", + "from keras.layers import Conv1D, MaxPooling1D, Dropout\n", + "from keras.models import Model" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "tk = Tokenizer(num_words=None, char_level=True, oov_token='UNK')\n", + "alphabet = \"abcdefghijklmnopqrstuvwxyz0123456789,;.!?:'\\\"/\\\\|_@#$%^&*~`+-=<>()[]{}\"\n", + "char_dict = {}\n", + "for i, char in enumerate(alphabet):\n", + " char_dict[char] = i + 1\n", + "\n", + "# # Use char_dict to replace the tk.word_index\n", + "tk.word_index = char_dict.copy()\n", + "# # Add 'UNK' to the vocabulary\n", + "tk.word_index[tk.oov_token] = max(char_dict.values()) + 1" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[9,\n", + " 43,\n", + " 13,\n", + " 69,\n", + " 10,\n", + " 21,\n", + " 19,\n", + " 20,\n", + " 69,\n", + " 1,\n", + " 69,\n", + " 20,\n", + " 5,\n", + " 19,\n", + " 20,\n", + " 9,\n", + " 14,\n", + " 7,\n", + " 69,\n", + " 19,\n", + " 20,\n", + " 18,\n", + " 9,\n", + " 14,\n", + " 7],\n", + " [1, 16, 16, 12, 5]]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "train_texts = [\"i'm just a testing string\", \"apple\"]\n", + "tk.texts_to_sequences(train_texts)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[258, 115, 101, 101, 109, 115, 259]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "word = \"seems\"\n", + "ELMO_PAD_CHAR = 260\n", + "ELMO_BOW_CHAR = 258\n", + "ELMO_EOW_CHAR = 259\n", + "chars = []\n", + "if len(word) > 0:\n", + " chars += [ELMO_BOW_CHAR]\n", + " chars += list(word.encode('utf-8', errors='ignore'))\n", + " chars += [ELMO_EOW_CHAR]\n", + "chars" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [], + "source": [ + "str.encode??" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/BFS_jigsaw/773_SlidingPuzzle_BFS_and_Jigsaw.ipynb b/BFS_jigsaw/773_SlidingPuzzle_BFS_and_Jigsaw.ipynb new file mode 100644 index 0000000..108aad3 --- /dev/null +++ b/BFS_jigsaw/773_SlidingPuzzle_BFS_and_Jigsaw.ipynb @@ -0,0 +1,1224 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. We implement 773. Sliding Puzzle as a warmup\n", + "On a 2x3 board, there are 5 tiles represented by the integers 1 through 5, and an empty square represented by 0. \n", + "\n", + "A move consists of choosing 0 and a 4-directionally adjacent number and swapping it. \n", + "\n", + "The state of the board is solved if and only if the board is [[1,2,3],[4,5,0]]. \n", + "\n", + "Given a puzzle board, return the least number of moves required so that the state of the board is solved. If it is impossible for the state of the board to be solved, return -1." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import copy\n", + "import math\n", + "\n", + "from anytree import Node, RenderTree" + ] + }, + { + "cell_type": "code", + "execution_count": 83, + "metadata": {}, + "outputs": [], + "source": [ + "# def slidingPuzzle(board: List[List[int]]) -> int:\n", + "# pass\n", + "len_x = 1\n", + "len_y = 2\n", + "def search_board(board, start_pos):\n", + " \"\"\"Given a board and starting position and moving direction,\n", + " make the move and return a new board.\n", + " e.g. [[1,2,3], [4,5,0]], start_pos=1, 2 (which is 0), dir=left,\n", + " return [[1,2,3], [4,0,5]]\"\"\"\n", + " x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + " out_boards = []\n", + " if y > 0:\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x][y-1] = new_board[x][y-1], new_board[x][y]\n", + " out_boards.append((new_board, x, y-1))\n", + " if y <= (len_y-1):\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x][y+1] = new_board[x][y+1], new_board[x][y]\n", + " out_boards.append((new_board, x, y+1))\n", + " if x >0:\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x-1][y] = new_board[x-1][y], new_board[x][y]\n", + " out_boards.append((new_board, x-1, y))\n", + " if x <= (len_x-1):\n", + " new_board = copy.deepcopy(board)\n", + " new_board[x][y], new_board[x+1][y] = new_board[x+1][y], new_board[x][y]\n", + " out_boards.append((new_board, x+1, y))\n", + " return out_boards\n", + "\n", + "def slidingPuzzle(board, x, y):\n", + " step = 0\n", + " Q = [(board, x, y, step)]\n", + " seen = []\n", + " while len(Q)>0:\n", + "# import pdb; pdb.set_trace()\n", + " to_explore, x, y, step = Q.pop(0)\n", + " print(to_explore, step)\n", + " if to_explore == [[1,2,3], [4,5,0]]:\n", + " print(\"Found! at step: \",step)\n", + " return step\n", + " \n", + " if to_explore in seen:\n", + " continue\n", + " else:\n", + " seen.append(to_explore)\n", + " if 0 in to_explore[0]:\n", + " x = 0\n", + " else:\n", + " x = 1\n", + " y = to_explore[x].index(0)\n", + " \n", + " new_possibilities = search_board(board=to_explore, start_pos=(x,y))\n", + " for index, new in enumerate(new_possibilities):\n", + " new_board, new_x, new_y = new\n", + " Q.append([new_board, new_x, new_y, step+1])\n", + " return -1\n" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1, 2, 3], [4, 0, 5]] 0\n", + "[[1, 2, 3], [0, 4, 5]] 1\n", + "[[1, 2, 3], [4, 5, 0]] 1\n", + "Found! at step: 1\n", + "1\n", + "[[4, 1, 2], [5, 0, 3]] 0\n", + "[[4, 1, 2], [0, 5, 3]] 1\n", + "[[4, 1, 2], [5, 3, 0]] 1\n", + "[[4, 0, 2], [5, 1, 3]] 1\n", + "[[4, 1, 2], [5, 0, 3]] 2\n", + "[[0, 1, 2], [4, 5, 3]] 2\n", + "[[4, 1, 2], [5, 0, 3]] 2\n", + "[[4, 1, 0], [5, 3, 2]] 2\n", + "[[0, 4, 2], [5, 1, 3]] 2\n", + "[[4, 2, 0], [5, 1, 3]] 2\n", + "[[4, 1, 2], [5, 0, 3]] 2\n", + "[[1, 0, 2], [4, 5, 3]] 3\n", + "[[4, 1, 2], [0, 5, 3]] 3\n", + "[[4, 0, 1], [5, 3, 2]] 3\n", + "[[4, 1, 2], [5, 3, 0]] 3\n", + "[[4, 0, 2], [5, 1, 3]] 3\n", + "[[5, 4, 2], [0, 1, 3]] 3\n", + "[[4, 0, 2], [5, 1, 3]] 3\n", + "[[4, 2, 3], [5, 1, 0]] 3\n", + "[[0, 1, 2], [4, 5, 3]] 4\n", + "[[1, 2, 0], [4, 5, 3]] 4\n", + "[[1, 5, 2], [4, 0, 3]] 4\n", + "[[0, 4, 1], [5, 3, 2]] 4\n", + "[[4, 1, 0], [5, 3, 2]] 4\n", + "[[4, 3, 1], [5, 0, 2]] 4\n", + "[[5, 4, 2], [1, 0, 3]] 4\n", + "[[0, 4, 2], [5, 1, 3]] 4\n", + "[[4, 2, 3], [5, 0, 1]] 4\n", + "[[4, 2, 0], [5, 1, 3]] 4\n", + "[[1, 0, 2], [4, 5, 3]] 5\n", + "[[1, 2, 3], [4, 5, 0]] 5\n", + "Found! at step: 5\n", + "5\n" + ] + } + ], + "source": [ + "# tests:\n", + "# print(slidingPuzzle([[1,2,3], [4,5,0]]))\n", + "board = [[1,2,3],[4,0,5]]\n", + "print(slidingPuzzle(board, 1, 1)) # 1\n", + "board = [[4,1,2],[5,0,3]]\n", + "print(slidingPuzzle(board, 1, 1)) # 5" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[3, 2, 4], [1, 5, 0]] 0\n", + "[[3, 2, 4], [1, 0, 5]] 1\n", + "[[3, 2, 0], [1, 5, 4]] 1\n", + "[[3, 2, 4], [0, 1, 5]] 2\n", + "[[3, 2, 4], [1, 5, 0]] 2\n", + "[[3, 0, 4], [1, 2, 5]] 2\n", + "[[3, 0, 2], [1, 5, 4]] 2\n", + "[[3, 2, 4], [1, 5, 0]] 2\n", + "[[3, 2, 4], [1, 0, 5]] 3\n", + "[[0, 2, 4], [3, 1, 5]] 3\n", + "[[0, 3, 4], [1, 2, 5]] 3\n", + "[[3, 4, 0], [1, 2, 5]] 3\n", + "[[3, 2, 4], [1, 0, 5]] 3\n", + "[[0, 3, 2], [1, 5, 4]] 3\n", + "[[3, 2, 0], [1, 5, 4]] 3\n", + "[[3, 5, 2], [1, 0, 4]] 3\n", + "[[2, 0, 4], [3, 1, 5]] 4\n", + "[[3, 2, 4], [0, 1, 5]] 4\n", + "[[3, 0, 4], [1, 2, 5]] 4\n", + "[[1, 3, 4], [0, 2, 5]] 4\n", + "[[3, 0, 4], [1, 2, 5]] 4\n", + "[[3, 4, 5], [1, 2, 0]] 4\n", + "[[3, 0, 2], [1, 5, 4]] 4\n", + "[[1, 3, 2], [0, 5, 4]] 4\n", + "[[3, 5, 2], [0, 1, 4]] 4\n", + "[[3, 5, 2], [1, 4, 0]] 4\n", + "[[3, 0, 2], [1, 5, 4]] 4\n", + "[[0, 2, 4], [3, 1, 5]] 5\n", + "[[2, 4, 0], [3, 1, 5]] 5\n", + "[[2, 1, 4], [3, 0, 5]] 5\n", + "[[1, 3, 4], [2, 0, 5]] 5\n", + "[[0, 3, 4], [1, 2, 5]] 5\n", + "[[3, 4, 5], [1, 0, 2]] 5\n", + "[[3, 4, 0], [1, 2, 5]] 5\n", + "[[1, 3, 2], [5, 0, 4]] 5\n", + "[[0, 3, 2], [1, 5, 4]] 5\n", + "[[3, 5, 2], [1, 0, 4]] 5\n", + "[[0, 5, 2], [3, 1, 4]] 5\n", + "[[3, 5, 2], [1, 0, 4]] 5\n", + "[[3, 5, 0], [1, 4, 2]] 5\n", + "[[2, 0, 4], [3, 1, 5]] 6\n", + "[[2, 4, 5], [3, 1, 0]] 6\n", + "[[2, 1, 4], [0, 3, 5]] 6\n", + "[[2, 1, 4], [3, 5, 0]] 6\n", + "[[2, 0, 4], [3, 1, 5]] 6\n", + "[[1, 3, 4], [0, 2, 5]] 6\n", + "[[1, 3, 4], [2, 5, 0]] 6\n", + "[[1, 0, 4], [2, 3, 5]] 6\n", + "[[3, 4, 5], [0, 1, 2]] 6\n", + "[[3, 4, 5], [1, 2, 0]] 6\n", + "[[3, 0, 5], [1, 4, 2]] 6\n", + "[[1, 3, 2], [0, 5, 4]] 6\n", + "[[1, 3, 2], [5, 4, 0]] 6\n", + "[[1, 0, 2], [5, 3, 4]] 6\n", + "[[5, 0, 2], [3, 1, 4]] 6\n", + "[[3, 5, 2], [0, 1, 4]] 6\n", + "[[3, 0, 5], [1, 4, 2]] 6\n", + "[[3, 5, 2], [1, 4, 0]] 6\n", + "[[2, 4, 5], [3, 0, 1]] 7\n", + "[[2, 4, 0], [3, 1, 5]] 7\n", + "[[2, 1, 4], [3, 0, 5]] 7\n", + "[[0, 1, 4], [2, 3, 5]] 7\n", + "[[2, 1, 4], [3, 0, 5]] 7\n", + "[[2, 1, 0], [3, 5, 4]] 7\n", + "[[1, 3, 4], [2, 0, 5]] 7\n", + "[[1, 3, 0], [2, 5, 4]] 7\n", + "[[0, 1, 4], [2, 3, 5]] 7\n", + "[[1, 4, 0], [2, 3, 5]] 7\n", + "[[1, 3, 4], [2, 0, 5]] 7\n", + "[[3, 4, 5], [1, 0, 2]] 7\n", + "[[0, 4, 5], [3, 1, 2]] 7\n", + "[[0, 3, 5], [1, 4, 2]] 7\n", + "[[3, 5, 0], [1, 4, 2]] 7\n", + "[[3, 4, 5], [1, 0, 2]] 7\n", + "[[1, 3, 2], [5, 0, 4]] 7\n", + "[[1, 3, 0], [5, 4, 2]] 7\n", + "[[0, 1, 2], [5, 3, 4]] 7\n", + "[[1, 2, 0], [5, 3, 4]] 7\n", + "[[1, 3, 2], [5, 0, 4]] 7\n", + "[[0, 5, 2], [3, 1, 4]] 7\n", + "[[5, 2, 0], [3, 1, 4]] 7\n", + "[[5, 1, 2], [3, 0, 4]] 7\n", + "[[2, 4, 5], [0, 3, 1]] 8\n", + "[[2, 4, 5], [3, 1, 0]] 8\n", + "[[2, 0, 5], [3, 4, 1]] 8\n", + "[[1, 0, 4], [2, 3, 5]] 8\n", + "[[2, 1, 4], [0, 3, 5]] 8\n", + "[[2, 0, 1], [3, 5, 4]] 8\n", + "[[2, 1, 4], [3, 5, 0]] 8\n", + "[[1, 0, 3], [2, 5, 4]] 8\n", + "[[1, 3, 4], [2, 5, 0]] 8\n", + "[[1, 0, 4], [2, 3, 5]] 8\n", + "[[1, 4, 5], [2, 3, 0]] 8\n", + "[[4, 0, 5], [3, 1, 2]] 8\n", + "[[3, 4, 5], [0, 1, 2]] 8\n", + "[[3, 0, 5], [1, 4, 2]] 8\n", + "[[1, 3, 5], [0, 4, 2]] 8\n", + "[[1, 0, 3], [5, 4, 2]] 8\n", + "[[1, 3, 2], [5, 4, 0]] 8\n", + "[[1, 0, 2], [5, 3, 4]] 8\n", + "[[5, 1, 2], [0, 3, 4]] 8\n", + "[[1, 0, 2], [5, 3, 4]] 8\n", + "[[1, 2, 4], [5, 3, 0]] 8\n", + "[[5, 0, 2], [3, 1, 4]] 8\n", + "[[5, 2, 4], [3, 1, 0]] 8\n", + "[[5, 1, 2], [0, 3, 4]] 8\n", + "[[5, 1, 2], [3, 4, 0]] 8\n", + "[[5, 0, 2], [3, 1, 4]] 8\n", + "[[2, 4, 5], [3, 0, 1]] 9\n", + "[[0, 4, 5], [2, 3, 1]] 9\n", + "[[0, 2, 5], [3, 4, 1]] 9\n", + "[[2, 5, 0], [3, 4, 1]] 9\n", + "[[2, 4, 5], [3, 0, 1]] 9\n", + "[[0, 2, 1], [3, 5, 4]] 9\n", + "[[2, 1, 0], [3, 5, 4]] 9\n", + "[[2, 5, 1], [3, 0, 4]] 9\n", + "[[0, 1, 3], [2, 5, 4]] 9\n", + "[[1, 3, 0], [2, 5, 4]] 9\n", + "[[1, 5, 3], [2, 0, 4]] 9\n", + "[[1, 4, 5], [2, 0, 3]] 9\n", + "[[1, 4, 0], [2, 3, 5]] 9\n", + "[[0, 4, 5], [3, 1, 2]] 9\n", + "[[4, 5, 0], [3, 1, 2]] 9\n", + "[[4, 1, 5], [3, 0, 2]] 9\n", + "[[1, 3, 5], [4, 0, 2]] 9\n", + "[[0, 3, 5], [1, 4, 2]] 9\n", + "[[0, 1, 3], [5, 4, 2]] 9\n", + "[[1, 3, 0], [5, 4, 2]] 9\n", + "[[1, 4, 3], [5, 0, 2]] 9\n", + "[[5, 1, 2], [3, 0, 4]] 9\n", + "[[0, 1, 2], [5, 3, 4]] 9\n", + "[[1, 2, 4], [5, 0, 3]] 9\n", + "[[1, 2, 0], [5, 3, 4]] 9\n", + "[[5, 2, 4], [3, 0, 1]] 9\n", + "[[5, 2, 0], [3, 1, 4]] 9\n", + "[[5, 1, 2], [3, 0, 4]] 9\n", + "[[5, 1, 0], [3, 4, 2]] 9\n", + "[[4, 0, 5], [2, 3, 1]] 10\n", + "[[2, 4, 5], [0, 3, 1]] 10\n", + "[[2, 0, 5], [3, 4, 1]] 10\n", + "[[3, 2, 5], [0, 4, 1]] 10\n", + "[[2, 0, 5], [3, 4, 1]] 10\n", + "[[2, 5, 1], [3, 4, 0]] 10\n", + "[[2, 0, 1], [3, 5, 4]] 10\n", + "[[3, 2, 1], [0, 5, 4]] 10\n", + "[[2, 5, 1], [0, 3, 4]] 10\n", + "[[2, 5, 1], [3, 4, 0]] 10\n", + "[[2, 0, 1], [3, 5, 4]] 10\n", + "[[1, 0, 3], [2, 5, 4]] 10\n", + "[[2, 1, 3], [0, 5, 4]] 10\n", + "[[1, 5, 3], [0, 2, 4]] 10\n", + "[[1, 5, 3], [2, 4, 0]] 10\n", + "[[1, 0, 3], [2, 5, 4]] 10\n", + "[[1, 4, 5], [0, 2, 3]] 10\n", + "[[1, 4, 5], [2, 3, 0]] 10\n", + "[[1, 0, 5], [2, 4, 3]] 10\n", + "[[4, 0, 5], [3, 1, 2]] 10\n", + "[[4, 5, 2], [3, 1, 0]] 10\n", + "[[4, 1, 5], [0, 3, 2]] 10\n", + "[[4, 1, 5], [3, 2, 0]] 10\n", + "[[4, 0, 5], [3, 1, 2]] 10\n", + "[[1, 3, 5], [0, 4, 2]] 10\n", + "[[1, 3, 5], [4, 2, 0]] 10\n", + "[[1, 0, 5], [4, 3, 2]] 10\n", + "[[1, 0, 3], [5, 4, 2]] 10\n", + "[[5, 1, 3], [0, 4, 2]] 10\n", + "[[1, 4, 3], [0, 5, 2]] 10\n", + "[[1, 4, 3], [5, 2, 0]] 10\n", + "[[1, 0, 3], [5, 4, 2]] 10\n", + "[[1, 2, 4], [0, 5, 3]] 10\n", + "[[1, 2, 4], [5, 3, 0]] 10\n", + "[[1, 0, 4], [5, 2, 3]] 10\n", + "[[5, 2, 4], [0, 3, 1]] 10\n", + "[[5, 2, 4], [3, 1, 0]] 10\n", + "[[5, 0, 4], [3, 2, 1]] 10\n", + "[[5, 0, 1], [3, 4, 2]] 10\n", + "[[5, 1, 2], [3, 4, 0]] 10\n", + "[[0, 4, 5], [2, 3, 1]] 11\n", + "[[4, 5, 0], [2, 3, 1]] 11\n", + "[[4, 3, 5], [2, 0, 1]] 11\n", + "[[3, 2, 5], [4, 0, 1]] 11\n", + "[[0, 2, 5], [3, 4, 1]] 11\n", + "[[2, 5, 1], [3, 0, 4]] 11\n", + "[[2, 5, 0], [3, 4, 1]] 11\n", + "[[3, 2, 1], [5, 0, 4]] 11\n", + "[[0, 2, 1], [3, 5, 4]] 11\n", + "[[2, 5, 1], [3, 0, 4]] 11\n", + "[[0, 5, 1], [2, 3, 4]] 11\n", + "[[2, 1, 3], [5, 0, 4]] 11\n", + "[[0, 1, 3], [2, 5, 4]] 11\n", + "[[1, 5, 3], [2, 0, 4]] 11\n", + "[[0, 5, 3], [1, 2, 4]] 11\n", + "[[1, 5, 3], [2, 0, 4]] 11\n", + "[[1, 5, 0], [2, 4, 3]] 11\n", + "[[1, 4, 5], [2, 0, 3]] 11\n", + "[[0, 4, 5], [1, 2, 3]] 11\n", + "[[0, 1, 5], [2, 4, 3]] 11\n", + "[[1, 5, 0], [2, 4, 3]] 11\n", + "[[1, 4, 5], [2, 0, 3]] 11\n", + "[[4, 5, 2], [3, 0, 1]] 11\n", + "[[4, 5, 0], [3, 1, 2]] 11\n", + "[[4, 1, 5], [3, 0, 2]] 11\n", + "[[0, 1, 5], [4, 3, 2]] 11\n", + "[[4, 1, 5], [3, 0, 2]] 11\n", + "[[4, 1, 0], [3, 2, 5]] 11\n", + "[[1, 3, 5], [4, 0, 2]] 11\n", + "[[1, 3, 0], [4, 2, 5]] 11\n", + "[[0, 1, 5], [4, 3, 2]] 11\n", + "[[1, 5, 0], [4, 3, 2]] 11\n", + "[[1, 3, 5], [4, 0, 2]] 11\n", + "[[5, 1, 3], [4, 0, 2]] 11\n", + "[[0, 1, 3], [5, 4, 2]] 11\n", + "[[1, 4, 3], [5, 0, 2]] 11\n", + "[[0, 4, 3], [1, 5, 2]] 11\n", + "[[1, 4, 3], [5, 0, 2]] 11\n", + "[[1, 4, 0], [5, 2, 3]] 11\n", + "[[1, 2, 4], [5, 0, 3]] 11\n", + "[[0, 2, 4], [1, 5, 3]] 11\n", + "[[0, 1, 4], [5, 2, 3]] 11\n", + "[[1, 4, 0], [5, 2, 3]] 11\n", + "[[1, 2, 4], [5, 0, 3]] 11\n", + "[[5, 2, 4], [3, 0, 1]] 11\n", + "[[0, 2, 4], [5, 3, 1]] 11\n", + "[[0, 5, 4], [3, 2, 1]] 11\n", + "[[5, 4, 0], [3, 2, 1]] 11\n", + "[[5, 2, 4], [3, 0, 1]] 11\n", + "[[0, 5, 1], [3, 4, 2]] 11\n", + "[[5, 1, 0], [3, 4, 2]] 11\n", + "[[5, 4, 1], [3, 0, 2]] 11\n", + "[[4, 0, 5], [2, 3, 1]] 12\n", + "[[4, 5, 1], [2, 3, 0]] 12\n", + "[[4, 3, 5], [0, 2, 1]] 12\n", + "[[4, 3, 5], [2, 1, 0]] 12\n", + "[[4, 0, 5], [2, 3, 1]] 12\n", + "[[3, 2, 5], [0, 4, 1]] 12\n", + "[[3, 2, 5], [4, 1, 0]] 12\n", + "[[3, 0, 5], [4, 2, 1]] 12\n", + "[[3, 2, 1], [0, 5, 4]] 12\n", + "[[3, 2, 1], [5, 4, 0]] 12\n", + "[[3, 0, 1], [5, 2, 4]] 12\n", + "[[5, 0, 1], [2, 3, 4]] 12\n", + "[[2, 5, 1], [0, 3, 4]] 12\n", + "[[2, 1, 3], [0, 5, 4]] 12\n", + "[[2, 1, 3], [5, 4, 0]] 12\n", + "[[2, 0, 3], [5, 1, 4]] 12\n", + "[[5, 0, 3], [1, 2, 4]] 12\n", + "[[1, 5, 3], [0, 2, 4]] 12\n", + "[[1, 0, 5], [2, 4, 3]] 12\n", + "[[1, 5, 3], [2, 4, 0]] 12\n", + "[[4, 0, 5], [1, 2, 3]] 12\n", + "[[1, 4, 5], [0, 2, 3]] 12\n", + "[[1, 0, 5], [2, 4, 3]] 12\n", + "[[2, 1, 5], [0, 4, 3]] 12\n", + "[[4, 5, 2], [0, 3, 1]] 12\n", + "[[4, 5, 2], [3, 1, 0]] 12\n", + "[[4, 0, 2], [3, 5, 1]] 12\n", + "[[1, 0, 5], [4, 3, 2]] 12\n", + "[[4, 1, 5], [0, 3, 2]] 12\n", + "[[4, 0, 1], [3, 2, 5]] 12\n", + "[[4, 1, 5], [3, 2, 0]] 12\n", + "[[1, 0, 3], [4, 2, 5]] 12\n", + "[[1, 3, 5], [4, 2, 0]] 12\n", + "[[1, 0, 5], [4, 3, 2]] 12\n", + "[[1, 5, 2], [4, 3, 0]] 12\n", + "[[5, 1, 3], [0, 4, 2]] 12\n", + "[[5, 1, 3], [4, 2, 0]] 12\n", + "[[5, 0, 3], [4, 1, 2]] 12\n", + "[[4, 0, 3], [1, 5, 2]] 12\n", + "[[1, 4, 3], [0, 5, 2]] 12\n", + "[[1, 0, 4], [5, 2, 3]] 12\n", + "[[1, 4, 3], [5, 2, 0]] 12\n", + "[[2, 0, 4], [1, 5, 3]] 12\n", + "[[1, 2, 4], [0, 5, 3]] 12\n", + "[[1, 0, 4], [5, 2, 3]] 12\n", + "[[5, 1, 4], [0, 2, 3]] 12\n", + "[[2, 0, 4], [5, 3, 1]] 12\n", + "[[5, 2, 4], [0, 3, 1]] 12\n", + "[[5, 0, 4], [3, 2, 1]] 12\n", + "[[3, 5, 4], [0, 2, 1]] 12\n", + "[[5, 0, 4], [3, 2, 1]] 12\n", + "[[5, 4, 1], [3, 2, 0]] 12\n", + "[[5, 0, 1], [3, 4, 2]] 12\n", + "[[3, 5, 1], [0, 4, 2]] 12\n", + "[[5, 4, 1], [0, 3, 2]] 12\n", + "[[5, 4, 1], [3, 2, 0]] 12\n", + "[[5, 0, 1], [3, 4, 2]] 12\n", + "[[4, 5, 1], [2, 0, 3]] 13\n", + "[[4, 5, 0], [2, 3, 1]] 13\n", + "[[4, 3, 5], [2, 0, 1]] 13\n", + "[[0, 3, 5], [4, 2, 1]] 13\n", + "[[4, 3, 5], [2, 0, 1]] 13\n", + "[[4, 3, 0], [2, 1, 5]] 13\n", + "[[3, 2, 5], [4, 0, 1]] 13\n", + "[[3, 2, 0], [4, 1, 5]] 13\n", + "[[0, 3, 5], [4, 2, 1]] 13\n", + "[[3, 5, 0], [4, 2, 1]] 13\n", + "[[3, 2, 5], [4, 0, 1]] 13\n", + "[[3, 2, 1], [5, 0, 4]] 13\n", + "[[3, 2, 0], [5, 4, 1]] 13\n", + "[[0, 3, 1], [5, 2, 4]] 13\n", + "[[3, 1, 0], [5, 2, 4]] 13\n", + "[[3, 2, 1], [5, 0, 4]] 13\n", + "[[0, 5, 1], [2, 3, 4]] 13\n", + "[[5, 1, 0], [2, 3, 4]] 13\n", + "[[5, 3, 1], [2, 0, 4]] 13\n", + "[[2, 1, 3], [5, 0, 4]] 13\n", + "[[2, 1, 0], [5, 4, 3]] 13\n", + "[[0, 2, 3], [5, 1, 4]] 13\n", + "[[2, 3, 0], [5, 1, 4]] 13\n", + "[[2, 1, 3], [5, 0, 4]] 13\n", + "[[0, 5, 3], [1, 2, 4]] 13\n", + "[[5, 3, 0], [1, 2, 4]] 13\n", + "[[5, 2, 3], [1, 0, 4]] 13\n", + "[[0, 4, 5], [1, 2, 3]] 13\n", + "[[4, 5, 0], [1, 2, 3]] 13\n", + "[[4, 2, 5], [1, 0, 3]] 13\n", + "[[2, 1, 5], [4, 0, 3]] 13\n", + "[[0, 1, 5], [2, 4, 3]] 13\n", + "[[4, 5, 2], [3, 0, 1]] 13\n", + "[[0, 5, 2], [4, 3, 1]] 13\n", + "[[0, 4, 2], [3, 5, 1]] 13\n", + "[[4, 2, 0], [3, 5, 1]] 13\n", + "[[4, 5, 2], [3, 0, 1]] 13\n", + "[[0, 4, 1], [3, 2, 5]] 13\n", + "[[4, 1, 0], [3, 2, 5]] 13\n", + "[[4, 2, 1], [3, 0, 5]] 13\n", + "[[0, 1, 3], [4, 2, 5]] 13\n", + "[[1, 3, 0], [4, 2, 5]] 13\n", + "[[1, 2, 3], [4, 0, 5]] 13\n", + "[[1, 5, 2], [4, 0, 3]] 13\n", + "[[1, 5, 0], [4, 3, 2]] 13\n", + "[[5, 1, 3], [4, 0, 2]] 13\n", + "[[5, 1, 0], [4, 2, 3]] 13\n", + "[[0, 5, 3], [4, 1, 2]] 13\n", + "[[5, 3, 0], [4, 1, 2]] 13\n", + "[[5, 1, 3], [4, 0, 2]] 13\n", + "[[0, 4, 3], [1, 5, 2]] 13\n", + "[[4, 3, 0], [1, 5, 2]] 13\n", + "[[4, 5, 3], [1, 0, 2]] 13\n", + "[[0, 2, 4], [1, 5, 3]] 13\n", + "[[2, 4, 0], [1, 5, 3]] 13\n", + "[[2, 5, 4], [1, 0, 3]] 13\n", + "[[5, 1, 4], [2, 0, 3]] 13\n", + "[[0, 1, 4], [5, 2, 3]] 13\n", + "[[0, 2, 4], [5, 3, 1]] 13\n", + "[[2, 4, 0], [5, 3, 1]] 13\n", + "[[2, 3, 4], [5, 0, 1]] 13\n", + "[[3, 5, 4], [2, 0, 1]] 13\n", + "[[0, 5, 4], [3, 2, 1]] 13\n", + "[[5, 4, 1], [3, 0, 2]] 13\n", + "[[5, 4, 0], [3, 2, 1]] 13\n", + "[[3, 5, 1], [4, 0, 2]] 13\n", + "[[0, 5, 1], [3, 4, 2]] 13\n", + "[[5, 4, 1], [3, 0, 2]] 13\n", + "[[0, 4, 1], [5, 3, 2]] 13\n", + "[[4, 5, 1], [0, 2, 3]] 14\n", + "[[4, 5, 1], [2, 3, 0]] 14\n", + "[[4, 0, 1], [2, 5, 3]] 14\n", + "[[3, 0, 5], [4, 2, 1]] 14\n", + "[[4, 3, 5], [0, 2, 1]] 14\n", + "[[4, 0, 3], [2, 1, 5]] 14\n", + "[[4, 3, 5], [2, 1, 0]] 14\n", + "[[3, 0, 2], [4, 1, 5]] 14\n", + "[[3, 2, 5], [4, 1, 0]] 14\n", + "[[3, 0, 5], [4, 2, 1]] 14\n", + "[[3, 5, 1], [4, 2, 0]] 14\n", + "[[3, 0, 2], [5, 4, 1]] 14\n", + "[[3, 2, 1], [5, 4, 0]] 14\n", + "[[3, 0, 1], [5, 2, 4]] 14\n", + "[[5, 3, 1], [0, 2, 4]] 14\n", + "[[3, 0, 1], [5, 2, 4]] 14\n", + "[[3, 1, 4], [5, 2, 0]] 14\n", + "[[5, 0, 1], [2, 3, 4]] 14\n", + "[[5, 1, 4], [2, 3, 0]] 14\n", + "[[5, 3, 1], [0, 2, 4]] 14\n", + "[[5, 3, 1], [2, 4, 0]] 14\n", + "[[5, 0, 1], [2, 3, 4]] 14\n", + "[[2, 0, 1], [5, 4, 3]] 14\n", + "[[2, 1, 3], [5, 4, 0]] 14\n", + "[[2, 0, 3], [5, 1, 4]] 14\n", + "[[5, 2, 3], [0, 1, 4]] 14\n", + "[[2, 0, 3], [5, 1, 4]] 14\n", + "[[2, 3, 4], [5, 1, 0]] 14\n", + "[[5, 0, 3], [1, 2, 4]] 14\n", + "[[5, 3, 4], [1, 2, 0]] 14\n", + "[[5, 2, 3], [0, 1, 4]] 14\n", + "[[5, 2, 3], [1, 4, 0]] 14\n", + "[[5, 0, 3], [1, 2, 4]] 14\n", + "[[4, 0, 5], [1, 2, 3]] 14\n", + "[[4, 5, 3], [1, 2, 0]] 14\n", + "[[4, 2, 5], [0, 1, 3]] 14\n", + "[[4, 2, 5], [1, 3, 0]] 14\n", + "[[4, 0, 5], [1, 2, 3]] 14\n", + "[[2, 1, 5], [0, 4, 3]] 14\n", + "[[2, 1, 5], [4, 3, 0]] 14\n", + "[[2, 0, 5], [4, 1, 3]] 14\n", + "[[5, 0, 2], [4, 3, 1]] 14\n", + "[[4, 5, 2], [0, 3, 1]] 14\n", + "[[4, 0, 2], [3, 5, 1]] 14\n", + "[[3, 4, 2], [0, 5, 1]] 14\n", + "[[4, 0, 2], [3, 5, 1]] 14\n", + "[[4, 2, 1], [3, 5, 0]] 14\n", + "[[4, 0, 1], [3, 2, 5]] 14\n", + "[[3, 4, 1], [0, 2, 5]] 14\n", + "[[4, 2, 1], [0, 3, 5]] 14\n", + "[[4, 2, 1], [3, 5, 0]] 14\n", + "[[4, 0, 1], [3, 2, 5]] 14\n", + "[[1, 0, 3], [4, 2, 5]] 14\n", + "[[4, 1, 3], [0, 2, 5]] 14\n", + "[[1, 2, 3], [0, 4, 5]] 14\n", + "[[1, 2, 3], [4, 5, 0]] 14\n", + "Found! at step: 14\n", + "14\n" + ] + } + ], + "source": [ + "board = [[3,2,4],[1,5,0]]\n", + "print(slidingPuzzle(board, 1, 2)) # 14" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[1, 2, 3], [4, 5, 0]] [[1, 2, 3], [4, 5, 0]]\n", + "[[2, 1, 3], [4, 5, 0]] [[1, 2, 3], [4, 5, 0]]\n" + ] + } + ], + "source": [ + "tmp = [[1,2,3], [4,5,0]]\n", + "# tmp[1].index(0)\n", + "# if 0 in tmp[0]: x = 0, \n", + "# else: x = 1\n", + "# new_tmp = tmp.copy()\n", + "import copy\n", + "new_tmp = copy.deepcopy(tmp)\n", + "print(tmp, new_tmp)\n", + "tmp[0][0], tmp[0][1] = tmp[0][1], tmp[0][0]\n", + "print(tmp, new_tmp)" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[[[1, 2, 3], [4, 5, 0]], 0, 0, 1], [[[[1, 2, 6], [4, 5, 0]], 1, 0, 2]]]" + ] + }, + "execution_count": 78, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tmp = [[[[1,2,3], [4,5,0]], 0, 0, 1]]\n", + "tmp.append([[[[1,2,6], [4,5,0]], 1, 0, 2]])\n", + "tmp" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1.1 A tree version\n", + "Well. We did solve the 773 above. However, we also want a road map to the min solution. \n", + "And it seems only possible with a tree structure (that way you get a hold of the last node, find the parent, then the parent's parent, etc.)" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": {}, + "outputs": [], + "source": [ + "# def slidingPuzzle(board: List[List[int]]) -> int:\n", + "# pass\n", + "len_x = 1\n", + "len_y = 2\n", + "def search_board(board, start_pos):\n", + " \"\"\"Given a board and starting position and moving direction,\n", + " make the move and return a new board.\n", + " e.g. [[1,2,3], [4,5,0]], start_pos=1, 2 (which is 0), dir=left,\n", + " return [[1,2,3], [4,0,5]]\"\"\"\n", + " x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + " out_boards = []\n", + " if y > 0:\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y-1] = new_board[x][y-1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y-1))\n", + " if y <= (len_y-1):\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y+1] = new_board[x][y+1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y+1))\n", + " if x >0:\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x-1][y] = new_board[x-1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x-1, y))\n", + " if x <= (len_x-1):\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x+1][y] = new_board[x+1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x+1, y))\n", + " return out_boards\n", + "\n", + "def slidingPuzzle(board, x, y):\n", + " step = 0\n", + " Q = [(board, x, y, step)]\n", + " seen = []\n", + " while len(Q)>0:\n", + " to_explore, x, y, step = Q.pop(0)\n", + " if to_explore.name == [[1,2,3], [4,5,0]]:\n", + " return to_explore.depth\n", + " \n", + " if to_explore.name in seen:\n", + " continue\n", + " else:\n", + " seen.append(to_explore.name)\n", + " if 0 in to_explore.name[0]:\n", + " x = 0\n", + " else:\n", + " x = 1\n", + " y = to_explore.name[x].index(0)\n", + " \n", + " new_possibilities = search_board(board=to_explore, start_pos=(x,y))\n", + " for index, new in enumerate(new_possibilities):\n", + " new_board, new_x, new_y = new\n", + " Q.append([new_board, new_x, new_y, step+1])\n", + " return -1\n" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1\n" + ] + } + ], + "source": [ + "board = Node([[1,2,3],[4,0,5]])\n", + "print(slidingPuzzle(board, 1, 1))" + ] + }, + { + "cell_type": "code", + "execution_count": 116, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n", + "[[4, 1, 2], [5, 0, 3]]\n", + "├── [[4, 1, 2], [0, 5, 3]]\n", + "│ ├── [[4, 1, 2], [5, 0, 3]]\n", + "│ └── [[0, 1, 2], [4, 5, 3]]\n", + "│ ├── [[1, 0, 2], [4, 5, 3]]\n", + "│ │ ├── [[0, 1, 2], [4, 5, 3]]\n", + "│ │ ├── [[1, 2, 0], [4, 5, 3]]\n", + "│ │ │ ├── [[1, 0, 2], [4, 5, 3]]\n", + "│ │ │ └── [[1, 2, 3], [4, 5, 0]]\n", + "│ │ └── [[1, 5, 2], [4, 0, 3]]\n", + "│ │ ├── [[1, 5, 2], [0, 4, 3]]\n", + "│ │ ├── [[1, 5, 2], [4, 3, 0]]\n", + "│ │ └── [[1, 0, 2], [4, 5, 3]]\n", + "│ └── [[4, 1, 2], [0, 5, 3]]\n", + "├── [[4, 1, 2], [5, 3, 0]]\n", + "│ ├── [[4, 1, 2], [5, 0, 3]]\n", + "│ └── [[4, 1, 0], [5, 3, 2]]\n", + "│ ├── [[4, 0, 1], [5, 3, 2]]\n", + "│ │ ├── [[0, 4, 1], [5, 3, 2]]\n", + "│ │ │ ├── [[4, 0, 1], [5, 3, 2]]\n", + "│ │ │ └── [[5, 4, 1], [0, 3, 2]]\n", + "│ │ ├── [[4, 1, 0], [5, 3, 2]]\n", + "│ │ └── [[4, 3, 1], [5, 0, 2]]\n", + "│ │ ├── [[4, 3, 1], [0, 5, 2]]\n", + "│ │ ├── [[4, 3, 1], [5, 2, 0]]\n", + "│ │ └── [[4, 0, 1], [5, 3, 2]]\n", + "│ └── [[4, 1, 2], [5, 3, 0]]\n", + "└── [[4, 0, 2], [5, 1, 3]]\n", + " ├── [[0, 4, 2], [5, 1, 3]]\n", + " │ ├── [[4, 0, 2], [5, 1, 3]]\n", + " │ └── [[5, 4, 2], [0, 1, 3]]\n", + " │ ├── [[5, 4, 2], [1, 0, 3]]\n", + " │ │ ├── [[5, 4, 2], [0, 1, 3]]\n", + " │ │ ├── [[5, 4, 2], [1, 3, 0]]\n", + " │ │ └── [[5, 0, 2], [1, 4, 3]]\n", + " │ └── [[0, 4, 2], [5, 1, 3]]\n", + " ├── [[4, 2, 0], [5, 1, 3]]\n", + " │ ├── [[4, 0, 2], [5, 1, 3]]\n", + " │ └── [[4, 2, 3], [5, 1, 0]]\n", + " │ ├── [[4, 2, 3], [5, 0, 1]]\n", + " │ │ ├── [[4, 2, 3], [0, 5, 1]]\n", + " │ │ ├── [[4, 2, 3], [5, 1, 0]]\n", + " │ │ └── [[4, 0, 3], [5, 2, 1]]\n", + " │ └── [[4, 2, 0], [5, 1, 3]]\n", + " └── [[4, 1, 2], [5, 0, 3]]\n" + ] + } + ], + "source": [ + "board = Node([[4,1,2],[5,0,3]])\n", + "print(slidingPuzzle(board, 1, 1))\n", + "for pre, fill, node in RenderTree(board):\n", + " print(\"%s%s\" % (pre, node.name))" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "14\n" + ] + } + ], + "source": [ + "board = Node([[3,2,4],[1,5,0]])\n", + "print(slidingPuzzle(board, 1, 2)) # 14" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 103, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# dir(board)\n", + "# ??Node" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 2. We use BFS to solve the jigsaw problem.\n", + "Problem: Given a 3x3 list with non repeating numbers, \n", + "(e.g. [[5, 0, 3], [1, 2, 6], [8, 7, 9]]) \n", + "each time you can swap two adjacent numbers (up, down, left, right.) \n", + "search through the possible space to find the minimum steps required to sort it, \n", + "and print out the road map.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 230, + "metadata": {}, + "outputs": [], + "source": [ + "len_x = 2\n", + "len_y = 2\n", + "def search_board(board, start_pos):\n", + " \"\"\"Given a board and starting position and moving direction,\n", + " make the move and return a new board.\n", + " e.g. [[1,2,3], [4,5,0]], start_pos=1, 2 (which is 0), dir=left,\n", + " return [[1,2,3], [4,0,5]]\"\"\"\n", + " x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + " out_boards = []\n", + " if y > 0: # left\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y-1] = new_board[x][y-1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y-1))\n", + " if y <= (len_y-1): #right\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x][y+1] = new_board[x][y+1], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x, y+1))\n", + " if x >0: # up\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x-1][y] = new_board[x-1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x-1, y))\n", + " if x <= (len_x-1): # down\n", + " new_board = copy.deepcopy(board.name)\n", + " new_board[x][y], new_board[x+1][y] = new_board[x+1][y], new_board[x][y]\n", + " new_node = Node(new_board, parent=board)\n", + " out_boards.append((new_node, x+1, y))\n", + " return out_boards\n", + "\n", + "def slidingPuzzle(board):\n", + " Q = []\n", + " for x in range(3):\n", + " for y in range(3):\n", + " Q.append(board)\n", + "# Q.append((board, x, y))\n", + " seen = []\n", + " while len(Q)>0:\n", + "# import pdb; pdb.set_trace()\n", + "# to_explore, x, y = Q.pop(0)\n", + "# print(to_explore.name, to_explore.depth)\n", + " to_explore = Q.pop(0)\n", + " if len(seen)%100 == 0:\n", + " print(len(seen), to_explore.depth)\n", + " if to_explore.name == [[1,2,3], [4,5,6], [7,8,9]]:\n", + " return to_explore.depth, to_explore\n", + " for x in range(3):\n", + " for y in range(3):\n", + " new_possibilities = search_board(board=to_explore, start_pos=(x,y))\n", + " for index, new in enumerate(new_possibilities):\n", + " new_board, _, _ = new\n", + " if new_board.name not in seen:\n", + " seen.append(new_board.name)\n", + " Q.append(new_board)\n", + " return -1, None" + ] + }, + { + "cell_type": "code", + "execution_count": 224, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(0, Node('/[[1, 2, 3], [4, 5, 6], [7, 8, 9]]'))\n", + "CPU times: user 108 µs, sys: 29 µs, total: 137 µs\n", + "Wall time: 125 µs\n" + ] + } + ], + "source": [ + "# test\n", + "board = Node([[1,2,3],[4,5,6], [7,8,9]])\n", + "%time print(slidingPuzzle(board)) # 0" + ] + }, + { + "cell_type": "code", + "execution_count": 222, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(1, Node('/[[1, 2, 3], [4, 5, 6], [7, 9, 8]]/[[1, 2, 3], [4, 5, 6], [7, 8, 9]]'))\n", + "CPU times: user 11 ms, sys: 935 µs, total: 11.9 ms\n", + "Wall time: 11.1 ms\n" + ] + } + ], + "source": [ + "board = Node([[1,2,3],[4,5,6], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 1" + ] + }, + { + "cell_type": "code", + "execution_count": 223, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(2, Node('/[[1, 2, 3], [4, 6, 5], [7, 9, 8]]/[[1, 2, 3], [4, 5, 6], [7, 9, 8]]/[[1, 2, 3], [4, 5, 6], [7, 8, 9]]'))\n", + "CPU times: user 405 ms, sys: 16.3 ms, total: 421 ms\n", + "Wall time: 421 ms\n" + ] + } + ], + "source": [ + "board = Node([[1,2,3],[4,6,5], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 2" + ] + }, + { + "cell_type": "code", + "execution_count": 225, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(3, Node('/[[1, 2, 3], [6, 4, 5], [7, 9, 8]]/[[1, 2, 3], [4, 6, 5], [7, 9, 8]]/[[1, 2, 3], [4, 5, 6], [7, 9, 8]]/[[1, 2, 3], [4, 5, 6], [7, 8, 9]]'))\n", + "CPU times: user 758 ms, sys: 4.87 ms, total: 763 ms\n", + "Wall time: 766 ms\n" + ] + } + ], + "source": [ + "board = Node([[1,2,3],[6,4,5], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 3" + ] + }, + { + "cell_type": "code", + "execution_count": 226, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(3, Node('/[[1, 6, 3], [4, 2, 5], [7, 9, 8]]/[[1, 2, 3], [4, 6, 5], [7, 9, 8]]/[[1, 2, 3], [4, 5, 6], [7, 9, 8]]/[[1, 2, 3], [4, 5, 6], [7, 8, 9]]'))\n", + "CPU times: user 586 ms, sys: 4.77 ms, total: 591 ms\n", + "Wall time: 592 ms\n" + ] + } + ], + "source": [ + "board = Node([[1,6,3],[4,2,5], [7,9,8]])\n", + "%time print(slidingPuzzle(board)) # 3" + ] + }, + { + "cell_type": "code", + "execution_count": 228, + "metadata": { + "collapsed": true + }, + "outputs": [ + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mslidingPuzzle\u001b[0;34m(board)\u001b[0m\n\u001b[1;32m 50\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnew\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_possibilities\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 51\u001b[0m \u001b[0mnew_board\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnew\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 52\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mnew_board\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mseen\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 53\u001b[0m \u001b[0mseen\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_board\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 54\u001b[0m \u001b[0mQ\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_board\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[[1, 2, 3], [4, 5, 0]], 0, 0, 1], [[[[1, 2, 6], [4, 5, 0]], 1, 0, 2]]]\n" + ] + } + ], + "source": [ + "board = Node([[4,6,3],[7,2,5], [1,9,8]])\n", + "%time tmp = slidingPuzzle(board)\n", + "print(tmp) # 5" + ] + }, + { + "cell_type": "code", + "execution_count": 229, + "metadata": {}, + "outputs": [ + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mslidingPuzzle\u001b[0;34m(board)\u001b[0m\n\u001b[1;32m 50\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnew\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_possibilities\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 51\u001b[0m \u001b[0mnew_board\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnew\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 52\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mnew_board\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mseen\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 53\u001b[0m \u001b[0mseen\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_board\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 54\u001b[0m \u001b[0mQ\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_board\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[[1, 2, 3], [4, 5, 0]], 0, 0, 1], [[[[1, 2, 6], [4, 5, 0]], 1, 0, 2]]]\n" + ] + } + ], + "source": [ + "board = Node([[5,4,6],[9,7,2], [8,1,3]])\n", + "%time tmp = slidingPuzzle(board)\n", + "print(tmp) # ghost examiner" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 231, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 0\n", + "500 2\n", + "900 3\n", + "1000 3\n", + "1800 3\n", + "2400 3\n", + "2500 3\n", + "3600 4\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mslidingPuzzle\u001b[0;34m(board)\u001b[0m\n\u001b[1;32m 51\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mindex\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnew\u001b[0m \u001b[0;32min\u001b[0m \u001b[0menumerate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_possibilities\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 52\u001b[0m \u001b[0mnew_board\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnew\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 53\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mnew_board\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mseen\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 54\u001b[0m \u001b[0mseen\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_board\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 55\u001b[0m \u001b[0mQ\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnew_board\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[[[1, 2, 3], [4, 5, 0]], 0, 0, 1], [[[[1, 2, 6], [4, 5, 0]], 1, 0, 2]]]\n" + ] + } + ], + "source": [ + "board = Node([[9,5,8],[2,4,1], [3,6,7]])\n", + "%time tmp = slidingPuzzle(board)\n", + "print(tmp) # monster examiner" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# x, y = start_pos # pack it in a tuple (x,y) fashion.\n", + "# if direction=='left' and y > 0:\n", + "# board[x][y], board[x][y-1] = board[x][y-1], board[x][y]\n", + "# if direction=='right' and to_explore.name, x, yy <= (len_y-1):\n", + "# board[x][y], board[x][y+1] = board[x][y+1], board[x][y]\n", + "# if direction=='up' and x >0:\n", + "# board[x][y], board[x-1][y] = board[x-1][y], board[x][y]\n", + "# if direction=='down' and x <= (len_x-1):\n", + "# board[x][y], board[x+1][y] = board[x+1][y], board[x][y]\n", + "# return board\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# from anytree import Node, RenderTree\n", + "\n", + "# udo = Node(\"Udo\")\n", + "# marc = Node(\"Marc\", parent=udo)\n", + "# lian = Node(\"Lian\", parent=marc)\n", + "# dan = Node(\"Dan\", parent=udo)\n", + "# jet = Node(\"Jet\", parent=dan)\n", + "# jan = Node(\"Jan\", parent=dan)\n", + "# joe = Node(\"Joe\", parent=dan)\n", + "\n", + "# print(udo)\n", + "# Node('/Udo')\n", + "# print(joe)\n", + "# Node('/Udo/Dan/Joe')\n", + "\n", + "# for pre, fill, node in RenderTree(udo):\n", + "# print(\"%s%s\" % (pre, node.name))\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/BasicCsharp_List.cs b/BasicCsharp_List.cs new file mode 100644 index 0000000..8dd49d8 --- /dev/null +++ b/BasicCsharp_List.cs @@ -0,0 +1,47 @@ +// 1. Init different data structures +using System; +using System.Collections.Generic; + +class Program +{ + static void Main() + { + // 1.1 Init List with input content + List list1 = new List() + { + "carrot", + "fox", + "exploer" + }; + + var list2 = new List() + { + "carrot", + "fox", + "exploer" + }; + + // 1.2 Init List with array as input + string[] array = {"carrot", "fox", "exploer"}; + List list3 = new List(array); + + // 1.3 Init List with capacity + List list4 = new List(3); + list4.Add(null); + list4.Add(null); + list4.Add(null); + list4[0] = "carrot"; + list4[1] = "fox"; + list4[2] = "exploer"; + + // 1.4 use Add method with unspecified pre condi + List list5 = new List(); + list5.Add("carrot"); + list5.Add("fox"); + list5.Add("exploer"); + + + // 2. Dictionary with Tuple + public Dictionary, int> store = new Dictionary, int>(); + } +} \ No newline at end of file diff --git a/BasicCsharp_functions.cs b/BasicCsharp_functions.cs new file mode 100644 index 0000000..b5d24f1 --- /dev/null +++ b/BasicCsharp_functions.cs @@ -0,0 +1,15 @@ + + + + + // 1. in order traverse of a tree function, + // !! a function without return (change in place) + // !! pass in a list as function parameter + public void inOrder(TreeNode node, List list){ + if (node != null) + { + inOrder(node.left, list); + list.Add(node.val); + inOrder(node.right, list); + } + } \ No newline at end of file diff --git a/LinkedList.py b/LinkedList.py new file mode 100644 index 0000000..b3f86d9 --- /dev/null +++ b/LinkedList.py @@ -0,0 +1,40 @@ +class ListNode(object): + def __init__(self, val=0, next=None): + self.val = val + self.next = next + + def __repr__(self): + out = "LinkedList Node: " + str(self.val) + cur = self.next + while cur: + out += "->" + str(cur.val) + cur = cur.next + out += " [end]" + return out + + def __str__(self): + out = "LinkedList Node: " + str(self.val) + cur = self.next + while cur: + out += "->" + str(cur.val) + cur = cur.next + out += " [end]" + return out + + def insert(self, val=0, next=None): + if self.next is None: + self.next = ListNode(val=val, next=next) + else: + cur = self.next + while cur.next: + cur = cur.next + cur.next = ListNode(val=val, next=next) + + +class LinkedList(object): + def __init__(self, head): + # head = ListNode + self.head = head + + def __repr__(self): + pass diff --git a/Linked_list_related.ipynb b/Linked_list_related.ipynb new file mode 100644 index 0000000..1a713c3 --- /dev/null +++ b/Linked_list_related.ipynb @@ -0,0 +1,582 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "class ListNode(object):\n", + " def __init__(self, val=0, next=None):\n", + " self.val = val\n", + " self.next = next" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "LN1 = ListNode(2, ListNode(4, ListNode(3)))\n", + "LN2 = ListNode(5, ListNode(6, ListNode(4)))\n", + "LN3 = ListNode(5, ListNode(6, ListNode(4, ListNode(1))))" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "num1=2, num2=5, tmp_num=7, total_num=7\n", + "num1=4, num2=6, tmp_num=100, total_num=107\n", + "num1=3, num2=4, tmp_num=700, total_num=807\n" + ] + } + ], + "source": [ + "def addTwoNumbers(l1, l2):\n", + " \"\"\"\n", + " :type l1: ListNode\n", + " :type l2: ListNode\n", + " :rtype: ListNode\n", + " \"\"\"\n", + " digit = 0\n", + " total_num = 0\n", + " while l1 and l2:\n", + " num1 = l1.val\n", + " num2 = l2.val\n", + " tmp_num = (num1+num2)*(10**digit)\n", + " total_num += tmp_num\n", + " print(f\"num1={num1}, num2={num2}, tmp_num={tmp_num}, total_num={total_num}\")\n", + " l1 = l1.next\n", + " l2 = l2.next\n", + " digit += 1\n", + "\n", + " while l1: #l2 exhausted\n", + " num1 = l1.val\n", + " tmp_num = num1 * (10**digit)\n", + " total_num += tmp_num\n", + " print(f\"num1={num1}, num2={num2}, tmp_num={tmp_num}, total_num={total_num}\")\n", + " l1 = l1.next\n", + " digit += 1\n", + "\n", + " while l2:\n", + " num2 = l2.val\n", + " tmp_num = num2 * (10**digit)\n", + " total_num += tmp_num\n", + " print(f\"num1={num1}, num2={num2}, tmp_num={tmp_num}, total_num={total_num}\")\n", + " l2 = l2.next\n", + " digit += 1\n", + " \n", + "# out = ListNode(0,ListNode())\n", + "# tmp = out.next\n", + "# for i in list(str(total_num))[::-1]:\n", + "# # print(i)\n", + "# tmp.val = int(i)\n", + "# tmp.next = ListNode()\n", + "# tmp = tmp.next\n", + "# return out.next\n", + " return total_num\n", + "\n", + "\n", + "total_num = addTwoNumbers(LN1, LN2) #807" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "num1=2, num2=5, tmp_num=7, total_num=7\n", + "num1=4, num2=6, tmp_num=100, total_num=107\n", + "num1=3, num2=4, tmp_num=700, total_num=807\n", + "num1=3, num2=1, tmp_num=1000, total_num=1807\n" + ] + }, + { + "data": { + "text/plain": [ + "1807" + ] + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "total_num = addTwoNumbers(LN1, LN3) #1807\n", + "total_num" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "num1=0, num2=1, tmp_num=1, total_num=1\n" + ] + }, + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "total_num = addTwoNumbers(ListNode(0), ListNode(1))\n", + "total_num" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "metadata": {}, + "outputs": [], + "source": [ + "if len(str(total_num)) <= 1:\n", + " return ListNode(total_num)\n", + "\n", + "out = ListNode(0,ListNode())\n", + "tmp = out.next\n", + "out_nums = [int(_) for _ in list(str(total_num))][::-1]\n", + "for i in range(len(out_nums)-1):\n", + " print(i, out_nums[i])\n", + " tmp.val = out_nums[i]\n", + " tmp.next = ListNode(out_nums[i+1])\n", + " tmp = tmp.next\n", + "tmp=None\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "metadata": {}, + "outputs": [ + { + "ename": "AttributeError", + "evalue": "'NoneType' object has no attribute 'val'", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mout\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnext\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mval\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mAttributeError\u001b[0m: 'NoneType' object has no attribute 'val'" + ] + } + ], + "source": [ + "out.next.next.next.val" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "out.val" + ] + }, + { + "cell_type": "code", + "execution_count": 84, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 1\n", + "1 -3\n", + "2 -3\n", + "3 9\n", + "4 -1\n", + "5 -2\n", + "6 5\n" + ] + } + ], + "source": [ + "nums = [-2,1,-3, -3, 9,-1, -2, 5]\n", + "for i, n in enumerate(nums[1:]):\n", + " print(i,n)" + ] + }, + { + "cell_type": "code", + "execution_count": 85, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "i=0, num=-2, cur_sum=-2, max_sum=-2\n", + "i=1, num=1, cur_sum=1, max_sum=1\n", + "i=2, num=-3, cur_sum=-2, max_sum=1\n", + "i=3, num=-3, cur_sum=-3, max_sum=1\n", + "i=4, num=9, cur_sum=9, max_sum=9\n", + "i=5, num=-1, cur_sum=8, max_sum=9\n", + "i=6, num=-2, cur_sum=6, max_sum=9\n", + "i=7, num=5, cur_sum=11, max_sum=11\n" + ] + }, + { + "data": { + "text/plain": [ + "11" + ] + }, + "execution_count": 85, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def maxSubArray(nums: 'List[int]') -> 'int':\n", + " n = len(nums)\n", + " curr_sum = max_sum = nums[0]\n", + " print(f\"i={0}, num={nums[0]}, cur_sum={curr_sum}, max_sum={max_sum}\")\n", + " for i in range(1, n):\n", + " curr_sum = max(nums[i], curr_sum + nums[i])\n", + " max_sum = max(max_sum, curr_sum)\n", + " print(f\"i={i}, num={nums[i]}, cur_sum={curr_sum}, max_sum={max_sum}\")\n", + " return max_sum\n", + "\n", + "maxSubArray(nums)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import defaultdict\n", + "words = " + ] + }, + { + "cell_type": "code", + "execution_count": 89, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 0\n", + "0 1\n", + "0 3\n", + "1 0\n", + "1 1\n", + "1 3\n", + "2 0\n", + "2 1\n", + "2 3\n", + "3 0\n", + "3 1\n", + "3 3\n", + "4 0\n", + "4 1\n", + "4 3\n" + ] + } + ], + "source": [ + "for i in range(5):\n", + " for j in range(4):\n", + " if j == 2:\n", + " continue\n", + " print(i,j)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "defaultdict(.()>,\n", + " {'l': 1, 'e': 2, 't': 1})" + ] + }, + "execution_count": 91, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def count_str_to_dict(string):\n", + " # given a string, count number of characters into a dict\n", + " from collections import defaultdict\n", + " outD = defaultdict(lambda: 0)\n", + " for s in string:\n", + " outD[s] += 1\n", + " return outD\n", + "\n", + "count_str_to_dict(\"leet\")" + ] + }, + { + "cell_type": "code", + "execution_count": 93, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'abc'" + ] + }, + "execution_count": 93, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"\".join(sorted(\"cba\"))" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from LinkedList import ListNode" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "LinkedList Node: 2->3 [end]" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tmp = ListNode(2, ListNode(3))\n", + "tmp" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "tmp.insert(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "LinkedList Node: 2->3->1 [end]" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tmp" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "LinkedList Node: 0->1 [end]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tmp = ListNode()\n", + "tmp.insert(1)\n", + "tmp" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": {}, + "outputs": [], + "source": [ + "S = \"ababcbacadefegdehijhklij\"\n" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0 8 ['b', 'c'] ['d', 'e', 'f', 'e', 'g', 'd', 'e', 'h', 'i', 'j', 'h', 'k', 'l', 'i', 'j']\n", + "9 15 ['g', 'f', 'e'] ['h', 'i', 'j', 'h', 'k', 'l', 'i', 'j']\n", + "16 23 ['i', 'j', 'l', 'k'] []\n" + ] + } + ], + "source": [ + "start_index = 0\n", + "# search_index = 1\n", + "out = []\n", + "while start_index < len(S):\n", + " # start with first letter, find the last apperance of this letter\n", + " # and save all the seen letters within\n", + " start_word = S[start_index]\n", + " words_within = []\n", + " tmp_words = []\n", + " for search_index in range(start_index, len(S)):\n", + " if S[search_index] == start_word or S[search_index] in words_within:\n", + " words_within.extend(list(set(tmp_words)))\n", + " tmp_words = []\n", + " end_index = search_index\n", + " else:\n", + " tmp_words.append(S[search_index])\n", + " print(start_index, end_index, words_within, tmp_words)\n", + " out.append(end_index+1-start_index)\n", + " start_index = end_index+1\n", + " \n", + "# break\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[9, 7, 8]" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "out" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "8" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "end_index" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Untitled1.ipynb b/Untitled1.ipynb new file mode 100644 index 0000000..d2b1d9f --- /dev/null +++ b/Untitled1.ipynb @@ -0,0 +1,125 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class Trie(object): \n", + "\n", + " class node(object):\n", + " def __init__(self, val=None):\n", + " self.val = val\n", + " self.kids = []\n", + " \n", + " def __init__(self):\n", + " \"\"\"\n", + " Initialize your data structure here.\n", + " \"\"\"\n", + " self.root = Trie.node()\n", + " \n", + "\n", + " def insert(self, word):\n", + " \"\"\"\n", + " Inserts a word into the trie.\n", + " :type word: str\n", + " :rtype: None\n", + " \"\"\"\n", + " cur = self.root\n", + " for index, letter in enumerate(word):\n", + " tmp = Trie.node(letter)\n", + " cur.kids.append(tmp)\n", + " cur = tmp\n", + " cur.kids.append(\"end\")\n", + "\n", + " def search(self, word):\n", + " \"\"\"\n", + " Returns if the word is in the trie.\n", + " :type word: str\n", + " :rtype: bool\n", + " \"\"\"\n", + " cur = self.root\n", + " for letter in word:\n", + " print(letter)\n", + " for kid in cur.kids:\n", + " if kid.val == letter:\n", + " cur = kid\n", + " print(\"found, continue\")\n", + " break\n", + " print(\"did find, return False\")\n", + " return False\n", + " print(\"end step, check cur.kids is None: {}\".format(cur.kids))\n", + " print(\"\")\n", + " return \"end\" in cur.kids\n", + " \n", + "\n", + "\n", + " def startsWith(self, prefix):\n", + " \"\"\"\n", + " Returns if there is any word in the trie that starts with the given prefix.\n", + " :type prefix: str\n", + " :rtype: bool\n", + " \"\"\"\n", + " cur = self.root\n", + " for letter in prefix:\n", + " for kid in cur.kids:\n", + " if kid.val == letter:\n", + " cur = kid\n", + " break\n", + " return False\n", + " return True\n", + " \n", + "\n", + "\n", + "# Your Trie object will be instantiated and called as such:\n", + "# obj = Trie()\n", + "# obj.insert(word)\n", + "# param_2 = obj.search(word)\n", + "# param_3 = obj.startsWith(prefix)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Untitled2.ipynb b/Untitled2.ipynb new file mode 100644 index 0000000..672b8fb --- /dev/null +++ b/Untitled2.ipynb @@ -0,0 +1,290 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# 23280666731155" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import string" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'!\"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "string.punctuation" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = {\"a\":2}" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import defaultdict" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "tmp = defaultdict(lambda: 0)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "0" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "tmp['a']" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'dsa we2'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "\"Dsa we2\".lower()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['ds fff', 'as eaaa bbbb', 'hum cccc dddd']" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "word_log = [\"ds fff\",\"as eaaa bbbb\", \"hum cccc dddd\"]\n", + "word_log.sort(key=lambda x: x[1])\n", + "word_log" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['Formatter',\n", + " 'Template',\n", + " '_ChainMap',\n", + " '_TemplateMetaclass',\n", + " '__all__',\n", + " '__builtins__',\n", + " '__cached__',\n", + " '__doc__',\n", + " '__file__',\n", + " '__loader__',\n", + " '__name__',\n", + " '__package__',\n", + " '__spec__',\n", + " '_re',\n", + " '_string',\n", + " 'ascii_letters',\n", + " 'ascii_lowercase',\n", + " 'ascii_uppercase',\n", + " 'capwords',\n", + " 'digits',\n", + " 'hexdigits',\n", + " 'octdigits',\n", + " 'printable',\n", + " 'punctuation',\n", + " 'whitespace']" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dir(string)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "string.ascii_letters" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "ename": "SyntaxError", + "evalue": "invalid syntax (, line 1)", + "output_type": "error", + "traceback": [ + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m assert isinstance([\"\"], list):\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + ] + } + ], + "source": [ + "assert isinstance([\"\"], list)\n", + " raise(\"lalala\")" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "import warnings" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/toby/anaconda3/envs/py36/lib/python3.6/site-packages/ipykernel_launcher.py:1: UserWarning: lalal\n", + " \"\"\"Entry point for launching an IPython kernel.\n" + ] + } + ], + "source": [ + "warnings.warn(\"lalal\")" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "ename": "AssertionError", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32massert\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mAssertionError\u001b[0m: " + ] + } + ], + "source": [ + "assert False" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/__pycache__/LinkedList.cpython-36.pyc b/__pycache__/LinkedList.cpython-36.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f72448f4f70bea572c88925f31589042a2f82c7 GIT binary patch literal 1539 zcmc&!OKTKC5bnq9?Cd6+Y!Xlr4{H=<4`u@jibx11;3X`ANMJ>q&2&rlk(s1tR+44+ zl;F)D;$NDpCr=&)PkzdVE#Y{j^dkf91bE{g#aVU~|L6dK;8H1bf3Y z)BFNt*tu+R?1h%tOSc!=d&la95I3g-_HzAAEDURL&00b)XsNvm-jceY{R`IebWsPG z3wlwPbQuy~3)re;!Cogxo3S=O$z(Gmdo*YkpdCnY1nWDqKBhk}8t)ThlSUdJoHcgiaByUzG-(UnBJd^Pt&15*RE)zK`k^so8IkrkshLR;P#+QK2=c~NTgUcB6oBti7 zEg{Nl7;TwO7l;v-IgCZ6kQAksaeNcR>RcJ!#cA_V1*cWq#Rhf5)93~EZpzV!Li2Cb zh%9e=fW4RNiB6w-E-xd32(&XcOvw0dWYaF zf-zL8DtuI{%!kWUF!?RGqNXL6`CO!$N9`k{R905%DAt2MtrwL#8MOPk#0Jo@WZYJW zQDe-d)g_qv$3;z%C!~M?yr2}6+-Zn|=^)qJpyVFd^mjnx<1dizkD$MyfaLgDdDi10 z>CvE>$UP@2bp8uW-apU0L(|s4NZoGNh+S?12j~IL6K7Hk*JfU>zg|K_oo2mYsS7QAWOjwvEYUN2v-Gaw$~wsXIROtmOD9ddb3Z=l anlN>#c87C-r}|m&DzERBs}Vu3-v0~W@*NZa literal 0 HcmV?d00001 diff --git a/akuna.py b/akuna.py index 8ab523b..bde79e1 100644 --- a/akuna.py +++ b/akuna.py @@ -30,6 +30,7 @@ def unusual_sort(numbers): #%% +def whatever(n, intList): delta = n # initalize the int to store difference between sum and n if sum(intList) < n: return False #impossible diff --git a/tmp.py b/tmp.py new file mode 100644 index 0000000..c5f3628 --- /dev/null +++ b/tmp.py @@ -0,0 +1,58 @@ +# import math + +# N = 1000 +# table = [None for _ in range(N + 2)] # p_i (0) +# table[2], table[3] = 1, 2 +# index = 4 + +# while index <= N: +# table[index] = (index - 1) * (table[index - 1] + table[index - 2]) +# index += 1 + +# print(table[N] / math.factorial(N)) + +# def bubble_sort(a): +# for i in range(n, 0, -1): # i = n, n - 1, ..., 1 +# for j in range(1, i): # j = 1, 2, ..., i - 1 +# if a[j] > a[j + 1]: +# a[j], a[j + 1] = a[j + 1], a[j] # swap +# return a + + +# # def rec(n): +# # if n == 2: +# # return 2 +# # return 2 * rec(n // 2) + n + + +# # print(rec(2048)) + + +# total = 0 +# for i in range(1, 12): +# top = i * 2 ** (i - 1) +# total += top +# print(f"i = {i}, top = {top}, total = {total}") + + +array = [4, 6, 10, 8, 2, 1] +m = 3 + +start = 0 +end = m + +maxSum = sum(array[start:end]) +print("maxSum = ", maxSum) +cur = maxSum + +while end < len(array) - 1: + cur -= array[start] + start += 1 + cur += array[end] + end += 1 + maxSum = max(maxSum, cur) + print("maxSum = ", maxSum) + +result = sum(array) - maxSum + +print(result) From ffa797f240d4c68da2999a415887cabb9944fee1 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Thu, 29 Sep 2022 20:18:13 -0700 Subject: [PATCH 04/20] add 1155. --- 1155.NumberOfDiceRollsWithTargetSum.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 1155.NumberOfDiceRollsWithTargetSum.py diff --git a/1155.NumberOfDiceRollsWithTargetSum.py b/1155.NumberOfDiceRollsWithTargetSum.py new file mode 100644 index 0000000..3dcb643 --- /dev/null +++ b/1155.NumberOfDiceRollsWithTargetSum.py @@ -0,0 +1,23 @@ +def numRollsToTarget(n: int, k: int, target: int) -> int: + # divid and conquer? -> dp from small to large + # f(n, k, target) = f(n-1, k, targe-1) + f(n-1, k, target-2) + ... + f(n-1, k, target-k) + dp = [[0] * (target + 1) for _ in range(n + 1)] # dp[n][target] + + for row in range(1, n + 1): # number of dices, also row + for i in range(1, target + 1): # target + if row == 1 and i <= k: + dp[row][i] = 1 + elif row == 1 and i > k: + continue + elif row * k < i: # n > 1 + continue + else: + dp[row][i] = sum( + [dp[row - 1][i - cur] for cur in range(1, min(i, k + 1))] + ) + print(dp[row]) + + return dp[n][target] + + +numRollsToTarget(30, 30, 500) From fb337768e21402b6495d0854e98fe2e4f324bf50 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Fri, 30 Sep 2022 13:08:12 -0700 Subject: [PATCH 05/20] add 79 word search --- 79.WordSearch.py | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 79.WordSearch.py diff --git a/79.WordSearch.py b/79.WordSearch.py new file mode 100644 index 0000000..7fe1061 --- /dev/null +++ b/79.WordSearch.py @@ -0,0 +1,76 @@ +""" +Sep 29 2022: +The most challenging part here is to mark the 'seen' elements. +I initially tried to do it was a set, but that passing the set +around is messy and TLE on LC. +Another way here is to modify the graph/board on the fly, and +here is an important backtracking technique! +1. you first check boundary condition (row, col, etc.) +2. check True condition (element == ) +3. visit the current node (modify) +4. use a for-loop to dfs +5. outside of the for-loop, convert the modified back +(so it doesn't affect other nodes' searchs) + +This convert back mechanism is interesting and totally new to me! +""" +import numpy as np + + +class Solution: + def exist(self, board, word): + """ + :type board: List[List[str]] + :type word: str + :rtype: bool + """ + self.ROWS = len(board) + self.COLS = len(board[0]) + self.board = board + + for row in range(self.ROWS): + for col in range(self.COLS): + if self.backtrack(row, col, word): + return True + + # no match found after all exploration + return False + + def backtrack(self, row, col, suffix): + # bottom case: we find match for each letter in the word + if len(suffix) == 0: + return True + + # Check the current status, before jumping into backtracking + if ( + row < 0 + or row == self.ROWS + or col < 0 + or col == self.COLS + or self.board[row][col] != suffix[0] + ): + return False + + ret = False + # mark the choice before exploring further. + self.board[row][col] = "#" + print(np.matrix(self.board)) + print() + # explore the 4 neighbor directions + for rowOffset, colOffset in [(0, 1), (1, 0), (0, -1), (-1, 0)]: + ret = self.backtrack(row + rowOffset, col + colOffset, suffix[1:]) + # break instead of return directly to do some cleanup afterwards + if ret: + break + + # revert the change, a clean slate and no side-effect + self.board[row][col] = suffix[0] + + # Tried all directions, and did not find any match + return ret + + +a = [["A", "B", "C", "E"], ["S", "F", "E", "S"], ["A", "E", "E", "E"]] +word = "FEEEC" +res = Solution().exist(board=a, word=word) +print(res) From a6de8616bd35bc259a7ea687aa928bd07b8945f5 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Mon, 10 Oct 2022 17:49:48 -0700 Subject: [PATCH 06/20] add 2430 and 1155. --- 1155.NumberOfDiceRollsWithTargetSum.py | 1 + 2430.MaximumDeletionsOnString.py | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 2430.MaximumDeletionsOnString.py diff --git a/1155.NumberOfDiceRollsWithTargetSum.py b/1155.NumberOfDiceRollsWithTargetSum.py index 3dcb643..f66c032 100644 --- a/1155.NumberOfDiceRollsWithTargetSum.py +++ b/1155.NumberOfDiceRollsWithTargetSum.py @@ -21,3 +21,4 @@ def numRollsToTarget(n: int, k: int, target: int) -> int: numRollsToTarget(30, 30, 500) + diff --git a/2430.MaximumDeletionsOnString.py b/2430.MaximumDeletionsOnString.py new file mode 100644 index 0000000..f7abaaa --- /dev/null +++ b/2430.MaximumDeletionsOnString.py @@ -0,0 +1,23 @@ +class Solution: + def deleteString(self, s: str) -> int: + if all(x == s[0] for x in s): + return len(s) + + @cache + def dfs(word_index): + length = len(s) - word_index + if length == 1: + return 1 + res = 1 + for i in range(1, length // 2 + 1): + if len(s) - word_index - i + 1 <= res: + break + if ( + s[word_index : word_index + i] + == s[word_index + i : word_index + 2 * i] + ): + res = max(res, 1 + dfs(word_index + i)) + return res + + res = dfs(0) + return res From aaf34c6797e474a11f19208c3872ab16e10a5109 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Thu, 13 Oct 2022 21:36:20 -0700 Subject: [PATCH 07/20] add 130 and 2434. --- .gitignore | 1 + .vscode/.ropeproject/config.py | 125 ++++++++++++++++++ .vscode/.ropeproject/objectdb | Bin 0 -> 6 bytes 130.Surrounded Regions.py | 51 +++++++ ...PrintTheLexicographicallySmallestString.py | 31 +++++ 5 files changed, 208 insertions(+) create mode 100644 .vscode/.ropeproject/config.py create mode 100644 .vscode/.ropeproject/objectdb create mode 100644 130.Surrounded Regions.py create mode 100644 2434.UsingaRobottoPrintTheLexicographicallySmallestString.py diff --git a/.gitignore b/.gitignore index e43b0f9..860f418 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .DS_Store +.vscode/ \ No newline at end of file diff --git a/.vscode/.ropeproject/config.py b/.vscode/.ropeproject/config.py new file mode 100644 index 0000000..455b3be --- /dev/null +++ b/.vscode/.ropeproject/config.py @@ -0,0 +1,125 @@ +# The default ``config.py`` +# flake8: noqa + + +def set_prefs(prefs): + """This function is called before opening the project""" + + # Specify which files and folders to ignore in the project. + # Changes to ignored resources are not added to the history and + # VCSs. Also they are not returned in `Project.get_files()`. + # Note that ``?`` and ``*`` match all characters but slashes. + # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' + # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' + # '.svn': matches 'pkg/.svn' and all of its children + # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' + # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' + prefs["ignored_resources"] = [ + "*.pyc", + "*~", + ".ropeproject", + ".hg", + ".svn", + "_svn", + ".git", + ".tox", + ".venv", + "venv", + ] + + # Specifies which files should be considered python files. It is + # useful when you have scripts inside your project. Only files + # ending with ``.py`` are considered to be python files by + # default. + # prefs['python_files'] = ['*.py'] + + # Custom source folders: By default rope searches the project + # for finding source folders (folders that should be searched + # for finding modules). You can add paths to that list. Note + # that rope guesses project source folders correctly most of the + # time; use this if you have any problems. + # The folders should be relative to project root and use '/' for + # separating folders regardless of the platform rope is running on. + # 'src/my_source_folder' for instance. + # prefs.add('source_folders', 'src') + + # You can extend python path for looking up modules + # prefs.add('python_path', '~/python/') + + # Should rope save object information or not. + prefs["save_objectdb"] = True + prefs["compress_objectdb"] = False + + # If `True`, rope analyzes each module when it is being saved. + prefs["automatic_soa"] = True + # The depth of calls to follow in static object analysis + prefs["soa_followed_calls"] = 0 + + # If `False` when running modules or unit tests "dynamic object + # analysis" is turned off. This makes them much faster. + prefs["perform_doa"] = True + + # Rope can check the validity of its object DB when running. + prefs["validate_objectdb"] = True + + # How many undos to hold? + prefs["max_history_items"] = 32 + + # Shows whether to save history across sessions. + prefs["save_history"] = True + prefs["compress_history"] = False + + # Set the number spaces used for indenting. According to + # :PEP:`8`, it is best to use 4 spaces. Since most of rope's + # unit-tests use 4 spaces it is more reliable, too. + prefs["indent_size"] = 4 + + # Builtin and c-extension modules that are allowed to be imported + # and inspected by rope. + prefs["extension_modules"] = [] + + # Add all standard c-extensions to extension_modules list. + prefs["import_dynload_stdmods"] = True + + # If `True` modules with syntax errors are considered to be empty. + # The default value is `False`; When `False` syntax errors raise + # `rope.base.exceptions.ModuleSyntaxError` exception. + prefs["ignore_syntax_errors"] = False + + # If `True`, rope ignores unresolvable imports. Otherwise, they + # appear in the importing namespace. + prefs["ignore_bad_imports"] = False + + # If `True`, rope will insert new module imports as + # `from import ` by default. + prefs["prefer_module_from_imports"] = False + + # If `True`, rope will transform a comma list of imports into + # multiple separate import statements when organizing + # imports. + prefs["split_imports"] = False + + # If `True`, rope will remove all top-level import statements and + # reinsert them at the top of the module when making changes. + prefs["pull_imports_to_top"] = True + + # If `True`, rope will sort imports alphabetically by module name instead + # of alphabetically by import statement, with from imports after normal + # imports. + prefs["sort_imports_alphabetically"] = False + + # Location of implementation of + # rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general + # case, you don't have to change this value, unless you're an rope expert. + # Change this value to inject you own implementations of interfaces + # listed in module rope.base.oi.type_hinting.providers.interfaces + # For example, you can add you own providers for Django Models, or disable + # the search type-hinting in a class hierarchy, etc. + prefs[ + "type_hinting_factory" + ] = "rope.base.oi.type_hinting.factory.default_type_hinting_factory" + + +def project_opened(project): + """This function is called after opening the project""" + # Do whatever you like here! diff --git a/.vscode/.ropeproject/objectdb b/.vscode/.ropeproject/objectdb new file mode 100644 index 0000000000000000000000000000000000000000..0a47446c0ad231c193bdd44ff327ba2ab28bf3d8 GIT binary patch literal 6 NcmZo*sx4&D0{{kv0iOT> literal 0 HcmV?d00001 diff --git a/130.Surrounded Regions.py b/130.Surrounded Regions.py new file mode 100644 index 0000000..28ede37 --- /dev/null +++ b/130.Surrounded Regions.py @@ -0,0 +1,51 @@ +from typing import List + + +def solve(board: List[List[str]]) -> None: + """ + Do not return anything, modify board in-place instead. + """ + # start from any boarder Os, keep them, other wise return + ROWS, COLS = len(board), len(board[0]) + res = [["X" for _ in range(COLS)] for _ in range(ROWS)] + visited = set() + + def dfs(row, col): + if ( + row < 0 + or row == ROWS + or col < 0 + or col == COLS + or board[row][col] == "X" + or (row, col) in visited + ): + return + + visited.add((row, col)) + res[row][col] = "O" + dfs(row + 1, col) + dfs(row - 1, col) + dfs(row, col + 1) + dfs(row, col - 1) + + for col in range(COLS): + dfs(0, col) + dfs(ROWS - 1, col) + + for row in range(ROWS): + dfs(row, 0) + dfs(row, COLS - 1) + + return res + + +tmp = solve( + [ + ["X", "X", "X", "X"], + ["X", "O", "O", "X"], + ["X", "X", "O", "X"], + ["X", "O", "X", "X"], + ] +) + +print(tmp) diff --git a/2434.UsingaRobottoPrintTheLexicographicallySmallestString.py b/2434.UsingaRobottoPrintTheLexicographicallySmallestString.py new file mode 100644 index 0000000..969907d --- /dev/null +++ b/2434.UsingaRobottoPrintTheLexicographicallySmallestString.py @@ -0,0 +1,31 @@ +from collections import Counter + + +def robotWithString(s: str) -> str: + res = "" + remain = "" + candidates = list(s) + while len(candidates) > 0: + print(candidates) + minVal = min(candidates) + while remain and remain[-1] <= minVal: + res += remain[-1] + remain = remain[:-1] + last = len(candidates) - 1 - candidates[::-1].index(minVal) + count = Counter(candidates)[minVal] + res += minVal * count + remain += "".join(candidates[:last]).replace(minVal, "") + candidates = candidates[last + 1 :] + # remain = "".join(candidates[first:]).replace(minVal, "") + # candidates = candidates[:first] + # if remain: + # candidates = [remain] + candidates + + # res += "".join(candidates) + res += remain[::-1] + print(res) + + +# robotWithString("zza") +robotWithString("vzhofnpo") +# robotWithString("bac") From 25256573dfcc8ababdbdbca5c8ddef3d093500f8 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Sun, 30 Oct 2022 22:02:13 -0700 Subject: [PATCH 08/20] add 1567 and 2458 --- ...imumLengthOfSubarrayWithPositiveProduct.py | 24 ++++++++ ...nary Tree After Subtree Removal Queries.py | 61 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 1567.MaximumLengthOfSubarrayWithPositiveProduct.py create mode 100644 2458. Height of Binary Tree After Subtree Removal Queries.py diff --git a/1567.MaximumLengthOfSubarrayWithPositiveProduct.py b/1567.MaximumLengthOfSubarrayWithPositiveProduct.py new file mode 100644 index 0000000..f512cb9 --- /dev/null +++ b/1567.MaximumLengthOfSubarrayWithPositiveProduct.py @@ -0,0 +1,24 @@ +def getMaxLength(nums): + for i in range(len(nums)): + print(nums[i]) + i += 1 + + +# def getMaxLength(nums): +# pos, neg, ans = 0, 0, 0 +# for n in nums: +# new_pos, new_neg = 0, 0 +# if n > 0: +# new_pos = pos + 1 +# new_neg = neg + 1 if neg > 0 else 0 +# elif n < 0: +# new_pos = neg + 1 if neg > 0 else 0 +# new_neg = pos + 1 + +# pos, neg = new_pos, new_neg +# ans = max(ans, pos) +# print(ans) +# return ans + + +getMaxLength([1, -2, -3, 4, 0, 5, -6, -7, 8, 9]) diff --git a/2458. Height of Binary Tree After Subtree Removal Queries.py b/2458. Height of Binary Tree After Subtree Removal Queries.py new file mode 100644 index 0000000..1ad472b --- /dev/null +++ b/2458. Height of Binary Tree After Subtree Removal Queries.py @@ -0,0 +1,61 @@ +# Definition for a binary tree node. +# class TreeNode: +# def __init__(self, val=0, left=None, right=None): +# self.val = val +# self.left = left +# self.right = right +class Solution: + def treeQueries(self, root: Optional[TreeNode], queries: List[int]) -> List[int]: + # idea: mark all the depth, then bfs one time to find the answer -> N + N + + # 1. mark the height of each node + def dfs(node): + if not node: + return 0 + if node.right or node.left: + node.height = max(dfs(node.left), dfs(node.right)) + 1 + if not node.right and not node.left: + node.height = 0 + # print(node, node.height) + return node.height + + dfs(root) + + # 2. bfs and find the ans + ret = [-1] * len(queries) + cache = {} + for num in queries: + cache[num] = 0 + queue = [root] + cur_level = 0 + while queue: + tmp_queue = [] + # while queue: + # tmp_queue.append(queue.pop(0)) + tmp_values = [_.val for _ in tmp_queue] + tmp_heights = [_.height for _ in tmp_queue] + targets = list(set(tmp_values).intersection(queries)) + for target in targets: + # queryId = queries.index(target) + heightId = tmp_values.index(target) + select = [_ for index, _ in enumerate(tmp_heights) if index != heightId] + if select: + queryAns = max(select) + cur_level + else: + queryAns = cur_level - 1 + # print(queryAns, cur_level) + # ret[queryId] = queryAns + cache[target] = queryAns + + cur_level += 1 + + for node in tmp_queue: + if node.left: + queue.append(node.left) + if node.right: + queue.append(node.right) + + # handle query duplicates + for i in range(len(ret)): + ret[i] = cache[queries[i]] + return ret From 8774b96159bd09aeb1d27853e205bc1ba07ca5c6 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Thu, 3 Nov 2022 16:08:35 -0700 Subject: [PATCH 09/20] add completet binary search problem 34, and interesting binary koko. 875 --- ...ast Position of Element in Sorted Array.py | 69 +++++++++++++++++++ 875. Koko Eating Bananas.py | 36 ++++++++++ 2 files changed, 105 insertions(+) create mode 100644 34. Find First and Last Position of Element in Sorted Array.py create mode 100644 875. Koko Eating Bananas.py diff --git a/34. Find First and Last Position of Element in Sorted Array.py b/34. Find First and Last Position of Element in Sorted Array.py new file mode 100644 index 0000000..f18b4cf --- /dev/null +++ b/34. Find First and Last Position of Element in Sorted Array.py @@ -0,0 +1,69 @@ +class Solution: + def searchRange(self, nums: List[int], target: int) -> List[int]: + def bs_lowerBound(nums, target): # return index + l, r = 0, len(nums) + while l < r: + m = l + (r - l) // 2 + if nums[m] < target: + l = m + 1 + else: + r = m + # print(l) + return l + + def bs_upperBound(nums, target): # not inclusive [l, r) + l, r = 0, len(nums) + while l < r: + m = l + (r - l) // 2 + if nums[m] <= target: + l = m + 1 + else: + r = m + # print(l, r) + return l + + # search to see find + upper = bs_upperBound(nums, target) - 1 + lower = bs_lowerBound(nums, target) + if lower == len(nums): + return [-1, -1] + if nums[lower] != target: + return [-1, -1] + return [lower, upper] + + +def bs_lowerBound(nums, target): # return index + l, r = 0, len(nums) + while l < r: + m = l + (r - l) // 2 + if nums[m] >= target: + r = m + else: + l = m + 1 + print(l) + return l + + +def bs_upperBound(nums, target): # not inclusive [l, r) + l, r = 0, len(nums) + while l < r: + m = l + (r - l) // 2 + if nums[m] > target: + r = m + else: + l = m + 1 + print(l, r) + return l + + +# test +a = [5, 7, 7, 8, 8, 10] +bs_lowerBound(a, 10) +bs_lowerBound(a, 8) +bs_lowerBound([5], 5) +bs_lowerBound(a, 6) + +bs_upperBound(a, 10) +bs_upperBound(a, 8) +bs_upperBound([5], 5) +bs_upperBound(a, 6) diff --git a/875. Koko Eating Bananas.py b/875. Koko Eating Bananas.py new file mode 100644 index 0000000..f96a458 --- /dev/null +++ b/875. Koko Eating Bananas.py @@ -0,0 +1,36 @@ +from typing import List +import math + + +def minEatingSpeed(piles: List[int], h: int) -> int: + def findTimeNeeded(piles: List[int], speed: int) -> int: + if speed == 0: + return math.inf + ret = 0 + for pile in piles: + ret += math.ceil(pile / speed) + return ret + + l, r = 1, max(piles) # speed in banana per hour + while l < r: # find the minimum such that time needed < h + m = l + (r - l) // 2 + time = findTimeNeeded(piles, m) # searching the lower upper bound + if time <= h: + r = m + else: + l = m + 1 + print(l) + return l + # m = l + (r - l) // 2 + # time = findTimeNeeded(piles, m) # searching the lower upper bound + # if time <= h: + # r = m + # else: + # l = m + 1 + + # return False + + +minEatingSpeed([1, 1, 1, 999999999], 10) # 142857143 +minEatingSpeed([30, 11, 23, 4, 20], 5) # 30 +minEatingSpeed([312884470], 312884469) # 2 From 7de27d5749cffda87349ce65a1fde58594036341 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Wed, 16 Nov 2022 02:39:59 -0800 Subject: [PATCH 10/20] dive deep into the dfs two price passing methods. add graph visual. --- 787.CheapestFlightsWithinKStops.py | 132 +++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 787.CheapestFlightsWithinKStops.py diff --git a/787.CheapestFlightsWithinKStops.py b/787.CheapestFlightsWithinKStops.py new file mode 100644 index 0000000..45024a4 --- /dev/null +++ b/787.CheapestFlightsWithinKStops.py @@ -0,0 +1,132 @@ +import math +from typing import List + + +#failed +class Solution: + def findCheapestPrice(self, n: int, flights: List[List[int]], src: int, dst: int, k: int) -> int: + # dfs with early stop (k) + # build graph + adj = {i: [] for i in range(n)} + for from_i, to_i, price_i in flights: + adj[from_i].append((to_i, price_i)) + + ret = math.inf + cache = {} + path = [] + + def dfs(node, priceSoFar, stepSoFar, pathSoFar): + nonlocal path + if node == dst and stepSoFar <= k: + path.append((priceSoFar, pathSoFar)) + return priceSoFar + if stepSoFar > k: + return math.inf + if (node, stepSoFar) in cache: + # print(node, stepSoFar, cache[(node, stepSoFar)]) + return cache[(node, stepSoFar)] + + ans = math.inf + for to_i, price_i in adj[node]: + ans = min(ans, dfs(to_i, priceSoFar+price_i, stepSoFar+1, pathSoFar + "-" + str(to_i))) + cache[(node, stepSoFar)] = ans + # print(path) + return ans + + ret = dfs(src, 0, -1, str(src)) + print(path) + return ret if ret != math.inf else -1 + + + + +print("solution1") +testFLights = [[10, 14, 43], [1, 12, 62], [4, 2, 62], [14, 10, 49], [9, 5, 29], [13, 7, 53], [4, 12, 90], [14, 9, 38], [11, 2, 64], [2, 13, 92], [11, 5, 42], [10, 1, 89], [14, 0, 32], [9, 4, 81], [3, 6, 97], [7, 13, 35], [11, 9, 63], [5, 7, 82], [13, 6, 57], [4, 5, 100], [2, 9, 34], [11, 13, 1], [14, 8, 1], [12, 10, 42], [2, 4, 41], [0, 6, 55], [ + 5, 12, 1], [13, 3, 67], [3, 13, 36], [3, 12, 73], [7, 5, 72], [5, 6, 100], [7, 6, 52], [4, 7, 43], [6, 3, 67], [3, 1, 66], [8, 12, 30], [8, 3, 42], [9, 3, 57], [12, 6, 31], [2, 7, 10], [14, 4, 91], [2, 3, 29], [8, 9, 29], [2, 11, 65], [3, 8, 49], [6, 14, 22], [4, 6, 38], [13, 0, 78], [1, 10, 97], [8, 14, 40], [7, 9, 3], [14, 6, 4], [4, 8, 75], [1, 6, 56]] +Solution().findCheapestPrice(n=15, flights=testFLights, src=1, dst=4, k=10) # expected: 169 + + +#case 1 +# testFLights = [[0,1,100],[1,2,100],[2,0,100],[1,3,600],[2,3,200]] +# Solution().findCheapestPrice(n=4, flights=testFLights, src=0, dst=3, k=1) # expected: 700 +# print() +# Solution().findCheapestPrice(n=4, flights=testFLights, src=0, dst=3, k=2) # expected: 400 + +# passed +class Solution: + def findCheapestPrice(self, n: int, flights: List[List[int]], src: int, dst: int, k: int) -> int: + # dfs with early stop (k) + # build graph + adj = {i: [] for i in range(n)} + for from_i, to_i, price_i in flights: + adj[from_i].append((to_i, price_i)) + + ret = math.inf + cache = {} + path = [] + def dfs(node, priceSoFar, stepSoFar, pathSoFar): + nonlocal path + if node == dst and stepSoFar <= k: + path.append((priceSoFar, pathSoFar)) + return 0 + if stepSoFar > k: + return math.inf + if (node, stepSoFar) in cache: + # print(node, stepSoFar, cache[(node, stepSoFar)]) + return cache[(node, stepSoFar)][0] + + ans = math.inf + for to_i, price_i in adj[node]: + # ans = min(ans, dfs(to_i, priceSoFar+price_i, stepSoFar+1)) + ans = dfs(to_i, priceSoFar+ price_i, stepSoFar+1, pathSoFar + "-" + str(to_i)) + price_i + + cache[(node, stepSoFar)] = [ans, pathSoFar+"-"+str(to_i)] + # print(cache) + # print(path) + return ans + + ret = dfs(src, 0, -1, str(src)) + print(path) + return ret if ret != math.inf else -1 + +print("solution2") +testFLights = [[10, 14, 43], [1, 12, 62], [4, 2, 62], [14, 10, 49], [9, 5, 29], [13, 7, 53], [4, 12, 90], [14, 9, 38], [11, 2, 64], [2, 13, 92], [11, 5, 42], [10, 1, 89], [14, 0, 32], [9, 4, 81], [3, 6, 97], [7, 13, 35], [11, 9, 63], [5, 7, 82], [13, 6, 57], [4, 5, 100], [2, 9, 34], [11, 13, 1], [14, 8, 1], [12, 10, 42], [2, 4, 41], [0, 6, 55], [ + 5, 12, 1], [13, 3, 67], [3, 13, 36], [3, 12, 73], [7, 5, 72], [5, 6, 100], [7, 6, 52], [4, 7, 43], [6, 3, 67], [3, 1, 66], [8, 12, 30], [8, 3, 42], [9, 3, 57], [12, 6, 31], [2, 7, 10], [14, 4, 91], [2, 3, 29], [8, 9, 29], [2, 11, 65], [3, 8, 49], [6, 14, 22], [4, 6, 38], [13, 0, 78], [1, 10, 97], [8, 14, 40], [7, 9, 3], [14, 6, 4], [4, 8, 75], [1, 6, 56]] +Solution().findCheapestPrice(n=15, flights=testFLights, src=1, dst=4, k=10) # expected: 169 + +print() + +# visualization +import matplotlib.pyplot as plt +import networkx as nx + +G = nx.Graph() + +for source, destination, weight in testFLights: + G.add_edge(str(source), str(destination), weight) + +elarge = [(u, v) for (u, v, d) in G.edges(data=True) if d["weight"] > 0.5] +esmall = [(u, v) for (u, v, d) in G.edges(data=True) if d["weight"] <= 0.5] + +pos = nx.spring_layout(G, seed=7) # positions for all nodes - seed for reproducibility + +# nodes +nx.draw_networkx_nodes(G, pos, node_size=700) + +# edges +nx.draw_networkx_edges(G, pos, edgelist=elarge, width=6) +nx.draw_networkx_edges( + G, pos, edgelist=esmall, width=6, alpha=0.5, edge_color="b", style="dashed" +) + +# node labels +nx.draw_networkx_labels(G, pos, font_size=20, font_family="sans-serif") +# edge weight labels +edge_labels = nx.get_edge_attributes(G, "weight") +nx.draw_networkx_edge_labels(G, pos, edge_labels) + +ax = plt.gca() +ax.margins(0.08) +plt.axis("off") +plt.tight_layout() +plt.show() \ No newline at end of file From 5253de7c48f0f3372ef892c0486c61af833737c2 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Wed, 16 Nov 2022 02:45:39 -0800 Subject: [PATCH 11/20] eh... its only weighted but missing direction. --- 787.CheapestFlightsWithinKStops.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/787.CheapestFlightsWithinKStops.py b/787.CheapestFlightsWithinKStops.py index 45024a4..b780774 100644 --- a/787.CheapestFlightsWithinKStops.py +++ b/787.CheapestFlightsWithinKStops.py @@ -78,7 +78,7 @@ def dfs(node, priceSoFar, stepSoFar, pathSoFar): ans = math.inf for to_i, price_i in adj[node]: # ans = min(ans, dfs(to_i, priceSoFar+price_i, stepSoFar+1)) - ans = dfs(to_i, priceSoFar+ price_i, stepSoFar+1, pathSoFar + "-" + str(to_i)) + price_i + ans = dfs(to_i, priceSoFar, stepSoFar+1, pathSoFar + "-" + str(to_i)) + price_i cache[(node, stepSoFar)] = [ans, pathSoFar+"-"+str(to_i)] # print(cache) @@ -103,20 +103,20 @@ def dfs(node, priceSoFar, stepSoFar, pathSoFar): G = nx.Graph() for source, destination, weight in testFLights: - G.add_edge(str(source), str(destination), weight) + G.add_edge(str(source), str(destination), weight=weight) elarge = [(u, v) for (u, v, d) in G.edges(data=True) if d["weight"] > 0.5] esmall = [(u, v) for (u, v, d) in G.edges(data=True) if d["weight"] <= 0.5] -pos = nx.spring_layout(G, seed=7) # positions for all nodes - seed for reproducibility +pos = nx.spring_layout(G, seed=1) # positions for all nodes - seed for reproducibility # nodes nx.draw_networkx_nodes(G, pos, node_size=700) # edges -nx.draw_networkx_edges(G, pos, edgelist=elarge, width=6) +nx.draw_networkx_edges(G, pos, edgelist=elarge, width=4) nx.draw_networkx_edges( - G, pos, edgelist=esmall, width=6, alpha=0.5, edge_color="b", style="dashed" + G, pos, edgelist=esmall, width=4, alpha=0.5, edge_color="b", style="dashed" ) # node labels From 251dc5bae2470ad1761832ec3aea2755bc7cfdbd Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Wed, 16 Nov 2022 02:57:32 -0800 Subject: [PATCH 12/20] hmmm get directed graph working, due to the node density, not very useful. --- 787.CheapestFlightsWithinKStops.py | 22 ++++++++++--- plot_directed.py | 53 ++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 plot_directed.py diff --git a/787.CheapestFlightsWithinKStops.py b/787.CheapestFlightsWithinKStops.py index b780774..673736a 100644 --- a/787.CheapestFlightsWithinKStops.py +++ b/787.CheapestFlightsWithinKStops.py @@ -100,7 +100,7 @@ def dfs(node, priceSoFar, stepSoFar, pathSoFar): import matplotlib.pyplot as plt import networkx as nx -G = nx.Graph() +G = nx.DiGraph() for source, destination, weight in testFLights: G.add_edge(str(source), str(destination), weight=weight) @@ -114,10 +114,22 @@ def dfs(node, priceSoFar, stepSoFar, pathSoFar): nx.draw_networkx_nodes(G, pos, node_size=700) # edges -nx.draw_networkx_edges(G, pos, edgelist=elarge, width=4) -nx.draw_networkx_edges( - G, pos, edgelist=esmall, width=4, alpha=0.5, edge_color="b", style="dashed" -) +# nx.draw_networkx_edges(G, pos, edgelist=elarge, width=4, arrowstyle="->", arrowsize=10) +nx.draw_networkx_edges(G, pos, node_size=300, width=4, arrowstyle="->", arrowsize=10) +# nx.draw_networkx_edges( +# G, pos, edgelist=esmall, width=4, alpha=0.5, edge_color="b", style="dashed" +# ) +# edges = nx.draw_networkx_edges( +# G, +# pos, +# node_size=node_sizes, +# arrowstyle="->", +# arrowsize=10, +# edge_color=edge_colors, +# edge_cmap=cmap, +# width=2, +# ) + # node labels nx.draw_networkx_labels(G, pos, font_size=20, font_family="sans-serif") diff --git a/plot_directed.py b/plot_directed.py new file mode 100644 index 0000000..d664430 --- /dev/null +++ b/plot_directed.py @@ -0,0 +1,53 @@ +""" +============== +Directed Graph +============== + +Draw a graph with directed edges using a colormap and different node sizes. + +Edges have different colors and alphas (opacity). Drawn using matplotlib. +""" + +import matplotlib as mpl +import matplotlib.pyplot as plt +import networkx as nx + +testFLights = [[10, 14, 43], [1, 12, 62], [4, 2, 62], [14, 10, 49], [9, 5, 29], [13, 7, 53], [4, 12, 90], [14, 9, 38], [11, 2, 64], [2, 13, 92], [11, 5, 42], [10, 1, 89], [14, 0, 32], [9, 4, 81], [3, 6, 97], [7, 13, 35], [11, 9, 63], [5, 7, 82], [13, 6, 57], [4, 5, 100], [2, 9, 34], [11, 13, 1], [14, 8, 1], [12, 10, 42], [2, 4, 41], [0, 6, 55], [ + 5, 12, 1], [13, 3, 67], [3, 13, 36], [3, 12, 73], [7, 5, 72], [5, 6, 100], [7, 6, 52], [4, 7, 43], [6, 3, 67], [3, 1, 66], [8, 12, 30], [8, 3, 42], [9, 3, 57], [12, 6, 31], [2, 7, 10], [14, 4, 91], [2, 3, 29], [8, 9, 29], [2, 11, 65], [3, 8, 49], [6, 14, 22], [4, 6, 38], [13, 0, 78], [1, 10, 97], [8, 14, 40], [7, 9, 3], [14, 6, 4], [4, 8, 75], [1, 6, 56]] + +seed = 13648 # Seed random number generators for reproducibility +# G = nx.random_k_out_graph(10, 3, 0.5, seed=seed) +G = nx.DiGraph() +for source, destination, weight in testFLights: + G.add_edge(str(source), str(destination), weight=weight) + +pos = nx.spring_layout(G, seed=seed) + +node_sizes = [3 + 10 * i for i in range(len(G))] +M = G.number_of_edges() +edge_colors = range(2, M + 2) +edge_alphas = [(5 + i) / (M + 4) for i in range(M)] +cmap = plt.cm.plasma + +nodes = nx.draw_networkx_nodes(G, pos, node_size=node_sizes, node_color="indigo") +edges = nx.draw_networkx_edges( + G, + pos, + node_size=node_sizes, + arrowstyle="->", + arrowsize=10, + edge_color=edge_colors, + edge_cmap=cmap, + width=2, +) +# set alpha value for each edge +# for i in range(M): +# edges[i].set_alpha(edge_alphas[i]) + +# pc = mpl.collections.PatchCollection(edges, cmap=cmap) +# pc.set_array(edge_colors) + +ax = plt.gca() +ax.set_axis_off() +# plt.colorbar(pc, ax=ax) +plt.show() From 269b57e40a6d62b1d3aff71c09c114278b110b5b Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Tue, 29 Nov 2022 22:00:59 -0800 Subject: [PATCH 13/20] use hashmap to remember previous presum for quick look up --- 2488. Count Subarrays With Median K.py | 42 ++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 2488. Count Subarrays With Median K.py diff --git a/2488. Count Subarrays With Median K.py b/2488. Count Subarrays With Median K.py new file mode 100644 index 0000000..586bf4e --- /dev/null +++ b/2488. Count Subarrays With Median K.py @@ -0,0 +1,42 @@ +from typing import List +import collections + + +def countSubarrays(nums: List[int], k: int) -> int: + n = len(nums) + + for i in range(n): + if nums[i] > k: + nums[i] = 1 + elif nums[i] == k: + nums[i] = 0 + else: + nums[i] = -1 + + ret = 0 + presum_even = collections.defaultdict(int) + presum_odd = collections.defaultdict(int) + + presum_even[0] = 1 + s = 0 # s是前缀和 + for i in range(n): + s += nums[i] + if i % 2 == 0: + ret += presum_even[ + s - 0 + ] # 寻找之前所有 长度为偶数 并且前缀和是s的项目,找到的话 nums[that+1:i]的和就是0! + ret += presum_odd[s - 1] + presum_odd[s] += 1 + else: + ret += presum_even[s - 1] + ret += presum_odd[s - 0] + presum_even[s] += 1 + return ret + + +k = 4 +case1 = [3, 2, 1, 4, 5] +case2 = [2, 3, 1, 2, 3, 1, 5, 2, 4, 4, 10, 2, 3, 1, 11, 22, 1, 9] + +countSubarrays(case1, k) + From 7db569ac8d155db7e337946b8deed85b7d8857bc Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Fri, 2 Dec 2022 11:44:50 -0800 Subject: [PATCH 14/20] update 2488 with more test case. --- 2488. Count Subarrays With Median K.py | 66 +++++++++++++++++++------- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/2488. Count Subarrays With Median K.py b/2488. Count Subarrays With Median K.py index 586bf4e..d72b08f 100644 --- a/2488. Count Subarrays With Median K.py +++ b/2488. Count Subarrays With Median K.py @@ -4,39 +4,69 @@ def countSubarrays(nums: List[int], k: int) -> int: n = len(nums) - for i in range(n): - if nums[i] > k: - nums[i] = 1 + if nums[i] < k: + nums[i] = -1 elif nums[i] == k: nums[i] = 0 else: - nums[i] = -1 + nums[i] = 1 ret = 0 - presum_even = collections.defaultdict(int) presum_odd = collections.defaultdict(int) + presum_even = collections.defaultdict(int) + # presum_even[0] = 1 + presum_odd[0] = 1 - presum_even[0] = 1 - s = 0 # s是前缀和 + curPresum = 0 for i in range(n): - s += nums[i] - if i % 2 == 0: - ret += presum_even[ - s - 0 - ] # 寻找之前所有 长度为偶数 并且前缀和是s的项目,找到的话 nums[that+1:i]的和就是0! - ret += presum_odd[s - 1] - presum_odd[s] += 1 + curPresum += nums[i] + if i % 2 == 0: # nums[0:i] is even length + ret += presum_odd[curPresum - 0] + ret += presum_even[curPresum - 1] + presum_even[curPresum] += 1 else: - ret += presum_even[s - 1] - ret += presum_odd[s - 0] - presum_even[s] += 1 + ret += presum_odd[curPresum - 1] + ret += presum_even[curPresum - 0] + presum_odd[curPresum] += 1 return ret + # n = len(nums) + + # for i in range(n): + # if nums[i] > k: + # nums[i] = 1 + # elif nums[i] == k: + # nums[i] = 0 + # else: + # nums[i] = -1 + + # ret = 0 + # presum_even = collections.defaultdict(int) + # presum_odd = collections.defaultdict(int) + + # presum_even[0] = 1 + # s = 0 # s是前缀和 + # for i in range(n): + # s += nums[i] + # if i % 2 == 0: + # ret += presum_even[ + # s - 0 + # ] # 寻找之前所有 长度为偶数 并且前缀和是s的项目,找到的话 nums[that+1:i]的和就是0! + # ret += presum_odd[s - 1] + # presum_odd[s] += 1 + # else: + # ret += presum_even[s - 1] + # ret += presum_odd[s - 0] + # presum_even[s] += 1 + # return ret k = 4 case1 = [3, 2, 1, 4, 5] case2 = [2, 3, 1, 2, 3, 1, 5, 2, 4, 4, 10, 2, 3, 1, 11, 22, 1, 9] +case3 = [2, 5, 1, 4, 3, 6] +case4 = [4, 1, 3, 2] -countSubarrays(case1, k) +# countSubarrays(case1, k) +countSubarrays(case4, 1) From 4882a5df6dd2fd1ef2aabf32b1d41a095d049534 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Fri, 2 Dec 2022 11:56:59 -0800 Subject: [PATCH 15/20] add word break, interesting recursion to dp improvement. --- 139.WordBreak.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 139.WordBreak.py diff --git a/139.WordBreak.py b/139.WordBreak.py new file mode 100644 index 0000000..df4aadc --- /dev/null +++ b/139.WordBreak.py @@ -0,0 +1,26 @@ +from typing import List + + +class Solution: + def wordBreak(self, s: str, wordDict: List[str]) -> bool: + if len(s) == 0: + return True + + for i in range(len(s) + 1): + if s[:i] in wordDict and self.wordBreak(s[i:], wordDict): + return True + return False + + def wordBreakDp(self, s: str, wordDict: List[str]) -> bool: + n = len(s) + dp = [False for _ in range(n + 1)] + dp[n] = True + + for i in range(n - 1, -1, -1): + for word in wordDict: + if s[i : i + len(word)] == word: + dp[i] = dp[i + len(word)] + return dp[0] + + +Solution().wordBreak("leetcode", ["leet", "code"]) From 44f8615d8cf79f70569f91ee394a0b23b7fb7f62 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Sat, 3 Dec 2022 04:35:46 -0800 Subject: [PATCH 16/20] clean up unneeded notebook. --- Untitled.ipynb | 52 --------- Untitled1.ipynb | 125 --------------------- Untitled2.ipynb | 290 ------------------------------------------------ 3 files changed, 467 deletions(-) delete mode 100644 Untitled.ipynb delete mode 100644 Untitled1.ipynb delete mode 100644 Untitled2.ipynb diff --git a/Untitled.ipynb b/Untitled.ipynb deleted file mode 100644 index 6d8f65f..0000000 --- a/Untitled.ipynb +++ /dev/null @@ -1,52 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[0, 1]\n", - "[2, 3, 4, 5, 6]\n" - ] - } - ], - "source": [ - "a = [0,1,2,3,4,5,6]\n", - "print(a[:2])\n", - "print(a[2:])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.7" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/Untitled1.ipynb b/Untitled1.ipynb deleted file mode 100644 index d2b1d9f..0000000 --- a/Untitled1.ipynb +++ /dev/null @@ -1,125 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "class Trie(object): \n", - "\n", - " class node(object):\n", - " def __init__(self, val=None):\n", - " self.val = val\n", - " self.kids = []\n", - " \n", - " def __init__(self):\n", - " \"\"\"\n", - " Initialize your data structure here.\n", - " \"\"\"\n", - " self.root = Trie.node()\n", - " \n", - "\n", - " def insert(self, word):\n", - " \"\"\"\n", - " Inserts a word into the trie.\n", - " :type word: str\n", - " :rtype: None\n", - " \"\"\"\n", - " cur = self.root\n", - " for index, letter in enumerate(word):\n", - " tmp = Trie.node(letter)\n", - " cur.kids.append(tmp)\n", - " cur = tmp\n", - " cur.kids.append(\"end\")\n", - "\n", - " def search(self, word):\n", - " \"\"\"\n", - " Returns if the word is in the trie.\n", - " :type word: str\n", - " :rtype: bool\n", - " \"\"\"\n", - " cur = self.root\n", - " for letter in word:\n", - " print(letter)\n", - " for kid in cur.kids:\n", - " if kid.val == letter:\n", - " cur = kid\n", - " print(\"found, continue\")\n", - " break\n", - " print(\"did find, return False\")\n", - " return False\n", - " print(\"end step, check cur.kids is None: {}\".format(cur.kids))\n", - " print(\"\")\n", - " return \"end\" in cur.kids\n", - " \n", - "\n", - "\n", - " def startsWith(self, prefix):\n", - " \"\"\"\n", - " Returns if there is any word in the trie that starts with the given prefix.\n", - " :type prefix: str\n", - " :rtype: bool\n", - " \"\"\"\n", - " cur = self.root\n", - " for letter in prefix:\n", - " for kid in cur.kids:\n", - " if kid.val == letter:\n", - " cur = kid\n", - " break\n", - " return False\n", - " return True\n", - " \n", - "\n", - "\n", - "# Your Trie object will be instantiated and called as such:\n", - "# obj = Trie()\n", - "# obj.insert(word)\n", - "# param_2 = obj.search(word)\n", - "# param_3 = obj.startsWith(prefix)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/Untitled2.ipynb b/Untitled2.ipynb deleted file mode 100644 index 672b8fb..0000000 --- a/Untitled2.ipynb +++ /dev/null @@ -1,290 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# 23280666731155" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import string" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'!\"#$%&\\'()*+,-./:;<=>?@[\\\\]^_`{|}~'" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "string.punctuation" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = {\"a\":2}" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "from collections import defaultdict" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "tmp = defaultdict(lambda: 0)" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "0" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "tmp['a']" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'dsa we2'" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "\"Dsa we2\".lower()" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['ds fff', 'as eaaa bbbb', 'hum cccc dddd']" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "word_log = [\"ds fff\",\"as eaaa bbbb\", \"hum cccc dddd\"]\n", - "word_log.sort(key=lambda x: x[1])\n", - "word_log" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['Formatter',\n", - " 'Template',\n", - " '_ChainMap',\n", - " '_TemplateMetaclass',\n", - " '__all__',\n", - " '__builtins__',\n", - " '__cached__',\n", - " '__doc__',\n", - " '__file__',\n", - " '__loader__',\n", - " '__name__',\n", - " '__package__',\n", - " '__spec__',\n", - " '_re',\n", - " '_string',\n", - " 'ascii_letters',\n", - " 'ascii_lowercase',\n", - " 'ascii_uppercase',\n", - " 'capwords',\n", - " 'digits',\n", - " 'hexdigits',\n", - " 'octdigits',\n", - " 'printable',\n", - " 'punctuation',\n", - " 'whitespace']" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "dir(string)" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "string.ascii_letters" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "ename": "SyntaxError", - "evalue": "invalid syntax (, line 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m assert isinstance([\"\"], list):\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" - ] - } - ], - "source": [ - "assert isinstance([\"\"], list)\n", - " raise(\"lalala\")" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [], - "source": [ - "import warnings" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/toby/anaconda3/envs/py36/lib/python3.6/site-packages/ipykernel_launcher.py:1: UserWarning: lalal\n", - " \"\"\"Entry point for launching an IPython kernel.\n" - ] - } - ], - "source": [ - "warnings.warn(\"lalal\")" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "ename": "AssertionError", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32massert\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mAssertionError\u001b[0m: " - ] - } - ], - "source": [ - "assert False" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.8" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} From f31235ae2ec377a2442f84412823b93b475dfac2 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Tue, 6 Dec 2022 00:01:36 -0800 Subject: [PATCH 17/20] add list investigation of 416. wrong without index, mle with index. shall use set. --- 416. Partition Equal Subset Sum.py | 44 ++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 416. Partition Equal Subset Sum.py diff --git a/416. Partition Equal Subset Sum.py b/416. Partition Equal Subset Sum.py new file mode 100644 index 0000000..cbe18c5 --- /dev/null +++ b/416. Partition Equal Subset Sum.py @@ -0,0 +1,44 @@ +from typing import List + + +class Solution: + def canPartition(self, nums: List[int]) -> bool: + if sum(nums) % 2 == 1: + return False + + target = sum(nums) // 2 + ## Let's look into way we can not use list and need set + ## It turns out that: + ## using for seenValue in dp will result an unexpected extended for loop + ## such that each iteration we add a new value to it and it keeps running. + ## What's more, using list instead of set will lead to a memory limit exceed + ## on leetcode + # dp = [0] + # for i, num in enumerate(nums): + # # for seenValue in dp: + # for j in range(len(dp)): + # seenValue = dp[j] + # if seenValue + num == target: + # return True + # dp.append(seenValue + num) + # return False + + # Correct way: using set + dp = set() + dp.add(0) + # for i in range(len(nums)): + for num in nums: + nextDP = set() + for seenValue in dp: + if seenValue + num == target: + return True + nextDP.add(seenValue + num) + nextDP.add(seenValue) + dp = nextDP + return False + + +case1 = [3, 3, 3, 4, 5] # true +case2 = [1, 2, 5] # false +result = Solution().canPartition(case2) +print(result) From 95545fe4b9b5dcd46348bc67061147993d4ddc74 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Sat, 17 Dec 2022 17:48:04 -0800 Subject: [PATCH 18/20] add 3 sum --- 15.3Sum.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 15.3Sum.py diff --git a/15.3Sum.py b/15.3Sum.py new file mode 100644 index 0000000..19f6ffd --- /dev/null +++ b/15.3Sum.py @@ -0,0 +1,35 @@ +class Solution: + def threeSum(self, nums: List[int]) -> List[List[int]]: + sortedNums = sorted(nums) + i = 0 + res = [] + + while i < len(sortedNums): + if i > 0 and sortedNums[i] == sortedNums[i - 1]: + i += 1 + continue + qualifiedPairs = self.twoSum(sortedNums[i + 1 :], sortedNums[i]) + if qualifiedPairs: + print(qualifiedPairs) + res.extend(qualifiedPairs) + i += 1 + + return res + + def twoSum(self, sortedNums, target): + l, r = 0, len(sortedNums) - 1 + res = [] + while l < r: + numL = sortedNums[l] + numR = sortedNums[r] + if numL + numR == -target: + toAdd = [numL, numR, target] + if toAdd not in res: + res.append(toAdd) + l += 1 + # r -= 1 + if numL + numR < target: + l += 1 + if numL + numR > target: + r -= 1 + return res From 56633b821202c85c2317beb0f69e0784fa053c09 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Sat, 17 Dec 2022 17:48:56 -0800 Subject: [PATCH 19/20] fix wrong boundary condition. --- 15.3Sum.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/15.3Sum.py b/15.3Sum.py index 19f6ffd..caa45cf 100644 --- a/15.3Sum.py +++ b/15.3Sum.py @@ -22,14 +22,14 @@ def twoSum(self, sortedNums, target): while l < r: numL = sortedNums[l] numR = sortedNums[r] - if numL + numR == -target: + if numL + numR + target == 0: toAdd = [numL, numR, target] if toAdd not in res: res.append(toAdd) l += 1 # r -= 1 - if numL + numR < target: + if numL + numR + target < 0: l += 1 - if numL + numR > target: + if numL + numR + target > 0: r -= 1 return res From ea6e8e4ffc13465539ad5388b74ad514aa535cf6 Mon Sep 17 00:00:00 2001 From: tobyatgithub Date: Tue, 20 Dec 2022 10:24:43 -0800 Subject: [PATCH 20/20] 12-20 update. --- 6265. Count Pairs Of Similar Strings.py | 372 ++++++++++++++++++ ...\225\350\260\203\346\240\210-monoStack.py" | 31 ++ 2 files changed, 403 insertions(+) create mode 100644 6265. Count Pairs Of Similar Strings.py create mode 100644 "\350\203\214\346\235\277-\345\215\225\350\260\203\346\240\210-monoStack.py" diff --git a/6265. Count Pairs Of Similar Strings.py b/6265. Count Pairs Of Similar Strings.py new file mode 100644 index 0000000..3587eae --- /dev/null +++ b/6265. Count Pairs Of Similar Strings.py @@ -0,0 +1,372 @@ +import math +from typing import List +from collections import defaultdict + + +# class Solution: +# def similarPairs(self, words: List[str]) -> int: +# # def getUniqueStr(string): +# # unique_str = "" +# # for char in sorted(string): + +# # store = defaultdict(list) +# store = {} + +# for word in words: +# unique_str = "".join(set(sorted(word))) +# if unique_str not in store: +# store[unique_str] = [] +# store[unique_str].append(word) + +# print(len(store)) +# res = 0 +# for value in store.values(): +# res += math.comb(len(value), 2) + +# print(res) +# return res + + +# case1 = [ +# "ofwqemdbhrcckcnqvovyjwnbqxckhfohlripwumugcirazdtwo", +# "hsrmuokwhksqkkjblkomibcifqilkwobwcpwwkjlzohffsajrt", +# "uzvsxxbdwfohaujijxmeijbwyydgjiifcqvxfzmkqgwnkpxlpp", +# "ksdoiwhffhymsxebloadgyigkveizbahnbmvmxsuuxaaegxmpe", +# "fcsjnezuizcnfsuaxpmxpdivamaijvvyyqlsjsqlkifahjuanb", +# "odfwurhxumkpwndsppoflaualeghyscdqqwpntxokxviqmjhyq", +# "jbahicbweamnlfbljwyloparlmgqlwiootzoeqovytpapzjezn", +# "vsjxngyknxpkjfexdvmoikjaiccplcwtxcfrljqavatpcoeaqe", +# "lxiztvpppvsjmnnuunvdxalvzuvxlxbdnipexklmgsssyzlesb", +# "kbmiambdsahiptndziqysctinvdekysrsslssusqwhshpwehco", +# "wuwkvgrrshrmbtpyozgzzwiyflpiuklsepljvthmxnppaspuqt", +# "lkajvmdzpsxoaqzrgrhuhhmwlgwfnruxsrjolnielwcyjvvhaa", +# "imvgnslsxyqfshgmgecdrignarewusftipgjpteocnlqsfkdcy", +# ] + +# case2 = [ +# "abcdefghijklmnopqrtuvwxyz", +# "abcdefghijklmnopqsuvwxyz", +# "abcdefhijklmnpqsuvxyz", +# "abcdehiklmnopqrstuvwyz", +# "abcefghijlmnopqrtvwyz", +# "abcfhijklmopqrstuwz", +# "abdefghiklmnopsuvwxyz", +# "abdegijklmnpstuvxyz", +# "abefghijklmnopqrstuvwxyz", +# "acdefghijklmnopqrstuvwxy", +# "acdefghijklmnopqrstuvwxy", +# "acdefghijklmnopqrsuvwxyz", +# "acdefgijklmnopqrstvwxy", +# ] +# Solution().similarPairs(case1) + +## P2 +# def largest_prime_factor(n): +# i = 2 +# while i * i <= n: +# if n % i: +# i += 1 +# else: +# n //= i +# return n + + +# def primeConvert(value): +# if value <= 4: +# return value + +# # check is prime +# if largest_prime_factor(value) == value: +# return value + +# primeDivident = largest_prime_factor(value) +# res = primeDivident +# reminder = value // primeDivident +# while largest_prime_factor(reminder) != reminder: +# primeDivident = largest_prime_factor(reminder) +# reminder = reminder // primeDivident +# res += primeDivident +# res += reminder +# print(res) +# return res + + +# primeConvert(12) + +## P3 +# edges = [[1, 2], [2, 3], [3, 4], [4, 2], [1, 4], [2, 5]] +# edges = [[1, 2], [3, 4]] +# edges = [[1, 2], [1, 3], [1, 4]] + + +def isPossible(n: int, edges: List[List[int]]) -> bool: + graph = defaultdict(list) + for a, b in edges: + graph[a].append(b) + graph[b].append(a) + + oddNodes = [] + for node in graph: + if len(graph[node]) % 2 == 1: + oddNodes.append(node) + + if len(oddNodes) == 0: + return True + + if len(oddNodes) > 4 or len(oddNodes) == 1: + return False + + if len(oddNodes) == 2: + # direct connect + if oddNodes[0] not in graph[oddNodes[1]]: + return True + # or link via the third common non-connected node + one, two = oddNodes + # for i in range(1, n + 1): + # if i != one and i != two: + # if i not in graph[one] and i not in graph[two]: + # return True + ## to speed up + candidate = set([_ for _ in range(1, n + 1)]) + candidate = candidate.difference(set(graph[one]), set(graph[two])) + for i in candidate: + if i not in graph[one] and i not in graph[two]: + return True + return False + + if len(oddNodes) == 3: + # # we will need two addable edges with 3 possibilities: 12, 23, 13 + # one, two, three = oddNodes + # possible_links = ( + # (one not in graph[two]) + # + (two not in graph[three]) + # + (one not in graph[three]) + # ) + # return possible_links >= 2 + return False + + if len(oddNodes) == 4: + one, two, three, four = oddNodes + # we will need two addable edges with 6 possibilities: 12, 23, 13 + return ( + ((one not in graph[two]) and (three not in graph[four])) + or ((one not in graph[three]) and (two not in graph[four])) + or ((one not in graph[four]) and (two not in graph[three])) + ) + + +# 1. +# print(isPossible(4, edges=edges)) + +n = 21 +edges = [ + [2, 19], + [16, 17], + [8, 14], + [2, 16], + [12, 20], + [12, 14], + [16, 18], + [15, 16], + [10, 21], + [3, 5], + [13, 18], + [17, 20], + [14, 17], + [9, 12], + [5, 15], + [5, 6], + [3, 7], + [2, 21], + [10, 13], + [8, 16], + [7, 18], + [4, 6], + [9, 1], + [13, 21], + [18, 20], + [7, 14], + [4, 19], + [5, 8], + [3, 11], + [11, 1], + [7, 12], + [4, 7], + [3, 16], + [13, 17], + [17, 19], + [9, 13], + [7, 19], + [10, 16], + [4, 13], + [4, 5], + [2, 15], + [12, 19], + [11, 16], + [2, 9], + [11, 17], + [17, 1], + [16, 21], + [4, 10], + [10, 14], + [14, 16], + [4, 1], + [13, 20], + [5, 20], + [4, 14], + [4, 21], + [10, 20], + [2, 14], + [8, 15], + [4, 8], + [6, 19], + [15, 1], + [19, 1], + [8, 19], + [15, 21], + [3, 12], + [11, 18], + [9, 17], + [18, 19], + [7, 21], + [3, 21], + [16, 19], + [11, 15], + [5, 1], + [8, 17], + [3, 15], + [8, 1], + [10, 19], + [3, 8], + [6, 16], + [2, 8], + [5, 18], + [11, 13], + [11, 20], + [14, 21], + [6, 20], + [4, 20], + [12, 13], + [5, 12], + [10, 11], + [9, 15], + [3, 19], + [9, 20], + [14, 18], + [21, 1], + [13, 19], + [8, 21], + [2, 13], + [3, 10], + [9, 18], + [19, 21], + [6, 7], + [3, 18], + [2, 18], + [6, 14], + [3, 17], + [5, 21], + [14, 20], + [8, 9], + [16, 1], + [3, 4], + [13, 1], + [5, 9], + [4, 15], + [17, 21], + [20, 21], + [2, 17], + [13, 14], + [11, 14], + [9, 16], + [10, 18], + [6, 15], + [6, 12], + [3, 13], + [5, 11], + [6, 1], + [12, 17], + [8, 10], + [5, 10], + [8, 18], + [4, 12], + [10, 1], + [6, 13], + [4, 18], + [7, 20], + [7, 16], + [2, 6], + [12, 21], + [4, 17], + [15, 18], + [13, 16], + [15, 20], + [7, 10], + [6, 10], + [2, 20], + [7, 15], + [18, 1], + [12, 1], + [3, 20], + [7, 1], + [14, 15], + [4, 9], + [11, 19], + [7, 9], + [5, 17], + [18, 21], + [6, 21], + [8, 11], + [6, 17], + [3, 14], + [7, 11], + [5, 7], + [7, 13], + [6, 8], + [6, 9], + [10, 12], + [5, 16], + [2, 4], + [17, 18], + [9, 11], + [12, 16], + [3, 6], + [12, 18], + [3, 9], + [11, 12], + [14, 19], + [10, 15], + [5, 13], + [8, 13], + [15, 17], + [2, 10], + [11, 21], + [20, 1], + [6, 18], + [2, 12], + [19, 20], + [6, 11], + [8, 12], + [2, 3], + [12, 15], + [2, 11], + [9, 10], + [7, 17], + [9, 19], + [13, 15], + [7, 8], + [4, 11], + [2, 5], + [5, 19], + [16, 20], + [15, 19], + [9, 14], + [14, 1], + [10, 17], + [9, 21], + [2, 7], + [8, 20], + [5, 14], + [4, 16], +] +print(isPossible(n, edges=edges)) diff --git "a/\350\203\214\346\235\277-\345\215\225\350\260\203\346\240\210-monoStack.py" "b/\350\203\214\346\235\277-\345\215\225\350\260\203\346\240\210-monoStack.py" new file mode 100644 index 0000000..bc5a17b --- /dev/null +++ "b/\350\203\214\346\235\277-\345\215\225\350\260\203\346\240\210-monoStack.py" @@ -0,0 +1,31 @@ +""" +monotonic stack is a super useful tool in many code challenges, +such as 84. Largest Rectangle in Histogram, 1950.Maximum-of-Minimum-Values-in-All-Subarrays, etc. +find more in https://github.com/wisdompeak/LeetCode (and search for monotonic stack key word) + +Here is one basic way of realizing it. +""" +heights = [] # input list + +n = len(heights) + +stack = [] +nextSmaller = [n] * n +for i in range(n): + while stack and height[stack[-1]] > height[i]: + nextSmaller[stack.pop(-1)] = i + stack.append(i) + +stack = [] +prevSmaller = [-1] * n +for i in range(n, -1, -1): + while stack and height[stack[-1]] > height[i]: + prevSmaller[stack.pop(-1)] = i + stack.append(i) + +# for example in the 84. histogram area question +ret = 0 +for i in range(n): + area = heights[i] * (nextSmaller[i] - prevSmaller[i] - 1) + ret = max(ret, area) +return ret