From ef6cff50ccf578af24d55565b631fd99956db3cb Mon Sep 17 00:00:00 2001 From: Rhitik Date: Sat, 14 Oct 2023 21:04:18 +0530 Subject: [PATCH 01/19] Added Solution for 1912. Movie Rental System in python. --- .../1912.Design Movie Rental System/README.md | 26 ++++++++++++++++++ .../README_EN.md | 27 ++++++++++++++++++- .../Solution.py | 26 ++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 solution/1900-1999/1912.Design Movie Rental System/Solution.py diff --git a/solution/1900-1999/1912.Design Movie Rental System/README.md b/solution/1900-1999/1912.Design Movie Rental System/README.md index 0a8c0c09ec8e8..6238f8e94c651 100644 --- a/solution/1900-1999/1912.Design Movie Rental System/README.md +++ b/solution/1900-1999/1912.Design Movie Rental System/README.md @@ -76,6 +76,32 @@ movieRentingSystem.search(2); // 返回 [0, 1] 。商店 0 和 1 有未借出 ```python +from sortedcontainers import SortedList + +class MovieRentingSystem: + def __init__(self, n: int, entries: List[List[int]]): + self.unrented = collections.defaultdict(SortedList) # {movie: (price, shop)} + self.shopAndMovieToPrice = {} # {(shop, movie): price} + self.rented = SortedList() # (price, shop, movie) + for shop, movie, price in entries: + self.unrented[movie].add((price, shop)) + self.shopAndMovieToPrice[(shop, movie)] = price + + def search(self, movie: int) -> List[int]: + return [shop for _, shop in self.unrented[movie][:5]] + + def rent(self, shop: int, movie: int) -> None: + price = self.shopAndMovieToPrice[(shop, movie)] + self.unrented[movie].remove((price, shop)) + self.rented.add((price, shop, movie)) + + def drop(self, shop: int, movie: int) -> None: + price = self.shopAndMovieToPrice[(shop, movie)] + self.unrented[movie].add((price, shop)) + self.rented.remove((price, shop, movie)) + + def report(self) -> List[List[int]]: + return [[shop, movie] for _, shop, movie in self.rented[:5]] ``` diff --git a/solution/1900-1999/1912.Design Movie Rental System/README_EN.md b/solution/1900-1999/1912.Design Movie Rental System/README_EN.md index b5f20dc46734f..18a5f67c40a28 100644 --- a/solution/1900-1999/1912.Design Movie Rental System/README_EN.md +++ b/solution/1900-1999/1912.Design Movie Rental System/README_EN.md @@ -68,7 +68,32 @@ movieRentingSystem.search(2); // return [0, 1]. Movies of ID 2 are unrented at ### **Python3** ```python - +from sortedcontainers import SortedList + +class MovieRentingSystem: + def __init__(self, n: int, entries: List[List[int]]): + self.unrented = collections.defaultdict(SortedList) # {movie: (price, shop)} + self.shopAndMovieToPrice = {} # {(shop, movie): price} + self.rented = SortedList() # (price, shop, movie) + for shop, movie, price in entries: + self.unrented[movie].add((price, shop)) + self.shopAndMovieToPrice[(shop, movie)] = price + + def search(self, movie: int) -> List[int]: + return [shop for _, shop in self.unrented[movie][:5]] + + def rent(self, shop: int, movie: int) -> None: + price = self.shopAndMovieToPrice[(shop, movie)] + self.unrented[movie].remove((price, shop)) + self.rented.add((price, shop, movie)) + + def drop(self, shop: int, movie: int) -> None: + price = self.shopAndMovieToPrice[(shop, movie)] + self.unrented[movie].add((price, shop)) + self.rented.remove((price, shop, movie)) + + def report(self) -> List[List[int]]: + return [[shop, movie] for _, shop, movie in self.rented[:5]] ``` ### **Java** diff --git a/solution/1900-1999/1912.Design Movie Rental System/Solution.py b/solution/1900-1999/1912.Design Movie Rental System/Solution.py new file mode 100644 index 0000000000000..3f0d1211a48b5 --- /dev/null +++ b/solution/1900-1999/1912.Design Movie Rental System/Solution.py @@ -0,0 +1,26 @@ +from sortedcontainers import SortedList + +class MovieRentingSystem: + def __init__(self, n: int, entries: List[List[int]]): + self.unrented = collections.defaultdict(SortedList) # {movie: (price, shop)} + self.shopAndMovieToPrice = {} # {(shop, movie): price} + self.rented = SortedList() # (price, shop, movie) + for shop, movie, price in entries: + self.unrented[movie].add((price, shop)) + self.shopAndMovieToPrice[(shop, movie)] = price + + def search(self, movie: int) -> List[int]: + return [shop for _, shop in self.unrented[movie][:5]] + + def rent(self, shop: int, movie: int) -> None: + price = self.shopAndMovieToPrice[(shop, movie)] + self.unrented[movie].remove((price, shop)) + self.rented.add((price, shop, movie)) + + def drop(self, shop: int, movie: int) -> None: + price = self.shopAndMovieToPrice[(shop, movie)] + self.unrented[movie].add((price, shop)) + self.rented.remove((price, shop, movie)) + + def report(self) -> List[List[int]]: + return [[shop, movie] for _, shop, movie in self.rented[:5]] From ca705c1a5219ad38c6314b32291499de6bd797be Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Sun, 15 Oct 2023 09:18:27 +0800 Subject: [PATCH 02/19] Update README.md --- .../1912.Design Movie Rental System/README.md | 56 +++++++++++-------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/solution/1900-1999/1912.Design Movie Rental System/README.md b/solution/1900-1999/1912.Design Movie Rental System/README.md index 6238f8e94c651..569ffe773e617 100644 --- a/solution/1900-1999/1912.Design Movie Rental System/README.md +++ b/solution/1900-1999/1912.Design Movie Rental System/README.md @@ -78,31 +78,39 @@ movieRentingSystem.search(2); // 返回 [0, 1] 。商店 0 和 1 有未借出 ```python from sortedcontainers import SortedList -class MovieRentingSystem: - def __init__(self, n: int, entries: List[List[int]]): - self.unrented = collections.defaultdict(SortedList) # {movie: (price, shop)} - self.shopAndMovieToPrice = {} # {(shop, movie): price} - self.rented = SortedList() # (price, shop, movie) - for shop, movie, price in entries: - self.unrented[movie].add((price, shop)) - self.shopAndMovieToPrice[(shop, movie)] = price - - def search(self, movie: int) -> List[int]: - return [shop for _, shop in self.unrented[movie][:5]] - - def rent(self, shop: int, movie: int) -> None: - price = self.shopAndMovieToPrice[(shop, movie)] - self.unrented[movie].remove((price, shop)) - self.rented.add((price, shop, movie)) - - def drop(self, shop: int, movie: int) -> None: - price = self.shopAndMovieToPrice[(shop, movie)] - self.unrented[movie].add((price, shop)) - self.rented.remove((price, shop, movie)) - - def report(self) -> List[List[int]]: - return [[shop, movie] for _, shop, movie in self.rented[:5]] +class MovieRentingSystem: + def __init__(self, n: int, entries: List[List[int]]): + self.unrented = collections.defaultdict(SortedList) # {movie: (price, shop)} + self.shopAndMovieToPrice = {} # {(shop, movie): price} + self.rented = SortedList() # (price, shop, movie) + for shop, movie, price in entries: + self.unrented[movie].add((price, shop)) + self.shopAndMovieToPrice[(shop, movie)] = price + + def search(self, movie: int) -> List[int]: + return [shop for _, shop in self.unrented[movie][:5]] + + def rent(self, shop: int, movie: int) -> None: + price = self.shopAndMovieToPrice[(shop, movie)] + self.unrented[movie].remove((price, shop)) + self.rented.add((price, shop, movie)) + + def drop(self, shop: int, movie: int) -> None: + price = self.shopAndMovieToPrice[(shop, movie)] + self.unrented[movie].add((price, shop)) + self.rented.remove((price, shop, movie)) + + def report(self) -> List[List[int]]: + return [[shop, movie] for _, shop, movie in self.rented[:5]] + + +# Your MovieRentingSystem object will be instantiated and called as such: +# obj = MovieRentingSystem(n, entries) +# param_1 = obj.search(movie) +# obj.rent(shop,movie) +# obj.drop(shop,movie) +# param_4 = obj.report() ``` ### **Java** From 727bd2c6d20bb8c8fd7916b0414064eba09aa21f Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Sun, 15 Oct 2023 09:18:46 +0800 Subject: [PATCH 03/19] Update README_EN.md --- .../README_EN.md | 55 +++++++++++-------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/solution/1900-1999/1912.Design Movie Rental System/README_EN.md b/solution/1900-1999/1912.Design Movie Rental System/README_EN.md index 18a5f67c40a28..8276a456cdb36 100644 --- a/solution/1900-1999/1912.Design Movie Rental System/README_EN.md +++ b/solution/1900-1999/1912.Design Movie Rental System/README_EN.md @@ -70,30 +70,39 @@ movieRentingSystem.search(2); // return [0, 1]. Movies of ID 2 are unrented at ```python from sortedcontainers import SortedList + class MovieRentingSystem: - def __init__(self, n: int, entries: List[List[int]]): - self.unrented = collections.defaultdict(SortedList) # {movie: (price, shop)} - self.shopAndMovieToPrice = {} # {(shop, movie): price} - self.rented = SortedList() # (price, shop, movie) - for shop, movie, price in entries: - self.unrented[movie].add((price, shop)) - self.shopAndMovieToPrice[(shop, movie)] = price - - def search(self, movie: int) -> List[int]: - return [shop for _, shop in self.unrented[movie][:5]] - - def rent(self, shop: int, movie: int) -> None: - price = self.shopAndMovieToPrice[(shop, movie)] - self.unrented[movie].remove((price, shop)) - self.rented.add((price, shop, movie)) - - def drop(self, shop: int, movie: int) -> None: - price = self.shopAndMovieToPrice[(shop, movie)] - self.unrented[movie].add((price, shop)) - self.rented.remove((price, shop, movie)) - - def report(self) -> List[List[int]]: - return [[shop, movie] for _, shop, movie in self.rented[:5]] + def __init__(self, n: int, entries: List[List[int]]): + self.unrented = collections.defaultdict(SortedList) # {movie: (price, shop)} + self.shopAndMovieToPrice = {} # {(shop, movie): price} + self.rented = SortedList() # (price, shop, movie) + for shop, movie, price in entries: + self.unrented[movie].add((price, shop)) + self.shopAndMovieToPrice[(shop, movie)] = price + + def search(self, movie: int) -> List[int]: + return [shop for _, shop in self.unrented[movie][:5]] + + def rent(self, shop: int, movie: int) -> None: + price = self.shopAndMovieToPrice[(shop, movie)] + self.unrented[movie].remove((price, shop)) + self.rented.add((price, shop, movie)) + + def drop(self, shop: int, movie: int) -> None: + price = self.shopAndMovieToPrice[(shop, movie)] + self.unrented[movie].add((price, shop)) + self.rented.remove((price, shop, movie)) + + def report(self) -> List[List[int]]: + return [[shop, movie] for _, shop, movie in self.rented[:5]] + + +# Your MovieRentingSystem object will be instantiated and called as such: +# obj = MovieRentingSystem(n, entries) +# param_1 = obj.search(movie) +# obj.rent(shop,movie) +# obj.drop(shop,movie) +# param_4 = obj.report() ``` ### **Java** From d1241abfeaff70a0cc28922eb95bdf96631b241e Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Sun, 15 Oct 2023 09:27:54 +0800 Subject: [PATCH 04/19] Update Solution.py --- .../Solution.py | 55 +++++++++++-------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/solution/1900-1999/1912.Design Movie Rental System/Solution.py b/solution/1900-1999/1912.Design Movie Rental System/Solution.py index 3f0d1211a48b5..3f309835db942 100644 --- a/solution/1900-1999/1912.Design Movie Rental System/Solution.py +++ b/solution/1900-1999/1912.Design Movie Rental System/Solution.py @@ -1,26 +1,35 @@ from sortedcontainers import SortedList + class MovieRentingSystem: - def __init__(self, n: int, entries: List[List[int]]): - self.unrented = collections.defaultdict(SortedList) # {movie: (price, shop)} - self.shopAndMovieToPrice = {} # {(shop, movie): price} - self.rented = SortedList() # (price, shop, movie) - for shop, movie, price in entries: - self.unrented[movie].add((price, shop)) - self.shopAndMovieToPrice[(shop, movie)] = price - - def search(self, movie: int) -> List[int]: - return [shop for _, shop in self.unrented[movie][:5]] - - def rent(self, shop: int, movie: int) -> None: - price = self.shopAndMovieToPrice[(shop, movie)] - self.unrented[movie].remove((price, shop)) - self.rented.add((price, shop, movie)) - - def drop(self, shop: int, movie: int) -> None: - price = self.shopAndMovieToPrice[(shop, movie)] - self.unrented[movie].add((price, shop)) - self.rented.remove((price, shop, movie)) - - def report(self) -> List[List[int]]: - return [[shop, movie] for _, shop, movie in self.rented[:5]] + def __init__(self, n: int, entries: List[List[int]]): + self.unrented = collections.defaultdict(SortedList) # {movie: (price, shop)} + self.shopAndMovieToPrice = {} # {(shop, movie): price} + self.rented = SortedList() # (price, shop, movie) + for shop, movie, price in entries: + self.unrented[movie].add((price, shop)) + self.shopAndMovieToPrice[(shop, movie)] = price + + def search(self, movie: int) -> List[int]: + return [shop for _, shop in self.unrented[movie][:5]] + + def rent(self, shop: int, movie: int) -> None: + price = self.shopAndMovieToPrice[(shop, movie)] + self.unrented[movie].remove((price, shop)) + self.rented.add((price, shop, movie)) + + def drop(self, shop: int, movie: int) -> None: + price = self.shopAndMovieToPrice[(shop, movie)] + self.unrented[movie].add((price, shop)) + self.rented.remove((price, shop, movie)) + + def report(self) -> List[List[int]]: + return [[shop, movie] for _, shop, movie in self.rented[:5]] + + +# Your MovieRentingSystem object will be instantiated and called as such: +# obj = MovieRentingSystem(n, entries) +# param_1 = obj.search(movie) +# obj.rent(shop,movie) +# obj.drop(shop,movie) +# param_4 = obj.report() From a02c4095bda9b8fd96b86b42777a6606dc80fd5c Mon Sep 17 00:00:00 2001 From: Rhitik Date: Mon, 16 Oct 2023 01:07:12 +0530 Subject: [PATCH 05/19] Solution for 1900. Earliest and Latest Rounds Where Players Compete. --- .../README.md | 28 +++++++++++++++++++ .../README_EN.md | 28 +++++++++++++++++++ .../Solution.py | 28 +++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 solution/1900-1999/1900.The Earliest and Latest Rounds Where Players Compete/Solution.py diff --git a/solution/1900-1999/1900.The Earliest and Latest Rounds Where Players Compete/README.md b/solution/1900-1999/1900.The Earliest and Latest Rounds Where Players Compete/README.md index 254647517b86f..50143e1ed8128 100644 --- a/solution/1900-1999/1900.The Earliest and Latest Rounds Where Players Compete/README.md +++ b/solution/1900-1999/1900.The Earliest and Latest Rounds Where Players Compete/README.md @@ -74,6 +74,34 @@ ```python +class Solution: + def earliestAndLatest( + self, n: int, firstPlayer: int, secondPlayer: int + ) -> List[int]: + # dp[i][j][k] := (earliest, latest) pair w/ firstPlayer is i-th player from + # Front, secondPlayer is j-th player from end, and there're k people + @functools.lru_cache(None) + def dp(l: int, r: int, k: int) -> List[int]: + if l == r: + return [1, 1] + if l > r: + return dp(r, l, k) + + a = math.inf + b = -math.inf + + # Enumerate all possible positions + for i in range(1, l + 1): + for j in range(l - i + 1, r - i + 1): + if not l + r - k // 2 <= i + j <= (k + 1) // 2: + continue + x, y = dp(i, j, (k + 1) // 2) + a = min(a, x + 1) + b = max(b, y + 1) + + return [a, b] + + return dp(firstPlayer, n - secondPlayer + 1, n) ``` diff --git a/solution/1900-1999/1900.The Earliest and Latest Rounds Where Players Compete/README_EN.md b/solution/1900-1999/1900.The Earliest and Latest Rounds Where Players Compete/README_EN.md index 44caf76986813..35a38bf73fbfc 100644 --- a/solution/1900-1999/1900.The Earliest and Latest Rounds Where Players Compete/README_EN.md +++ b/solution/1900-1999/1900.The Earliest and Latest Rounds Where Players Compete/README_EN.md @@ -68,6 +68,34 @@ There is no way to make them compete in any other round. ### **Python3** ```python +class Solution: + def earliestAndLatest( + self, n: int, firstPlayer: int, secondPlayer: int + ) -> List[int]: + # dp[i][j][k] := (earliest, latest) pair w/ firstPlayer is i-th player from + # Front, secondPlayer is j-th player from end, and there're k people + @functools.lru_cache(None) + def dp(l: int, r: int, k: int) -> List[int]: + if l == r: + return [1, 1] + if l > r: + return dp(r, l, k) + + a = math.inf + b = -math.inf + + # Enumerate all possible positions + for i in range(1, l + 1): + for j in range(l - i + 1, r - i + 1): + if not l + r - k // 2 <= i + j <= (k + 1) // 2: + continue + x, y = dp(i, j, (k + 1) // 2) + a = min(a, x + 1) + b = max(b, y + 1) + + return [a, b] + + return dp(firstPlayer, n - secondPlayer + 1, n) ``` diff --git a/solution/1900-1999/1900.The Earliest and Latest Rounds Where Players Compete/Solution.py b/solution/1900-1999/1900.The Earliest and Latest Rounds Where Players Compete/Solution.py new file mode 100644 index 0000000000000..f16f724b7a0ab --- /dev/null +++ b/solution/1900-1999/1900.The Earliest and Latest Rounds Where Players Compete/Solution.py @@ -0,0 +1,28 @@ +class Solution: + def earliestAndLatest( + self, n: int, firstPlayer: int, secondPlayer: int + ) -> List[int]: + # dp[i][j][k] := (earliest, latest) pair w/ firstPlayer is i-th player from + # Front, secondPlayer is j-th player from end, and there're k people + @functools.lru_cache(None) + def dp(l: int, r: int, k: int) -> List[int]: + if l == r: + return [1, 1] + if l > r: + return dp(r, l, k) + + a = math.inf + b = -math.inf + + # Enumerate all possible positions + for i in range(1, l + 1): + for j in range(l - i + 1, r - i + 1): + if not l + r - k // 2 <= i + j <= (k + 1) // 2: + continue + x, y = dp(i, j, (k + 1) // 2) + a = min(a, x + 1) + b = max(b, y + 1) + + return [a, b] + + return dp(firstPlayer, n - secondPlayer + 1, n) From dd85b2ca656cb36757ac42ecb7f20d24f22cde6b Mon Sep 17 00:00:00 2001 From: Rhitik Date: Mon, 16 Oct 2023 17:15:03 +0530 Subject: [PATCH 06/19] Added Solution for 1307. Verbal Arithmetic Puzzel and Updated README.md and README_EN.md --- .../1307.Verbal Arithmetic Puzzle/README.md | 39 +++++++++++++++++++ .../README_EN.md | 39 +++++++++++++++++++ .../1307.Verbal Arithmetic Puzzle/Solution.py | 39 +++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 solution/1300-1399/1307.Verbal Arithmetic Puzzle/Solution.py diff --git a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README.md b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README.md index 4c4659ecb9f0d..8a38194b377d5 100644 --- a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README.md +++ b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README.md @@ -69,6 +69,45 @@ ```python +class Solution: + def isSolvable(self, words: List[str], result: str) -> bool: + words.append(result) + rows = len(words) + cols = max(map(len, words)) + letterToDigit = {} + usedDigit = [False] * 10 + + def dfs(row: int, col: int, summ: int) -> bool: + if col == cols: + return summ == 0 + if row == rows: + return summ % 10 == 0 and dfs(0, col + 1, summ // 10) + + word = words[row] + if col >= len(word): + return dfs(row + 1, col, summ) + + letter = word[~col] + sign = -1 if row == rows - 1 else 1 + + if letter in letterToDigit and ( + letterToDigit[letter] > 0 or col < len(word) - 1 + ): + return dfs(row + 1, col, summ + sign * letterToDigit[letter]) + + for digit, used in enumerate(usedDigit): + if not used and (digit > 0 or col < len(word) - 1): + letterToDigit[letter] = digit + usedDigit[digit] = True + if dfs(row + 1, col, summ + sign * digit): + return True + usedDigit[digit] = False + if letter in letterToDigit: + del letterToDigit[letter] + + return False + + return dfs(0, 0, 0) ``` diff --git a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README_EN.md b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README_EN.md index 6fe660b2b7903..9d9fa88ceba28 100644 --- a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README_EN.md +++ b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README_EN.md @@ -60,6 +60,45 @@ Note that two different characters cannot map to the same digit. ### **Python3** ```python +class Solution: + def isSolvable(self, words: List[str], result: str) -> bool: + words.append(result) + rows = len(words) + cols = max(map(len, words)) + letterToDigit = {} + usedDigit = [False] * 10 + + def dfs(row: int, col: int, summ: int) -> bool: + if col == cols: + return summ == 0 + if row == rows: + return summ % 10 == 0 and dfs(0, col + 1, summ // 10) + + word = words[row] + if col >= len(word): + return dfs(row + 1, col, summ) + + letter = word[~col] + sign = -1 if row == rows - 1 else 1 + + if letter in letterToDigit and ( + letterToDigit[letter] > 0 or col < len(word) - 1 + ): + return dfs(row + 1, col, summ + sign * letterToDigit[letter]) + + for digit, used in enumerate(usedDigit): + if not used and (digit > 0 or col < len(word) - 1): + letterToDigit[letter] = digit + usedDigit[digit] = True + if dfs(row + 1, col, summ + sign * digit): + return True + usedDigit[digit] = False + if letter in letterToDigit: + del letterToDigit[letter] + + return False + + return dfs(0, 0, 0) ``` diff --git a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/Solution.py b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/Solution.py new file mode 100644 index 0000000000000..175fed29a1015 --- /dev/null +++ b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/Solution.py @@ -0,0 +1,39 @@ +class Solution: + def isSolvable(self, words: List[str], result: str) -> bool: + words.append(result) + rows = len(words) + cols = max(map(len, words)) + letterToDigit = {} + usedDigit = [False] * 10 + + def dfs(row: int, col: int, summ: int) -> bool: + if col == cols: + return summ == 0 + if row == rows: + return summ % 10 == 0 and dfs(0, col + 1, summ // 10) + + word = words[row] + if col >= len(word): + return dfs(row + 1, col, summ) + + letter = word[~col] + sign = -1 if row == rows - 1 else 1 + + if letter in letterToDigit and ( + letterToDigit[letter] > 0 or col < len(word) - 1 + ): + return dfs(row + 1, col, summ + sign * letterToDigit[letter]) + + for digit, used in enumerate(usedDigit): + if not used and (digit > 0 or col < len(word) - 1): + letterToDigit[letter] = digit + usedDigit[digit] = True + if dfs(row + 1, col, summ + sign * digit): + return True + usedDigit[digit] = False + if letter in letterToDigit: + del letterToDigit[letter] + + return False + + return dfs(0, 0, 0) From cce5b39cc76ea6ae47eabdb708c67cc1c71dd7c2 Mon Sep 17 00:00:00 2001 From: Rhitik Date: Mon, 16 Oct 2023 17:18:16 +0530 Subject: [PATCH 07/19] Added solution for 1354. --- .../README.md | 23 +++++++++++++++++++ .../README_EN.md | 23 +++++++++++++++++++ .../Solution.py | 23 +++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 solution/1300-1399/1354.Construct Target Array With Multiple Sums/Solution.py diff --git a/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README.md b/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README.md index 41867015b1e1d..2f70357cedf60 100644 --- a/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README.md +++ b/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README.md @@ -63,6 +63,29 @@ ```python +class Solution: + def isPossible(self, target: List[int]) -> bool: + if len(target) == 1: + return target[0] == 1 + + summ = sum(target) + maxHeap = [-num for num in target] + heapq.heapify(maxHeap) + + while -maxHeap[0] > 1: + maxi = -heapq.heappop(maxHeap) + restSum = summ - maxi + # Only occurs if n == 2. + if restSum == 1: + return True + updated = maxi % restSum + # Updated == 0 (invalid) or didn't change. + if updated == 0 or updated == maxi: + return False + heapq.heappush(maxHeap, -updated) + summ = summ - maxi + updated + + return True ``` diff --git a/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README_EN.md b/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README_EN.md index 64cb1603eaf11..7839c8a3ff817 100644 --- a/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README_EN.md +++ b/solution/1300-1399/1354.Construct Target Array With Multiple Sums/README_EN.md @@ -58,6 +58,29 @@ ### **Python3** ```python +class Solution: + def isPossible(self, target: List[int]) -> bool: + if len(target) == 1: + return target[0] == 1 + + summ = sum(target) + maxHeap = [-num for num in target] + heapq.heapify(maxHeap) + + while -maxHeap[0] > 1: + maxi = -heapq.heappop(maxHeap) + restSum = summ - maxi + # Only occurs if n == 2. + if restSum == 1: + return True + updated = maxi % restSum + # Updated == 0 (invalid) or didn't change. + if updated == 0 or updated == maxi: + return False + heapq.heappush(maxHeap, -updated) + summ = summ - maxi + updated + + return True ``` diff --git a/solution/1300-1399/1354.Construct Target Array With Multiple Sums/Solution.py b/solution/1300-1399/1354.Construct Target Array With Multiple Sums/Solution.py new file mode 100644 index 0000000000000..ec3ecc99ba728 --- /dev/null +++ b/solution/1300-1399/1354.Construct Target Array With Multiple Sums/Solution.py @@ -0,0 +1,23 @@ +class Solution: + def isPossible(self, target: List[int]) -> bool: + if len(target) == 1: + return target[0] == 1 + + summ = sum(target) + maxHeap = [-num for num in target] + heapq.heapify(maxHeap) + + while -maxHeap[0] > 1: + maxi = -heapq.heappop(maxHeap) + restSum = summ - maxi + # Only occurs if n == 2. + if restSum == 1: + return True + updated = maxi % restSum + # Updated == 0 (invalid) or didn't change. + if updated == 0 or updated == maxi: + return False + heapq.heappush(maxHeap, -updated) + summ = summ - maxi + updated + + return True From b1d5882ba0ddb3d9c6e86286e0b9ab20e4cfe15f Mon Sep 17 00:00:00 2001 From: Rhitik Date: Mon, 16 Oct 2023 18:49:26 +0530 Subject: [PATCH 08/19] Updated solution for 1307 to pass all the test cases. --- .../1307.Verbal Arithmetic Puzzle/Solution.py | 77 +++++++++++-------- 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/Solution.py b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/Solution.py index 175fed29a1015..53b0787aff3a6 100644 --- a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/Solution.py +++ b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/Solution.py @@ -1,39 +1,56 @@ class Solution: def isSolvable(self, words: List[str], result: str) -> bool: - words.append(result) - rows = len(words) - cols = max(map(len, words)) - letterToDigit = {} - usedDigit = [False] * 10 - - def dfs(row: int, col: int, summ: int) -> bool: - if col == cols: - return summ == 0 - if row == rows: - return summ % 10 == 0 and dfs(0, col + 1, summ // 10) + if max(map(len, words)) > len( + result + ): # If any of the words are bigger than the result, it will be impossible to solve + return False + # Add the result to the list, this way we will only subtract values when it comes to the result word. + # Thus at every index, if the total is zero, then for that letter index the formulat is correct + words = [word[::-1] for word in words] + [result[::-1]] + values = {} # Mapping from letter to values + nums = [0] * 10 - word = words[row] - if col >= len(word): - return dfs(row + 1, col, summ) + # i: word index, j: ltr index, total: total current Sum + def dfs(i, j, total): + if j == len( + result + ): # Reached end of the indecies for ltrs in all words (END) + return ( + total % 10 == 0 + ) # Checking to see if the total for the current character is correct or not + if i == len(words): # Checked ltr at index j for all the words + return total % 10 == 0 and dfs(0, j + 1, total // 10) - letter = word[~col] - sign = -1 if row == rows - 1 else 1 + if j >= len(words[i]): + return dfs(i + 1, j, total) - if letter in letterToDigit and ( - letterToDigit[letter] > 0 or col < len(word) - 1 - ): - return dfs(row + 1, col, summ + sign * letterToDigit[letter]) + if words[i][j] in values: + if ( + values[words[i][j]] == 0 + and j == len(words[i]) - 1 + and len(words[i]) > 1 + ): + return False + if i == len(words) - 1: + return dfs(i + 1, j, total - values[words[i][j]]) + else: + return dfs(i + 1, j, total + values[words[i][j]]) + else: + for val, isUsed in enumerate(nums): + if not isUsed and (val != 0 or j == 0 or j < len(words[i]) - 1): + values[words[i][j]] = val + nums[val] = True - for digit, used in enumerate(usedDigit): - if not used and (digit > 0 or col < len(word) - 1): - letterToDigit[letter] = digit - usedDigit[digit] = True - if dfs(row + 1, col, summ + sign * digit): - return True - usedDigit[digit] = False - if letter in letterToDigit: - del letterToDigit[letter] + if i == len(words) - 1 and dfs( + i + 1, j, total - values[words[i][j]] + ): + return True + elif i < len(words) - 1 and dfs( + i + 1, j, total + values[words[i][j]] + ): + return True - return False + values.pop(words[i][j]) + nums[val] = False return dfs(0, 0, 0) From ea5191338edce227eecebe458d648cd3bde08d31 Mon Sep 17 00:00:00 2001 From: Rhitik Date: Mon, 16 Oct 2023 18:53:50 +0530 Subject: [PATCH 09/19] Updated README for 1307. --- .../1307.Verbal Arithmetic Puzzle/README.md | 85 ++++++++++-------- .../README_EN.md | 86 +++++++++++-------- 2 files changed, 102 insertions(+), 69 deletions(-) diff --git a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README.md b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README.md index 8a38194b377d5..716480fb96f05 100644 --- a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README.md +++ b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README.md @@ -71,41 +71,58 @@ ```python class Solution: def isSolvable(self, words: List[str], result: str) -> bool: - words.append(result) - rows = len(words) - cols = max(map(len, words)) - letterToDigit = {} - usedDigit = [False] * 10 - - def dfs(row: int, col: int, summ: int) -> bool: - if col == cols: - return summ == 0 - if row == rows: - return summ % 10 == 0 and dfs(0, col + 1, summ // 10) - - word = words[row] - if col >= len(word): - return dfs(row + 1, col, summ) - - letter = word[~col] - sign = -1 if row == rows - 1 else 1 - - if letter in letterToDigit and ( - letterToDigit[letter] > 0 or col < len(word) - 1 - ): - return dfs(row + 1, col, summ + sign * letterToDigit[letter]) - - for digit, used in enumerate(usedDigit): - if not used and (digit > 0 or col < len(word) - 1): - letterToDigit[letter] = digit - usedDigit[digit] = True - if dfs(row + 1, col, summ + sign * digit): - return True - usedDigit[digit] = False - if letter in letterToDigit: - del letterToDigit[letter] - + if max(map(len, words)) > len( + result + ): # If any of the words are bigger than the result, it will be impossible to solve return False + # Add the result to the list, this way we will only subtract values when it comes to the result word. + # Thus at every index, if the total is zero, then for that letter index the formulat is correct + words = [word[::-1] for word in words] + [result[::-1]] + values = {} # Mapping from letter to values + nums = [0] * 10 + + # i: word index, j: ltr index, total: total current Sum + def dfs(i, j, total): + if j == len( + result + ): # Reached end of the indecies for ltrs in all words (END) + return ( + total % 10 == 0 + ) # Checking to see if the total for the current character is correct or not + if i == len(words): # Checked ltr at index j for all the words + return total % 10 == 0 and dfs(0, j + 1, total // 10) + + if j >= len(words[i]): + return dfs(i + 1, j, total) + + if words[i][j] in values: + if ( + values[words[i][j]] == 0 + and j == len(words[i]) - 1 + and len(words[i]) > 1 + ): + return False + if i == len(words) - 1: + return dfs(i + 1, j, total - values[words[i][j]]) + else: + return dfs(i + 1, j, total + values[words[i][j]]) + else: + for val, isUsed in enumerate(nums): + if not isUsed and (val != 0 or j == 0 or j < len(words[i]) - 1): + values[words[i][j]] = val + nums[val] = True + + if i == len(words) - 1 and dfs( + i + 1, j, total - values[words[i][j]] + ): + return True + elif i < len(words) - 1 and dfs( + i + 1, j, total + values[words[i][j]] + ): + return True + + values.pop(words[i][j]) + nums[val] = False return dfs(0, 0, 0) diff --git a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README_EN.md b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README_EN.md index 9d9fa88ceba28..7bfd90e001cb5 100644 --- a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README_EN.md +++ b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README_EN.md @@ -62,44 +62,60 @@ Note that two different characters cannot map to the same digit. ```python class Solution: def isSolvable(self, words: List[str], result: str) -> bool: - words.append(result) - rows = len(words) - cols = max(map(len, words)) - letterToDigit = {} - usedDigit = [False] * 10 - - def dfs(row: int, col: int, summ: int) -> bool: - if col == cols: - return summ == 0 - if row == rows: - return summ % 10 == 0 and dfs(0, col + 1, summ // 10) - - word = words[row] - if col >= len(word): - return dfs(row + 1, col, summ) - - letter = word[~col] - sign = -1 if row == rows - 1 else 1 - - if letter in letterToDigit and ( - letterToDigit[letter] > 0 or col < len(word) - 1 - ): - return dfs(row + 1, col, summ + sign * letterToDigit[letter]) - - for digit, used in enumerate(usedDigit): - if not used and (digit > 0 or col < len(word) - 1): - letterToDigit[letter] = digit - usedDigit[digit] = True - if dfs(row + 1, col, summ + sign * digit): - return True - usedDigit[digit] = False - if letter in letterToDigit: - del letterToDigit[letter] - + if max(map(len, words)) > len( + result + ): # If any of the words are bigger than the result, it will be impossible to solve return False + # Add the result to the list, this way we will only subtract values when it comes to the result word. + # Thus at every index, if the total is zero, then for that letter index the formulat is correct + words = [word[::-1] for word in words] + [result[::-1]] + values = {} # Mapping from letter to values + nums = [0] * 10 + + # i: word index, j: ltr index, total: total current Sum + def dfs(i, j, total): + if j == len( + result + ): # Reached end of the indecies for ltrs in all words (END) + return ( + total % 10 == 0 + ) # Checking to see if the total for the current character is correct or not + if i == len(words): # Checked ltr at index j for all the words + return total % 10 == 0 and dfs(0, j + 1, total // 10) + + if j >= len(words[i]): + return dfs(i + 1, j, total) + + if words[i][j] in values: + if ( + values[words[i][j]] == 0 + and j == len(words[i]) - 1 + and len(words[i]) > 1 + ): + return False + if i == len(words) - 1: + return dfs(i + 1, j, total - values[words[i][j]]) + else: + return dfs(i + 1, j, total + values[words[i][j]]) + else: + for val, isUsed in enumerate(nums): + if not isUsed and (val != 0 or j == 0 or j < len(words[i]) - 1): + values[words[i][j]] = val + nums[val] = True + + if i == len(words) - 1 and dfs( + i + 1, j, total - values[words[i][j]] + ): + return True + elif i < len(words) - 1 and dfs( + i + 1, j, total + values[words[i][j]] + ): + return True + + values.pop(words[i][j]) + nums[val] = False return dfs(0, 0, 0) - ``` ### **Java** From 68821c3a1f9782c9d6e4a14d03e78e65511a8f57 Mon Sep 17 00:00:00 2001 From: Rhitik Date: Wed, 18 Oct 2023 20:36:41 +0530 Subject: [PATCH 10/19] Removed solution for 1307. --- .../1307.Verbal Arithmetic Puzzle/README.md | 56 ------------------ .../README_EN.md | 57 +------------------ .../1307.Verbal Arithmetic Puzzle/Solution.py | 56 ------------------ 3 files changed, 1 insertion(+), 168 deletions(-) delete mode 100644 solution/1300-1399/1307.Verbal Arithmetic Puzzle/Solution.py diff --git a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README.md b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README.md index 716480fb96f05..4c4659ecb9f0d 100644 --- a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README.md +++ b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README.md @@ -69,62 +69,6 @@ ```python -class Solution: - def isSolvable(self, words: List[str], result: str) -> bool: - if max(map(len, words)) > len( - result - ): # If any of the words are bigger than the result, it will be impossible to solve - return False - # Add the result to the list, this way we will only subtract values when it comes to the result word. - # Thus at every index, if the total is zero, then for that letter index the formulat is correct - words = [word[::-1] for word in words] + [result[::-1]] - values = {} # Mapping from letter to values - nums = [0] * 10 - - # i: word index, j: ltr index, total: total current Sum - def dfs(i, j, total): - if j == len( - result - ): # Reached end of the indecies for ltrs in all words (END) - return ( - total % 10 == 0 - ) # Checking to see if the total for the current character is correct or not - if i == len(words): # Checked ltr at index j for all the words - return total % 10 == 0 and dfs(0, j + 1, total // 10) - - if j >= len(words[i]): - return dfs(i + 1, j, total) - - if words[i][j] in values: - if ( - values[words[i][j]] == 0 - and j == len(words[i]) - 1 - and len(words[i]) > 1 - ): - return False - if i == len(words) - 1: - return dfs(i + 1, j, total - values[words[i][j]]) - else: - return dfs(i + 1, j, total + values[words[i][j]]) - else: - for val, isUsed in enumerate(nums): - if not isUsed and (val != 0 or j == 0 or j < len(words[i]) - 1): - values[words[i][j]] = val - nums[val] = True - - if i == len(words) - 1 and dfs( - i + 1, j, total - values[words[i][j]] - ): - return True - elif i < len(words) - 1 and dfs( - i + 1, j, total + values[words[i][j]] - ): - return True - - values.pop(words[i][j]) - nums[val] = False - - return dfs(0, 0, 0) ``` diff --git a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README_EN.md b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README_EN.md index 7bfd90e001cb5..6fe660b2b7903 100644 --- a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README_EN.md +++ b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/README_EN.md @@ -60,62 +60,7 @@ Note that two different characters cannot map to the same digit. ### **Python3** ```python -class Solution: - def isSolvable(self, words: List[str], result: str) -> bool: - if max(map(len, words)) > len( - result - ): # If any of the words are bigger than the result, it will be impossible to solve - return False - # Add the result to the list, this way we will only subtract values when it comes to the result word. - # Thus at every index, if the total is zero, then for that letter index the formulat is correct - words = [word[::-1] for word in words] + [result[::-1]] - values = {} # Mapping from letter to values - nums = [0] * 10 - - # i: word index, j: ltr index, total: total current Sum - def dfs(i, j, total): - if j == len( - result - ): # Reached end of the indecies for ltrs in all words (END) - return ( - total % 10 == 0 - ) # Checking to see if the total for the current character is correct or not - if i == len(words): # Checked ltr at index j for all the words - return total % 10 == 0 and dfs(0, j + 1, total // 10) - - if j >= len(words[i]): - return dfs(i + 1, j, total) - - if words[i][j] in values: - if ( - values[words[i][j]] == 0 - and j == len(words[i]) - 1 - and len(words[i]) > 1 - ): - return False - if i == len(words) - 1: - return dfs(i + 1, j, total - values[words[i][j]]) - else: - return dfs(i + 1, j, total + values[words[i][j]]) - else: - for val, isUsed in enumerate(nums): - if not isUsed and (val != 0 or j == 0 or j < len(words[i]) - 1): - values[words[i][j]] = val - nums[val] = True - - if i == len(words) - 1 and dfs( - i + 1, j, total - values[words[i][j]] - ): - return True - elif i < len(words) - 1 and dfs( - i + 1, j, total + values[words[i][j]] - ): - return True - - values.pop(words[i][j]) - nums[val] = False - - return dfs(0, 0, 0) + ``` ### **Java** diff --git a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/Solution.py b/solution/1300-1399/1307.Verbal Arithmetic Puzzle/Solution.py deleted file mode 100644 index 53b0787aff3a6..0000000000000 --- a/solution/1300-1399/1307.Verbal Arithmetic Puzzle/Solution.py +++ /dev/null @@ -1,56 +0,0 @@ -class Solution: - def isSolvable(self, words: List[str], result: str) -> bool: - if max(map(len, words)) > len( - result - ): # If any of the words are bigger than the result, it will be impossible to solve - return False - # Add the result to the list, this way we will only subtract values when it comes to the result word. - # Thus at every index, if the total is zero, then for that letter index the formulat is correct - words = [word[::-1] for word in words] + [result[::-1]] - values = {} # Mapping from letter to values - nums = [0] * 10 - - # i: word index, j: ltr index, total: total current Sum - def dfs(i, j, total): - if j == len( - result - ): # Reached end of the indecies for ltrs in all words (END) - return ( - total % 10 == 0 - ) # Checking to see if the total for the current character is correct or not - if i == len(words): # Checked ltr at index j for all the words - return total % 10 == 0 and dfs(0, j + 1, total // 10) - - if j >= len(words[i]): - return dfs(i + 1, j, total) - - if words[i][j] in values: - if ( - values[words[i][j]] == 0 - and j == len(words[i]) - 1 - and len(words[i]) > 1 - ): - return False - if i == len(words) - 1: - return dfs(i + 1, j, total - values[words[i][j]]) - else: - return dfs(i + 1, j, total + values[words[i][j]]) - else: - for val, isUsed in enumerate(nums): - if not isUsed and (val != 0 or j == 0 or j < len(words[i]) - 1): - values[words[i][j]] = val - nums[val] = True - - if i == len(words) - 1 and dfs( - i + 1, j, total - values[words[i][j]] - ): - return True - elif i < len(words) - 1 and dfs( - i + 1, j, total + values[words[i][j]] - ): - return True - - values.pop(words[i][j]) - nums[val] = False - - return dfs(0, 0, 0) From 54ba9acdd2ae0eb3af8cc785f80fea5096011d17 Mon Sep 17 00:00:00 2001 From: Rhitik Date: Thu, 19 Oct 2023 19:04:26 +0530 Subject: [PATCH 11/19] Solution for 1728. --- .../1700-1799/1728.Cat and Mouse II/README.md | 70 +++++++++++++++++++ .../1728.Cat and Mouse II/README_EN.md | 70 +++++++++++++++++++ .../1728.Cat and Mouse II/Solution.py | 70 +++++++++++++++++++ 3 files changed, 210 insertions(+) create mode 100644 solution/1700-1799/1728.Cat and Mouse II/Solution.py diff --git a/solution/1700-1799/1728.Cat and Mouse II/README.md b/solution/1700-1799/1728.Cat and Mouse II/README.md index dc19968a0e962..5d62429fa9da2 100644 --- a/solution/1700-1799/1728.Cat and Mouse II/README.md +++ b/solution/1700-1799/1728.Cat and Mouse II/README.md @@ -105,6 +105,76 @@ ```python +class Solution: + def canMouseWin(self, grid: List[str], catJump: int, mouseJump: int) -> bool: + dirs = [0, 1, 0, -1, 0] + m = len(grid) + n = len(grid[0]) + nFloors = 0 + cat = 0 # cat's position + mouse = 0 # mouse's position + + def hash(i: int, j: int) -> int: + return i * n + j + + for i in range(m): + for j in range(n): + if grid[i][j] != "#": + nFloors += 1 + if grid[i][j] == "C": + cat = hash(i, j) + elif grid[i][j] == "M": + mouse = hash(i, j) + + # dp(i, j, k) := True if mouse can win w// + # Cat on (i // 8, i % 8), mouse on (j // 8, j % 8), and turns = k + @functools.lru_cache(None) + def dp(cat: int, mouse: int, turn: int) -> bool: + # We already search whole touchable grid + if turn == nFloors * 2: + return False + + if turn % 2 == 0: + # mouse's turn + i = mouse // n + j = mouse % n + for k in range(4): + for jump in range(mouseJump + 1): + x = i + dirs[k] * jump + y = j + dirs[k + 1] * jump + if x < 0 or x == m or y < 0 or y == n: + break + if grid[x][y] == "#": + break + if grid[x][y] == "F": # Mouse eats the food, so mouse win + return True + if dp(cat, hash(x, y), turn + 1): + return True + # Mouse can't win, so mouse lose + return False + else: + # cat's turn + i = cat // n + j = cat % n + for k in range(4): + for jump in range(catJump + 1): + x = i + dirs[k] * jump + y = j + dirs[k + 1] * jump + if x < 0 or x == m or y < 0 or y == n: + break + if grid[x][y] == "#": + break + if grid[x][y] == "F": # Cat eats the food, so mouse lose + return False + nextCat = hash(x, y) + if nextCat == mouse: # Cat catches mouse, so mouse lose + return False + if not dp(nextCat, mouse, turn + 1): + return False + # Cat can't win, so mouse win + return True + + return dp(cat, mouse, 0) ``` diff --git a/solution/1700-1799/1728.Cat and Mouse II/README_EN.md b/solution/1700-1799/1728.Cat and Mouse II/README_EN.md index 2c22b6bbd3361..beef115aeaae9 100644 --- a/solution/1700-1799/1728.Cat and Mouse II/README_EN.md +++ b/solution/1700-1799/1728.Cat and Mouse II/README_EN.md @@ -79,6 +79,76 @@ ### **Python3** ```python +class Solution: + def canMouseWin(self, grid: List[str], catJump: int, mouseJump: int) -> bool: + dirs = [0, 1, 0, -1, 0] + m = len(grid) + n = len(grid[0]) + nFloors = 0 + cat = 0 # cat's position + mouse = 0 # mouse's position + + def hash(i: int, j: int) -> int: + return i * n + j + + for i in range(m): + for j in range(n): + if grid[i][j] != "#": + nFloors += 1 + if grid[i][j] == "C": + cat = hash(i, j) + elif grid[i][j] == "M": + mouse = hash(i, j) + + # dp(i, j, k) := True if mouse can win w// + # Cat on (i // 8, i % 8), mouse on (j // 8, j % 8), and turns = k + @functools.lru_cache(None) + def dp(cat: int, mouse: int, turn: int) -> bool: + # We already search whole touchable grid + if turn == nFloors * 2: + return False + + if turn % 2 == 0: + # mouse's turn + i = mouse // n + j = mouse % n + for k in range(4): + for jump in range(mouseJump + 1): + x = i + dirs[k] * jump + y = j + dirs[k + 1] * jump + if x < 0 or x == m or y < 0 or y == n: + break + if grid[x][y] == "#": + break + if grid[x][y] == "F": # Mouse eats the food, so mouse win + return True + if dp(cat, hash(x, y), turn + 1): + return True + # Mouse can't win, so mouse lose + return False + else: + # cat's turn + i = cat // n + j = cat % n + for k in range(4): + for jump in range(catJump + 1): + x = i + dirs[k] * jump + y = j + dirs[k + 1] * jump + if x < 0 or x == m or y < 0 or y == n: + break + if grid[x][y] == "#": + break + if grid[x][y] == "F": # Cat eats the food, so mouse lose + return False + nextCat = hash(x, y) + if nextCat == mouse: # Cat catches mouse, so mouse lose + return False + if not dp(nextCat, mouse, turn + 1): + return False + # Cat can't win, so mouse win + return True + + return dp(cat, mouse, 0) ``` diff --git a/solution/1700-1799/1728.Cat and Mouse II/Solution.py b/solution/1700-1799/1728.Cat and Mouse II/Solution.py new file mode 100644 index 0000000000000..7154a272c06d1 --- /dev/null +++ b/solution/1700-1799/1728.Cat and Mouse II/Solution.py @@ -0,0 +1,70 @@ +class Solution: + def canMouseWin(self, grid: List[str], catJump: int, mouseJump: int) -> bool: + dirs = [0, 1, 0, -1, 0] + m = len(grid) + n = len(grid[0]) + nFloors = 0 + cat = 0 # cat's position + mouse = 0 # mouse's position + + def hash(i: int, j: int) -> int: + return i * n + j + + for i in range(m): + for j in range(n): + if grid[i][j] != "#": + nFloors += 1 + if grid[i][j] == "C": + cat = hash(i, j) + elif grid[i][j] == "M": + mouse = hash(i, j) + + # dp(i, j, k) := True if mouse can win w// + # Cat on (i // 8, i % 8), mouse on (j // 8, j % 8), and turns = k + @functools.lru_cache(None) + def dp(cat: int, mouse: int, turn: int) -> bool: + # We already search whole touchable grid + if turn == nFloors * 2: + return False + + if turn % 2 == 0: + # mouse's turn + i = mouse // n + j = mouse % n + for k in range(4): + for jump in range(mouseJump + 1): + x = i + dirs[k] * jump + y = j + dirs[k + 1] * jump + if x < 0 or x == m or y < 0 or y == n: + break + if grid[x][y] == "#": + break + if grid[x][y] == "F": # Mouse eats the food, so mouse win + return True + if dp(cat, hash(x, y), turn + 1): + return True + # Mouse can't win, so mouse lose + return False + else: + # cat's turn + i = cat // n + j = cat % n + for k in range(4): + for jump in range(catJump + 1): + x = i + dirs[k] * jump + y = j + dirs[k + 1] * jump + if x < 0 or x == m or y < 0 or y == n: + break + if grid[x][y] == "#": + break + if grid[x][y] == "F": # Cat eats the food, so mouse lose + return False + nextCat = hash(x, y) + if nextCat == mouse: # Cat catches mouse, so mouse lose + return False + if not dp(nextCat, mouse, turn + 1): + return False + # Cat can't win, so mouse win + return True + + return dp(cat, mouse, 0) From 22ebd8b9990e6a19e15b83001e60caef9e2df578 Mon Sep 17 00:00:00 2001 From: Rhitik Date: Fri, 20 Oct 2023 13:22:37 +0530 Subject: [PATCH 12/19] Solution for 2902. --- .../README.md | 21 +++++++++++++++++++ .../README_EN.md | 21 +++++++++++++++++++ .../Solution.py | 21 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 solution/2900-2999/2902.Count of Sub-Multisets With Bounded Sum/Solution.py diff --git a/solution/2900-2999/2902.Count of Sub-Multisets With Bounded Sum/README.md b/solution/2900-2999/2902.Count of Sub-Multisets With Bounded Sum/README.md index e86259fc288ef..d8e54f9631ab1 100644 --- a/solution/2900-2999/2902.Count of Sub-Multisets With Bounded Sum/README.md +++ b/solution/2900-2999/2902.Count of Sub-Multisets With Bounded Sum/README.md @@ -68,6 +68,27 @@ ```python +class Solution: + def countSubMultisets(self, nums: List[int], l: int, r: int) -> int: + kMod = 1_000_000_007 + # dp[i] := # of submultisets of nums with sum i + dp = [1] + [0] * r + count = collections.Counter(nums) + zeros = count.pop(0, 0) + + for num, freq in count.items(): + # stride[i] := dp[i] + dp[i - num] + dp[i - 2 * num] + ... + stride = dp.copy() + for i in range(num, r + 1): + stride[i] += stride[i - num] + for i in range(r, 0, -1): + if i >= num * (freq + 1): + # dp[i] + dp[i - num] + dp[i - freq * num] + dp[i] = stride[i] - stride[i - num * (freq + 1)] + else: + dp[i] = stride[i] + + return (zeros + 1) * sum(dp[l : r + 1]) % kMod ``` diff --git a/solution/2900-2999/2902.Count of Sub-Multisets With Bounded Sum/README_EN.md b/solution/2900-2999/2902.Count of Sub-Multisets With Bounded Sum/README_EN.md index 164d3f62a5df3..234d87c17fae3 100644 --- a/solution/2900-2999/2902.Count of Sub-Multisets With Bounded Sum/README_EN.md +++ b/solution/2900-2999/2902.Count of Sub-Multisets With Bounded Sum/README_EN.md @@ -60,6 +60,27 @@ ### **Python3** ```python +class Solution: + def countSubMultisets(self, nums: List[int], l: int, r: int) -> int: + kMod = 1_000_000_007 + # dp[i] := # of submultisets of nums with sum i + dp = [1] + [0] * r + count = collections.Counter(nums) + zeros = count.pop(0, 0) + + for num, freq in count.items(): + # stride[i] := dp[i] + dp[i - num] + dp[i - 2 * num] + ... + stride = dp.copy() + for i in range(num, r + 1): + stride[i] += stride[i - num] + for i in range(r, 0, -1): + if i >= num * (freq + 1): + # dp[i] + dp[i - num] + dp[i - freq * num] + dp[i] = stride[i] - stride[i - num * (freq + 1)] + else: + dp[i] = stride[i] + + return (zeros + 1) * sum(dp[l : r + 1]) % kMod ``` diff --git a/solution/2900-2999/2902.Count of Sub-Multisets With Bounded Sum/Solution.py b/solution/2900-2999/2902.Count of Sub-Multisets With Bounded Sum/Solution.py new file mode 100644 index 0000000000000..2616edb2c3ac5 --- /dev/null +++ b/solution/2900-2999/2902.Count of Sub-Multisets With Bounded Sum/Solution.py @@ -0,0 +1,21 @@ +class Solution: + def countSubMultisets(self, nums: List[int], l: int, r: int) -> int: + kMod = 1_000_000_007 + # dp[i] := # of submultisets of nums with sum i + dp = [1] + [0] * r + count = collections.Counter(nums) + zeros = count.pop(0, 0) + + for num, freq in count.items(): + # stride[i] := dp[i] + dp[i - num] + dp[i - 2 * num] + ... + stride = dp.copy() + for i in range(num, r + 1): + stride[i] += stride[i - num] + for i in range(r, 0, -1): + if i >= num * (freq + 1): + # dp[i] + dp[i - num] + dp[i - freq * num] + dp[i] = stride[i] - stride[i - num * (freq + 1)] + else: + dp[i] = stride[i] + + return (zeros + 1) * sum(dp[l : r + 1]) % kMod From 7576497ffdcf0d0558cda409bbebf850d22875f2 Mon Sep 17 00:00:00 2001 From: Rhitik Date: Fri, 20 Oct 2023 22:10:15 +0530 Subject: [PATCH 13/19] Solution for 176. --- .../0100-0199/0176.Second Highest Salary/README.md | 10 ++++++++++ .../0100-0199/0176.Second Highest Salary/README_EN.md | 10 ++++++++++ .../0100-0199/0176.Second Highest Salary/Solution.py | 7 +++++++ 3 files changed, 27 insertions(+) create mode 100644 solution/0100-0199/0176.Second Highest Salary/Solution.py diff --git a/solution/0100-0199/0176.Second Highest Salary/README.md b/solution/0100-0199/0176.Second Highest Salary/README.md index 371e9db7b0ca3..7e9ff887af297 100644 --- a/solution/0100-0199/0176.Second Highest Salary/README.md +++ b/solution/0100-0199/0176.Second Highest Salary/README.md @@ -113,4 +113,14 @@ WITH T AS (SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rk FROM Em SELECT (SELECT DISTINCT salary FROM T WHERE rk = 2) AS SecondHighestSalary; ``` +```pandas +import pandas as pd + + +def combine_two_tables(person: pd.DataFrame, address: pd.DataFrame) -> pd.DataFrame: + return pd.merge(left=person, right=address, how="left", on="personId")[ + ["firstName", "lastName", "city", "state"] + ] + +``` diff --git a/solution/0100-0199/0176.Second Highest Salary/README_EN.md b/solution/0100-0199/0176.Second Highest Salary/README_EN.md index 28829a5fe7097..22980f2032c41 100644 --- a/solution/0100-0199/0176.Second Highest Salary/README_EN.md +++ b/solution/0100-0199/0176.Second Highest Salary/README_EN.md @@ -98,4 +98,14 @@ WITH T AS (SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rk FROM Em SELECT (SELECT DISTINCT salary FROM T WHERE rk = 2) AS SecondHighestSalary; ``` +```pandas +import pandas as pd + + +def combine_two_tables(person: pd.DataFrame, address: pd.DataFrame) -> pd.DataFrame: + return pd.merge(left=person, right=address, how="left", on="personId")[ + ["firstName", "lastName", "city", "state"] + ] + +``` diff --git a/solution/0100-0199/0176.Second Highest Salary/Solution.py b/solution/0100-0199/0176.Second Highest Salary/Solution.py new file mode 100644 index 0000000000000..c70cd436c9b57 --- /dev/null +++ b/solution/0100-0199/0176.Second Highest Salary/Solution.py @@ -0,0 +1,7 @@ +import pandas as pd + + +def combine_two_tables(person: pd.DataFrame, address: pd.DataFrame) -> pd.DataFrame: + return pd.merge(left=person, right=address, how="left", on="personId")[ + ["firstName", "lastName", "city", "state"] + ] From 91669224be37108abc3e53f2f8d20c79816d9f96 Mon Sep 17 00:00:00 2001 From: Rhitik Date: Fri, 20 Oct 2023 22:17:31 +0530 Subject: [PATCH 14/19] Solution for 175, 176. --- .../0175.Combine Two Tables/README.md | 12 ++++++++++ .../0175.Combine Two Tables/README_EN.md | 11 +++++++++ .../0175.Combine Two Tables/Solution.py | 7 ++++++ .../0176.Second Highest Salary/README.md | 23 ++++++++++++++---- .../0176.Second Highest Salary/README_EN.md | 24 +++++++++++++++---- .../0176.Second Highest Salary/Solution.py | 21 ++++++++++++---- 6 files changed, 84 insertions(+), 14 deletions(-) create mode 100644 solution/0100-0199/0175.Combine Two Tables/Solution.py diff --git a/solution/0100-0199/0175.Combine Two Tables/README.md b/solution/0100-0199/0175.Combine Two Tables/README.md index a7687edaed4b0..8359efafd2ec9 100644 --- a/solution/0100-0199/0175.Combine Two Tables/README.md +++ b/solution/0100-0199/0175.Combine Two Tables/README.md @@ -96,4 +96,16 @@ FROM LEFT JOIN Address USING (personId); ``` +```pandas +import pandas as pd + + +def combine_two_tables(person: pd.DataFrame, address: pd.DataFrame) -> pd.DataFrame: + return pd.merge(left=person, right=address, how="left", on="personId")[ + ["firstName", "lastName", "city", "state"] + ] + +``` + + diff --git a/solution/0100-0199/0175.Combine Two Tables/README_EN.md b/solution/0100-0199/0175.Combine Two Tables/README_EN.md index 5b9e82e82eb9b..8356f8440b9e5 100644 --- a/solution/0100-0199/0175.Combine Two Tables/README_EN.md +++ b/solution/0100-0199/0175.Combine Two Tables/README_EN.md @@ -92,4 +92,15 @@ FROM LEFT JOIN Address USING (personId); ``` +```pandas +import pandas as pd + + +def combine_two_tables(person: pd.DataFrame, address: pd.DataFrame) -> pd.DataFrame: + return pd.merge(left=person, right=address, how="left", on="personId")[ + ["firstName", "lastName", "city", "state"] + ] + +``` + diff --git a/solution/0100-0199/0175.Combine Two Tables/Solution.py b/solution/0100-0199/0175.Combine Two Tables/Solution.py new file mode 100644 index 0000000000000..c70cd436c9b57 --- /dev/null +++ b/solution/0100-0199/0175.Combine Two Tables/Solution.py @@ -0,0 +1,7 @@ +import pandas as pd + + +def combine_two_tables(person: pd.DataFrame, address: pd.DataFrame) -> pd.DataFrame: + return pd.merge(left=person, right=address, how="left", on="personId")[ + ["firstName", "lastName", "city", "state"] + ] diff --git a/solution/0100-0199/0176.Second Highest Salary/README.md b/solution/0100-0199/0176.Second Highest Salary/README.md index 7e9ff887af297..04cdfeb3ee3aa 100644 --- a/solution/0100-0199/0176.Second Highest Salary/README.md +++ b/solution/0100-0199/0176.Second Highest Salary/README.md @@ -113,14 +113,27 @@ WITH T AS (SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rk FROM Em SELECT (SELECT DISTINCT salary FROM T WHERE rk = 2) AS SecondHighestSalary; ``` -```pandas +```python import pandas as pd -def combine_two_tables(person: pd.DataFrame, address: pd.DataFrame) -> pd.DataFrame: - return pd.merge(left=person, right=address, how="left", on="personId")[ - ["firstName", "lastName", "city", "state"] - ] +def second_highest_salary(employee: pd.DataFrame) -> pd.DataFrame: + # Drop any duplicate salary values to avoid counting duplicates as separate salary ranks + unique_salaries = employee["salary"].drop_duplicates() + + # Sort the unique salaries in descending order and get the second highest salary + second_highest = ( + unique_salaries.nlargest(2).iloc[-1] if len(unique_salaries) >= 2 else None + ) + + # If the second highest salary doesn't exist (e.g., there are fewer than two unique salaries), return None + if second_highest is None: + return pd.DataFrame({"SecondHighestSalary": [None]}) + + # Create a DataFrame with the second highest salary + result_df = pd.DataFrame({"SecondHighestSalary": [second_highest]}) + + return result_df ``` diff --git a/solution/0100-0199/0176.Second Highest Salary/README_EN.md b/solution/0100-0199/0176.Second Highest Salary/README_EN.md index 22980f2032c41..8140c9eafcd6c 100644 --- a/solution/0100-0199/0176.Second Highest Salary/README_EN.md +++ b/solution/0100-0199/0176.Second Highest Salary/README_EN.md @@ -98,14 +98,28 @@ WITH T AS (SELECT salary, DENSE_RANK() OVER (ORDER BY salary DESC) AS rk FROM Em SELECT (SELECT DISTINCT salary FROM T WHERE rk = 2) AS SecondHighestSalary; ``` -```pandas +```python import pandas as pd -def combine_two_tables(person: pd.DataFrame, address: pd.DataFrame) -> pd.DataFrame: - return pd.merge(left=person, right=address, how="left", on="personId")[ - ["firstName", "lastName", "city", "state"] - ] +def second_highest_salary(employee: pd.DataFrame) -> pd.DataFrame: + # Drop any duplicate salary values to avoid counting duplicates as separate salary ranks + unique_salaries = employee["salary"].drop_duplicates() + + # Sort the unique salaries in descending order and get the second highest salary + second_highest = ( + unique_salaries.nlargest(2).iloc[-1] if len(unique_salaries) >= 2 else None + ) + + # If the second highest salary doesn't exist (e.g., there are fewer than two unique salaries), return None + if second_highest is None: + return pd.DataFrame({"SecondHighestSalary": [None]}) + + # Create a DataFrame with the second highest salary + result_df = pd.DataFrame({"SecondHighestSalary": [second_highest]}) + + return result_df ``` + diff --git a/solution/0100-0199/0176.Second Highest Salary/Solution.py b/solution/0100-0199/0176.Second Highest Salary/Solution.py index c70cd436c9b57..6e0c551233216 100644 --- a/solution/0100-0199/0176.Second Highest Salary/Solution.py +++ b/solution/0100-0199/0176.Second Highest Salary/Solution.py @@ -1,7 +1,20 @@ import pandas as pd -def combine_two_tables(person: pd.DataFrame, address: pd.DataFrame) -> pd.DataFrame: - return pd.merge(left=person, right=address, how="left", on="personId")[ - ["firstName", "lastName", "city", "state"] - ] +def second_highest_salary(employee: pd.DataFrame) -> pd.DataFrame: + # Drop any duplicate salary values to avoid counting duplicates as separate salary ranks + unique_salaries = employee["salary"].drop_duplicates() + + # Sort the unique salaries in descending order and get the second highest salary + second_highest = ( + unique_salaries.nlargest(2).iloc[-1] if len(unique_salaries) >= 2 else None + ) + + # If the second highest salary doesn't exist (e.g., there are fewer than two unique salaries), return None + if second_highest is None: + return pd.DataFrame({"SecondHighestSalary": [None]}) + + # Create a DataFrame with the second highest salary + result_df = pd.DataFrame({"SecondHighestSalary": [second_highest]}) + + return result_df From 03984255c7c863a026d3f423dc19436cd332dbb0 Mon Sep 17 00:00:00 2001 From: nrhitik Date: Fri, 20 Oct 2023 16:50:25 +0000 Subject: [PATCH 15/19] style: format code and docs with prettier --- solution/0100-0199/0175.Combine Two Tables/README.md | 1 - solution/0100-0199/0176.Second Highest Salary/README.md | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/solution/0100-0199/0175.Combine Two Tables/README.md b/solution/0100-0199/0175.Combine Two Tables/README.md index 8359efafd2ec9..6330f7c78f8f0 100644 --- a/solution/0100-0199/0175.Combine Two Tables/README.md +++ b/solution/0100-0199/0175.Combine Two Tables/README.md @@ -107,5 +107,4 @@ def combine_two_tables(person: pd.DataFrame, address: pd.DataFrame) -> pd.DataFr ``` - diff --git a/solution/0100-0199/0176.Second Highest Salary/README.md b/solution/0100-0199/0176.Second Highest Salary/README.md index 04cdfeb3ee3aa..575055bc6a533 100644 --- a/solution/0100-0199/0176.Second Highest Salary/README.md +++ b/solution/0100-0199/0176.Second Highest Salary/README.md @@ -136,4 +136,5 @@ def second_highest_salary(employee: pd.DataFrame) -> pd.DataFrame: return result_df ``` + From bc885bf07bf2dfaafda6ffc150030f57639875d5 Mon Sep 17 00:00:00 2001 From: Rhitik Date: Sat, 21 Oct 2023 20:40:41 +0530 Subject: [PATCH 16/19] Solution for 177. --- .../0100-0199/0177.Nth Highest Salary/README.md | 14 ++++++++++++++ .../0100-0199/0177.Nth Highest Salary/README_EN.md | 14 ++++++++++++++ .../0100-0199/0177.Nth Highest Salary/Solution.py | 10 ++++++++++ 3 files changed, 38 insertions(+) create mode 100644 solution/0100-0199/0177.Nth Highest Salary/Solution.py diff --git a/solution/0100-0199/0177.Nth Highest Salary/README.md b/solution/0100-0199/0177.Nth Highest Salary/README.md index d9776ffff2d18..10d32136eacdf 100644 --- a/solution/0100-0199/0177.Nth Highest Salary/README.md +++ b/solution/0100-0199/0177.Nth Highest Salary/README.md @@ -94,4 +94,18 @@ BEGIN END ``` +```python +import pandas as pd + + +def nth_highest_salary(employee: pd.DataFrame, N: int) -> pd.DataFrame: + unique_salaries = employee.salary.unique() + if len(unique_salaries) < N: + return pd.DataFrame([np.NaN], columns=[f"getNthHighestSalary({N})"]) + else: + salary = sorted(unique_salaries, reverse=True)[N - 1] + return pd.DataFrame([salary], columns=[f"getNthHighestSalary({N})"]) + +``` + diff --git a/solution/0100-0199/0177.Nth Highest Salary/README_EN.md b/solution/0100-0199/0177.Nth Highest Salary/README_EN.md index f404199ede26b..aa7620135200d 100644 --- a/solution/0100-0199/0177.Nth Highest Salary/README_EN.md +++ b/solution/0100-0199/0177.Nth Highest Salary/README_EN.md @@ -86,4 +86,18 @@ BEGIN END ``` +```python +import pandas as pd + + +def nth_highest_salary(employee: pd.DataFrame, N: int) -> pd.DataFrame: + unique_salaries = employee.salary.unique() + if len(unique_salaries) < N: + return pd.DataFrame([np.NaN], columns=[f"getNthHighestSalary({N})"]) + else: + salary = sorted(unique_salaries, reverse=True)[N - 1] + return pd.DataFrame([salary], columns=[f"getNthHighestSalary({N})"]) + +``` + diff --git a/solution/0100-0199/0177.Nth Highest Salary/Solution.py b/solution/0100-0199/0177.Nth Highest Salary/Solution.py new file mode 100644 index 0000000000000..243d9cf95a300 --- /dev/null +++ b/solution/0100-0199/0177.Nth Highest Salary/Solution.py @@ -0,0 +1,10 @@ +import pandas as pd + + +def nth_highest_salary(employee: pd.DataFrame, N: int) -> pd.DataFrame: + unique_salaries = employee.salary.unique() + if len(unique_salaries) < N: + return pd.DataFrame([np.NaN], columns=[f"getNthHighestSalary({N})"]) + else: + salary = sorted(unique_salaries, reverse=True)[N - 1] + return pd.DataFrame([salary], columns=[f"getNthHighestSalary({N})"]) From ae345dd7d55ab4667d5f0f5e58b9163cd167ff68 Mon Sep 17 00:00:00 2001 From: Rhitik Date: Sat, 21 Oct 2023 20:45:12 +0530 Subject: [PATCH 17/19] Solution for 178. --- solution/0100-0199/0178.Rank Scores/README.md | 15 +++++++++++++++ solution/0100-0199/0178.Rank Scores/README_EN.md | 15 +++++++++++++++ solution/0100-0199/0178.Rank Scores/Solution.py | 11 +++++++++++ 3 files changed, 41 insertions(+) create mode 100644 solution/0100-0199/0178.Rank Scores/Solution.py diff --git a/solution/0100-0199/0178.Rank Scores/README.md b/solution/0100-0199/0178.Rank Scores/README.md index 354e40d4b0530..e66598d93bb16 100644 --- a/solution/0100-0199/0178.Rank Scores/README.md +++ b/solution/0100-0199/0178.Rank Scores/README.md @@ -122,4 +122,19 @@ FROM ) s; ``` +```python +import pandas as pd + + +def order_scores(scores: pd.DataFrame) -> pd.DataFrame: + # Use the rank method to assign ranks to the scores in descending order with no gaps + scores["rank"] = scores["score"].rank(method="dense", ascending=False) + + # Drop id column & Sort the DataFrame by score in descending order + result_df = scores.drop("id", axis=1).sort_values(by="score", ascending=False) + + return result_df + +``` + diff --git a/solution/0100-0199/0178.Rank Scores/README_EN.md b/solution/0100-0199/0178.Rank Scores/README_EN.md index 988e3c12c2f02..91e79b5f5cc5e 100644 --- a/solution/0100-0199/0178.Rank Scores/README_EN.md +++ b/solution/0100-0199/0178.Rank Scores/README_EN.md @@ -113,4 +113,19 @@ FROM ) s; ``` +```python +import pandas as pd + + +def order_scores(scores: pd.DataFrame) -> pd.DataFrame: + # Use the rank method to assign ranks to the scores in descending order with no gaps + scores["rank"] = scores["score"].rank(method="dense", ascending=False) + + # Drop id column & Sort the DataFrame by score in descending order + result_df = scores.drop("id", axis=1).sort_values(by="score", ascending=False) + + return result_df + +``` + diff --git a/solution/0100-0199/0178.Rank Scores/Solution.py b/solution/0100-0199/0178.Rank Scores/Solution.py new file mode 100644 index 0000000000000..a9f397d798f8b --- /dev/null +++ b/solution/0100-0199/0178.Rank Scores/Solution.py @@ -0,0 +1,11 @@ +import pandas as pd + + +def order_scores(scores: pd.DataFrame) -> pd.DataFrame: + # Use the rank method to assign ranks to the scores in descending order with no gaps + scores["rank"] = scores["score"].rank(method="dense", ascending=False) + + # Drop id column & Sort the DataFrame by score in descending order + result_df = scores.drop("id", axis=1).sort_values(by="score", ascending=False) + + return result_df From 8fd676e30a9bd68b616f8e29c8049fa7e7b75b60 Mon Sep 17 00:00:00 2001 From: Rhitik Date: Sun, 22 Oct 2023 14:18:47 +0530 Subject: [PATCH 18/19] Solution for 180. --- .../0180.Consecutive Numbers/README.md | 17 +++++++++++++++++ .../0180.Consecutive Numbers/README_EN.md | 17 +++++++++++++++++ .../0180.Consecutive Numbers/Solution.py | 13 +++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 solution/0100-0199/0180.Consecutive Numbers/Solution.py diff --git a/solution/0100-0199/0180.Consecutive Numbers/README.md b/solution/0100-0199/0180.Consecutive Numbers/README.md index eec43a99ba503..f1ea2771a7b55 100644 --- a/solution/0100-0199/0180.Consecutive Numbers/README.md +++ b/solution/0100-0199/0180.Consecutive Numbers/README.md @@ -116,4 +116,21 @@ GROUP BY p HAVING COUNT(1) >= 3; ``` +```python +import pandas as pd + + +def consecutive_numbers(logs: pd.DataFrame) -> pd.DataFrame: + all_the_same = lambda lst: lst.nunique() == 1 + logs["is_consecutive"] = ( + logs["num"].rolling(window=3, center=True, min_periods=3).apply(all_the_same) + ) + return ( + logs.query("is_consecutive == 1.0")[["num"]] + .drop_duplicates() + .rename(columns={"num": "ConsecutiveNums"}) + ) + +``` + diff --git a/solution/0100-0199/0180.Consecutive Numbers/README_EN.md b/solution/0100-0199/0180.Consecutive Numbers/README_EN.md index 9825ed57bba6c..86e3c7daf945c 100644 --- a/solution/0100-0199/0180.Consecutive Numbers/README_EN.md +++ b/solution/0100-0199/0180.Consecutive Numbers/README_EN.md @@ -112,4 +112,21 @@ GROUP BY p HAVING COUNT(1) >= 3; ``` +```python +import pandas as pd + + +def consecutive_numbers(logs: pd.DataFrame) -> pd.DataFrame: + all_the_same = lambda lst: lst.nunique() == 1 + logs["is_consecutive"] = ( + logs["num"].rolling(window=3, center=True, min_periods=3).apply(all_the_same) + ) + return ( + logs.query("is_consecutive == 1.0")[["num"]] + .drop_duplicates() + .rename(columns={"num": "ConsecutiveNums"}) + ) + +``` + diff --git a/solution/0100-0199/0180.Consecutive Numbers/Solution.py b/solution/0100-0199/0180.Consecutive Numbers/Solution.py new file mode 100644 index 0000000000000..54fda91e5a8c7 --- /dev/null +++ b/solution/0100-0199/0180.Consecutive Numbers/Solution.py @@ -0,0 +1,13 @@ +import pandas as pd + + +def consecutive_numbers(logs: pd.DataFrame) -> pd.DataFrame: + all_the_same = lambda lst: lst.nunique() == 1 + logs["is_consecutive"] = ( + logs["num"].rolling(window=3, center=True, min_periods=3).apply(all_the_same) + ) + return ( + logs.query("is_consecutive == 1.0")[["num"]] + .drop_duplicates() + .rename(columns={"num": "ConsecutiveNums"}) + ) From 7d732e24079a716bb62cc6e3280c76b6a80ab508 Mon Sep 17 00:00:00 2001 From: Rhitik Date: Sun, 22 Oct 2023 20:11:15 +0530 Subject: [PATCH 19/19] Solution for 181. --- .../README.md | 12 ++++++++++++ .../README_EN.md | 12 ++++++++++++ .../Solution.py | 8 ++++++++ 3 files changed, 32 insertions(+) create mode 100644 solution/0100-0199/0181.Employees Earning More Than Their Managers/Solution.py diff --git a/solution/0100-0199/0181.Employees Earning More Than Their Managers/README.md b/solution/0100-0199/0181.Employees Earning More Than Their Managers/README.md index d17397fb31abb..282a9d4b8413f 100644 --- a/solution/0100-0199/0181.Employees Earning More Than Their Managers/README.md +++ b/solution/0100-0199/0181.Employees Earning More Than Their Managers/README.md @@ -81,4 +81,16 @@ FROM WHERE e1.salary > e2.salary; ``` +```python +import pandas as pd + + +def find_employees(employee: pd.DataFrame) -> pd.DataFrame: + df = employee.merge(right=employee, how="left", left_on="managerId", right_on="id") + emp = df[df["salary_x"] > df["salary_y"]]["name_x"] + + return pd.DataFrame({"Employee": emp}) + +``` + diff --git a/solution/0100-0199/0181.Employees Earning More Than Their Managers/README_EN.md b/solution/0100-0199/0181.Employees Earning More Than Their Managers/README_EN.md index 57e0e070d13ab..8cd49e900a806 100644 --- a/solution/0100-0199/0181.Employees Earning More Than Their Managers/README_EN.md +++ b/solution/0100-0199/0181.Employees Earning More Than Their Managers/README_EN.md @@ -77,4 +77,16 @@ FROM WHERE e1.salary > e2.salary; ``` +```python +import pandas as pd + + +def find_employees(employee: pd.DataFrame) -> pd.DataFrame: + df = employee.merge(right=employee, how="left", left_on="managerId", right_on="id") + emp = df[df["salary_x"] > df["salary_y"]]["name_x"] + + return pd.DataFrame({"Employee": emp}) + +``` + diff --git a/solution/0100-0199/0181.Employees Earning More Than Their Managers/Solution.py b/solution/0100-0199/0181.Employees Earning More Than Their Managers/Solution.py new file mode 100644 index 0000000000000..2084f018ba6ad --- /dev/null +++ b/solution/0100-0199/0181.Employees Earning More Than Their Managers/Solution.py @@ -0,0 +1,8 @@ +import pandas as pd + + +def find_employees(employee: pd.DataFrame) -> pd.DataFrame: + df = employee.merge(right=employee, how="left", left_on="managerId", right_on="id") + emp = df[df["salary_x"] > df["salary_y"]]["name_x"] + + return pd.DataFrame({"Employee": emp})