Skip to content

Commit

Permalink
Thing
Browse files Browse the repository at this point in the history
diff --git a/.gitignore b/.gitignore
index 68bc17f..51e9d59 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,160 +1,160 @@
-# Byte-compiled / optimized / DLL files
-__pycache__/
-*.py[cod]
-*$py.class
-
-# C extensions
-*.so
-
-# Distribution / packaging
-.Python
-build/
-develop-eggs/
-dist/
-downloads/
-eggs/
-.eggs/
-lib/
-lib64/
-parts/
-sdist/
-var/
-wheels/
-share/python-wheels/
-*.egg-info/
-.installed.cfg
-*.egg
-MANIFEST
-
-# PyInstaller
-#  Usually these files are written by a python script from a template
-#  before PyInstaller builds the exe, so as to inject date/other infos into it.
-*.manifest
-*.spec
-
-# Installer logs
-pip-log.txt
-pip-delete-this-directory.txt
-
-# Unit test / coverage reports
-htmlcov/
-.tox/
-.nox/
-.coverage
-.coverage.*
-.cache
-nosetests.xml
-coverage.xml
-*.cover
-*.py,cover
-.hypothesis/
-.pytest_cache/
-cover/
-
-# Translations
-*.mo
-*.pot
-
-# Django stuff:
-*.log
-local_settings.py
-db.sqlite3
-db.sqlite3-journal
-
-# Flask stuff:
-instance/
-.webassets-cache
-
-# Scrapy stuff:
-.scrapy
-
-# Sphinx documentation
-docs/_build/
-
-# PyBuilder
-.pybuilder/
-target/
-
-# Jupyter Notebook
-.ipynb_checkpoints
-
-# IPython
-profile_default/
-ipython_config.py
-
-# pyenv
-#   For a library or package, you might want to ignore these files since the code is
-#   intended to run in multiple environments; otherwise, check them in:
-# .python-version
-
-# pipenv
-#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
-#   However, in case of collaboration, if having platform-specific dependencies or dependencies
-#   having no cross-platform support, pipenv may install dependencies that don't work, or not
-#   install all needed dependencies.
-#Pipfile.lock
-
-# poetry
-#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
-#   This is especially recommended for binary packages to ensure reproducibility, and is more
-#   commonly ignored for libraries.
-#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
-#poetry.lock
-
-# pdm
-#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
-#pdm.lock
-#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
-#   in version control.
-#   https://pdm.fming.dev/#use-with-ide
-.pdm.toml
-
-# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
-__pypackages__/
-
-# Celery stuff
-celerybeat-schedule
-celerybeat.pid
-
-# SageMath parsed files
-*.sage.py
-
-# Environments
-.env
-.venv
-env/
-venv/
-ENV/
-env.bak/
-venv.bak/
-
-# Spyder project settings
-.spyderproject
-.spyproject
-
-# Rope project settings
-.ropeproject
-
-# mkdocs documentation
-/site
-
-# mypy
-.mypy_cache/
-.dmypy.json
-dmypy.json
-
-# Pyre type checker
-.pyre/
-
-# pytype static type analyzer
-.pytype/
-
-# Cython debug symbols
-cython_debug/
-
-# PyCharm
-#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
-#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
-#  and can be added to the global gitignore or merged into this file.  For a more nuclear
-#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
-#.idea/
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+#   For a library or package, you might want to ignore these files since the code is
+#   intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+#   However, in case of collaboration, if having platform-specific dependencies or dependencies
+#   having no cross-platform support, pipenv may install dependencies that don't work, or not
+#   install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+#   This is especially recommended for binary packages to ensure reproducibility, and is more
+#   commonly ignored for libraries.
+#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+#   in version control.
+#   https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+#  and can be added to the global gitignore or merged into this file.  For a more nuclear
+#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
diff --git a/Ex1/1-unique_rand.py b/Ex1/1-unique_rand.py
index f69c014..d501396 100644
--- a/Ex1/1-unique_rand.py
+++ b/Ex1/1-unique_rand.py
@@ -1,15 +1,15 @@
-import random
-
-
-def unique_rand(n):
-    rands = list(range(n))
-    random.shuffle(rands)
-    return rands
-
-
-if __name__ == "__main__":
-    # start = int(input("Enter the start for the range of random numbers: "))
-    # end = int(input("Enter the end for the range of random numbers(inclusive): "))
-    n = int(input("Enter the no. random nums you want to generate: "))
-    nums = unique_rand(n)
-    print(f"The numbers: {nums}")
+import random
+
+
+def unique_rand(n):
+    rands = list(range(n))
+    random.shuffle(rands)
+    return rands
+
+
+if __name__ == "__main__":
+    # start = int(input("Enter the start for the range of random numbers: "))
+    # end = int(input("Enter the end for the range of random numbers(inclusive): "))
+    n = int(input("Enter the no. random nums you want to generate: "))
+    nums = unique_rand(n)
+    print(f"The numbers: {nums}")
diff --git a/Ex1/2-sort.py b/Ex1/2-sort.py
index bd89460..986a33f 100644
--- a/Ex1/2-sort.py
+++ b/Ex1/2-sort.py
@@ -1,109 +1,109 @@
-import matplotlib.pyplot as plt
-import time
-import random
-
-
-def unique_rand(n):
-    rands = list(range(n))
-    random.shuffle(rands)
-    return rands
-
-def bucket_sort(elems, power, radix):
-    digit_buckets = [[] for i in range(radix)]
-    ended = True
-
-    for elem in elems:
-        digit = (elem // power) % radix
-        if digit != 0:
-            ended = False
-        digit_buckets[digit].append(elem)
-
-    k = 0
-    for bucket in digit_buckets:
-        for elem in bucket:
-            elems[k] = elem
-            k+=1
-    return ended
-
-
-def count_sort(elems, radix, radix_to_n):
-    digit_sorted_elems = [0 for i in range(len(elems))]
-    digit_counts = [0 for i in range(radix)]
-    is_radix_too_big = True
-
-    for elem in elems:
-        digit = int(elem / radix_to_n) % radix
-        if digit != 0:
-            is_radix_too_big = False
-        digit_counts[digit] += 1
-
-    cum_sum = 0
-    for i in range(len(digit_counts)):
-        count = digit_counts[i]
-        digit_counts[i] = cum_sum
-        cum_sum += count
-
-    for elem in elems:
-        digit = int(elem / radix_to_n) % radix
-        digit_sorted_elems[digit_counts[digit]] = elem
-        digit_counts[digit] += 1
-
-    for i in range(len(elems)):
-        elems[i] = digit_sorted_elems[i]
-
-    return is_radix_too_big
-
-
-def radix_sort(elems, radix):
-    power = 1
-    while not bucket_sort(elems, power, radix):
-        power *= radix
-
-
-def increment_sort(elems, increment):
-    for i in range(increment, len(elems)):
-        for j in range(i, increment - 1, -increment):
-            if elems[j] < elems[j - increment]:
-                elems[j], elems[j - increment] = elems[j - increment], elems[j]
-            else:
-                break
-
-
-def insertion_sort(elems):
-    increment_sort(elems, 1)
-
-
-def shell_sort(elems):
-    increment = int(len(elems) / 2)
-    while increment > 0:
-        increment_sort(elems, increment)
-        increment = int(increment / 2)
-
-
-if __name__ == "__main__":
-    ns = [10, 1000, 2000, 5000, 100000]
-    timeRadix, timeShell, timeInsertion = [], [], []
-    for i in ns:
-        #print(f"Now considering arrays of size {i}: ")
-        nums = unique_rand(i)
-        nums1, nums2, nums3 = list(nums), list(nums), list(nums)
-        start = time.perf_counter()
-        radix_sort(nums1, 256)
-        timeRadix.append(time.perf_counter() - start)
-        start = time.perf_counter()
-        shell_sort(nums2)
-        timeShell.append(time.perf_counter() - start)
-        start = time.perf_counter()
-        insertion_sort(nums3)
-        timeInsertion.append(time.perf_counter() - start)
-        #print(f"{timeInsertion[-1]=}, {timeRadix[-1]=}, {timeShell[-1]=}")
-
-    fig1 = plt.plot(ns, timeRadix, label="radix")
-    fig2 = plt.plot(ns, timeShell, label="shell")
-    fig3 = plt.plot(ns, timeInsertion, label="insertion")
-    plt.legend()
-    plt.xscale("log")
-    plt.yscale("log")
-    plt.savefig("sorts_compared.png")
-    # fig2.savefig("2.png")
-    # fig3.savefig("3.png")
+import matplotlib.pyplot as plt
+import time
+import random
+
+
+def unique_rand(n):
+    rands = list(range(n))
+    random.shuffle(rands)
+    return rands
+
+def bucket_sort(elems, power, radix):
+    digit_buckets = [[] for i in range(radix)]
+    ended = True
+
+    for elem in elems:
+        digit = (elem // power) % radix
+        if digit != 0:
+            ended = False
+        digit_buckets[digit].append(elem)
+
+    k = 0
+    for bucket in digit_buckets:
+        for elem in bucket:
+            elems[k] = elem
+            k+=1
+    return ended
+
+
+def count_sort(elems, radix, radix_to_n):
+    digit_sorted_elems = [0 for i in range(len(elems))]
+    digit_counts = [0 for i in range(radix)]
+    is_radix_too_big = True
+
+    for elem in elems:
+        digit = int(elem / radix_to_n) % radix
+        if digit != 0:
+            is_radix_too_big = False
+        digit_counts[digit] += 1
+
+    cum_sum = 0
+    for i in range(len(digit_counts)):
+        count = digit_counts[i]
+        digit_counts[i] = cum_sum
+        cum_sum += count
+
+    for elem in elems:
+        digit = int(elem / radix_to_n) % radix
+        digit_sorted_elems[digit_counts[digit]] = elem
+        digit_counts[digit] += 1
+
+    for i in range(len(elems)):
+        elems[i] = digit_sorted_elems[i]
+
+    return is_radix_too_big
+
+
+def radix_sort(elems, radix):
+    power = 1
+    while not bucket_sort(elems, power, radix):
+        power *= radix
+
+
+def increment_sort(elems, increment):
+    for i in range(increment, len(elems)):
+        for j in range(i, increment - 1, -increment):
+            if elems[j] < elems[j - increment]:
+                elems[j], elems[j - increment] = elems[j - increment], elems[j]
+            else:
+                break
+
+
+def insertion_sort(elems):
+    increment_sort(elems, 1)
+
+
+def shell_sort(elems):
+    increment = int(len(elems) / 2)
+    while increment > 0:
+        increment_sort(elems, increment)
+        increment = int(increment / 2)
+
+
+if __name__ == "__main__":
+    ns = [10, 1000, 2000, 5000, 100000]
+    timeRadix, timeShell, timeInsertion = [], [], []
+    for i in ns:
+        #print(f"Now considering arrays of size {i}: ")
+        nums = unique_rand(i)
+        nums1, nums2, nums3 = list(nums), list(nums), list(nums)
+        start = time.perf_counter()
+        radix_sort(nums1, 256)
+        timeRadix.append(time.perf_counter() - start)
+        start = time.perf_counter()
+        shell_sort(nums2)
+        timeShell.append(time.perf_counter() - start)
+        start = time.perf_counter()
+        insertion_sort(nums3)
+        timeInsertion.append(time.perf_counter() - start)
+        #print(f"{timeInsertion[-1]=}, {timeRadix[-1]=}, {timeShell[-1]=}")
+
+    fig1 = plt.plot(ns, timeRadix, label="radix")
+    fig2 = plt.plot(ns, timeShell, label="shell")
+    fig3 = plt.plot(ns, timeInsertion, label="insertion")
+    plt.legend()
+    plt.xscale("log")
+    plt.yscale("log")
+    plt.savefig("sorts_compared.png")
+    # fig2.savefig("2.png")
+    # fig3.savefig("3.png")
diff --git a/Ex1/3-insertion_order.py b/Ex1/3-insertion_order.py
index e58e29d..a5d3b6e 100644
--- a/Ex1/3-insertion_order.py
+++ b/Ex1/3-insertion_order.py
@@ -1,45 +1,45 @@
-import random
-import time
-
-def increment_sort(elems, increment):
-    for i in range(increment, len(elems)):
-        #print(f"{i=}")
-        for j in range(i, increment - 1, -increment):
-            if elems[j] < elems[j - increment]:
-                elems[j], elems[j - increment] = elems[j - increment], elems[j]
-            else:
-                break
-
-
-def insertion_sort(elems):
-    increment_sort(elems, 1)
-
-def unique_rand(n):
-    rands = list(range(n))
-    random.shuffle(rands)
-    return rands
-
-unsorted_elems = unique_rand(100000)
-ascending_elems = sorted(unsorted_elems)
-descending_elems = sorted(unsorted_elems, reverse=True)
-
-ascending_start_ns = time.process_time_ns()
-insertion_sort(ascending_elems)
-ascending_end_ns = time.process_time_ns()
-ascending_time = (ascending_end_ns - ascending_start_ns)/10**9
-print(f"{ascending_time=}")
-
-descending_start_ns = time.process_time_ns()
-insertion_sort(descending_elems)
-descending_end_ns = time.process_time_ns()
-descending_time = (descending_end_ns - descending_start_ns)/10**9
-print(f"{descending_time=}")
-
-unsorted_start_ns = time.process_time_ns()
-insertion_sort(unsorted_elems)
-unsorted_end_ns = time.process_time_ns()
-unsorted_time = (unsorted_end_ns - unsorted_start_ns)/10**9
-print(f"{unsorted_time=}")
-
-with open("results.txt", "a", encoding="utf-8") as f:
+import random
+import time
+
+def increment_sort(elems, increment):
+    for i in range(increment, len(elems)):
+        #print(f"{i=}")
+        for j in range(i, increment - 1, -increment):
+            if elems[j] < elems[j - increment]:
+                elems[j], elems[j - increment] = elems[j - increment], elems[j]
+            else:
+                break
+
+
+def insertion_sort(elems):
+    increment_sort(elems, 1)
+
+def unique_rand(n):
+    rands = list(range(n))
+    random.shuffle(rands)
+    return rands
+
+unsorted_elems = unique_rand(100000)
+ascending_elems = sorted(unsorted_elems)
+descending_elems = sorted(unsorted_elems, reverse=True)
+
+ascending_start_ns = time.process_time_ns()
+insertion_sort(ascending_elems)
+ascending_end_ns = time.process_time_ns()
+ascending_time = (ascending_end_ns - ascending_start_ns)/10**9
+print(f"{ascending_time=}")
+
+descending_start_ns = time.process_time_ns()
+insertion_sort(descending_elems)
+descending_end_ns = time.process_time_ns()
+descending_time = (descending_end_ns - descending_start_ns)/10**9
+print(f"{descending_time=}")
+
+unsorted_start_ns = time.process_time_ns()
+insertion_sort(unsorted_elems)
+unsorted_end_ns = time.process_time_ns()
+unsorted_time = (unsorted_end_ns - unsorted_start_ns)/10**9
+print(f"{unsorted_time=}")
+
+with open("results.txt", "a", encoding="utf-8") as f:
     f.write(f"{ascending_time=}, {descending_time=}, {unsorted_time=}")
\ No newline at end of file
diff --git a/Ex1/4-search.py b/Ex1/4-search.py
index e48a365..9a71c15 100644
--- a/Ex1/4-search.py
+++ b/Ex1/4-search.py
@@ -1,41 +1,41 @@
-import random
-import time
-
-def unique_rand(n):
-    rands = list(range(n))
-    random.shuffle(rands)
-    return rands
-
-def rec_binary_search(elems, elem, start, end):
-    if end < start:
-        return -1
-    mid_ind = (start + end)//2
-    if elem == elems[mid_ind]:
-        return mid_ind
-    if elem < elems[mid_ind]:
-        return rec_binary_search(elems, elem, start, mid_ind-1)
-    return rec_binary_search(elems, elem, mid_ind + 1, end)
-
-def iter_binary_search(elems, elem):
-    start, end = 0, len(elems) - 1
-    while end >= start:
-        mid_ind = (start + end)//2
-        if elem == elems[mid_ind]:
-            return mid_ind
-        if elem < elems[mid_ind]:
-            end = mid_ind - 1
-        else:
-            start = mid_ind + 1
-    return -1
-
-nums = unique_rand(100000)
-iter_start = time.perf_counter_ns()
-iter_binary_search(nums, -1)
-iter_end = time.perf_counter_ns()
-iter_time = (iter_end - iter_start)/1000
-print(f"{iter_time=}us")
-rec_start = time.perf_counter_ns()
-rec_binary_search(nums, -1, 0, len(nums)-1)
-rec_end = time.perf_counter_ns()
-rec_time = (rec_end - rec_start)/1000
+import random
+import time
+
+def unique_rand(n):
+    rands = list(range(n))
+    random.shuffle(rands)
+    return rands
+
+def rec_binary_search(elems, elem, start, end):
+    if end < start:
+        return -1
+    mid_ind = (start + end)//2
+    if elem == elems[mid_ind]:
+        return mid_ind
+    if elem < elems[mid_ind]:
+        return rec_binary_search(elems, elem, start, mid_ind-1)
+    return rec_binary_search(elems, elem, mid_ind + 1, end)
+
+def iter_binary_search(elems, elem):
+    start, end = 0, len(elems) - 1
+    while end >= start:
+        mid_ind = (start + end)//2
+        if elem == elems[mid_ind]:
+            return mid_ind
+        if elem < elems[mid_ind]:
+            end = mid_ind - 1
+        else:
+            start = mid_ind + 1
+    return -1
+
+nums = unique_rand(100000)
+iter_start = time.perf_counter_ns()
+iter_binary_search(nums, -1)
+iter_end = time.perf_counter_ns()
+iter_time = (iter_end - iter_start)/1000
+print(f"{iter_time=}us")
+rec_start = time.perf_counter_ns()
+rec_binary_search(nums, -1, 0, len(nums)-1)
+rec_end = time.perf_counter_ns()
+rec_time = (rec_end - rec_start)/1000
 print(f"{rec_time=}us")
\ No newline at end of file
diff --git a/Ex1/unique_rand.py b/Ex1/unique_rand.py
index 6a11093..c9b5c92 100644
--- a/Ex1/unique_rand.py
+++ b/Ex1/unique_rand.py
@@ -1,19 +1,19 @@
-import random;
-def unique_rand(start, end, n):
-	nums = {}
-	while len(nums) < n:
-		nums[random.randint(start, end)]=None
-	return list(nums.keys())
-
-def unique_rand_2(n):
-	lst = list(range(n))
-	random.shuffle(lst)
-	return lst
-
-if __name__ == "__main__":
-	start = int(input("Enter the start for the range of random numbers: "))
-	end = int(input("Enter the end for the range of random numbers(inclusive): "))
-	n = int(input("Enter the no. random nums you want to generate: "))
-	nums = unique_rand(start, end, n)
-	print(f"The numbers: {nums}")
-
+import random;
+def unique_rand(start, end, n):
+	nums = {}
+	while len(nums) < n:
+		nums[random.randint(start, end)]=None
+	return list(nums.keys())
+
+def unique_rand_2(n):
+	lst = list(range(n))
+	random.shuffle(lst)
+	return lst
+
+if __name__ == "__main__":
+	start = int(input("Enter the start for the range of random numbers: "))
+	end = int(input("Enter the end for the range of random numbers(inclusive): "))
+	n = int(input("Enter the no. random nums you want to generate: "))
+	nums = unique_rand(start, end, n)
+	print(f"The numbers: {nums}")
+
diff --git a/Ex2/1-unique_elems.py b/Ex2/1-unique_elems.py
index 1ac60b7..80379a0 100644
--- a/Ex2/1-unique_elems.py
+++ b/Ex2/1-unique_elems.py
@@ -1,19 +1,19 @@
-def unique_elems(arr):
-    unique = []
-    for i in range(len(arr)):
-        if not containsMult(arr, arr[i]):
-            unique.append(arr[i])
-    return unique
-
-def containsMult(arr, elem):
-    count = 0
-    for i in range(len(arr)):
-        if arr[i] == elem:
-            count += 1
-    return count > 1
-
-if __name__ == "__main__":
-    text = input("Enter some space separated numbers: ")
-    nums = [int(num) for num in text.split()]
-    print(f"Unique nums: {unique_elems(nums)}")
-
+def unique_elems(arr):
+    unique = []
+    for i in range(len(arr)):
+        if not containsMult(arr, arr[i]):
+            unique.append(arr[i])
+    return unique
+
+def containsMult(arr, elem):
+    count = 0
+    for i in range(len(arr)):
+        if arr[i] == elem:
+            count += 1
+    return count > 1
+
+if __name__ == "__main__":
+    text = input("Enter some space separated numbers: ")
+    nums = [int(num) for num in text.split()]
+    print(f"Unique nums: {unique_elems(nums)}")
+
diff --git a/Ex2/2-sum.py b/Ex2/2-sum.py
index afe0c8e..97bf205 100644
--- a/Ex2/2-sum.py
+++ b/Ex2/2-sum.py
@@ -1,6 +1,6 @@
-def calc_sum(n):
-    return n * (n+1) * (n+2) / 6
-
-if __name__ == "__main__":
-    n = int(input("Enter n: "))
+def calc_sum(n):
+    return n * (n+1) * (n+2) / 6
+
+if __name__ == "__main__":
+    n = int(input("Enter n: "))
     print(f"Sum: {calc_sum(n)}")
\ No newline at end of file
diff --git a/Ex2/3-most_freq.py b/Ex2/3-most_freq.py
index 248e35f..f4c0ebc 100644
--- a/Ex2/3-most_freq.py
+++ b/Ex2/3-most_freq.py
@@ -1,21 +1,21 @@
-def most_freq(text):
-    max_count = 0
-    char_counts = {}
-    for i in range(len(text)):
-        letter = text[i]
-        letter_count = 1
-        if letter in char_counts:
-            letter_count = char_counts[letter] + 1
-        if letter_count > max_count:
-            max_count = letter_count
-        char_counts[letter] = letter_count
-    most_freq_chars = []
-    for key in char_counts:
-        if char_counts[key] == max_count:
-            most_freq_chars.append(key)
-
-    return most_freq_chars
-
-if __name__ == "__main__":
-    text = input("Enter some text: ")
-    print(f"Most frequent chars: {most_freq(text)}")
+def most_freq(text):
+    max_count = 0
+    char_counts = {}
+    for i in range(len(text)):
+        letter = text[i]
+        letter_count = 1
+        if letter in char_counts:
+            letter_count = char_counts[letter] + 1
+        if letter_count > max_count:
+            max_count = letter_count
+        char_counts[letter] = letter_count
+    most_freq_chars = []
+    for key in char_counts:
+        if char_counts[key] == max_count:
+            most_freq_chars.append(key)
+
+    return most_freq_chars
+
+if __name__ == "__main__":
+    text = input("Enter some text: ")
+    print(f"Most frequent chars: {most_freq(text)}")
diff --git a/Ex3/1-inversions.py b/Ex3/1-inversions.py
index 85cdb8a..1988737 100644
--- a/Ex3/1-inversions.py
+++ b/Ex3/1-inversions.py
@@ -1,42 +1,42 @@
-def merge_count(nums, start, end):
-    if start == end:
-        return 0
-    count = 0
-    mid = (start + end) // 2
-    count += merge_count(nums, start, mid)
-    count += merge_count(nums, mid + 1, end)
-    count += merge(nums, start, end)
-
-    return count
-
-
-def merge(nums, start, end):
-    tot_len = end - start + 1
-    aux = [0] * (tot_len)
-    count = 0
-    mid = (start + end) // 2
-    i, j = 0, 0
-    while i + j < tot_len:
-        if mid + 1 + j > end or (
-            start + i < mid + 1 and nums[start + i] <= nums[mid + 1 + j]
-        ):
-            aux[i + j] = nums[start + i]
-            i += 1
-        else:
-            aux[i + j] = nums[mid + 1 + j]
-            count += mid + 1 - start - i
-            j += 1
-    for i in range(start, end + 1):
-        nums[i] = aux[i - start]
-
-    return count
-
-
-def count_inversions(nums):
-    return merge_count(nums, 0, len(nums) - 1)
-
-
-if __name__ == "__main__":
-    text = input("Enter some space separated numbers: ")
-    nums = [int(num) for num in text.split()]
-    print(f"{count_inversions(nums)=}")
+def merge_count(nums, start, end):
+    if start == end:
+        return 0
+    count = 0
+    mid = (start + end) // 2
+    count += merge_count(nums, start, mid)
+    count += merge_count(nums, mid + 1, end)
+    count += merge(nums, start, end)
+
+    return count
+
+
+def merge(nums, start, end):
+    tot_len = end - start + 1
+    aux = [0] * (tot_len)
+    count = 0
+    mid = (start + end) // 2
+    i, j = 0, 0
+    while i + j < tot_len:
+        if mid + 1 + j > end or (
+            start + i < mid + 1 and nums[start + i] <= nums[mid + 1 + j]
+        ):
+            aux[i + j] = nums[start + i]
+            i += 1
+        else:
+            aux[i + j] = nums[mid + 1 + j]
+            count += mid + 1 - start - i
+            j += 1
+    for i in range(start, end + 1):
+        nums[i] = aux[i - start]
+
+    return count
+
+
+def count_inversions(nums):
+    return merge_count(nums, 0, len(nums) - 1)
+
+
+if __name__ == "__main__":
+    text = input("Enter some space separated numbers: ")
+    nums = [int(num) for num in text.split()]
+    print(f"{count_inversions(nums)=}")
diff --git a/Ex3/2-comp_count_sort.py b/Ex3/2-comp_count_sort.py
index e7081c6..02d4614 100644
--- a/Ex3/2-comp_count_sort.py
+++ b/Ex3/2-comp_count_sort.py
@@ -1,18 +1,18 @@
-def comparison_count_sort(nums):
-    count = [0] * len(nums)
-    nums_sorted = [0] * len(nums)
-    for i in range(len(nums) - 1):
-        for j in range(i + 1, len(nums)):
-            if nums[i] > nums[j]:
-                count[i] += 1
-            elif nums[i] <= nums[j]:
-                count[j] += 1
-    for i in range(len(nums)):
-        nums_sorted[count[i]] = nums[i]
-    return nums_sorted
-
-
-if __name__ == "__main__":
-    text = input("Enter some space separated numbers: ")
-    nums = [int(num) for num in text.split()]
-    print(f"{comparison_count_sort(nums)=}")
+def comparison_count_sort(nums):
+    count = [0] * len(nums)
+    nums_sorted = [0] * len(nums)
+    for i in range(len(nums) - 1):
+        for j in range(i + 1, len(nums)):
+            if nums[i] > nums[j]:
+                count[i] += 1
+            elif nums[i] <= nums[j]:
+                count[j] += 1
+    for i in range(len(nums)):
+        nums_sorted[count[i]] = nums[i]
+    return nums_sorted
+
+
+if __name__ == "__main__":
+    text = input("Enter some space separated numbers: ")
+    nums = [int(num) for num in text.split()]
+    print(f"{comparison_count_sort(nums)=}")
diff --git a/Ex4/1-max.py b/Ex4/1-max.py
index 11f7456..0cf18a6 100644
--- a/Ex4/1-max.py
+++ b/Ex4/1-max.py
@@ -1,15 +1,15 @@
-def my_max(arr, start, end):
-    if start == end:
-        return arr[start]
-    mid = (start + end) // 2
-    max1 = my_max(arr, start, mid)
-    max2 = my_max(arr, mid + 1, end)
-    real_max = max1 if max1 > max2 else max2
-    return real_max
-
-
-if __name__ == "__main__":
-    text = input("Enter some space separated numbers: ")
-    nums = [int(num) for num in text.split()]
-    print(f"{my_max(nums, 0, len(nums)-1)=}")
-
+def my_max(arr, start, end):
+    if start == end:
+        return arr[start]
+    mid = (start + end) // 2
+    max1 = my_max(arr, start, mid)
+    max2 = my_max(arr, mid + 1, end)
+    real_max = max1 if max1 > max2 else max2
+    return real_max
+
+
+if __name__ == "__main__":
+    text = input("Enter some space separated numbers: ")
+    nums = [int(num) for num in text.split()]
+    print(f"{my_max(nums, 0, len(nums)-1)=}")
+
diff --git a/Ex4/2-merge_inversion.py b/Ex4/2-merge_inversion.py
index 85cdb8a..1988737 100644
--- a/Ex4/2-merge_inversion.py
+++ b/Ex4/2-merge_inversion.py
@@ -1,42 +1,42 @@
-def merge_count(nums, start, end):
-    if start == end:
-        return 0
-    count = 0
-    mid = (start + end) // 2
-    count += merge_count(nums, start, mid)
-    count += merge_count(nums, mid + 1, end)
-    count += merge(nums, start, end)
-
-    return count
-
-
-def merge(nums, start, end):
-    tot_len = end - start + 1
-    aux = [0] * (tot_len)
-    count = 0
-    mid = (start + end) // 2
-    i, j = 0, 0
-    while i + j < tot_len:
-        if mid + 1 + j > end or (
-            start + i < mid + 1 and nums[start + i] <= nums[mid + 1 + j]
-        ):
-            aux[i + j] = nums[start + i]
-            i += 1
-        else:
-            aux[i + j] = nums[mid + 1 + j]
-            count += mid + 1 - start - i
-            j += 1
-    for i in range(start, end + 1):
-        nums[i] = aux[i - start]
-
-    return count
-
-
-def count_inversions(nums):
-    return merge_count(nums, 0, len(nums) - 1)
-
-
-if __name__ == "__main__":
-    text = input("Enter some space separated numbers: ")
-    nums = [int(num) for num in text.split()]
-    print(f"{count_inversions(nums)=}")
+def merge_count(nums, start, end):
+    if start == end:
+        return 0
+    count = 0
+    mid = (start + end) // 2
+    count += merge_count(nums, start, mid)
+    count += merge_count(nums, mid + 1, end)
+    count += merge(nums, start, end)
+
+    return count
+
+
+def merge(nums, start, end):
+    tot_len = end - start + 1
+    aux = [0] * (tot_len)
+    count = 0
+    mid = (start + end) // 2
+    i, j = 0, 0
+    while i + j < tot_len:
+        if mid + 1 + j > end or (
+            start + i < mid + 1 and nums[start + i] <= nums[mid + 1 + j]
+        ):
+            aux[i + j] = nums[start + i]
+            i += 1
+        else:
+            aux[i + j] = nums[mid + 1 + j]
+            count += mid + 1 - start - i
+            j += 1
+    for i in range(start, end + 1):
+        nums[i] = aux[i - start]
+
+    return count
+
+
+def count_inversions(nums):
+    return merge_count(nums, 0, len(nums) - 1)
+
+
+if __name__ == "__main__":
+    text = input("Enter some space separated numbers: ")
+    nums = [int(num) for num in text.split()]
+    print(f"{count_inversions(nums)=}")
diff --git a/Ex4/3-max_subarray_sum.py b/Ex4/3-max_subarray_sum.py
index c41a699..3c12b7f 100644
--- a/Ex4/3-max_subarray_sum.py
+++ b/Ex4/3-max_subarray_sum.py
@@ -1,32 +1,32 @@
-def max_subarray_sum(arr, start, end):
-    if start == end:
-        return arr[start]
-
-    mid = (start + end) // 2
-    max1 = max_subarray_sum(arr, start, mid)
-    max2 = max_subarray_sum(arr, mid + 1, end)
-
-    max_left = 0
-    cum_left = 0
-    for i in range(mid, start - 1, -1):
-        cum_left += arr[i]
-        if cum_left > max_left:
-            max_left = cum_left
-
-    max_right = 0
-    cum_right = 0
-    for i in range(mid + 1, end + 1):
-        cum_right += arr[i]
-        if cum_right > max_right:
-            max_right = cum_right
-
-    max3 = max_left + max_right
-
-    return max(max1, max2, max3)
-
-
-if __name__ == "__main__":
-    text = input("Enter some space separated numbers: ")
-    nums = [int(num) for num in text.split()]
-    print(f"{max_subarray_sum(nums, 0, len(nums)-1)}")
+def max_subarray_sum(arr, start, end):
+    if start == end:
+        return arr[start]
+
+    mid = (start + end) // 2
+    max1 = max_subarray_sum(arr, start, mid)
+    max2 = max_subarray_sum(arr, mid + 1, end)
+
+    max_left = 0
+    cum_left = 0
+    for i in range(mid, start - 1, -1):
+        cum_left += arr[i]
+        if cum_left > max_left:
+            max_left = cum_left
+
+    max_right = 0
+    cum_right = 0
+    for i in range(mid + 1, end + 1):
+        cum_right += arr[i]
+        if cum_right > max_right:
+            max_right = cum_right
+
+    max3 = max_left + max_right
+
+    return max(max1, max2, max3)
+
+
+if __name__ == "__main__":
+    text = input("Enter some space separated numbers: ")
+    nums = [int(num) for num in text.split()]
+    print(f"{max_subarray_sum(nums, 0, len(nums)-1)}")

\ No newline at end of file
diff --git a/Ex4/4-max_sub_2.py b/Ex4/4-max_sub_2.py
index 51aa511..d5eb271 100644
--- a/Ex4/4-max_sub_2.py
+++ b/Ex4/4-max_sub_2.py
@@ -1,25 +1,25 @@
-def max_subarray_sum(nums):
-    aux = [0] * len(nums)
-    prev = 0
-    for i, num in enumerate(nums):
-        aux[i] = prev + num
-        prev = aux[i]
-
-    print(f"{aux=}")
-
-    cur_lowest = 0
-    cur_max = 0
-
-    for num in aux:
-        cur_sum = num - cur_lowest
-        if cur_sum > cur_max:
-            cur_max = cur_sum
-        if num < cur_lowest:
-            cur_lowest = num
-
-    return cur_max
-
-
-if __name__ == "__main__":
-    nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
-    print(f"{max_subarray_sum(nums)}")
+def max_subarray_sum(nums):
+    aux = [0] * len(nums)
+    prev = 0
+    for i, num in enumerate(nums):
+        aux[i] = prev + num
+        prev = aux[i]
+
+    print(f"{aux=}")
+
+    cur_lowest = 0
+    cur_max = 0
+
+    for num in aux:
+        cur_sum = num - cur_lowest
+        if cur_sum > cur_max:
+            cur_max = cur_sum
+        if num < cur_lowest:
+            cur_lowest = num
+
+    return cur_max
+
+
+if __name__ == "__main__":
+    nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
+    print(f"{max_subarray_sum(nums)}")
diff --git a/Ex4/store.c b/Ex4/store.c
new file mode 100644
index 0000000..55f0d4b
--- /dev/null
+++ b/Ex4/store.c
@@ -0,0 +1,178 @@
+// void non_preemptive(PriorityFunc pf, Event *event, double timedelta, double quanta) {
+// 	handle_event_arrived_and_done(event, pf(event->pcb));
+
+// 	if(event->type == QuantaOver) {
+// 		cur_pcb->burst_left -= timedelta;
+// 		pqueue_add(pqueue, init_pentry(cur_pcb->priority, cur_pcb), false);
+// 		cur_pcb = NULL;
+// 	}
+
+// 	if(cur_pcb == NULL) {
+// 		PEntry *entry = pqueue_extract_min(pqueue);
+// 		if(entry != NULL) {
+// 			cur_pcb = entry->pcb;
+// 			if(cur_pcb->burst_left <= quanta) {
+// 				event_queue_add(event_queue, init_event(event->time + cur_pcb->burst_left, cur_pcb, Done));
+// 			} else {
+// 				event_queue_add(event_queue, init_event(event->time + quanta, cur_pcb, QuantaOver));
+// 			}
+// 		}
+// 		free(entry);
+// 	}
+// }
+
+
+
+
+
+// void sjfs_non_preemptive(Event *event, double timedelta) {
+
+// 	handle_event_arrived_and_done(event, 1/event->pcb->burst_left);
+
+// 	if(cur_pcb == NULL) {
+// 		PEntry *entry = pqueue_extract_min(pqueue);
+// 		if(entry != NULL) {
+// 			cur_pcb = entry->pcb;
+// 			event_queue_add(event_queue, init_event(event->time + cur_pcb->burst_left, cur_pcb, Done));
+// 		}
+// 		free(entry);
+// 	}
+// }
+
+// void round_robin_priority_nonpreemptive(Event *event, double timedelta, double quanta) {
+
+// 	handle_event_arrived_and_done(event, event->pcb->priority);
+
+// 	// if(event->type == Arrived) {
+// 	// 	pqueue_add(pqueue, init_pentry(event->pcb->priority, event->pcb), false);
+// 	// }
+
+// 	// if(event->type == Done) {
+// 	// 	free(cur_pcb);
+// 	// 	cur_pcb = NULL;
+// 	// }
+
+// 	if(event->type == QuantaOver) {
+// 		cur_pcb->burst_left -= timedelta;
+// 		pqueue_add(pqueue, init_pentry(cur_pcb->priority, cur_pcb), false);
+// 		cur_pcb = NULL;
+// 	}
+
+// 	if(cur_pcb == NULL) {
+// 		PEntry *entry = pqueue_extract_min(pqueue);
+// 		if(entry != NULL) {
+// 			cur_pcb = entry->pcb;
+// 			if(cur_pcb->burst_left <= quanta) {
+// 				event_queue_add(event_queue, init_event(event->time + cur_pcb->burst_left, cur_pcb, Done));
+// 			} else {
+// 				event_queue_add(event_queue, init_event(event->time + quanta, cur_pcb, QuantaOver));
+// 			}
+// 		}
+// 		free(entry);
+// 	}
+// }
+
+// void preemptive(PriorityFunc pf, Event *event, double timedelta) {
+// 	handle_event_arrived_and_done(event, pf(event->pcb));
+
+// 	if(cur_pcb != NULL) {
+// 		event_queue_remove(event_queue, cur_pcb->pid);
+// 		cur_pcb->burst_left -= timedelta;
+// 		pqueue_add(pqueue, init_pentry(pf(cur_pcb), cur_pcb), true);
+// 	}
+
+// 	cur_pcb = NULL;
+// 	PEntry *entry = pqueue_extract_min(pqueue);
+// 	if(entry != NULL) {
+// 		cur_pcb = entry->pcb;
+// 		event_queue_add(event_queue, init_event(event->time + cur_pcb->burst_left, cur_pcb, Done));
+// 	}
+// 	free(entry);
+// }
+
+// void sjfs_preemptive(Event *event, double timedelta) {
+// 	// if(event->type == Arrived) {
+// 	// 	pqueue_add(pqueue, init_pentry(1/event->pcb->burst_left, event->pcb), false);
+// 	// }
+
+// 	// if(event->type == Done) {
+// 	// 	free(cur_pcb);
+// 	// 	cur_pcb = NULL;
+// 	// }
+
+// 	handle_event_arrived_and_done(event, 1/event->pcb->burst_left);
+
+// 	if(cur_pcb != NULL) {
+// 		event_queue_remove(event_queue, cur_pcb->pid);
+// 		cur_pcb->burst_left -= timedelta;
+// 		pqueue_add(pqueue, init_pentry(1/cur_pcb->burst_left, cur_pcb), true);
+// 	}
+
+// 	cur_pcb = NULL;
+// 	PEntry *entry = pqueue_extract_min(pqueue);
+// 	if(entry != NULL) {
+// 		cur_pcb = entry->pcb;
+// 		event_queue_add(event_queue, init_event(event->time + cur_pcb->burst_left, cur_pcb, Done));
+// 	}
+// 	free(entry);
+// }
+
+
+// void priority_preemptive(Event *event, double timedelta) {
+// 	// if(event->type == Arrived) {
+// 	// 	pqueue_add(pqueue, init_pentry(event->pcb->priority, event->pcb), false);
+// 	// }
+
+// 	// if(event->type == Done) {
+// 	// 	free(cur_pcb);
+// 	// 	cur_pcb = NULL;
+// 	// }
+
+// 	handle_event_arrived_and_done(event, event->pcb->priority);
+
+// 	if(cur_pcb != NULL) {
+// 		event_queue_remove(event_queue, cur_pcb->pid);
+// 		cur_pcb->burst_left -= timedelta;
+// 		pqueue_add(pqueue, init_pentry(cur_pcb->priority, cur_pcb), true);
+// 	}
+
+// 	cur_pcb = NULL;
+// 	PEntry *entry = pqueue_extract_min(pqueue);
+// 	if(entry != NULL) {
+// 		cur_pcb = entry->pcb;
+// 		event_queue_add(event_queue, init_event(event->time + cur_pcb->burst_left, cur_pcb, Done));
+// 	}
+
+// 	free(entry);
+// }
+
+// void handle_event_arrived_and_done(Event *event, double priority) {
+// 	if(event->type == Arrived) {
+// 		pqueue_add(pqueue, init_pentry(priority, event->pcb), false);
+// 	}
+
+// 	if(event->type == Done) {
+// 		free(cur_pcb);
+// 		cur_pcb = NULL;
+// 	}
+// }
+
+// void fcfs_priority_non_preemptive(Event *event) {
+// 	if(event->type == Arrived) {
+// 		pqueue_add(pqueue, init_pentry(event->pcb->priority, event->pcb), false);
+// 	}
+
+// 	if(event->type == Done) {
+// 		free(cur_pcb)
+// 		cur_pcb = NULL;
+// 	}
+
+// 	if(cur_pcb == NULL) {
+// 		PEntry *entry = pqueue_extract_min(pqueue);
+// 		if(entry != NULL) {
+// 			cur_pcb = entry->pcb;
+// 			event_queue_add(event_queue, init_event(event->time + cur_pcb->burst_left, cur_pcb, Done));
+// 		}
+// 		free(entry);
+// 	}
+// }
\ No newline at end of file
diff --git a/Ex5/1-kth_smallest_elem.py b/Ex5/1-kth_smallest_elem.py
new file mode 100644
index 0000000..ae6369f
--- /dev/null
+++ b/Ex5/1-kth_smallest_elem.py
@@ -0,0 +1,45 @@
+import random
+import time
+
+def increment_sort(elems, increment):
+    for i in range(increment, len(elems)):
+        for j in range(i, increment - 1, -increment):
+            if elems[j] < elems[j - increment]:
+                elems[j], elems[j - increment] = elems[j - increment], elems[j]
+            else:
+                break
+
+
+def insertion_sort(elems):
+    increment_sort(elems, 1)
+
+def partition(arr, start, end, pivot_ind):
+    arr[pivot_ind], arr[start] = arr[start], arr[pivot_ind]
+    pivot_ind = start
+    for i in range(pivot_ind, end + 1):
+        if arr[i] < arr[pivot_ind]:
+            arr[i], arr[pivot_ind + 1] = arr[pivot_ind + 1], arr[i]
+            arr[pivot_ind], arr[pivot_ind + 1] = arr[pivot_ind + 1], arr[pivot_ind]
+            pivot_ind += 1
+    return pivot_ind
+
+def k_smallest(arr, k, start, end):
+    print(f"{start=}, {end=}")
+    if start == end:
+        return arr[start]
+    pivot_ind = partition(arr, start, end, random.randint(start, end))
+    if pivot_ind == k - 1:
+        return arr[pivot_ind]
+    if pivot_ind > k - 1:
+        return k_smallest(arr, k, start, pivot_ind - 1)
+    return k_smallest(arr, k, pivot_ind + 1, end)
+
+if __name__ == "__main__":
+    seed = time.time_ns()
+    #random.seed(seed)
+    #print(f"{seed=}")
+    nums_str = input("Enter comma separated numbers: ")
+    nums = [int(num_str) for num_str in nums_str.split(',')]
+    k = int(input("Enter k: "))
+    k_small = k_smallest(nums, k, 0, len(nums) - 1)
+    print(f"K-th smallest elem: {k_small}")
diff --git a/Ex5/2-tree_sum.py b/Ex5/2-tree_sum.py
new file mode 100644
index 0000000..100ba79
--- /dev/null
+++ b/Ex5/2-tree_sum.py
@@ -0,0 +1,60 @@
+import random
+class TreeNode:
+    def __init__(self):
+        self.data = 0
+        self.left = None
+        self.right = None
+
+    def insert(self, data):
+        if data < self.data:
+            if self.left == None:
+                tempNode = TreeNode()
+                self.left = tempNode
+                self.left.data = data
+            else:
+                self.left.insert(data)
+        elif data > self.data:
+            if self.right == None:
+                tempNode = TreeNode()
+                self.right = tempNode
+                self.right.data = data
+            else:
+                self.right.insert(data)
+    def traverseInOrder(self):
+        if self.left != None:
+            self.left.traverseInOrder()
+        print(self.data, end=' ')
+        if self.right != None:
+            self.right.traverseInOrder()
+def createRoot():
+    i = random.randint(1, 10)
+    rootNode = TreeNode()
+    rootNode.data = i
+    return rootNode
+
+def createTree():
+    rootNode = createRoot()
+    numNodes = random.randint(1, 10)
+    print(f"{numNodes=}")
+    currentNode = rootNode
+    j = 1
+    L = [rootNode.data]
+    while (j < numNodes):
+        newVal = random.randint(1,20)
+        if newVal not in L:
+            currentNode.insert(newVal)
+            L.append(newVal)
+            j+=1
+    rootNode.traverseInOrder()
+    return rootNode
+# Code to populate the tree ends here
+def getSum(node):
+    if node == None:
+        return 0
+    else:
+        leftSum = getSum(node.left)
+        rightSum = getSum(node.right)
+        return node.data + leftSum + rightSum
+
+rootNode = createTree()
+print("Sum = ",getSum(rootNode))
\ No newline at end of file
diff --git a/Ex5/3-closest_points.py b/Ex5/3-closest_points.py
new file mode 100644
index 0000000..7458c37
--- /dev/null
+++ b/Ex5/3-closest_points.py
@@ -0,0 +1,72 @@
+import math
+import matplotlib.pyplot as plt
+import random
+import time
+
+class Point:
+    def __init__(self, x, y):
+        self.x = x
+        self.y = y
+
+    def tuple(self):
+        return (self.x, self.y)
+
+    @staticmethod
+    def dist(a, b):
+        return (a.x - b.x)**2 + (a.y - b.y)**2
+
+def closest_points(points):
+    points_sorted_x = sorted(points, key = lambda p:p.x)
+    points_sorted_y = sorted(points, key = lambda p:p.y)
+    return closest_points_helper(points_sorted_x, points_sorted_y)
+
+def closest_points_helper(points_x, points_y):
+    if len(points_x) == 1:
+        return None, None, math.inf
+    if len(points_x) == 2:
+        return points_x[0], points_x[1], Point.dist(points_x[0], points_x[1])
+
+    left_x, right_x = points_x[:len(points_x)//2], points_x[len(points_x)//2:]
+    boundary_x = (left_x[-1].x + right_x[0].x) / 2
+    #plt.vlines(boundary_x, 0, 100)
+    left_y, right_y = [point for point in points_y if point.x <= boundary_x], [point for point in points_y if point.x > boundary_x]
+
+    left_p1, left_p2, left_d = closest_points_helper(left_x, left_y)
+    right_p1, right_p2, right_d = closest_points_helper(right_x, right_y)
+
+    p1, p2, d = (left_p1, left_p2, left_d) if left_d < right_d else (right_p1, right_p2, right_d)
+
+    cross_y = [point for point in points_y if abs(point.x - boundary_x) < d]
+
+    for i, point in enumerate(cross_y):
+        for j in range(i+1, len(cross_y)):
+            if cross_y[j].y - point.y >= d:
+                break
+            if (temp_d := Point.dist(point, cross_y[j])) < d:
+                p1, p2, d = point, cross_y[j], temp_d
+
+    return p1, p2, d
+
+n = 100
+points = [Point(random.uniform(0, 100), random.uniform(0, 100)) for i in range(n)]
+start = time.perf_counter()
+ap1, ap2, ad = None,  None, math.inf
+for i, t1 in enumerate(points):
+    for t2 in points[i+1:]:
+        if((temp_d:=Point.dist(t1, t2)) < ad):
+            ad = temp_d
+            ap1 = t1
+            ap2 = t2
+print(f"{ad=}")
+end = time.perf_counter()
+print(f"{end - start = }")
+plt.scatter(*zip(*[p.tuple() for p in points]), c='blue')
+start = time.perf_counter()
+p1, p2, d = closest_points(points)
+print(f"{d=}")
+end = time.perf_counter()
+print(f"{end - start = }")
+plt.scatter([p1.x, p2.x], [p1.y, p2.y], color = 'green')
+plt.scatter([ap1.x,ap2.x], [ap1.y, ap2.y], color = 'red')
+#plt.hlines(0, 0, 100)
+plt.show()
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
index 9f61605..0820fa4 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,24 +1,24 @@
-BSD 2-Clause License
-
-Copyright (c) 2024, Depixelate
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
-   list of conditions and the following disclaimer.
-
-2. Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+BSD 2-Clause License
+
+Copyright (c) 2024, Depixelate
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
index 4e1bbd1..be86360 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,2 @@
-# algo-analysis
-A Practice Repository For Learning About different kinds of algorithms
+# algo-analysis
+A Practice Repository For Learning About different kinds of algorithms
  • Loading branch information
Depixelate committed Apr 10, 2024
1 parent bc8ec8a commit 88a0579
Show file tree
Hide file tree
Showing 21 changed files with 986 additions and 631 deletions.
320 changes: 160 additions & 160 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,160 +1,160 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock

# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
30 changes: 15 additions & 15 deletions Ex1/1-unique_rand.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import random


def unique_rand(n):
rands = list(range(n))
random.shuffle(rands)
return rands


if __name__ == "__main__":
# start = int(input("Enter the start for the range of random numbers: "))
# end = int(input("Enter the end for the range of random numbers(inclusive): "))
n = int(input("Enter the no. random nums you want to generate: "))
nums = unique_rand(n)
print(f"The numbers: {nums}")
import random


def unique_rand(n):
rands = list(range(n))
random.shuffle(rands)
return rands


if __name__ == "__main__":
# start = int(input("Enter the start for the range of random numbers: "))
# end = int(input("Enter the end for the range of random numbers(inclusive): "))
n = int(input("Enter the no. random nums you want to generate: "))
nums = unique_rand(n)
print(f"The numbers: {nums}")
Loading

0 comments on commit 88a0579

Please sign in to comment.