Skip to content

Commit

Permalink
feat(python): add leet code 140, 2109
Browse files Browse the repository at this point in the history
  • Loading branch information
jerodg committed Dec 3, 2024
1 parent 600f16b commit aab5177
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 111 deletions.
64 changes: 64 additions & 0 deletions check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#!/bin/bash

# Find all directories containing "leet_code" folder
roots=()
for dir in */; do
if [ -d "${dir}leet_code" ]; then
roots+=("${dir%/}")
fi
done

if [ ${#roots[@]} -eq 0 ]; then
echo "No directories containing 'leet_code' folder found."
exit 1
fi

# Create associative array to store all unique numeric filenames
declare -A all_files
# Create associative array to track which roots are missing which files
declare -A missing_files

# First pass: collect all numeric filenames
for root in "${roots[@]}"; do
while IFS= read -r file; do
# Extract basename without extension
base=$(basename "$file")
filename="${base%.*}"
# Check if filename contains only digits
if [[ $filename =~ ^[0-9]+$ ]]; then
all_files[$filename]=1
fi
done < <(find "${root}/leet_code" -type f 2>/dev/null)
done

# Second pass: check which files are missing from each root
for filename in "${!all_files[@]}"; do
missing=""
for root in "${roots[@]}"; do
# Check if any file with this numeric base exists (regardless of extension)
if ! ls "${root}/leet_code/${filename}".* >/dev/null 2>&1; then
if [ -z "$missing" ]; then
missing="$root"
else
missing="$missing, $root"
fi
fi
done
if [ ! -z "$missing" ]; then
missing_files[$filename]="$missing"
fi
done

# Output results
if [ ${#missing_files[@]} -eq 0 ]; then
echo "All roots contain the same numeric files."
else
echo "Missing files by root:"
echo "----------------------"
# Sort the filenames numerically
while IFS= read -r filename; do
if [ -n "${missing_files[$filename]}" ]; then
echo "File $filename missing from: ${missing_files[$filename]}"
fi
done < <(printf "%s\n" "${!missing_files[@]}" | sort -n)
fi
5 changes: 5 additions & 0 deletions python/.idea/codeStyles/codeStyleConfig.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion python/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion python/.idea/python.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions python/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13
92 changes: 92 additions & 0 deletions python/leet_code/140.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
"""Copyright ©2010-2024 <a href="https://github.com/jerodg/">JerodG</a>.
This program is free software: you can redistribute it and/or modify it under the terms of the
Server Side Public License (SSPL) as published by MongoDB, Inc., either version 1 of the License,
or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the SSPL
for more details.
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software. You should have received a copy of the SSPL along with this
program. If not, see SSPL.
"""
import copy


class TrieNode:
"""A node in the Trie data structure used to store words."""

def __init__(self):
"""Initializes a TrieNode with an empty dictionary for children and a boolean to mark the end of a word."""
self.children = {}
self.word = False

def add_word(self, word: str) -> None:
"""
Adds a word to the Trie.
Args:
word (str): The word to be added to the Trie.
"""
cur = self
for c in word:
if c not in cur.children:
cur.children[c] = TrieNode()
cur = cur.children[c]
cur.word = True


class Solution:
"""A class to solve the problem of word segmentation using a Trie and depth-first search."""

def wordBreak(self, s: str, word_dict: list[str]) -> list[str]:
"""
Finds all possible sentences that can be formed by segmenting the string `s` using words from `word_dict`.
Args:
s (str): The input string to be segmented.
word_dict (list[str]): A list of valid words for segmentation.
Returns:
list[str]: A list of all possible sentences formed by valid segmentations.
"""
root = TrieNode()
for w in word_dict:
root.add_word(w)

res = []

def dfs(i: int, node: TrieNode, word: str, a: list[str], flag: bool = False) -> None:
"""
Performs depth-first search to find all valid segmentations.
Args:
i (int): The current index in the string `s`.
node (TrieNode): The current node in the Trie.
word (str): The current word being formed.
a (list[str]): The current list of words formed so far.
flag (bool): A flag indicating if a valid word has been formed.
"""
if i == len(s):
if flag:
res.append(" ".join(a))
return

if s[i] not in node.children:
return

word += s[i]
node = node.children[s[i]]

if node.word:
a1 = copy.copy(a)
a1.append(word)
dfs(i + 1, root, '', a1, flag=True)

dfs(i + 1, node, word, a)

dfs(0, root, '', [])

return res
43 changes: 43 additions & 0 deletions python/leet_code/2109.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""Copyright ©2010-2024 <a href="https://github.com/jerodg/">JerodG</a>.
This program is free software: you can redistribute it and/or modify it under the terms of the
Server Side Public License (SSPL) as published by MongoDB, Inc., either version 1 of the License,
or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the SSPL
for more details.
The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software. You should have received a copy of the SSPL along with this
program. If not, see SSPL.
"""


class Solution:
"""A class to solve the problem of adding spaces at specified positions in a string."""

def addSpaces(self, s: str, spaces: List[int]) -> str:
"""
Inserts spaces into the string `s` at the positions specified in the list `spaces`.
Args:
s (str): The input string where spaces need to be added.
spaces (List[int]): A list of indices where spaces should be inserted.
Returns:
str: The modified string with spaces inserted at the specified positions.
"""
index, result = 0, []

for space in spaces:
# Append the substring from the current index to the space index
result.append(s[index: space])
# Update the index to the current space position
index = space

# Append the remaining part of the string after the last space
result.append(s[index:])

# Join all parts with a space and return the final string
return ' '.join(result)
113 changes: 8 additions & 105 deletions python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,109 +1,12 @@
[project]
name = "python-code-challenges"
version = "0.4.0"
description = "Code Challenges"
name = "python"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
license-files = { paths = ["../LICENSE.adoc"] }
requires-python = ">= 3.12"
authors = [{ name = "JerodG", email = "[email protected]" }]
dependencies = [
]


[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"


[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.0.2",
"pytest-benchmark>=4.0.0",
"pytest-cov>=4.1.0",
]


[[tool.rye.sources]]
name = "default"
url = "https://pypi.org/simple/"


[tool.hatch.metadata]
allow-direct-references = true
requires-python = ">=3.13"
dependencies = []


[tool.hatch.build.targets.wheel]
packages = ["code_wars/", "hackerrank/", "leetcode/"]


[tool.ruff]
# Exclude a variety of commonly ignored directories.
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".ipynb_checkpoints",
".mypy_cache",
".nox",
".pants.d",
".pyenv",
".pytest_cache",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
".vscode",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"node_modules",
"site-packages",
"venv",
".idea",
".venv"
[dependency-groups]
dev = [
"ruff>=0.8.1",
]

line-length = 120
fix = true
indent-width = 4
target-version = "py312"
include = ["*.py"]
respect-gitignore = true



[tool.ruff.lint]
# Enable Pyflakes (`F`) and a subset of the pycodestyle (`E`) codes by default.
# Unlike Flake8, Ruff doesn't enable pycodestyle warnings (`W`) or
# McCabe complexity (`C901`) by default.
select = ["E4", "E7", "E9", "F", "W", "C901", "C"]
ignore = []
preview = true
task-tags = ["TODO", "FIXME"]
# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
unfixable = []
# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[tool.ruff.format]
quote-style = "single"
indent-style = "space"
skip-magic-trailing-comma = true
line-ending = "lf"
docstring-code-format = true
docstring-code-line-length = 100


[tool.pytest.ini_options]
minversion = "6.0"
addopts = "-ra -q"
testpaths = ["tests"]
markers = ["random: marks tests as random (deselect with '-m \"not random\"')"]
43 changes: 39 additions & 4 deletions python/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit aab5177

Please sign in to comment.