Compare commits

..

10 Commits

Author SHA1 Message Date
3f5146d5a8 Added leetcode exercise 36 2022-09-03 15:59:16 +02:00
fb0684dd27 Fixed import and formatting of leetcode 17 2022-09-03 15:59:02 +02:00
5e3a66aa45 Added typing.List import to leetcode template 2022-09-03 15:56:19 +02:00
749f7846a5 Added leetcode exercise 17 2022-09-03 15:27:32 +02:00
cf785e707d Added README.md 2022-08-31 19:02:09 +00:00
cc6a5e28b3 Added leetcode 695 2022-08-31 19:08:05 +02:00
38bf6a3084 Added leetcode 383 and 733 2022-08-31 17:50:53 +02:00
64cb9ea7ae Fixed exercise 81 and added 74 2022-08-31 12:32:24 +02:00
65e8af6bb7 Added small cli for templating leetcode exercises 2022-08-31 12:28:56 +02:00
2f32bdc7b9 Add 2 more exercises 2022-08-31 12:00:11 +02:00
12 changed files with 327 additions and 0 deletions

3
README.md Normal file
View File

@ -0,0 +1,3 @@
# algo-grind
Sometimes I'm too lazy to add the exercises to this repo. In that case you can take a look at my [LeetCode profile](https://leetcode.com/strNophix/).

41
cli.py Normal file
View File

@ -0,0 +1,41 @@
import click
import jinja2
from os import path
class LeetCode:
@staticmethod
def filename_from_url(url: str) -> str:
num = input("Number: ")
name = url.split("/")[4].replace("-", "_")
return f"{num}_{name}.py"
@click.group()
@click.option("--template-dir", default="./templates")
@click.pass_context
def cli(ctx: click.Context, template_dir: str):
ctx.obj["template"] = jinja2.Environment(
loader=jinja2.FileSystemLoader(template_dir)
)
@cli.command()
@click.pass_context
@click.argument("url")
def leetcode(ctx: click.Context, url: str):
file_path = path.join("leetcode", LeetCode.filename_from_url(url))
if path.exists(file_path):
print("File already exists")
return 1
templates: jinja2.Environment = ctx.obj["template"]
templ = templates.get_template("leetcode.j2")
result = templ.render()
with open(file_path, mode="w", encoding="utf8") as f:
f.write(result)
if __name__ == "__main__":
cli(obj={})

View File

@ -0,0 +1,24 @@
from typing import List
class Solution:
def letterCombinations(self, digits: str) -> List[str]:
if len(digits) == 0:
return []
options = {
"2": ("a", "b", "c"),
"3": ("d", "e", "f"),
"4": ("g", "h", "i"),
"5": ("j", "k", "l"),
"6": ("m", "n", "o"),
"7": ("p", "q", "r", "s"),
"8": ("t", "u", "v"),
"9": ("w", "x", "y", "z"),
}
pools = (options[digit] for digit in digits)
result = [""]
for pool in pools:
result = [x + y for x in result for y in pool]
return result

View File

@ -0,0 +1,50 @@
from typing import List
import pytest
class Solution:
def isValidSudoku(self, board: List[List[str]]) -> bool:
rows, cols, cubes = set(), set(), set()
for i in range(9):
for j in range(9):
val = board[i][j]
if not val.isdigit():
continue
cube = (i // 3) * 3 + (j // 3)
if (i, val) in rows or (j, val) in cols or (cube, val) in cubes:
return False
rows.add((i, val))
cols.add((j, val))
cubes.add((cube, val))
return True
@pytest.fixture
def solution():
return Solution()
@pytest.mark.parametrize(
"sudoku, expected",
[
(
[
["5", "3", ".", ".", "7", ".", ".", ".", "."],
["6", ".", ".", "1", "9", "5", ".", ".", "."],
[".", "9", "8", ".", ".", ".", ".", "6", "."],
["8", ".", ".", ".", "6", ".", ".", ".", "3"],
["4", ".", ".", "8", ".", "3", ".", ".", "1"],
["7", ".", ".", ".", "2", ".", ".", ".", "6"],
[".", "6", ".", ".", ".", ".", "2", "8", "."],
[".", ".", ".", "4", "1", "9", ".", ".", "5"],
[".", ".", ".", ".", "8", ".", ".", "7", "9"],
],
True,
)
],
)
def test_search(solution: Solution, sudoku: List[List[str]], expected: bool):
assert solution.isValidSudoku(sudoku) == expected

View File

@ -0,0 +1,17 @@
import pytest
from collections import Counter
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
return not Counter(ransomNote) - Counter(magazine)
@pytest.fixture
def solution():
return Solution()
@pytest.mark.parametrize("", [])
def test_search(solution: Solution):
pass

View File

@ -0,0 +1,28 @@
class Solution:
def maxAreaOfIsland(self, grid: list[list[int]]) -> int:
biggest_island = 0
counter = 0
def dfs(row: int, col: int):
nonlocal counter
if not (0 <= row < len(grid)) or not (0 <= col < len(grid[0])):
return
if grid[row][col] != 1:
return
counter += 1
grid[row][col] = 0
dfs(row + 1, col)
dfs(row - 1, col)
dfs(row, col + 1)
dfs(row, col - 1)
for row in range(len(grid)):
for col in range(len(grid[0])):
if grid[row][col] == 1:
dfs(row, col)
biggest_island = max(biggest_island, counter)
counter = 0
return biggest_island

26
leetcode/69_sqrtx.py Normal file
View File

@ -0,0 +1,26 @@
import pytest
class Solution:
def mySqrt(self, x: int) -> int:
left, right = 0, x
while left <= right:
mid = left + (right - left) // 2
val = mid * mid
if val <= x < (mid + 1) * (mid + 1):
return mid
elif x < val:
right = mid - 1
else:
left = mid + 1
return 0
@pytest.fixture
def solution():
return Solution()
@pytest.mark.parametrize("x, expected", [(4, 2), (8, 2)])
def test_my_sqrt(solution: Solution, x: int, expected: int):
assert solution.mySqrt(x) == expected

View File

@ -0,0 +1,44 @@
import pytest
class Solution:
def floodFill(
self, image: list[list[int]], sr: int, sc: int, color: int
) -> list[list[int]]:
orig = image[sr][sc]
def dfs(i: int, j: int):
if (
0 <= i < len(image)
and 0 <= j < len(image[0])
and image[i][j] == orig
and image[i][j] != color
):
image[i][j] = color
dfs(i + 1, j)
dfs(i - 1, j)
dfs(i, j + 1)
dfs(i, j - 1)
dfs(sr, sc)
return image
@pytest.fixture
def solution():
return Solution()
@pytest.mark.parametrize(
"image, sr, sc, color, expected",
[([[1, 1, 1], [1, 1, 0], [1, 0, 1]], 1, 1, 2, [[2, 2, 2], [2, 2, 0], [2, 0, 1]])],
)
def test_search(
solution: Solution,
image: list[list[int]],
sr: int,
sc: int,
color: int,
expected: list[list[int]],
):
assert solution.floodFill(image, sr, sc, color) == expected

View File

@ -0,0 +1,33 @@
import pytest
class Solution:
def searchMatrix(self, matrix: list[list[int]], target: int) -> bool:
rows, cols = len(matrix), len(matrix[0])
left, right = 0, rows * cols - 1
while left <= right:
mid = left + (right - left) // 2
val = matrix[mid // cols][mid % cols]
if val == target:
return True
elif val < target:
left = mid + 1
else:
right = mid - 1
return False
@pytest.fixture
def solution():
return Solution()
@pytest.mark.parametrize(
"matrix, target, expected",
[([[1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 60]], 3, True)],
)
def test_search(
solution: Solution, matrix: list[list[int]], target: int, expected: bool
):
assert solution.searchMatrix(matrix, target) == expected

View File

@ -0,0 +1,43 @@
import pytest
class Solution:
def search(self, nums: list[int], target: int) -> bool:
low, high = 0, len(nums) - 1
while low <= high:
mid = low + (high - low) // 2
if nums[mid] == target:
return True
while low < mid and nums[low] == nums[mid]:
low += 1
if nums[mid] >= nums[low]:
if nums[low] <= target < nums[mid]:
high = mid - 1
else:
low = mid + 1
else:
if nums[mid] < target <= nums[high]:
low = mid + 1
else:
high = mid - 1
return False
@pytest.fixture
def solution():
return Solution()
@pytest.mark.parametrize(
"nums, target, expected",
[
([2, 5, 6, 0, 0, 1, 2], 0, True),
([2, 5, 6, 0, 0, 1, 2], 3, False),
([1, 0, 1, 1, 1], 0, True),
],
)
def test_search(solution: Solution, nums: list[int], target: int, expected: bool):
assert solution.search(nums, target) == expected

View File

@ -1,2 +1,4 @@
pytest
black
click
jinja2

16
templates/leetcode.j2 Normal file
View File

@ -0,0 +1,16 @@
from typing import List
import pytest
class Solution:
pass
@pytest.fixture
def solution():
return Solution()
@pytest.mark.parametrize("", [])
def test_search(solution: Solution):
pass