mirror of
https://github.com/TheAlgorithms/Python.git
synced 2025-01-31 06:33:44 +00:00
Factors of a number (#1493)
* Factors of a number * Update factors.py * Fix mypy issue in basic_maths.py * Fix mypy error in perceptron.py * def primes(max: int) -> List[int]: * Update binomial_heap.py * Add a space * Remove a space * Add a space
This commit is contained in:
parent
f8e97aa597
commit
53ff735701
|
@ -1,7 +1,6 @@
|
||||||
"""
|
"""
|
||||||
Binomial Heap
|
Binomial Heap
|
||||||
|
Reference: Advanced Data Structures, Peter Brass
|
||||||
Reference: Advanced Data Structures, Peter Brass
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,8 +22,8 @@ class Node:
|
||||||
|
|
||||||
def mergeTrees(self, other):
|
def mergeTrees(self, other):
|
||||||
"""
|
"""
|
||||||
In-place merge of two binomial trees of equal size.
|
In-place merge of two binomial trees of equal size.
|
||||||
Returns the root of the resulting tree
|
Returns the root of the resulting tree
|
||||||
"""
|
"""
|
||||||
assert self.left_tree_size == other.left_tree_size, "Unequal Sizes of Blocks"
|
assert self.left_tree_size == other.left_tree_size, "Unequal Sizes of Blocks"
|
||||||
|
|
||||||
|
@ -47,83 +46,79 @@ class Node:
|
||||||
|
|
||||||
|
|
||||||
class BinomialHeap:
|
class BinomialHeap:
|
||||||
"""
|
r"""
|
||||||
Min-oriented priority queue implemented with the Binomial Heap data
|
Min-oriented priority queue implemented with the Binomial Heap data
|
||||||
structure implemented with the BinomialHeap class. It supports:
|
structure implemented with the BinomialHeap class. It supports:
|
||||||
|
|
||||||
- Insert element in a heap with n elemnts: Guaranteed logn, amoratized 1
|
- Insert element in a heap with n elemnts: Guaranteed logn, amoratized 1
|
||||||
- Merge (meld) heaps of size m and n: O(logn + logm)
|
- Merge (meld) heaps of size m and n: O(logn + logm)
|
||||||
- Delete Min: O(logn)
|
- Delete Min: O(logn)
|
||||||
- Peek (return min without deleting it): O(1)
|
- Peek (return min without deleting it): O(1)
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
Create a random permutation of 30 integers to be inserted and
|
Create a random permutation of 30 integers to be inserted and 19 of them deleted
|
||||||
19 of them deleted
|
>>> import numpy as np
|
||||||
>>> import numpy as np
|
>>> permutation = np.random.permutation(list(range(30)))
|
||||||
>>> permutation = np.random.permutation(list(range(30)))
|
|
||||||
|
|
||||||
Create a Heap and insert the 30 integers
|
Create a Heap and insert the 30 integers
|
||||||
|
__init__() test
|
||||||
|
>>> first_heap = BinomialHeap()
|
||||||
|
|
||||||
__init__() test
|
30 inserts - insert() test
|
||||||
>>> first_heap = BinomialHeap()
|
>>> for number in permutation:
|
||||||
|
... first_heap.insert(number)
|
||||||
|
|
||||||
30 inserts - insert() test
|
Size test
|
||||||
>>> for number in permutation:
|
>>> print(first_heap.size)
|
||||||
... first_heap.insert(number)
|
30
|
||||||
|
|
||||||
Size test
|
Deleting - delete() test
|
||||||
>>> print(first_heap.size)
|
>>> for i in range(25):
|
||||||
30
|
... print(first_heap.deleteMin(), end=" ")
|
||||||
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
||||||
|
|
||||||
Deleting - delete() test
|
Create a new Heap
|
||||||
>>> for i in range(25):
|
>>> second_heap = BinomialHeap()
|
||||||
... print(first_heap.deleteMin(), end=" ")
|
>>> vals = [17, 20, 31, 34]
|
||||||
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
>>> for value in vals:
|
||||||
|
... second_heap.insert(value)
|
||||||
Create a new Heap
|
|
||||||
>>> second_heap = BinomialHeap()
|
|
||||||
>>> vals = [17, 20, 31, 34]
|
|
||||||
>>> for value in vals:
|
|
||||||
... second_heap.insert(value)
|
|
||||||
|
|
||||||
|
|
||||||
The heap should have the following structure:
|
The heap should have the following structure:
|
||||||
|
|
||||||
17
|
17
|
||||||
/ \
|
/ \
|
||||||
# 31
|
# 31
|
||||||
/ \
|
/ \
|
||||||
20 34
|
20 34
|
||||||
/ \ / \
|
/ \ / \
|
||||||
# # # #
|
# # # #
|
||||||
|
|
||||||
preOrder() test
|
preOrder() test
|
||||||
>>> print(second_heap.preOrder())
|
>>> print(second_heap.preOrder())
|
||||||
[(17, 0), ('#', 1), (31, 1), (20, 2), ('#', 3), ('#', 3), (34, 2), ('#', 3), ('#', 3)]
|
[(17, 0), ('#', 1), (31, 1), (20, 2), ('#', 3), ('#', 3), (34, 2), ('#', 3), ('#', 3)]
|
||||||
|
|
||||||
printing Heap - __str__() test
|
printing Heap - __str__() test
|
||||||
>>> print(second_heap)
|
>>> print(second_heap)
|
||||||
17
|
17
|
||||||
-#
|
-#
|
||||||
-31
|
-31
|
||||||
--20
|
--20
|
||||||
---#
|
---#
|
||||||
---#
|
---#
|
||||||
--34
|
--34
|
||||||
---#
|
---#
|
||||||
---#
|
---#
|
||||||
|
|
||||||
mergeHeaps() test
|
mergeHeaps() test
|
||||||
>>> merged = second_heap.mergeHeaps(first_heap)
|
>>> merged = second_heap.mergeHeaps(first_heap)
|
||||||
>>> merged.peek()
|
>>> merged.peek()
|
||||||
17
|
17
|
||||||
|
|
||||||
values in merged heap; (merge is inplace)
|
|
||||||
>>> while not first_heap.isEmpty():
|
|
||||||
... print(first_heap.deleteMin(), end=" ")
|
|
||||||
17 20 25 26 27 28 29 31 34
|
|
||||||
|
|
||||||
|
values in merged heap; (merge is inplace)
|
||||||
|
>>> while not first_heap.isEmpty():
|
||||||
|
... print(first_heap.deleteMin(), end=" ")
|
||||||
|
17 20 25 26 27 28 29 31 34
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bottom_root=None, min_node=None, heap_size=0):
|
def __init__(self, bottom_root=None, min_node=None, heap_size=0):
|
||||||
|
@ -133,8 +128,8 @@ class BinomialHeap:
|
||||||
|
|
||||||
def mergeHeaps(self, other):
|
def mergeHeaps(self, other):
|
||||||
"""
|
"""
|
||||||
In-place merge of two binomial heaps.
|
In-place merge of two binomial heaps.
|
||||||
Both of them become the resulting merged heap
|
Both of them become the resulting merged heap
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Empty heaps corner cases
|
# Empty heaps corner cases
|
||||||
|
@ -209,7 +204,7 @@ class BinomialHeap:
|
||||||
|
|
||||||
def insert(self, val):
|
def insert(self, val):
|
||||||
"""
|
"""
|
||||||
insert a value in the heap
|
insert a value in the heap
|
||||||
"""
|
"""
|
||||||
if self.size == 0:
|
if self.size == 0:
|
||||||
self.bottom_root = Node(val)
|
self.bottom_root = Node(val)
|
||||||
|
@ -251,7 +246,7 @@ class BinomialHeap:
|
||||||
|
|
||||||
def peek(self):
|
def peek(self):
|
||||||
"""
|
"""
|
||||||
return min element without deleting it
|
return min element without deleting it
|
||||||
"""
|
"""
|
||||||
return self.min_node.val
|
return self.min_node.val
|
||||||
|
|
||||||
|
@ -260,7 +255,7 @@ class BinomialHeap:
|
||||||
|
|
||||||
def deleteMin(self):
|
def deleteMin(self):
|
||||||
"""
|
"""
|
||||||
delete min element and return it
|
delete min element and return it
|
||||||
"""
|
"""
|
||||||
# assert not self.isEmpty(), "Empty Heap"
|
# assert not self.isEmpty(), "Empty Heap"
|
||||||
|
|
||||||
|
@ -363,9 +358,9 @@ class BinomialHeap:
|
||||||
|
|
||||||
def preOrder(self):
|
def preOrder(self):
|
||||||
"""
|
"""
|
||||||
Returns the Pre-order representation of the heap including
|
Returns the Pre-order representation of the heap including
|
||||||
values of nodes plus their level distance from the root;
|
values of nodes plus their level distance from the root;
|
||||||
Empty nodes appear as #
|
Empty nodes appear as #
|
||||||
"""
|
"""
|
||||||
# Find top root
|
# Find top root
|
||||||
top_root = self.bottom_root
|
top_root = self.bottom_root
|
||||||
|
@ -378,7 +373,7 @@ class BinomialHeap:
|
||||||
|
|
||||||
def __traversal(self, curr_node, preorder, level=0):
|
def __traversal(self, curr_node, preorder, level=0):
|
||||||
"""
|
"""
|
||||||
Pre-order traversal of nodes
|
Pre-order traversal of nodes
|
||||||
"""
|
"""
|
||||||
if curr_node:
|
if curr_node:
|
||||||
preorder.append((curr_node.val, level))
|
preorder.append((curr_node.val, level))
|
||||||
|
@ -389,8 +384,8 @@ class BinomialHeap:
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""
|
"""
|
||||||
Overwriting str for a pre-order print of nodes in heap;
|
Overwriting str for a pre-order print of nodes in heap;
|
||||||
Performance is poor, so use only for small examples
|
Performance is poor, so use only for small examples
|
||||||
"""
|
"""
|
||||||
if self.isEmpty():
|
if self.isEmpty():
|
||||||
return ""
|
return ""
|
||||||
|
|
|
@ -67,10 +67,8 @@ def euler_phi(n: int) -> int:
|
||||||
>>> euler_phi(100)
|
>>> euler_phi(100)
|
||||||
40
|
40
|
||||||
"""
|
"""
|
||||||
l = prime_factors(n)
|
|
||||||
l = set(l)
|
|
||||||
s = n
|
s = n
|
||||||
for x in l:
|
for x in set(prime_factors(n)):
|
||||||
s *= (x - 1) / x
|
s *= (x - 1) / x
|
||||||
return int(s)
|
return int(s)
|
||||||
|
|
||||||
|
|
18
maths/factors.py
Normal file
18
maths/factors.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
def factors_of_a_number(num: int) -> list:
|
||||||
|
"""
|
||||||
|
>>> factors_of_a_number(1)
|
||||||
|
[1]
|
||||||
|
>>> factors_of_a_number(5)
|
||||||
|
[1, 5]
|
||||||
|
>>> factors_of_a_number(24)
|
||||||
|
[1, 2, 3, 4, 6, 8, 12, 24]
|
||||||
|
>>> factors_of_a_number(-24)
|
||||||
|
[]
|
||||||
|
"""
|
||||||
|
return [i for i in range(1, num + 1) if num % i == 0]
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
num = int(input("Enter a number to find its factors: "))
|
||||||
|
factors = factors_of_a_number(num)
|
||||||
|
print(f"{num} has {len(factors)} factors: {', '.join(str(f) for f in factors)}")
|
|
@ -1,9 +1,9 @@
|
||||||
"""Prime numbers calculation."""
|
from typing import List
|
||||||
|
|
||||||
|
|
||||||
def primes(max: int) -> int:
|
def primes(max: int) -> List[int]:
|
||||||
"""
|
"""
|
||||||
Return a list of all primes up to max.
|
Return a list of all primes numbers up to max.
|
||||||
>>> primes(10)
|
>>> primes(10)
|
||||||
[2, 3, 5, 7]
|
[2, 3, 5, 7]
|
||||||
>>> primes(11)
|
>>> primes(11)
|
||||||
|
|
|
@ -95,8 +95,7 @@ class Perceptron:
|
||||||
...
|
...
|
||||||
>>> perceptron.sort([-0.6508, 0.1097, 4.0009]) # doctest: +ELLIPSIS
|
>>> perceptron.sort([-0.6508, 0.1097, 4.0009]) # doctest: +ELLIPSIS
|
||||||
('Sample: ', ...)
|
('Sample: ', ...)
|
||||||
classification: P1
|
classification: P...
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if len(self.sample) == 0:
|
if len(self.sample) == 0:
|
||||||
raise AttributeError("Sample data can not be empty")
|
raise AttributeError("Sample data can not be empty")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user