Skip to content
Closed
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
1 change: 1 addition & 0 deletions .github/workflows/directory_writer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ jobs:
git config --global user.name github-actions
git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com'
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
git add DIRECTORY.md
git commit -am "updating DIRECTORY.md" || true
git push --force origin HEAD:$GITHUB_REF || true
576 changes: 576 additions & 0 deletions DIRECTORY.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# https://en.wikipedia.org/wiki/Lowest_common_ancestor
# https://en.wikipedia.org/wiki/Breadth-first_search

import queue


Expand Down
49 changes: 27 additions & 22 deletions data_structures/linked_list/deque_doubly.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,36 @@
4. remove from the end -> O(1)
"""


class _DoublyLinkedBase:
""" A Private class (to be inherited) """

class _Node:
__slots__ = '_prev', '_data', '_next'
__slots__ = "_prev", "_data", "_next"

def __init__(self, link_p, element, link_n):
self._prev = link_p
self._data = element
self._next = link_n

def has_next_and_prev(self):
return " Prev -> {0}, Next -> {1}".format(self._prev != None, self._next != None)

return " Prev -> {0}, Next -> {1}".format(
self._prev != None, self._next != None
)

def __init__(self):
self._header = self._Node(None, None, None)
self._trailer = self._Node(None, None, None)
self._header._next = self._trailer
self._trailer._prev = self._header
self._size = 0

def __len__(self):
return self._size

def is_empty(self):
return self.__len__() == 0

def _insert(self, predecessor, e, successor):
# Create new_node by setting it's prev.link -> header
# setting it's next.link -> trailer
Expand All @@ -40,11 +45,11 @@ def _insert(self, predecessor, e, successor):
successor._prev = new_node
self._size += 1
return self

def _delete(self, node):
predecessor = node._prev
successor = node._next

predecessor._next = successor
successor._prev = predecessor
self._size -= 1
Expand All @@ -53,20 +58,20 @@ def _delete(self, node):
del node
return temp


class LinkedDeque(_DoublyLinkedBase):

def first(self):
""" return first element
>>> d = LinkedDeque()
>>> d.add_first('A').first()
'A'
>>> d.add_first('B').first()
'B'
"""
"""
if self.is_empty():
raise Exception('List is empty')
raise Exception("List is empty")
return self._header._next._data

def last(self):
""" return last element
>>> d = LinkedDeque()
Expand All @@ -76,27 +81,27 @@ def last(self):
'B'
"""
if self.is_empty():
raise Exception('List is empty')
raise Exception("List is empty")
return self._trailer._prev._data

### DEque Insert Operations (At the front, At the end) ###

def add_first(self, element):
""" insertion in the front
>>> LinkedDeque().add_first('AV').first()
'AV'
"""
return self._insert(self._header, element, self._header._next)

def add_last(self, element):
""" insertion in the end
>>> LinkedDeque().add_last('B').last()
'B'
"""
return self._insert(self._trailer._prev, element, self._trailer)

### DEqueu Remove Operations (At the front, At the end) ###

def remove_first(self):
""" removal from the front
>>> d = LinkedDeque()
Expand All @@ -114,9 +119,9 @@ def remove_first(self):
True
"""
if self.is_empty():
raise IndexError('remove_first from empty list')
raise IndexError("remove_first from empty list")
return self._delete(self._header._next)

def remove_last(self):
""" removal in the end
>>> d = LinkedDeque()
Expand All @@ -134,5 +139,5 @@ def remove_last(self):
True
"""
if self.is_empty():
raise IndexError('remove_first from empty list')
raise IndexError("remove_first from empty list")
return self._delete(self._trailer._prev)
60 changes: 60 additions & 0 deletions data_structures/stacks/prefix_evaluation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
"""
Python3 program to evaluate a prefix expression.
"""

calc = {
"+": lambda x, y: x + y,
"-": lambda x, y: x - y,
"*": lambda x, y: x * y,
"/": lambda x, y: x / y,
}


def is_operand(c):
"""
Return True if the given char c is an operand, e.g. it is a number

>>> is_operand("1")
True
>>> is_operand("+")
False
"""
return c.isdigit()


def evaluate(expression):
"""
Evaluate a given expression in prefix notation.
Asserts that the given expression is valid.

>>> evaluate("+ 9 * 2 6")
21
>>> evaluate("/ * 10 2 + 4 1 ")
4.0
"""
stack = []

# iterate over the string in reverse order
for c in expression.split()[::-1]:

# push operand to stack
if is_operand(c):
stack.append(int(c))

else:
# pop values from stack can calculate the result
# push the result onto the stack again
o1 = stack.pop()
o2 = stack.pop()
stack.append(calc[c](o1, o2))

return stack.pop()


# Driver code
if __name__ == "__main__":
test_expression = "+ 9 * 2 6"
print(evaluate(test_expression))

test_expression = "/ * 10 2 + 4 1 "
print(evaluate(test_expression))
33 changes: 33 additions & 0 deletions divide_and_conquer/power.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
def actual_power(a: int, b: int):
"""
Function using divide and conquer to calculate a^b.
It only works for integer a,b.
"""
if b == 0:
return 1
if (b % 2) == 0:
return actual_power(a, int(b / 2)) * actual_power(a, int(b / 2))
else:
return a * actual_power(a, int(b / 2)) * actual_power(a, int(b / 2))


def power(a: int, b: int) -> float:
"""
>>> power(4,6)
4096
>>> power(2,3)
8
>>> power(-2,3)
-8
>>> power(2,-3)
0.125
>>> power(-2,-3)
-0.125
"""
if b < 0:
return 1 / actual_power(a, b)
return actual_power(a, b)


if __name__ == "__main__":
print(power(-2, -3))
Loading