Skip to content

Commit

Permalink
Pylint refactor (keon#851)
Browse files Browse the repository at this point in the history
* refactor(pylint): unionfind/count_islands.py

improves pylint score from 3.71 to 10.00

fixes KTH-Software-Engineering-DD2480#2

* refactor(pylint): algorithms/search/*.py

improves pylint score from 5.83 to 10.00.

fixes KTH-Software-Engineering-DD2480#7

* feat: improving pylint score

* refactor dp.combination_sum: lint score from 5.42 to 9.13

* refactor(pylint): algorithms/graph/*.py

Improves pylint score from 5.51 to 9.96.

Score is lower than 10 due to duplication between maximum_flow_bfs.py
and maximum_flow_dfs.py. However, due to the educational nature of this
repo, keeping it as is will probably be benefitial as it reduces
complexity while reading (having to jump between files).

fixes KTH-Software-Engineering-DD2480#9

* refactor egg_drop, hosoya_triangle, min_cost_path and planting_trees

* feat: improving pylint score of one_sparse_recovery

* refactor: move tests from regex_matching to tests folder

* refactor: lint score from 4.27 to 9.46

a reason that lint score isn't 10.00 is that the module is called dp,
which in turn makes pylint raise invalid name for all files in dp.
I leave that as it is, since I don't want to mess with the current folder structure.

fixes keon#3

* Fix: Fixed lint error, lint value now aboe 8

* refactor: add docstring to misra, score 10

* fix (misra): add a newline

* refactor: add docstring for one_sparse, score 9.33

* wip: refactor (pylint): algorithms/maths/
wip: keon#4

* Fix: pylint is above 8 for tree

* refactor (pylint): algorithms/maths/
Finished improving pylint score for maths folder.
fixes: keon#4

* Fixed: comments

* fix: small intendation fix

Co-authored-by: ekorre1001 <[email protected]>
Co-authored-by: Philip Salqvist <[email protected]>
Co-authored-by: psalqvist <[email protected]>
Co-authored-by: Kubha99 <[email protected]>
Co-authored-by: mantaur <[email protected]>
  • Loading branch information
6 people authored Mar 7, 2022
1 parent 15e5292 commit 3259a07
Show file tree
Hide file tree
Showing 102 changed files with 2,235 additions and 1,735 deletions.
2 changes: 1 addition & 1 deletion algorithms/dp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
from .word_break import *
from .int_divide import *
from .k_factor import *
from .planting_trees import *
from .planting_trees import *
24 changes: 14 additions & 10 deletions algorithms/dp/climbing_stairs.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,36 @@
"""
You are climbing a stair case.
It takes n steps to reach to the top.
It takes `steps` number of steps to reach to the top.
Each time you can either climb 1 or 2 steps.
In how many distinct ways can you climb to the top?
Note: Given n will be a positive integer.
Note: Given argument `steps` will be a positive integer.
"""


# O(n) space

def climb_stairs(n):
def climb_stairs(steps):
"""
:type n: int
:type steps: int
:rtype: int
"""
arr = [1, 1]
for _ in range(1, n):
for _ in range(1, steps):
arr.append(arr[-1] + arr[-2])
return arr[-1]


# the above function can be optimized as:
# O(1) space

def climb_stairs_optimized(n):
a = b = 1
for _ in range(n):
a, b = b, a + b
return a
def climb_stairs_optimized(steps):
"""
:type steps: int
:rtype: int
"""
a_steps = b_steps = 1
for _ in range(steps):
a_steps, b_steps = b_steps, a_steps + b_steps
return a_steps
31 changes: 17 additions & 14 deletions algorithms/dp/coin_change.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
"""
Problem
Given a value n, if we want to make change for N cents,
and we have infinite supply of each of
coins = {S1, S2, .. , Sm} valued coins, how many ways
can we make the change?
The order of coins doesn't matter.
For example, for n = 4 and coins = [1, 2, 3], there are
four solutions:
Given a value `value`, if we want to make change for `value` cents, and we have infinite
supply of each of coins = {S1, S2, .. , Sm} valued `coins`, how many ways can we make the change?
The order of `coins` doesn't matter.
For example, for `value` = 4 and `coins` = [1, 2, 3], there are four solutions:
[1, 1, 1, 1], [1, 1, 2], [2, 2], [1, 3].
So output should be 4.
For n = 10 and coins = [2, 5, 3, 6], there are five solutions:
For `value` = 10 and `coins` = [2, 5, 3, 6], there are five solutions:
[2, 2, 2, 2, 2], [2, 2, 3, 3], [2, 2, 6], [2, 3, 5] and [5, 5].
So the output should be 5.
Time complexity: O(n * m) where n is the value and m is the number of coins
Time complexity: O(n * m) where n is the `value` and m is the number of `coins`
Space complexity: O(n)
"""

def count(coins, value):
""" Find number of combination of `coins` that adds upp to `value`
def count(coins, n):
Keyword arguments:
coins -- int[]
value -- int
"""
# initialize dp array and set base case as 1
dp = [1] + [0] * n
dp_array = [1] + [0] * value

# fill dp in a bottom up manner
for coin in coins:
for i in range(coin, n+1):
dp[i] += dp[i-coin]
for i in range(coin, value+1):
dp_array[i] += dp_array[i-coin]

return dp[n]
return dp_array[value]
56 changes: 35 additions & 21 deletions algorithms/dp/combination_sum.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,48 @@
"""

dp = None

DP = None

def helper_topdown(nums, target):
global dp
if dp[target] != -1:
return dp[target]
"""Generates DP and finds result.
Keyword arguments:
nums -- positive integer array without duplicates
target -- integer describing what a valid combination should add to
"""
if DP[target] != -1:
return DP[target]
res = 0
for i in range(0, len(nums)):
if target >= nums[i]:
res += helper_topdown(nums, target - nums[i])
dp[target] = res
for num in nums:
if target >= num:
res += helper_topdown(nums, target - num)
DP[target] = res
return res


def combination_sum_topdown(nums, target):
global dp
dp = [-1] * (target + 1)
dp[0] = 1
return helper_topdown(nums, target)
"""Find number of possible combinations in nums that add up to target, in top-down manner.
Keyword arguments:
nums -- positive integer array without duplicates
target -- integer describing what a valid combination should add to
"""
global DP
DP = [-1] * (target + 1)
DP[0] = 1
return helper_topdown(nums, target)

# EDIT: The above solution is top-down. How about a bottom-up one?
def combination_sum_bottom_up(nums, target):
comb = [0] * (target + 1)
comb[0] = 1
for i in range(0, len(comb)):
for j in range(len(nums)):
if i - nums[j] >= 0:
comb[i] += comb[i - nums[j]]
return comb[target]
"""Find number of possible combinations in nums that add up to target, in bottom-up manner.
Keyword arguments:
nums -- positive integer array without duplicates
target -- integer describing what a valid combination should add to
"""
combs = [0] * (target + 1)
combs[0] = 1
for i in range(0, len(combs)):
for num in nums:
if i - num >= 0:
combs[i] += combs[i - num]
return combs[target]
32 changes: 19 additions & 13 deletions algorithms/dp/edit_distance.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,28 +36,34 @@
indexes i and j, respectively.
To find the edit distance between two words A and B,
we need to find edit(m, n), where m is the length of A and n
is the length of B.
we need to find edit(length_a, length_b).
Time: O(length_a*length_b)
Space: O(length_a*length_b)
"""


def edit_distance(A, B):
# Time: O(m*n)
# Space: O(m*n)
def edit_distance(word_a, word_b):
"""Finds edit distance between word_a and word_b
Kwyword arguments:
word_a -- string
word_b -- string
"""

m, n = len(A) + 1, len(B) + 1
length_a, length_b = len(word_a) + 1, len(word_b) + 1

edit = [[0 for _ in range(n)] for _ in range(m)]
edit = [[0 for _ in range(length_b)] for _ in range(length_a)]

for i in range(1, m):
for i in range(1, length_a):
edit[i][0] = i

for j in range(1, n):
for j in range(1, length_b):
edit[0][j] = j

for i in range(1, m):
for j in range(1, n):
cost = 0 if A[i - 1] == B[j - 1] else 1
for i in range(1, length_a):
for j in range(1, length_b):
cost = 0 if word_a[i - 1] == word_b[j - 1] else 1
edit[i][j] = min(edit[i - 1][j] + 1, edit[i][j - 1] + 1, edit[i - 1][j - 1] + cost)

return edit[-1][-1] # this is the same as edit[m][n]
return edit[-1][-1] # this is the same as edit[length_a][length_b]
7 changes: 6 additions & 1 deletion algorithms/dp/egg_drop.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,14 @@


def egg_drop(n, k):
"""
Keyword arguments:
n -- number of floors
k -- number of eggs
"""
# A 2D table where entery eggFloor[i][j] will represent minimum
# number of trials needed for i eggs and j floors.
egg_floor = [[0 for x in range(k+1)] for x in range(n + 1)]
egg_floor = [[0 for _ in range(k + 1)] for _ in range(n + 1)]

# We need one trial for one floor and 0 trials for 0 floors
for i in range(1, n+1):
Expand Down
11 changes: 5 additions & 6 deletions algorithms/dp/fib.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ def fib_recursive(n):

if n <= 1:
return n
else:
return fib_recursive(n-1) + fib_recursive(n-2)
return fib_recursive(n-1) + fib_recursive(n-2)

# print(fib_recursive(35)) # => 9227465 (slow)

Expand Down Expand Up @@ -81,13 +80,13 @@ def fib_iter(n):

fib_1 = 0
fib_2 = 1
sum = 0
res = 0
if n <= 1:
return n
for _ in range(n-1):
sum = fib_1 + fib_2
res = fib_1 + fib_2
fib_1 = fib_2
fib_2 = sum
return sum
fib_2 = res
return res

# print(fib_iter(100)) # => 354224848179261915075
49 changes: 29 additions & 20 deletions algorithms/dp/hosoya_triangle.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,38 @@
"""

def hosoya(height, width):
""" Calculates the hosoya triangle
def hosoya(n, m):
if ((n == 0 and m == 0) or (n == 1 and m == 0) or
(n == 1 and m == 1) or (n == 2 and m == 1)):
height -- height of the triangle
"""
if (width == 0) and (height in (0,1)):
return 1
if n > m:
return hosoya(n - 1, m) + hosoya(n - 2, m)
elif m == n:
return hosoya(n - 1, m - 1) + hosoya(n - 2, m - 2)
else:
return 0


def print_hosoya(n):
for i in range(n):
if (width == 1) and (height in (1,2)):
return 1
if height > width:
return hosoya(height - 1, width) + hosoya(height - 2, width)
if width == height:
return hosoya(height - 1, width - 1) + hosoya(height - 2, width - 2)
return 0

def print_hosoya(height):
"""Prints the hosoya triangle
height -- height of the triangle
"""
for i in range(height):
for j in range(i + 1):
print(hosoya(i, j), end=" ")
print("\n", end="")
print(hosoya(i, j) , end = " ")
print ("\n", end = "")

def hosoya_testing(height):
"""Test hosoya function
def hosoya_testing(n):
x = []
for i in range(n):
height -- height of the triangle
"""
res = []
for i in range(height):
for j in range(i + 1):
x.append(hosoya(i, j))
return x
res.append(hosoya(i, j))
return res
17 changes: 11 additions & 6 deletions algorithms/dp/int_divide.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""
Given positive integer n, find an algorithm to find the number of non-negative number division, or descomposition.
Given positive integer decompose, find an algorithm to find the number of
non-negative number division, or decomposition.
The complexity is O(n^2).
Expand Down Expand Up @@ -36,15 +37,19 @@
"""


def int_divide(n):
arr = [[0 for i in range(n + 1)] for j in range(n + 1)]
def int_divide(decompose):
"""Find number of decompositions from `decompose`
decompose -- integer
"""
arr = [[0 for i in range(decompose + 1)] for j in range(decompose + 1)]
arr[1][1] = 1
for i in range(1, n + 1):
for j in range(1, n + 1):
for i in range(1, decompose + 1):
for j in range(1, decompose + 1):
if i < j:
arr[i][j] = arr[i][i]
elif i == j:
arr[i][j] = 1 + arr[i][j - 1]
else:
arr[i][j] = arr[i][j - 1] + arr[i - j][j]
return arr[n][n]
return arr[decompose][decompose]
Loading

0 comments on commit 3259a07

Please sign in to comment.