Skip to content

Factors of a number #1493

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Oct 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 86 additions & 91 deletions data_structures/heap/binomial_heap.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""
Binomial Heap

Reference: Advanced Data Structures, Peter Brass
Binomial Heap
Reference: Advanced Data Structures, Peter Brass
"""


Expand All @@ -10,7 +9,7 @@ class Node:
Node in a doubly-linked binomial tree, containing:
- value
- size of left subtree
- link to left, right and parent nodes
- link to left, right and parent nodes
"""

def __init__(self, val):
Expand All @@ -23,8 +22,8 @@ def __init__(self, val):

def mergeTrees(self, other):
"""
In-place merge of two binomial trees of equal size.
Returns the root of the resulting tree
In-place merge of two binomial trees of equal size.
Returns the root of the resulting tree
"""
assert self.left_tree_size == other.left_tree_size, "Unequal Sizes of Blocks"

Expand All @@ -47,83 +46,79 @@ def mergeTrees(self, other):


class BinomialHeap:
"""
Min-oriented priority queue implemented with the Binomial Heap data
structure implemented with the BinomialHeap class. It supports:

r"""
Min-oriented priority queue implemented with the Binomial Heap data
structure implemented with the BinomialHeap class. It supports:
- Insert element in a heap with n elemnts: Guaranteed logn, amoratized 1
- 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)

Example:

Create a random permutation of 30 integers to be inserted and
19 of them deleted
>>> import numpy as np
>>> permutation = np.random.permutation(list(range(30)))

Create a Heap and insert the 30 integers

__init__() test
>>> first_heap = BinomialHeap()

30 inserts - insert() test
>>> for number in permutation:
... first_heap.insert(number)

Size test
>>> print(first_heap.size)
30

Deleting - delete() test
>>> for i in range(25):
... 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

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:

17
/ \
# 31
/ \
20 34
/ \ / \
# # # #

preOrder() test
>>> print(second_heap.preOrder())
[(17, 0), ('#', 1), (31, 1), (20, 2), ('#', 3), ('#', 3), (34, 2), ('#', 3), ('#', 3)]

printing Heap - __str__() test
>>> print(second_heap)
17
-#
-31
--20
---#
---#
--34
---#
---#

mergeHeaps() test
>>> merged = second_heap.mergeHeaps(first_heap)
>>> merged.peek()
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


Example:

Create a random permutation of 30 integers to be inserted and 19 of them deleted
>>> import numpy as np
>>> permutation = np.random.permutation(list(range(30)))

Create a Heap and insert the 30 integers
__init__() test
>>> first_heap = BinomialHeap()

30 inserts - insert() test
>>> for number in permutation:
... first_heap.insert(number)

Size test
>>> print(first_heap.size)
30

Deleting - delete() test
>>> for i in range(25):
... 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

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:

17
/ \
# 31
/ \
20 34
/ \ / \
# # # #

preOrder() test
>>> print(second_heap.preOrder())
[(17, 0), ('#', 1), (31, 1), (20, 2), ('#', 3), ('#', 3), (34, 2), ('#', 3), ('#', 3)]

printing Heap - __str__() test
>>> print(second_heap)
17
-#
-31
--20
---#
---#
--34
---#
---#

mergeHeaps() test
>>> merged = second_heap.mergeHeaps(first_heap)
>>> merged.peek()
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
"""

def __init__(self, bottom_root=None, min_node=None, heap_size=0):
Expand All @@ -133,8 +128,8 @@ def __init__(self, bottom_root=None, min_node=None, heap_size=0):

def mergeHeaps(self, other):
"""
In-place merge of two binomial heaps.
Both of them become the resulting merged heap
In-place merge of two binomial heaps.
Both of them become the resulting merged heap
"""

# Empty heaps corner cases
Expand Down Expand Up @@ -209,7 +204,7 @@ def mergeHeaps(self, other):

def insert(self, val):
"""
insert a value in the heap
insert a value in the heap
"""
if self.size == 0:
self.bottom_root = Node(val)
Expand Down Expand Up @@ -251,7 +246,7 @@ def insert(self, val):

def peek(self):
"""
return min element without deleting it
return min element without deleting it
"""
return self.min_node.val

Expand All @@ -260,7 +255,7 @@ def isEmpty(self):

def deleteMin(self):
"""
delete min element and return it
delete min element and return it
"""
# assert not self.isEmpty(), "Empty Heap"

Expand Down Expand Up @@ -363,9 +358,9 @@ def deleteMin(self):

def preOrder(self):
"""
Returns the Pre-order representation of the heap including
values of nodes plus their level distance from the root;
Empty nodes appear as #
Returns the Pre-order representation of the heap including
values of nodes plus their level distance from the root;
Empty nodes appear as #
"""
# Find top root
top_root = self.bottom_root
Expand All @@ -378,7 +373,7 @@ def preOrder(self):

def __traversal(self, curr_node, preorder, level=0):
"""
Pre-order traversal of nodes
Pre-order traversal of nodes
"""
if curr_node:
preorder.append((curr_node.val, level))
Expand All @@ -389,8 +384,8 @@ def __traversal(self, curr_node, preorder, level=0):

def __str__(self):
"""
Overwriting str for a pre-order print of nodes in heap;
Performance is poor, so use only for small examples
Overwriting str for a pre-order print of nodes in heap;
Performance is poor, so use only for small examples
"""
if self.isEmpty():
return ""
Expand Down
4 changes: 1 addition & 3 deletions maths/basic_maths.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,8 @@ def euler_phi(n: int) -> int:
>>> euler_phi(100)
40
"""
l = prime_factors(n)
l = set(l)
s = n
for x in l:
for x in set(prime_factors(n)):
s *= (x - 1) / x
return int(s)

Expand Down
18 changes: 18 additions & 0 deletions maths/factors.py
Original file line number Diff line number Diff line change
@@ -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)}")
6 changes: 3 additions & 3 deletions maths/prime_numbers.py
Original file line number Diff line number Diff line change
@@ -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)
[2, 3, 5, 7]
>>> primes(11)
Expand Down
3 changes: 1 addition & 2 deletions neural_network/perceptron.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ def sort(self, sample) -> None:
...
>>> perceptron.sort([-0.6508, 0.1097, 4.0009]) # doctest: +ELLIPSIS
('Sample: ', ...)
classification: P1

classification: P...
"""
if len(self.sample) == 0:
raise AttributeError("Sample data can not be empty")
Expand Down