Compare commits

...

10 Commits

Author SHA1 Message Date
Ilkin Mengusoglu
a1acf503d6
Merge branch 'TheAlgorithms:master' into master 2023-07-24 22:37:17 +02:00
Sangmin Jeon
a03b739d23
Fix radix_tree.py insertion fail in ["*X", "*XX"] cases (#8870)
* Fix insertion fail in ["*X", "*XX"] cases

Consider a word, and a copy of that word, but with the last letter repeating twice. (e.g., ["ABC", "ABCC"])
When adding the second word's last letter, it only compares the previous word's prefix—the last letter of the word already in the Radix Tree: 'C'—and the letter to be added—the last letter of the word we're currently adding: 'C'. So it wrongly passes the "Case 1" check, marks the current node as a leaf node when it already was, then returns when there's still one more letter to add.
The issue arises because `prefix` includes the letter of the node itself. (e.g., `nodes: {'C' : RadixNode()}, is_leaf: True, prefix: 'C'`) It can be easily fixed by simply adding the `is_leaf` check, asking if there are more letters to be added.

- Test Case: `"A AA AAA AAAA"`
  - Fixed correct output:
  ```
  Words: ['A', 'AA', 'AAA', 'AAAA']
  Tree:
  - A   (leaf)
  -- A   (leaf)
  --- A   (leaf)
  ---- A   (leaf)
  ```
  - Current incorrect output:
  ```
  Words: ['A', 'AA', 'AAA', 'AAAA']
  Tree:
  - A   (leaf)
  -- AA   (leaf)
  --- A   (leaf)
  ```

*N.B.* This passed test cases for [Croatian Open Competition in Informatics 2012/2013 Contest #3 Task 5 HERKABE](https://hsin.hr/coci/archive/2012_2013/)

* Add a doctest for previous fix

* improve doctest readability
2023-07-24 11:29:05 +02:00
Caeden Perelli-Harris
9e08c7726d
Small docstring time complexity fix in number_container _system (#8875)
* fix: Write time is O(log n) not O(n log n)

* chore: Update pre-commit ruff version

* revert: Undo previous commit
2023-07-22 12:34:19 +02:00
Tianyi Zheng
f7531d9874
Add note in CONTRIBUTING.md about not asking to be assigned to issues (#8871)
* Add note in CONTRIBUTING.md about not asking to be assigned to issues

Add a paragraph to CONTRIBUTING.md explicitly asking contributors to not ask to be assigned to issues

* Update CONTRIBUTING.md

* Update CONTRIBUTING.md

---------

Co-authored-by: Christian Clauss <cclauss@me.com>
2023-07-22 12:11:04 +02:00
Caeden Perelli-Harris
93fb169627
[Upgrade Ruff] Fix all errors raised from ruff (#8879)
* chore: Fix tests

* chore: Fix failing ruff

* chore: Fix ruff errors

* chore: Fix ruff errors

* chore: Fix ruff errors

* chore: Fix ruff errors

* chore: Fix ruff errors

* chore: Fix ruff errors

* chore: Fix ruff errors

* chore: Fix ruff errors

* chore: Fix ruff errors

* chore: Fix ruff errors

* chore: Fix ruff errors

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* chore: Fix ruff errors

* chore: Fix ruff errors

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update cellular_automata/game_of_life.py

Co-authored-by: Christian Clauss <cclauss@me.com>

* chore: Update ruff version in pre-commit

* chore: Fix ruff errors

* Update edmonds_karp_multiple_source_and_sink.py

* Update factorial.py

* Update primelib.py

* Update min_cost_string_conversion.py

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
2023-07-22 12:05:10 +02:00
pre-commit-ci[bot]
5aefc00f0f
[pre-commit.ci] pre-commit autoupdate (#8872)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.277 → v0.0.278](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.277...v0.0.278)
- [github.com/psf/black: 23.3.0 → 23.7.0](https://github.com/psf/black/compare/23.3.0...23.7.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-07-18 09:58:22 +05:30
pre-commit-ci[bot]
f614ed7217
[pre-commit.ci] pre-commit autoupdate (#8860)
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.276 → v0.0.277](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.276...v0.0.277)
- [github.com/tox-dev/pyproject-fmt: 0.12.1 → 0.13.0](https://github.com/tox-dev/pyproject-fmt/compare/0.12.1...0.13.0)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-07-11 11:55:32 +02:00
Caeden Perelli-Harris
44b1bcc7c7
Fix failing tests from ruff/newton_raphson (ignore S307 "possibly insecure function") (#8862)
* chore: Fix failing tests (ignore S307 "possibly insecure function")

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix: Move noqa back to right line

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2023-07-11 11:51:21 +02:00
Tianyi Zheng
a0eec90466
Consolidate duplicate implementations of max subarray (#8849)
* Remove max subarray sum duplicate implementations

* updating DIRECTORY.md

* Rename max_sum_contiguous_subsequence.py

* Fix typo in dynamic_programming/max_subarray_sum.py

* Remove duplicate divide and conquer max subarray

* updating DIRECTORY.md

---------

Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
2023-07-11 11:44:12 +02:00
pre-commit-ci[bot]
c9ee6ed188
[pre-commit.ci] pre-commit autoupdate (#8853)
* [pre-commit.ci] pre-commit autoupdate

updates:
- [github.com/astral-sh/ruff-pre-commit: v0.0.275 → v0.0.276](https://github.com/astral-sh/ruff-pre-commit/compare/v0.0.275...v0.0.276)

* Update double_ended_queue.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update double_ended_queue.py

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
2023-07-04 00:20:35 +02:00
27 changed files with 224 additions and 350 deletions

View File

@ -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

View File

@ -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:
``` ```

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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:

View 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()

View File

@ -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),
)

View File

@ -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()

View 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) = }")

View File

@ -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))

View File

@ -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

View File

@ -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

View File

@ -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__":

View File

@ -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.")

View File

@ -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))))

View File

@ -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'

View File

@ -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():

View File

@ -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))

View File

@ -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.

View File

@ -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__":

View File

@ -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__":

View File

@ -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

View File

@ -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