mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-02-25 10:28:39 +00:00
Compare commits
10 Commits
0594f33fd5
...
a1acf503d6
Author | SHA1 | Date | |
---|---|---|---|
|
a1acf503d6 | ||
|
a03b739d23 | ||
|
9e08c7726d | ||
|
f7531d9874 | ||
|
93fb169627 | ||
|
5aefc00f0f | ||
|
f614ed7217 | ||
|
44b1bcc7c7 | ||
|
a0eec90466 | ||
|
c9ee6ed188 |
@ -16,12 +16,12 @@ repos:
|
|||||||
- id: auto-walrus
|
- id: auto-walrus
|
||||||
|
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
rev: v0.0.275
|
rev: v0.0.280
|
||||||
hooks:
|
hooks:
|
||||||
- id: ruff
|
- id: ruff
|
||||||
|
|
||||||
- repo: https://github.com/psf/black
|
- repo: https://github.com/psf/black
|
||||||
rev: 23.3.0
|
rev: 23.7.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: black
|
- id: black
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ repos:
|
|||||||
- tomli
|
- tomli
|
||||||
|
|
||||||
- repo: https://github.com/tox-dev/pyproject-fmt
|
- repo: https://github.com/tox-dev/pyproject-fmt
|
||||||
rev: "0.12.1"
|
rev: "0.13.0"
|
||||||
hooks:
|
hooks:
|
||||||
- id: pyproject-fmt
|
- id: pyproject-fmt
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ We appreciate any contribution, from fixing a grammar mistake in a comment to im
|
|||||||
|
|
||||||
Your contribution will be tested by our [automated testing on GitHub Actions](https://github.com/TheAlgorithms/Python/actions) to save time and mental energy. After you have submitted your pull request, you should see the GitHub Actions tests start to run at the bottom of your submission page. If those tests fail, then click on the ___details___ button try to read through the GitHub Actions output to understand the failure. If you do not understand, please leave a comment on your submission page and a community member will try to help.
|
Your contribution will be tested by our [automated testing on GitHub Actions](https://github.com/TheAlgorithms/Python/actions) to save time and mental energy. After you have submitted your pull request, you should see the GitHub Actions tests start to run at the bottom of your submission page. If those tests fail, then click on the ___details___ button try to read through the GitHub Actions output to understand the failure. If you do not understand, please leave a comment on your submission page and a community member will try to help.
|
||||||
|
|
||||||
|
If you are interested in resolving an [open issue](https://github.com/TheAlgorithms/Python/issues), simply make a pull request with your proposed fix. __We do not assign issues in this repo__ so please do not ask for permission to work on an issue.
|
||||||
|
|
||||||
Please help us keep our issue list small by adding `Fixes #{$ISSUE_NUMBER}` to the description of pull requests that resolve open issues.
|
Please help us keep our issue list small by adding `Fixes #{$ISSUE_NUMBER}` to the description of pull requests that resolve open issues.
|
||||||
For example, if your pull request fixes issue #10, then please add the following to its description:
|
For example, if your pull request fixes issue #10, then please add the following to its description:
|
||||||
```
|
```
|
||||||
|
@ -293,7 +293,7 @@
|
|||||||
* [Inversions](divide_and_conquer/inversions.py)
|
* [Inversions](divide_and_conquer/inversions.py)
|
||||||
* [Kth Order Statistic](divide_and_conquer/kth_order_statistic.py)
|
* [Kth Order Statistic](divide_and_conquer/kth_order_statistic.py)
|
||||||
* [Max Difference Pair](divide_and_conquer/max_difference_pair.py)
|
* [Max Difference Pair](divide_and_conquer/max_difference_pair.py)
|
||||||
* [Max Subarray Sum](divide_and_conquer/max_subarray_sum.py)
|
* [Max Subarray](divide_and_conquer/max_subarray.py)
|
||||||
* [Mergesort](divide_and_conquer/mergesort.py)
|
* [Mergesort](divide_and_conquer/mergesort.py)
|
||||||
* [Peak](divide_and_conquer/peak.py)
|
* [Peak](divide_and_conquer/peak.py)
|
||||||
* [Power](divide_and_conquer/power.py)
|
* [Power](divide_and_conquer/power.py)
|
||||||
@ -324,8 +324,7 @@
|
|||||||
* [Matrix Chain Order](dynamic_programming/matrix_chain_order.py)
|
* [Matrix Chain Order](dynamic_programming/matrix_chain_order.py)
|
||||||
* [Max Non Adjacent Sum](dynamic_programming/max_non_adjacent_sum.py)
|
* [Max Non Adjacent Sum](dynamic_programming/max_non_adjacent_sum.py)
|
||||||
* [Max Product Subarray](dynamic_programming/max_product_subarray.py)
|
* [Max Product Subarray](dynamic_programming/max_product_subarray.py)
|
||||||
* [Max Sub Array](dynamic_programming/max_sub_array.py)
|
* [Max Subarray Sum](dynamic_programming/max_subarray_sum.py)
|
||||||
* [Max Sum Contiguous Subsequence](dynamic_programming/max_sum_contiguous_subsequence.py)
|
|
||||||
* [Min Distance Up Bottom](dynamic_programming/min_distance_up_bottom.py)
|
* [Min Distance Up Bottom](dynamic_programming/min_distance_up_bottom.py)
|
||||||
* [Minimum Coin Change](dynamic_programming/minimum_coin_change.py)
|
* [Minimum Coin Change](dynamic_programming/minimum_coin_change.py)
|
||||||
* [Minimum Cost Path](dynamic_programming/minimum_cost_path.py)
|
* [Minimum Cost Path](dynamic_programming/minimum_cost_path.py)
|
||||||
@ -591,12 +590,10 @@
|
|||||||
* [Is Square Free](maths/is_square_free.py)
|
* [Is Square Free](maths/is_square_free.py)
|
||||||
* [Jaccard Similarity](maths/jaccard_similarity.py)
|
* [Jaccard Similarity](maths/jaccard_similarity.py)
|
||||||
* [Juggler Sequence](maths/juggler_sequence.py)
|
* [Juggler Sequence](maths/juggler_sequence.py)
|
||||||
* [Kadanes](maths/kadanes.py)
|
|
||||||
* [Karatsuba](maths/karatsuba.py)
|
* [Karatsuba](maths/karatsuba.py)
|
||||||
* [Krishnamurthy Number](maths/krishnamurthy_number.py)
|
* [Krishnamurthy Number](maths/krishnamurthy_number.py)
|
||||||
* [Kth Lexicographic Permutation](maths/kth_lexicographic_permutation.py)
|
* [Kth Lexicographic Permutation](maths/kth_lexicographic_permutation.py)
|
||||||
* [Largest Of Very Large Numbers](maths/largest_of_very_large_numbers.py)
|
* [Largest Of Very Large Numbers](maths/largest_of_very_large_numbers.py)
|
||||||
* [Largest Subarray Sum](maths/largest_subarray_sum.py)
|
|
||||||
* [Least Common Multiple](maths/least_common_multiple.py)
|
* [Least Common Multiple](maths/least_common_multiple.py)
|
||||||
* [Line Length](maths/line_length.py)
|
* [Line Length](maths/line_length.py)
|
||||||
* [Liouville Lambda](maths/liouville_lambda.py)
|
* [Liouville Lambda](maths/liouville_lambda.py)
|
||||||
@ -733,7 +730,6 @@
|
|||||||
* [Linear Congruential Generator](other/linear_congruential_generator.py)
|
* [Linear Congruential Generator](other/linear_congruential_generator.py)
|
||||||
* [Lru Cache](other/lru_cache.py)
|
* [Lru Cache](other/lru_cache.py)
|
||||||
* [Magicdiamondpattern](other/magicdiamondpattern.py)
|
* [Magicdiamondpattern](other/magicdiamondpattern.py)
|
||||||
* [Maximum Subarray](other/maximum_subarray.py)
|
|
||||||
* [Maximum Subsequence](other/maximum_subsequence.py)
|
* [Maximum Subsequence](other/maximum_subsequence.py)
|
||||||
* [Nested Brackets](other/nested_brackets.py)
|
* [Nested Brackets](other/nested_brackets.py)
|
||||||
* [Number Container System](other/number_container_system.py)
|
* [Number Container System](other/number_container_system.py)
|
||||||
|
@ -25,9 +25,11 @@ def newton_raphson(
|
|||||||
"""
|
"""
|
||||||
x = a
|
x = a
|
||||||
while True:
|
while True:
|
||||||
x = Decimal(x) - (Decimal(eval(func)) / Decimal(eval(str(diff(func)))))
|
x = Decimal(x) - (
|
||||||
|
Decimal(eval(func)) / Decimal(eval(str(diff(func)))) # noqa: S307
|
||||||
|
)
|
||||||
# This number dictates the accuracy of the answer
|
# This number dictates the accuracy of the answer
|
||||||
if abs(eval(func)) < precision:
|
if abs(eval(func)) < precision: # noqa: S307
|
||||||
return float(x)
|
return float(x)
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ def __judge_point(pt: bool, neighbours: list[list[bool]]) -> bool:
|
|||||||
if pt:
|
if pt:
|
||||||
if alive < 2:
|
if alive < 2:
|
||||||
state = False
|
state = False
|
||||||
elif alive == 2 or alive == 3:
|
elif alive in {2, 3}:
|
||||||
state = True
|
state = True
|
||||||
elif alive > 3:
|
elif alive > 3:
|
||||||
state = False
|
state = False
|
||||||
|
@ -152,7 +152,7 @@ class RedBlackTree:
|
|||||||
self.grandparent.color = 1
|
self.grandparent.color = 1
|
||||||
self.grandparent._insert_repair()
|
self.grandparent._insert_repair()
|
||||||
|
|
||||||
def remove(self, label: int) -> RedBlackTree:
|
def remove(self, label: int) -> RedBlackTree: # noqa: PLR0912
|
||||||
"""Remove label from this tree."""
|
"""Remove label from this tree."""
|
||||||
if self.label == label:
|
if self.label == label:
|
||||||
if self.left and self.right:
|
if self.left and self.right:
|
||||||
|
@ -54,7 +54,7 @@ class Deque:
|
|||||||
the current node of the iteration.
|
the current node of the iteration.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = "_cur"
|
__slots__ = ("_cur",)
|
||||||
|
|
||||||
def __init__(self, cur: Deque._Node | None) -> None:
|
def __init__(self, cur: Deque._Node | None) -> None:
|
||||||
self._cur = cur
|
self._cur = cur
|
||||||
|
@ -54,10 +54,17 @@ class RadixNode:
|
|||||||
word (str): word to insert
|
word (str): word to insert
|
||||||
|
|
||||||
>>> RadixNode("myprefix").insert("mystring")
|
>>> RadixNode("myprefix").insert("mystring")
|
||||||
|
|
||||||
|
>>> root = RadixNode()
|
||||||
|
>>> root.insert_many(['myprefix', 'myprefixA', 'myprefixAA'])
|
||||||
|
>>> root.print_tree()
|
||||||
|
- myprefix (leaf)
|
||||||
|
-- A (leaf)
|
||||||
|
--- A (leaf)
|
||||||
"""
|
"""
|
||||||
# Case 1: If the word is the prefix of the node
|
# Case 1: If the word is the prefix of the node
|
||||||
# Solution: We set the current node as leaf
|
# Solution: We set the current node as leaf
|
||||||
if self.prefix == word:
|
if self.prefix == word and not self.is_leaf:
|
||||||
self.is_leaf = True
|
self.is_leaf = True
|
||||||
|
|
||||||
# Case 2: The node has no edges that have a prefix to the word
|
# Case 2: The node has no edges that have a prefix to the word
|
||||||
@ -156,7 +163,7 @@ class RadixNode:
|
|||||||
del self.nodes[word[0]]
|
del self.nodes[word[0]]
|
||||||
# We merge the current node with its only child
|
# We merge the current node with its only child
|
||||||
if len(self.nodes) == 1 and not self.is_leaf:
|
if len(self.nodes) == 1 and not self.is_leaf:
|
||||||
merging_node = list(self.nodes.values())[0]
|
merging_node = next(iter(self.nodes.values()))
|
||||||
self.is_leaf = merging_node.is_leaf
|
self.is_leaf = merging_node.is_leaf
|
||||||
self.prefix += merging_node.prefix
|
self.prefix += merging_node.prefix
|
||||||
self.nodes = merging_node.nodes
|
self.nodes = merging_node.nodes
|
||||||
@ -165,7 +172,7 @@ class RadixNode:
|
|||||||
incoming_node.is_leaf = False
|
incoming_node.is_leaf = False
|
||||||
# If there is 1 edge, we merge it with its child
|
# If there is 1 edge, we merge it with its child
|
||||||
else:
|
else:
|
||||||
merging_node = list(incoming_node.nodes.values())[0]
|
merging_node = next(iter(incoming_node.nodes.values()))
|
||||||
incoming_node.is_leaf = merging_node.is_leaf
|
incoming_node.is_leaf = merging_node.is_leaf
|
||||||
incoming_node.prefix += merging_node.prefix
|
incoming_node.prefix += merging_node.prefix
|
||||||
incoming_node.nodes = merging_node.nodes
|
incoming_node.nodes = merging_node.nodes
|
||||||
|
@ -266,7 +266,7 @@ def convex_hull_bf(points: list[Point]) -> list[Point]:
|
|||||||
points_left_of_ij = points_right_of_ij = False
|
points_left_of_ij = points_right_of_ij = False
|
||||||
ij_part_of_convex_hull = True
|
ij_part_of_convex_hull = True
|
||||||
for k in range(n):
|
for k in range(n):
|
||||||
if k != i and k != j:
|
if k not in {i, j}:
|
||||||
det_k = _det(points[i], points[j], points[k])
|
det_k = _det(points[i], points[j], points[k])
|
||||||
|
|
||||||
if det_k > 0:
|
if det_k > 0:
|
||||||
|
112
divide_and_conquer/max_subarray.py
Normal file
112
divide_and_conquer/max_subarray.py
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
"""
|
||||||
|
The maximum subarray problem is the task of finding the continuous subarray that has the
|
||||||
|
maximum sum within a given array of numbers. For example, given the array
|
||||||
|
[-2, 1, -3, 4, -1, 2, 1, -5, 4], the contiguous subarray with the maximum sum is
|
||||||
|
[4, -1, 2, 1], which has a sum of 6.
|
||||||
|
|
||||||
|
This divide-and-conquer algorithm finds the maximum subarray in O(n log n) time.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import time
|
||||||
|
from collections.abc import Sequence
|
||||||
|
from random import randint
|
||||||
|
|
||||||
|
from matplotlib import pyplot as plt
|
||||||
|
|
||||||
|
|
||||||
|
def max_subarray(
|
||||||
|
arr: Sequence[float], low: int, high: int
|
||||||
|
) -> tuple[int | None, int | None, float]:
|
||||||
|
"""
|
||||||
|
Solves the maximum subarray problem using divide and conquer.
|
||||||
|
:param arr: the given array of numbers
|
||||||
|
:param low: the start index
|
||||||
|
:param high: the end index
|
||||||
|
:return: the start index of the maximum subarray, the end index of the
|
||||||
|
maximum subarray, and the maximum subarray sum
|
||||||
|
|
||||||
|
>>> nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
|
||||||
|
>>> max_subarray(nums, 0, len(nums) - 1)
|
||||||
|
(3, 6, 6)
|
||||||
|
>>> nums = [2, 8, 9]
|
||||||
|
>>> max_subarray(nums, 0, len(nums) - 1)
|
||||||
|
(0, 2, 19)
|
||||||
|
>>> nums = [0, 0]
|
||||||
|
>>> max_subarray(nums, 0, len(nums) - 1)
|
||||||
|
(0, 0, 0)
|
||||||
|
>>> nums = [-1.0, 0.0, 1.0]
|
||||||
|
>>> max_subarray(nums, 0, len(nums) - 1)
|
||||||
|
(2, 2, 1.0)
|
||||||
|
>>> nums = [-2, -3, -1, -4, -6]
|
||||||
|
>>> max_subarray(nums, 0, len(nums) - 1)
|
||||||
|
(2, 2, -1)
|
||||||
|
>>> max_subarray([], 0, 0)
|
||||||
|
(None, None, 0)
|
||||||
|
"""
|
||||||
|
if not arr:
|
||||||
|
return None, None, 0
|
||||||
|
if low == high:
|
||||||
|
return low, high, arr[low]
|
||||||
|
|
||||||
|
mid = (low + high) // 2
|
||||||
|
left_low, left_high, left_sum = max_subarray(arr, low, mid)
|
||||||
|
right_low, right_high, right_sum = max_subarray(arr, mid + 1, high)
|
||||||
|
cross_left, cross_right, cross_sum = max_cross_sum(arr, low, mid, high)
|
||||||
|
if left_sum >= right_sum and left_sum >= cross_sum:
|
||||||
|
return left_low, left_high, left_sum
|
||||||
|
elif right_sum >= left_sum and right_sum >= cross_sum:
|
||||||
|
return right_low, right_high, right_sum
|
||||||
|
return cross_left, cross_right, cross_sum
|
||||||
|
|
||||||
|
|
||||||
|
def max_cross_sum(
|
||||||
|
arr: Sequence[float], low: int, mid: int, high: int
|
||||||
|
) -> tuple[int, int, float]:
|
||||||
|
left_sum, max_left = float("-inf"), -1
|
||||||
|
right_sum, max_right = float("-inf"), -1
|
||||||
|
|
||||||
|
summ: int | float = 0
|
||||||
|
for i in range(mid, low - 1, -1):
|
||||||
|
summ += arr[i]
|
||||||
|
if summ > left_sum:
|
||||||
|
left_sum = summ
|
||||||
|
max_left = i
|
||||||
|
|
||||||
|
summ = 0
|
||||||
|
for i in range(mid + 1, high + 1):
|
||||||
|
summ += arr[i]
|
||||||
|
if summ > right_sum:
|
||||||
|
right_sum = summ
|
||||||
|
max_right = i
|
||||||
|
|
||||||
|
return max_left, max_right, (left_sum + right_sum)
|
||||||
|
|
||||||
|
|
||||||
|
def time_max_subarray(input_size: int) -> float:
|
||||||
|
arr = [randint(1, input_size) for _ in range(input_size)]
|
||||||
|
start = time.time()
|
||||||
|
max_subarray(arr, 0, input_size - 1)
|
||||||
|
end = time.time()
|
||||||
|
return end - start
|
||||||
|
|
||||||
|
|
||||||
|
def plot_runtimes() -> None:
|
||||||
|
input_sizes = [10, 100, 1000, 10000, 50000, 100000, 200000, 300000, 400000, 500000]
|
||||||
|
runtimes = [time_max_subarray(input_size) for input_size in input_sizes]
|
||||||
|
print("No of Inputs\t\tTime Taken")
|
||||||
|
for input_size, runtime in zip(input_sizes, runtimes):
|
||||||
|
print(input_size, "\t\t", runtime)
|
||||||
|
plt.plot(input_sizes, runtimes)
|
||||||
|
plt.xlabel("Number of Inputs")
|
||||||
|
plt.ylabel("Time taken in seconds")
|
||||||
|
plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
"""
|
||||||
|
A random simulation of this algorithm.
|
||||||
|
"""
|
||||||
|
from doctest import testmod
|
||||||
|
|
||||||
|
testmod()
|
@ -1,78 +0,0 @@
|
|||||||
"""
|
|
||||||
Given a array of length n, max_subarray_sum() finds
|
|
||||||
the maximum of sum of contiguous sub-array using divide and conquer method.
|
|
||||||
|
|
||||||
Time complexity : O(n log n)
|
|
||||||
|
|
||||||
Ref : INTRODUCTION TO ALGORITHMS THIRD EDITION
|
|
||||||
(section : 4, sub-section : 4.1, page : 70)
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def max_sum_from_start(array):
|
|
||||||
"""This function finds the maximum contiguous sum of array from 0 index
|
|
||||||
|
|
||||||
Parameters :
|
|
||||||
array (list[int]) : given array
|
|
||||||
|
|
||||||
Returns :
|
|
||||||
max_sum (int) : maximum contiguous sum of array from 0 index
|
|
||||||
|
|
||||||
"""
|
|
||||||
array_sum = 0
|
|
||||||
max_sum = float("-inf")
|
|
||||||
for num in array:
|
|
||||||
array_sum += num
|
|
||||||
if array_sum > max_sum:
|
|
||||||
max_sum = array_sum
|
|
||||||
return max_sum
|
|
||||||
|
|
||||||
|
|
||||||
def max_cross_array_sum(array, left, mid, right):
|
|
||||||
"""This function finds the maximum contiguous sum of left and right arrays
|
|
||||||
|
|
||||||
Parameters :
|
|
||||||
array, left, mid, right (list[int], int, int, int)
|
|
||||||
|
|
||||||
Returns :
|
|
||||||
(int) : maximum of sum of contiguous sum of left and right arrays
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
max_sum_of_left = max_sum_from_start(array[left : mid + 1][::-1])
|
|
||||||
max_sum_of_right = max_sum_from_start(array[mid + 1 : right + 1])
|
|
||||||
return max_sum_of_left + max_sum_of_right
|
|
||||||
|
|
||||||
|
|
||||||
def max_subarray_sum(array, left, right):
|
|
||||||
"""Maximum contiguous sub-array sum, using divide and conquer method
|
|
||||||
|
|
||||||
Parameters :
|
|
||||||
array, left, right (list[int], int, int) :
|
|
||||||
given array, current left index and current right index
|
|
||||||
|
|
||||||
Returns :
|
|
||||||
int : maximum of sum of contiguous sub-array
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# base case: array has only one element
|
|
||||||
if left == right:
|
|
||||||
return array[right]
|
|
||||||
|
|
||||||
# Recursion
|
|
||||||
mid = (left + right) // 2
|
|
||||||
left_half_sum = max_subarray_sum(array, left, mid)
|
|
||||||
right_half_sum = max_subarray_sum(array, mid + 1, right)
|
|
||||||
cross_sum = max_cross_array_sum(array, left, mid, right)
|
|
||||||
return max(left_half_sum, right_half_sum, cross_sum)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
array = [-2, -5, 6, -2, -3, 1, 5, -6]
|
|
||||||
array_length = len(array)
|
|
||||||
print(
|
|
||||||
"Maximum sum of contiguous subarray:",
|
|
||||||
max_subarray_sum(array, 0, array_length - 1),
|
|
||||||
)
|
|
@ -1,93 +0,0 @@
|
|||||||
"""
|
|
||||||
author : Mayank Kumar Jha (mk9440)
|
|
||||||
"""
|
|
||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
|
|
||||||
def find_max_sub_array(a, low, high):
|
|
||||||
if low == high:
|
|
||||||
return low, high, a[low]
|
|
||||||
else:
|
|
||||||
mid = (low + high) // 2
|
|
||||||
left_low, left_high, left_sum = find_max_sub_array(a, low, mid)
|
|
||||||
right_low, right_high, right_sum = find_max_sub_array(a, mid + 1, high)
|
|
||||||
cross_left, cross_right, cross_sum = find_max_cross_sum(a, low, mid, high)
|
|
||||||
if left_sum >= right_sum and left_sum >= cross_sum:
|
|
||||||
return left_low, left_high, left_sum
|
|
||||||
elif right_sum >= left_sum and right_sum >= cross_sum:
|
|
||||||
return right_low, right_high, right_sum
|
|
||||||
else:
|
|
||||||
return cross_left, cross_right, cross_sum
|
|
||||||
|
|
||||||
|
|
||||||
def find_max_cross_sum(a, low, mid, high):
|
|
||||||
left_sum, max_left = -999999999, -1
|
|
||||||
right_sum, max_right = -999999999, -1
|
|
||||||
summ = 0
|
|
||||||
for i in range(mid, low - 1, -1):
|
|
||||||
summ += a[i]
|
|
||||||
if summ > left_sum:
|
|
||||||
left_sum = summ
|
|
||||||
max_left = i
|
|
||||||
summ = 0
|
|
||||||
for i in range(mid + 1, high + 1):
|
|
||||||
summ += a[i]
|
|
||||||
if summ > right_sum:
|
|
||||||
right_sum = summ
|
|
||||||
max_right = i
|
|
||||||
return max_left, max_right, (left_sum + right_sum)
|
|
||||||
|
|
||||||
|
|
||||||
def max_sub_array(nums: list[int]) -> int:
|
|
||||||
"""
|
|
||||||
Finds the contiguous subarray which has the largest sum and return its sum.
|
|
||||||
|
|
||||||
>>> max_sub_array([-2, 1, -3, 4, -1, 2, 1, -5, 4])
|
|
||||||
6
|
|
||||||
|
|
||||||
An empty (sub)array has sum 0.
|
|
||||||
>>> max_sub_array([])
|
|
||||||
0
|
|
||||||
|
|
||||||
If all elements are negative, the largest subarray would be the empty array,
|
|
||||||
having the sum 0.
|
|
||||||
>>> max_sub_array([-1, -2, -3])
|
|
||||||
0
|
|
||||||
>>> max_sub_array([5, -2, -3])
|
|
||||||
5
|
|
||||||
>>> max_sub_array([31, -41, 59, 26, -53, 58, 97, -93, -23, 84])
|
|
||||||
187
|
|
||||||
"""
|
|
||||||
best = 0
|
|
||||||
current = 0
|
|
||||||
for i in nums:
|
|
||||||
current += i
|
|
||||||
current = max(current, 0)
|
|
||||||
best = max(best, current)
|
|
||||||
return best
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
"""
|
|
||||||
A random simulation of this algorithm.
|
|
||||||
"""
|
|
||||||
import time
|
|
||||||
from random import randint
|
|
||||||
|
|
||||||
from matplotlib import pyplot as plt
|
|
||||||
|
|
||||||
inputs = [10, 100, 1000, 10000, 50000, 100000, 200000, 300000, 400000, 500000]
|
|
||||||
tim = []
|
|
||||||
for i in inputs:
|
|
||||||
li = [randint(1, i) for j in range(i)]
|
|
||||||
strt = time.time()
|
|
||||||
(find_max_sub_array(li, 0, len(li) - 1))
|
|
||||||
end = time.time()
|
|
||||||
tim.append(end - strt)
|
|
||||||
print("No of Inputs Time Taken")
|
|
||||||
for i in range(len(inputs)):
|
|
||||||
print(inputs[i], "\t\t", tim[i])
|
|
||||||
plt.plot(inputs, tim)
|
|
||||||
plt.xlabel("Number of Inputs")
|
|
||||||
plt.ylabel("Time taken in seconds ")
|
|
||||||
plt.show()
|
|
60
dynamic_programming/max_subarray_sum.py
Normal file
60
dynamic_programming/max_subarray_sum.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
"""
|
||||||
|
The maximum subarray sum problem is the task of finding the maximum sum that can be
|
||||||
|
obtained from a contiguous subarray within a given array of numbers. For example, given
|
||||||
|
the array [-2, 1, -3, 4, -1, 2, 1, -5, 4], the contiguous subarray with the maximum sum
|
||||||
|
is [4, -1, 2, 1], so the maximum subarray sum is 6.
|
||||||
|
|
||||||
|
Kadane's algorithm is a simple dynamic programming algorithm that solves the maximum
|
||||||
|
subarray sum problem in O(n) time and O(1) space.
|
||||||
|
|
||||||
|
Reference: https://en.wikipedia.org/wiki/Maximum_subarray_problem
|
||||||
|
"""
|
||||||
|
from collections.abc import Sequence
|
||||||
|
|
||||||
|
|
||||||
|
def max_subarray_sum(
|
||||||
|
arr: Sequence[float], allow_empty_subarrays: bool = False
|
||||||
|
) -> float:
|
||||||
|
"""
|
||||||
|
Solves the maximum subarray sum problem using Kadane's algorithm.
|
||||||
|
:param arr: the given array of numbers
|
||||||
|
:param allow_empty_subarrays: if True, then the algorithm considers empty subarrays
|
||||||
|
|
||||||
|
>>> max_subarray_sum([2, 8, 9])
|
||||||
|
19
|
||||||
|
>>> max_subarray_sum([0, 0])
|
||||||
|
0
|
||||||
|
>>> max_subarray_sum([-1.0, 0.0, 1.0])
|
||||||
|
1.0
|
||||||
|
>>> max_subarray_sum([1, 2, 3, 4, -2])
|
||||||
|
10
|
||||||
|
>>> max_subarray_sum([-2, 1, -3, 4, -1, 2, 1, -5, 4])
|
||||||
|
6
|
||||||
|
>>> max_subarray_sum([2, 3, -9, 8, -2])
|
||||||
|
8
|
||||||
|
>>> max_subarray_sum([-2, -3, -1, -4, -6])
|
||||||
|
-1
|
||||||
|
>>> max_subarray_sum([-2, -3, -1, -4, -6], allow_empty_subarrays=True)
|
||||||
|
0
|
||||||
|
>>> max_subarray_sum([])
|
||||||
|
0
|
||||||
|
"""
|
||||||
|
if not arr:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
max_sum = 0 if allow_empty_subarrays else float("-inf")
|
||||||
|
curr_sum = 0.0
|
||||||
|
for num in arr:
|
||||||
|
curr_sum = max(0 if allow_empty_subarrays else num, curr_sum + num)
|
||||||
|
max_sum = max(max_sum, curr_sum)
|
||||||
|
|
||||||
|
return max_sum
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from doctest import testmod
|
||||||
|
|
||||||
|
testmod()
|
||||||
|
|
||||||
|
nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
|
||||||
|
print(f"{max_subarray_sum(nums) = }")
|
@ -1,20 +0,0 @@
|
|||||||
def max_subarray_sum(nums: list) -> int:
|
|
||||||
"""
|
|
||||||
>>> max_subarray_sum([6 , 9, -1, 3, -7, -5, 10])
|
|
||||||
17
|
|
||||||
"""
|
|
||||||
if not nums:
|
|
||||||
return 0
|
|
||||||
n = len(nums)
|
|
||||||
|
|
||||||
res, s, s_pre = nums[0], nums[0], nums[0]
|
|
||||||
for i in range(1, n):
|
|
||||||
s = max(nums[i], s_pre + nums[i])
|
|
||||||
s_pre = s
|
|
||||||
res = max(res, s)
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
nums = [6, 9, -1, 3, -7, -5, 10]
|
|
||||||
print(max_subarray_sum(nums))
|
|
@ -39,7 +39,7 @@ class DirectedGraph:
|
|||||||
stack = []
|
stack = []
|
||||||
visited = []
|
visited = []
|
||||||
if s == -2:
|
if s == -2:
|
||||||
s = list(self.graph)[0]
|
s = next(iter(self.graph))
|
||||||
stack.append(s)
|
stack.append(s)
|
||||||
visited.append(s)
|
visited.append(s)
|
||||||
ss = s
|
ss = s
|
||||||
@ -87,7 +87,7 @@ class DirectedGraph:
|
|||||||
d = deque()
|
d = deque()
|
||||||
visited = []
|
visited = []
|
||||||
if s == -2:
|
if s == -2:
|
||||||
s = list(self.graph)[0]
|
s = next(iter(self.graph))
|
||||||
d.append(s)
|
d.append(s)
|
||||||
visited.append(s)
|
visited.append(s)
|
||||||
while d:
|
while d:
|
||||||
@ -114,7 +114,7 @@ class DirectedGraph:
|
|||||||
stack = []
|
stack = []
|
||||||
visited = []
|
visited = []
|
||||||
if s == -2:
|
if s == -2:
|
||||||
s = list(self.graph)[0]
|
s = next(iter(self.graph))
|
||||||
stack.append(s)
|
stack.append(s)
|
||||||
visited.append(s)
|
visited.append(s)
|
||||||
ss = s
|
ss = s
|
||||||
@ -146,7 +146,7 @@ class DirectedGraph:
|
|||||||
def cycle_nodes(self):
|
def cycle_nodes(self):
|
||||||
stack = []
|
stack = []
|
||||||
visited = []
|
visited = []
|
||||||
s = list(self.graph)[0]
|
s = next(iter(self.graph))
|
||||||
stack.append(s)
|
stack.append(s)
|
||||||
visited.append(s)
|
visited.append(s)
|
||||||
parent = -2
|
parent = -2
|
||||||
@ -199,7 +199,7 @@ class DirectedGraph:
|
|||||||
def has_cycle(self):
|
def has_cycle(self):
|
||||||
stack = []
|
stack = []
|
||||||
visited = []
|
visited = []
|
||||||
s = list(self.graph)[0]
|
s = next(iter(self.graph))
|
||||||
stack.append(s)
|
stack.append(s)
|
||||||
visited.append(s)
|
visited.append(s)
|
||||||
parent = -2
|
parent = -2
|
||||||
@ -305,7 +305,7 @@ class Graph:
|
|||||||
stack = []
|
stack = []
|
||||||
visited = []
|
visited = []
|
||||||
if s == -2:
|
if s == -2:
|
||||||
s = list(self.graph)[0]
|
s = next(iter(self.graph))
|
||||||
stack.append(s)
|
stack.append(s)
|
||||||
visited.append(s)
|
visited.append(s)
|
||||||
ss = s
|
ss = s
|
||||||
@ -353,7 +353,7 @@ class Graph:
|
|||||||
d = deque()
|
d = deque()
|
||||||
visited = []
|
visited = []
|
||||||
if s == -2:
|
if s == -2:
|
||||||
s = list(self.graph)[0]
|
s = next(iter(self.graph))
|
||||||
d.append(s)
|
d.append(s)
|
||||||
visited.append(s)
|
visited.append(s)
|
||||||
while d:
|
while d:
|
||||||
@ -371,7 +371,7 @@ class Graph:
|
|||||||
def cycle_nodes(self):
|
def cycle_nodes(self):
|
||||||
stack = []
|
stack = []
|
||||||
visited = []
|
visited = []
|
||||||
s = list(self.graph)[0]
|
s = next(iter(self.graph))
|
||||||
stack.append(s)
|
stack.append(s)
|
||||||
visited.append(s)
|
visited.append(s)
|
||||||
parent = -2
|
parent = -2
|
||||||
@ -424,7 +424,7 @@ class Graph:
|
|||||||
def has_cycle(self):
|
def has_cycle(self):
|
||||||
stack = []
|
stack = []
|
||||||
visited = []
|
visited = []
|
||||||
s = list(self.graph)[0]
|
s = next(iter(self.graph))
|
||||||
stack.append(s)
|
stack.append(s)
|
||||||
visited.append(s)
|
visited.append(s)
|
||||||
parent = -2
|
parent = -2
|
||||||
|
@ -113,7 +113,7 @@ class PushRelabelExecutor(MaximumFlowAlgorithmExecutor):
|
|||||||
vertices_list = [
|
vertices_list = [
|
||||||
i
|
i
|
||||||
for i in range(self.verticies_count)
|
for i in range(self.verticies_count)
|
||||||
if i != self.source_index and i != self.sink_index
|
if i not in {self.source_index, self.sink_index}
|
||||||
]
|
]
|
||||||
|
|
||||||
# move through list
|
# move through list
|
||||||
|
@ -55,7 +55,7 @@ def factorial_recursive(n: int) -> int:
|
|||||||
raise ValueError("factorial() only accepts integral values")
|
raise ValueError("factorial() only accepts integral values")
|
||||||
if n < 0:
|
if n < 0:
|
||||||
raise ValueError("factorial() not defined for negative values")
|
raise ValueError("factorial() not defined for negative values")
|
||||||
return 1 if n == 0 or n == 1 else n * factorial(n - 1)
|
return 1 if n in {0, 1} else n * factorial(n - 1)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
"""
|
|
||||||
Kadane's algorithm to get maximum subarray sum
|
|
||||||
https://medium.com/@rsinghal757/kadanes-algorithm-dynamic-programming-how-and-why-does-it-work-3fd8849ed73d
|
|
||||||
https://en.wikipedia.org/wiki/Maximum_subarray_problem
|
|
||||||
"""
|
|
||||||
test_data: tuple = ([-2, -8, -9], [2, 8, 9], [-1, 0, 1], [0, 0], [])
|
|
||||||
|
|
||||||
|
|
||||||
def negative_exist(arr: list) -> int:
|
|
||||||
"""
|
|
||||||
>>> negative_exist([-2,-8,-9])
|
|
||||||
-2
|
|
||||||
>>> [negative_exist(arr) for arr in test_data]
|
|
||||||
[-2, 0, 0, 0, 0]
|
|
||||||
"""
|
|
||||||
arr = arr or [0]
|
|
||||||
max_number = arr[0]
|
|
||||||
for i in arr:
|
|
||||||
if i >= 0:
|
|
||||||
return 0
|
|
||||||
elif max_number <= i:
|
|
||||||
max_number = i
|
|
||||||
return max_number
|
|
||||||
|
|
||||||
|
|
||||||
def kadanes(arr: list) -> int:
|
|
||||||
"""
|
|
||||||
If negative_exist() returns 0 than this function will execute
|
|
||||||
else it will return the value return by negative_exist function
|
|
||||||
|
|
||||||
For example: arr = [2, 3, -9, 8, -2]
|
|
||||||
Initially we set value of max_sum to 0 and max_till_element to 0 than when
|
|
||||||
max_sum is less than max_till particular element it will assign that value to
|
|
||||||
max_sum and when value of max_till_sum is less than 0 it will assign 0 to i
|
|
||||||
and after that whole process, return the max_sum
|
|
||||||
So the output for above arr is 8
|
|
||||||
|
|
||||||
>>> kadanes([2, 3, -9, 8, -2])
|
|
||||||
8
|
|
||||||
>>> [kadanes(arr) for arr in test_data]
|
|
||||||
[-2, 19, 1, 0, 0]
|
|
||||||
"""
|
|
||||||
max_sum = negative_exist(arr)
|
|
||||||
if max_sum < 0:
|
|
||||||
return max_sum
|
|
||||||
|
|
||||||
max_sum = 0
|
|
||||||
max_till_element = 0
|
|
||||||
|
|
||||||
for i in arr:
|
|
||||||
max_till_element += i
|
|
||||||
max_sum = max(max_sum, max_till_element)
|
|
||||||
max_till_element = max(max_till_element, 0)
|
|
||||||
return max_sum
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
try:
|
|
||||||
print("Enter integer values sepatated by spaces")
|
|
||||||
arr = [int(x) for x in input().split()]
|
|
||||||
print(f"Maximum subarray sum of {arr} is {kadanes(arr)}")
|
|
||||||
except ValueError:
|
|
||||||
print("Please enter integer values.")
|
|
@ -1,21 +0,0 @@
|
|||||||
from sys import maxsize
|
|
||||||
|
|
||||||
|
|
||||||
def max_sub_array_sum(a: list, size: int = 0):
|
|
||||||
"""
|
|
||||||
>>> max_sub_array_sum([-13, -3, -25, -20, -3, -16, -23, -12, -5, -22, -15, -4, -7])
|
|
||||||
-3
|
|
||||||
"""
|
|
||||||
size = size or len(a)
|
|
||||||
max_so_far = -maxsize - 1
|
|
||||||
max_ending_here = 0
|
|
||||||
for i in range(0, size):
|
|
||||||
max_ending_here = max_ending_here + a[i]
|
|
||||||
max_so_far = max(max_so_far, max_ending_here)
|
|
||||||
max_ending_here = max(max_ending_here, 0)
|
|
||||||
return max_so_far
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
a = [-13, -3, -25, -20, 1, -16, -23, -12, -5, -22, -15, -4, -7]
|
|
||||||
print(("Maximum contiguous sum is", max_sub_array_sum(a, len(a))))
|
|
@ -154,7 +154,7 @@ def prime_factorization(number):
|
|||||||
|
|
||||||
quotient = number
|
quotient = number
|
||||||
|
|
||||||
if number == 0 or number == 1:
|
if number in {0, 1}:
|
||||||
ans.append(number)
|
ans.append(number)
|
||||||
|
|
||||||
# if 'number' not prime then builds the prime factorization of 'number'
|
# if 'number' not prime then builds the prime factorization of 'number'
|
||||||
|
@ -253,7 +253,7 @@ def find_unit_clauses(
|
|||||||
unit_symbols = []
|
unit_symbols = []
|
||||||
for clause in clauses:
|
for clause in clauses:
|
||||||
if len(clause) == 1:
|
if len(clause) == 1:
|
||||||
unit_symbols.append(list(clause.literals.keys())[0])
|
unit_symbols.append(next(iter(clause.literals.keys())))
|
||||||
else:
|
else:
|
||||||
f_count, n_count = 0, 0
|
f_count, n_count = 0, 0
|
||||||
for literal, value in clause.literals.items():
|
for literal, value in clause.literals.items():
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
from collections.abc import Sequence
|
|
||||||
|
|
||||||
|
|
||||||
def max_subarray_sum(nums: Sequence[int]) -> int:
|
|
||||||
"""Return the maximum possible sum amongst all non - empty subarrays.
|
|
||||||
|
|
||||||
Raises:
|
|
||||||
ValueError: when nums is empty.
|
|
||||||
|
|
||||||
>>> max_subarray_sum([1,2,3,4,-2])
|
|
||||||
10
|
|
||||||
>>> max_subarray_sum([-2,1,-3,4,-1,2,1,-5,4])
|
|
||||||
6
|
|
||||||
"""
|
|
||||||
if not nums:
|
|
||||||
raise ValueError("Input sequence should not be empty")
|
|
||||||
|
|
||||||
curr_max = ans = nums[0]
|
|
||||||
nums_len = len(nums)
|
|
||||||
|
|
||||||
for i in range(1, nums_len):
|
|
||||||
num = nums[i]
|
|
||||||
curr_max = max(curr_max + num, num)
|
|
||||||
ans = max(curr_max, ans)
|
|
||||||
|
|
||||||
return ans
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
n = int(input("Enter number of elements : ").strip())
|
|
||||||
array = list(map(int, input("\nEnter the numbers : ").strip().split()))[:n]
|
|
||||||
print(max_subarray_sum(array))
|
|
@ -1,6 +1,6 @@
|
|||||||
"""
|
"""
|
||||||
A number container system that uses binary search to delete and insert values into
|
A number container system that uses binary search to delete and insert values into
|
||||||
arrays with O(n logn) write times and O(1) read times.
|
arrays with O(log n) write times and O(1) read times.
|
||||||
|
|
||||||
This container system holds integers at indexes.
|
This container system holds integers at indexes.
|
||||||
|
|
||||||
|
@ -28,12 +28,16 @@ def solution() -> int:
|
|||||||
31875000
|
31875000
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return [
|
return next(
|
||||||
|
iter(
|
||||||
|
[
|
||||||
a * b * (1000 - a - b)
|
a * b * (1000 - a - b)
|
||||||
for a in range(1, 999)
|
for a in range(1, 999)
|
||||||
for b in range(a, 999)
|
for b in range(a, 999)
|
||||||
if (a * a + b * b == (1000 - a - b) ** 2)
|
if (a * a + b * b == (1000 - a - b) ** 2)
|
||||||
][0]
|
]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -107,7 +107,7 @@ def ripple_adder(
|
|||||||
res = qiskit.execute(circuit, backend, shots=1).result()
|
res = qiskit.execute(circuit, backend, shots=1).result()
|
||||||
|
|
||||||
# The result is in binary. Convert it back to int
|
# The result is in binary. Convert it back to int
|
||||||
return int(list(res.get_counts())[0], 2)
|
return int(next(iter(res.get_counts())), 2)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -61,7 +61,7 @@ def assemble_transformation(ops: list[list[str]], i: int, j: int) -> list[str]:
|
|||||||
if i == 0 and j == 0:
|
if i == 0 and j == 0:
|
||||||
return []
|
return []
|
||||||
else:
|
else:
|
||||||
if ops[i][j][0] == "C" or ops[i][j][0] == "R":
|
if ops[i][j][0] in {"C", "R"}:
|
||||||
seq = assemble_transformation(ops, i - 1, j - 1)
|
seq = assemble_transformation(ops, i - 1, j - 1)
|
||||||
seq.append(ops[i][j])
|
seq.append(ops[i][j])
|
||||||
return seq
|
return seq
|
||||||
|
@ -90,9 +90,7 @@ def convert(number: int) -> str:
|
|||||||
else:
|
else:
|
||||||
addition = ""
|
addition = ""
|
||||||
if counter in placevalue:
|
if counter in placevalue:
|
||||||
if current == 0 and ((temp_num % 100) // 10) == 0:
|
if current != 0 and ((temp_num % 100) // 10) != 0:
|
||||||
addition = ""
|
|
||||||
else:
|
|
||||||
addition = placevalue[counter]
|
addition = placevalue[counter]
|
||||||
if ((temp_num % 100) // 10) == 1:
|
if ((temp_num % 100) // 10) == 1:
|
||||||
words = teens[current] + addition + words
|
words = teens[current] + addition + words
|
||||||
|
Loading…
x
Reference in New Issue
Block a user