master 266e5608b0c3 cached
88 files
1.5 MB
425.1k tokens
245 symbols
1 requests
Download .txt
Showing preview only (1,602K chars total). Download the full file or copy to clipboard to get everything.
Repository: aladdinpersson/Algorithms-Collection-Python
Branch: master
Commit: 266e5608b0c3
Files: 88
Total size: 1.5 MB

Directory structure:
gitextract_4q2tk5k2/

├── .gitignore
├── .travis.yml
├── Algorithm_tests/
│   ├── cryptology_tests/
│   │   └── ceasar_test.py
│   ├── dynamic_programming_tests/
│   │   ├── knapsack_tests/
│   │   │   └── knapsack_bottomup_test.py
│   │   ├── sequence_alignment/
│   │   │   └── sequence_alignment_test.py
│   │   └── weighted_interval_scheduling/
│   │       └── weighted_interval_scheduling_test.py
│   ├── graphtheory_tests/
│   │   ├── BFS_test.py
│   │   ├── DFS_test.py
│   │   ├── Djikstra/
│   │   │   ├── djikstra_heap_test.py
│   │   │   └── djikstra_naive_test.py
│   │   ├── bellman_ford_test.py
│   │   ├── kahn_topological_ordering_test.py
│   │   ├── kruskal_unionfind_test.py
│   │   ├── prims_algorithm_test.py
│   │   ├── test_NN.py
│   │   └── test_graph.txt
│   ├── math_tests/
│   │   ├── intersection_test.py
│   │   └── union_test.py
│   ├── other_tests/
│   │   ├── test_binarysearch.py
│   │   ├── test_intervalscheduling.py
│   │   └── test_medianmaintenance.py
│   └── sorting_tests/
│       └── test_sorting.py
├── Algorithms/
│   ├── cryptology/
│   │   ├── RSA_algorithm/
│   │   │   ├── RSA.py
│   │   │   └── euclid_gcd.py
│   │   ├── ceasar_shifting_cipher/
│   │   │   └── ceasar_shift_cipher.py
│   │   ├── hill_cipher/
│   │   │   └── hill_cipher.py
│   │   ├── one_time_pad/
│   │   │   └── one_time_pad.py
│   │   └── vigenere_cipher/
│   │       └── vigenere.py
│   ├── dynamic_programming/
│   │   ├── knapsack/
│   │   │   ├── knapsack_bottomup.py
│   │   │   ├── knapsack_memoization_recursive_topdown.py
│   │   │   └── knapsack_naive_recursive.py
│   │   ├── longest_increasing_subsequence.py
│   │   ├── sequence_alignment.py
│   │   └── weighted_interval_scheduling.py
│   ├── graphtheory/
│   │   ├── bellman-ford/
│   │   │   ├── bellman_ford.py
│   │   │   └── data.txt
│   │   ├── breadth-first-search/
│   │   │   ├── BFS_queue_iterative.py
│   │   │   └── exgraph.txt
│   │   ├── depth-first-search/
│   │   │   ├── DFS_recursive.py
│   │   │   ├── DFS_stack_iterative.py
│   │   │   └── exgraph.txt
│   │   ├── dijkstra/
│   │   │   ├── dijkstra.py
│   │   │   ├── dijkstraData.txt
│   │   │   └── heapdijkstra.py
│   │   ├── floyd-warshall/
│   │   │   ├── floyd-warshall.py
│   │   │   └── test_graph.txt
│   │   ├── kahns-toposort/
│   │   │   ├── example.txt
│   │   │   └── kahn_topological_ordering.py
│   │   ├── kargers/
│   │   │   ├── kargermincut.py
│   │   │   └── kargermincutdata.txt
│   │   ├── kruskal/
│   │   │   ├── edges.txt
│   │   │   ├── kruskal.py
│   │   │   ├── kruskal_unionfind.py
│   │   │   └── testedges.txt
│   │   ├── nearest-neighbor-tsp/
│   │   │   ├── NearestNeighborTSP.py
│   │   │   └── graph.txt
│   │   └── prims/
│   │       ├── edges.txt
│   │       ├── prim_heap.py
│   │       └── prim_naive.py
│   ├── math/
│   │   ├── euclid_gcd/
│   │   │   └── euclid_gcd.py
│   │   ├── extended_euclidean_algorithm/
│   │   │   └── euclid_gcd.py
│   │   ├── intersection_of_two_sets/
│   │   │   └── intersection_of_two_sets.py
│   │   ├── karatsuba/
│   │   │   └── karatsuba.py
│   │   ├── pollard_p1/
│   │   │   └── pollard_p1.py
│   │   ├── prime_factorization/
│   │   │   └── primefactorization.py
│   │   ├── sieve_of_eratosthenes/
│   │   │   └── sieve_eratosthenes.py
│   │   └── union_of_two_sets/
│   │       └── union_of_two_sets.py
│   ├── numerical_methods/
│   │   ├── bisection.py
│   │   └── fixpoint.py
│   ├── other/
│   │   ├── Huffman/
│   │   │   ├── Huffman.py
│   │   │   ├── huffman.txt
│   │   │   └── test.txt
│   │   ├── Kadanes_algorithm.py
│   │   ├── binarysearch.py
│   │   ├── counting_inversions.py
│   │   ├── interval_scheduling.py
│   │   └── median_maintenance.py
│   └── sorting/
│       ├── bubblesort.py
│       ├── hopesort.py
│       ├── insertionsort.py
│       ├── mergesort.py
│       ├── quicksort.py
│       ├── randomized_quicksort.py
│       └── selectionsort.py
├── LICENSE
├── README.md
├── requirements.txt
└── setup.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
plot_complexity.py

================================================
FILE: .travis.yml
================================================
language: python

# Default Python version is usually 2.7
python: 3.7

# Install ruby to get gem command
before_install:
    - python --version
    - pip install -U pip
    - pip install -U pytest
    - pip install codecov
    - sudo apt-add-repository -y ppa:brightbox/ruby-ng
    - sudo apt-get -y update
    - sudo apt-get -y install ruby-full

before_script:
    - gem install awesome_bot

install:
    - pip3 install -r requirements.txt
    - pip3 install pytest
    - pip3 install pytest-cov
    - pip3 install codecov

script: 
    - awesome_bot README.md --allow-dupe --allow-redirect
    - pytest --cov=Algorithms/
    
     # # Dynamic Programming Tests
     # - python Algorithm_tests/dynamic_programming_tests/knapsack_tests/knapsack_bottomup_test.py
     # - python Algorithm_tests/dynamic_programming_tests/sequence_alignment/sequence_alignment_test.py
     # - python Algorithm_tests/dynamic_programming_tests/weighted_interval_scheduling/weighted_interval_scheduling_test.py
     #
     # # Graph Theory Tests
     # - python Algorithm_tests/graphtheory_tests/bellman_ford_test.py
     # - python Algorithm_tests/graphtheory_tests/kahn_topological_ordering_test.py
     # - python Algorithm_tests/graphtheory_tests/Djikstra/djikstra_heap_test.py
     # - python Algorithm_tests/graphtheory_tests/Djikstra/djikstra_naive_test.py
     # - python Algorithm_tests/graphtheory_tests/kruskal_unionfind_test.py
     # - python Algorithm_tests/graphtheory_tests/prims_algorithm_test.py
     # - python Algorithm_tests/graphtheory_tests/BFS_test.py
     # - python Algorithm_tests/graphtheory_tests/DFS_test.py
     #
     # # Math tests
     # - python Algorithm_tests/other_tests/test_binarysearch.py
     # - python Algorithm_tests/math_tests/intersection_test.py
     # - python Algorithm_tests/math_tests/union_test.py
     #
     # # Cryptography tests
     # - python Algorithm_tests/cryptology_tests/ceasar_test.py
     #
     # # "Other" tests
     # - python Algorithm_tests/other_tests/test_medianmaintenance.py
     # - python Algorithm_tests/other_tests/test_intervalscheduling.py
     #
     # # Sorting tests
     # - python Algorithm_tests/sorting_tests/test_sorting.py

after_success:
    - codecov


================================================
FILE: Algorithm_tests/cryptology_tests/ceasar_test.py
================================================
# Import folder where sorting algorithms
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/cryptology/ceasar_shifting_cipher")

# If run from local:
# sys.path.append('../../Algorithms/cryptology/ceasar_shifting_cipher')

from ceasar_shift_cipher import encrypt, decrypt

# Note this is not robust.. but im trying to make it a habit to make some tests.
# Some are better than nothing. But these are not complete at all.
class test_ceasar_cipher(unittest.TestCase):
    def setUp(self):
        # test cases we wish to run
        self.message1 = "abc"
        self.shift1 = 3
        self.correct_encrypt1 = "def"

        self.message2 = "xyz "
        self.shift2 = 1
        self.correct_encrypt2 = "yz a"

    def test_encryption_message1(self):
        encrypted_message1 = encrypt(self.message1, self.shift1)
        self.assertEqual(encrypted_message1, self.correct_encrypt1)

    def test_decryption_message1(self):
        decrypted_message1 = decrypt(self.correct_encrypt1, self.shift1)
        self.assertEqual(decrypted_message1, self.message1)

    def test_encryption_message2(self):
        encrypted_message2 = encrypt(self.message2, self.shift2)
        self.assertEqual(encrypted_message2, self.correct_encrypt2)

    def test_decryption_message2(self):
        decrypted_message2 = decrypt(self.correct_encrypt2, self.shift2)
        self.assertEqual(decrypted_message2, self.message2)


if __name__ == "__main__":
    print("Running ceasar cipher tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/dynamic_programming_tests/knapsack_tests/knapsack_bottomup_test.py
================================================
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/dynamic_programming/knapsack")

# If run from local:
# sys.path.append('../../../Algorithms/dynamic_programming/knapsack/')
from knapsack_bottomup import knapsack


class test_KnapSack(unittest.TestCase):
    def setUp(self):
        self.weights1, self.values1, self.capacity1 = [], [], 100
        self.n1 = len(self.weights1)
        self.correctvalue1, self.correctitems1 = 0, []

        self.weights2, self.values2, self.capacity2 = [10], [50], 100
        self.n2 = len(self.weights2)
        self.correctvalue2, self.correctitems2 = 50, [0]

        self.weights3, self.values3, self.capacity3 = [10, 20, 30], [-10, -20, -30], 100
        self.n3 = len(self.weights2)
        self.correctvalue3, self.correctitems3 = 0, []

        self.weights4, self.values4, self.capacity4 = (
            [1, 2, 4, 2, 5],
            [5, 3, 5, 3, 2],
            5,
        )
        self.n4 = len(self.weights4)
        self.correctvalue4, self.correctitems4 = 11, [0, 1, 3]

        self.weights5, self.values5, self.capacity5 = [10, 10, 10], [30, 30, 30], 5
        self.n5 = len(self.weights5)
        self.correctvalue5, self.correctitems5 = 0, []

    def test_noitems(self):
        total_value, items = knapsack(
            self.n1, self.capacity1, self.weights1, self.values1
        )
        self.assertEqual(self.correctvalue1, total_value)
        self.assertEqual(self.correctitems1, items)

    def test_singleitem_value(self):
        total_value, items = knapsack(
            self.n2, self.capacity2, self.weights2, self.values2
        )
        self.assertEqual(self.correctvalue2, total_value)
        self.assertEqual(self.correctitems2, items)

    def test_negativevalues(self):
        total_value, items = knapsack(
            self.n3, self.capacity3, self.weights3, self.values3
        )
        self.assertEqual(self.correctvalue3, total_value)
        self.assertEqual(self.correctitems3, items)

    def test_simpleexample(self):
        total_value, items = knapsack(
            self.n4, self.capacity4, self.weights4, self.values4
        )
        self.assertEqual(self.correctvalue4, total_value)
        self.assertEqual(self.correctitems4, items)

    def test_weight_too_heavy(self):
        total_value, items = knapsack(
            self.n5, self.capacity5, self.weights5, self.values5
        )
        self.assertEqual(self.correctvalue5, total_value)
        self.assertEqual(self.correctitems5, items)


if __name__ == "__main__":
    print("Running Knapsack tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/dynamic_programming_tests/sequence_alignment/sequence_alignment_test.py
================================================
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/dynamic_programming/")

# If run from local:
# sys.path.append('../../../Algorithms/dynamic_programming/')
from sequence_alignment import SequenceAlignment


class test_sequence_alignment(unittest.TestCase):
    def setUp(self):
        self.x1 = "ABC"
        self.y1 = "ADC"
        self.correct_editstep1 = 1

        self.x2 = "AB"
        self.y2 = "A"
        self.correct_editstep2 = 1

        self.x3 = "A"
        self.y3 = ""
        self.correct_editstep3 = 1

        self.x4 = "ABC"
        self.y4 = "ABCDE"
        self.correct_editstep4 = 2

        self.x5 = "ABCKL"
        self.y5 = "ADCE"
        self.correct_editstep5 = 3

        self.x6 = "A" * 10
        self.y6 = ""
        self.correct_editstep6 = 10

        self.x7 = ""
        self.y7 = "A" * 10
        self.correct_editstep7 = 10

        self.x8 = "TGACGTGC"
        self.y8 = "TCGACGTCA"
        self.correct_editstep8 = 3

        self.x9 = "XYZ"
        self.y9 = "XKZ"
        self.correct_solution9 = ["align_X", "align_K", "align_Z"]

        self.x10 = "XX"
        self.y10 = ""
        self.correct_solution10 = ["remove_X", "remove_X"]

        self.x11 = ""
        self.y11 = "XX"
        self.correct_solution11 = ["insert_X", "insert_X"]

    def test_simplecase(self):
        sequence_align = SequenceAlignment(self.x1, self.y1)
        editsteps, _ = sequence_align.alignment()
        self.assertEqual(self.correct_editstep1, editsteps)

    def test_remove(self):
        sequence_align = SequenceAlignment(self.x2, self.y2)
        editsteps, _ = sequence_align.alignment()
        self.assertEqual(self.correct_editstep2, editsteps)

    def test_remove_to_empty(self):
        sequence_align = SequenceAlignment(self.x3, self.y3)
        editsteps, _ = sequence_align.alignment()
        self.assertEqual(self.correct_editstep3, editsteps)

    def test_insert_elements(self):
        sequence_align = SequenceAlignment(self.x4, self.y4)
        editsteps, _ = sequence_align.alignment()
        self.assertEqual(self.correct_editstep4, editsteps)

    def test_remove_insert_align(self):
        sequence_align = SequenceAlignment(self.x5, self.y5)
        editsteps, _ = sequence_align.alignment()
        self.assertEqual(self.correct_editstep5, editsteps)

    def test_x_longer_than_y(self):
        sequence_align = SequenceAlignment(self.x6, self.y6)
        editsteps, _ = sequence_align.alignment()
        self.assertEqual(self.correct_editstep6, editsteps)

    def test_y_longer_than_x(self):
        sequence_align = SequenceAlignment(self.x7, self.y7)
        editsteps, _ = sequence_align.alignment()
        self.assertEqual(self.correct_editstep7, editsteps)

    def test_more_complicated_example(self):
        sequence_align = SequenceAlignment(self.x8, self.y8)
        editsteps, _ = sequence_align.alignment()
        self.assertEqual(self.correct_editstep8, editsteps)

    def test_findsolution_simplecase(self):
        sequence_align = SequenceAlignment(self.x9, self.y9)
        _, solution = sequence_align.alignment()
        self.assertEqual(self.correct_solution9, solution)

    def test_findsolution_empty_y(self):
        sequence_align = SequenceAlignment(self.x10, self.y10)
        _, solution = sequence_align.alignment()
        self.assertEqual(self.correct_solution10, solution)

    def test_findsolution_empty_x(self):
        sequence_align = SequenceAlignment(self.x11, self.y11)
        _, solution = sequence_align.alignment()
        self.assertEqual(self.correct_solution11, solution)


if __name__ == "__main__":
    print("Running Sequence Alignment tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/dynamic_programming_tests/weighted_interval_scheduling/weighted_interval_scheduling_test.py
================================================
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/dynamic_programming/")

# If run from local:
# sys.path.append('../../../Algorithms/dynamic_programming/')
from weighted_interval_scheduling import WeightedIntervalScheduling


class test_weighted_interval_scheduling(unittest.TestCase):
    def setUp(self):
        self.I1 = []
        self.correct_maxweight1 = 0
        self.correct_intervals1 = []

        self.I2 = [(0, 3, 10)]
        self.correct_maxweight2 = 10
        self.correct_intervals2 = [(0, 3, 10)]

        self.I3 = [(0, 3, 5), (2, 5, 15), (4, 6, 5)]
        self.correct_maxweight3 = 15
        self.correct_intervals3 = [(2, 5, 15)]

        self.I4 = [(0, 3, 5), (3, 5, 15), (5, 7, 5)]
        self.correct_maxweight4 = 25
        self.correct_intervals4 = [(0, 3, 5), (3, 5, 15), (5, 7, 5)]

        self.I5 = [(0, 3, 5), (3, 5, -100), (5, 7, -50)]
        self.correct_maxweight5 = 5
        self.correct_intervals5 = [(0, 3, 5)]

        self.I6 = [(0, 50, 1), (0, 49, 1), (0, 48, 1), (15, 20, 10)]
        self.correct_maxweight6 = 10
        self.correct_intervals6 = [(15, 20, 10)]

        self.I7 = [(0, 50, 1), (0, 50, 1), (0, 50, 1), (0, 50, 1)]
        self.correct_maxweight7 = 1
        self.correct_intervals7 = [(0, 50, 1)]

        self.I8 = [(0, 50, 1), (0, 49, 1), (0, 48, 1), (0, 47, 1)]
        self.correct_maxweight8 = 1
        self.correct_intervals8 = [(0, 47, 1)]

        self.I9 = [(0, 50, 2), (0, 49, 1), (0, 48, 1), (0, 47, 1)]
        self.correct_maxweight9 = 2
        self.correct_intervals9 = [(0, 50, 2)]

    def test_empty_interval(self):
        weightedinterval = WeightedIntervalScheduling(self.I1)
        max_weight, best_intervals = weightedinterval.weighted_interval()
        self.assertEqual(self.correct_maxweight1, max_weight)
        self.assertEqual(self.correct_intervals1, best_intervals)

    def test_single_interval(self):
        weightedinterval = WeightedIntervalScheduling(self.I2)
        max_weight, best_intervals = weightedinterval.weighted_interval()
        self.assertEqual(self.correct_maxweight2, max_weight)
        self.assertEqual(self.correct_intervals2, best_intervals)

    def test_overlapping_intervals(self):
        weightedinterval = WeightedIntervalScheduling(self.I3)
        max_weight, best_intervals = weightedinterval.weighted_interval()
        self.assertEqual(self.correct_maxweight3, max_weight)
        self.assertEqual(self.correct_intervals3, best_intervals)

    def test_no_overlapping_intervals(self):
        weightedinterval = WeightedIntervalScheduling(self.I4)
        max_weight, best_intervals = weightedinterval.weighted_interval()
        self.assertEqual(self.correct_maxweight4, max_weight)
        self.assertEqual(self.correct_intervals4, best_intervals)

    def test_negative_weights(self):
        weightedinterval = WeightedIntervalScheduling(self.I5)
        max_weight, best_intervals = weightedinterval.weighted_interval()
        self.assertEqual(self.correct_maxweight5, max_weight)
        self.assertEqual(self.correct_intervals5, best_intervals)

    def test_interval_contained_in_all_intervals(self):
        weightedinterval = WeightedIntervalScheduling(self.I6)
        max_weight, best_intervals = weightedinterval.weighted_interval()
        self.assertEqual(self.correct_maxweight6, max_weight)
        self.assertEqual(self.correct_intervals6, best_intervals)

    def test_all_intervals_same(self):
        weightedinterval = WeightedIntervalScheduling(self.I7)
        max_weight, best_intervals = weightedinterval.weighted_interval()
        self.assertEqual(self.correct_maxweight7, max_weight)
        self.assertEqual(self.correct_intervals7, best_intervals)

    def test_earliest_finish_time(self):
        weightedinterval = WeightedIntervalScheduling(self.I8)
        max_weight, best_intervals = weightedinterval.weighted_interval()
        self.assertEqual(self.correct_maxweight8, max_weight)
        self.assertEqual(self.correct_intervals8, best_intervals)

    def test_earliest_finish_time_not_best(self):
        weightedinterval = WeightedIntervalScheduling(self.I9)
        max_weight, best_intervals = weightedinterval.weighted_interval()
        self.assertEqual(self.correct_maxweight9, max_weight)
        self.assertEqual(self.correct_intervals9, best_intervals)


if __name__ == "__main__":
    print("Running Weighted Interval Scheduling tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/graphtheory_tests/BFS_test.py
================================================
# Import folder where sorting algorithms
import sys
import unittest
from collections import deque

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/graphtheory/breadth-first-search/")

# If run from local:
# sys.path.append('../../Algorithms/graphtheory/breadth-first-search/')
from BFS_queue_iterative import BFS


class test_BFS(unittest.TestCase):
    def setUp(self):
        self.G1 = {1: [2], 2: [1, 3], 3: [2]}
        self.correct_visited1 = [True] * 3
        self.correct_path1 = [1, 2, 3]

        self.G2 = {1: [2], 2: [1, 3, 4], 3: [2], 4: [2, 5], 5: [4]}
        self.correct_visited2 = [True] * 5

        self.G3 = {1: [2], 2: [1, 3, 4], 3: [2], 4: [2], 5: []}
        self.correct_visited3 = [True] * 4 + [False]

        self.G4 = {1: [2, 3, 4], 2: [1, 3, 4], 3: [1, 2, 4], 4: [1, 2, 3]}
        self.correct_visited4 = [True] * 4

        self.G5 = {
            1: [2, 3, 4],
            2: [1, 5],
            3: [1, 7],
            4: [1, 6],
            5: [2],
            6: [4],
            7: [3],
        }
        self.correct_visited5 = [True] * 7

    def test_linear_graph(self):
        visited, path = BFS(self.G1, start_node=1)
        self.assertEqual(visited, self.correct_visited1)
        self.assertEqual(path, self.correct_path1)

    def test_simple_graph(self):
        visited, path = BFS(self.G2, start_node=1)
        self.assertTrue(path.index(3) < path.index(5))
        self.assertEqual(visited, self.correct_visited2)

    def test_disconnected_graph(self):
        visited, path = BFS(self.G3, start_node=1)
        self.assertEqual(visited, self.correct_visited3)

    def test_complete_graph(self):
        visited, path = BFS(self.G4, start_node=1)
        self.assertEqual(visited, self.correct_visited4)

    def test_breadth_before_depth(self):
        visited, path = BFS(self.G5, start_node=1)
        self.assertEqual(visited, self.correct_visited5)

        # Make sure it goes breadth first
        self.assertTrue(path.index(2) < path.index(5))
        self.assertTrue(path.index(2) < path.index(6))
        self.assertTrue(path.index(2) < path.index(7))
        self.assertTrue(path.index(3) < path.index(5))
        self.assertTrue(path.index(3) < path.index(6))
        self.assertTrue(path.index(3) < path.index(7))
        self.assertTrue(path.index(4) < path.index(5))
        self.assertTrue(path.index(4) < path.index(6))
        self.assertTrue(path.index(4) < path.index(7))


if __name__ == "__main__":
    print("Running BFS/DFS tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/graphtheory_tests/DFS_test.py
================================================
# Import folder where sorting algorithms
import sys
import unittest
from collections import deque

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/graphtheory/depth-first-search/")

# If run from local:
# sys.path.append('../../Algorithms/graphtheory/depth-first-search/')
from DFS_recursive import DFS as DFS_rec
from DFS_stack_iterative import DFS as DFS_stack


class test_DFS(unittest.TestCase):
    def setUp(self):
        self.G1 = {1: [2], 2: [1, 3], 3: [2]}
        self.correct_visited1 = [True] * 3
        self.correct_path1 = [1, 2, 3]
        self.DFS_recursive_visited1 = [False for i in range(1, len(self.G1) + 1)]

        self.G2 = {1: [2], 2: [1, 3, 4], 3: [2], 4: [2, 5], 5: [4]}
        self.correct_visited2 = [True] * 5
        self.DFS_recursive_visited2 = [False for i in range(1, len(self.G2) + 1)]

        self.G3 = {1: [2], 2: [1, 3, 4], 3: [2], 4: [2], 5: []}
        self.correct_visited3 = [True] * 4 + [False]
        self.DFS_recursive_visited3 = [False for i in range(1, len(self.G3) + 1)]

        self.G4 = {1: [2, 3, 4], 2: [1, 3, 4], 3: [1, 2, 4], 4: [1, 2, 3]}
        self.correct_visited4 = [True] * 4
        self.DFS_recursive_visited4 = [False for i in range(1, len(self.G4) + 1)]

    def test_linear_graph(self):
        visited, path = DFS_stack(self.G1, start_node=1)
        self.assertEqual(visited, self.correct_visited1)
        self.assertEqual(path, self.correct_path1)

        DFS_rec(self.G1, 1, self.DFS_recursive_visited1)
        self.assertEqual(self.DFS_recursive_visited1, self.correct_visited1)

    def test_simple_graph(self):
        visited, path = DFS_stack(self.G2, start_node=1)
        self.assertEqual(visited, self.correct_visited2)

        DFS_rec(self.G2, 1, self.DFS_recursive_visited2)
        self.assertEqual(self.DFS_recursive_visited2, self.correct_visited2)

    def test_disconnected_graph(self):
        visited, path = DFS_stack(self.G3, start_node=1)
        self.assertEqual(visited, self.correct_visited3)

        DFS_rec(self.G3, 1, self.DFS_recursive_visited3)
        self.assertEqual(self.DFS_recursive_visited3, self.correct_visited3)

    def test_complete_graph(self):
        visited, path = DFS_stack(self.G4, start_node=1)
        self.assertEqual(visited, self.correct_visited4)

        DFS_rec(self.G4, 1, self.DFS_recursive_visited4)
        self.assertEqual(self.DFS_recursive_visited4, self.correct_visited4)


if __name__ == "__main__":
    print("Running BFS/DFS tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/graphtheory_tests/Djikstra/djikstra_heap_test.py
================================================
# Import folder where sorting algorithms
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/graphtheory/dijkstra/")

# If run from local:
# sys.path.append('../../../Algorithms/graphtheory/dijkstra/')

from heapdijkstra import dijkstra


class test_Dijkstra(unittest.TestCase):
    def setUp(self):
        self.G1 = {}
        self.correct_path1 = []
        self.correct_dist1 = float("inf")

        self.G2 = {1: {2: 1, 4: 10}, 2: {3: 15}, 3: {6: 5}, 4: {5: 1}, 5: {6: 1}, 6: {}}
        self.correct_path2 = [1, 4, 5, 6]
        self.correct_dist2 = 12

        self.G3 = {1: {2: 1, 4: 10}, 2: {3: 15}, 3: {}, 4: {5: 1}, 5: {}, 6: {}}
        self.correct_path3 = []
        self.correct_dist3 = float("inf")

        self.G4 = {1: {2: 1, 4: 10}, 2: {3: 15}, 3: {6: 5}, 4: {5: 1}, 5: {6: 1}, 6: {}}
        self.correct_path4 = [1, 4, 5]
        self.correct_dist4 = 11

    def test_emptygraph(self):
        path_to_take, distances = dijkstra(self.G1, 0, 1)
        self.assertEqual(distances[1], self.correct_dist1)
        self.assertEqual(path_to_take, self.correct_path1)

    def test_simplegraph(self):
        path_to_take, distances = dijkstra(self.G2, 1, 6)
        self.assertEqual(distances[6], self.correct_dist2)
        self.assertEqual(path_to_take, self.correct_path2)

    def test_no_path_exists(self):
        path_to_take, distances = dijkstra(self.G3, 1, 6)
        self.assertEqual(distances[6], self.correct_dist3)
        self.assertEqual(path_to_take, self.correct_path3)

    def test_not_endpoint(self):
        path_to_take, distances = dijkstra(self.G4, 1, 5)
        self.assertEqual(distances[5], self.correct_dist4)
        self.assertEqual(path_to_take, self.correct_path4)


if __name__ == "__main__":
    print("Running Djikstra tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/graphtheory_tests/Djikstra/djikstra_naive_test.py
================================================
# Import folder where sorting algorithms
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/graphtheory/dijkstra/")

# If run from local:
# sys.path.append('../../../Algorithms/graphtheory/dijkstra/')

from dijkstra import dijkstra


class test_Dijkstra(unittest.TestCase):
    def setUp(self):
        self.G1 = {}
        self.correct_path1 = []
        self.correct_dist1 = float("inf")

        self.G2 = {1: {2: 1, 4: 10}, 2: {3: 15}, 3: {6: 5}, 4: {5: 1}, 5: {6: 1}, 6: {}}
        self.correct_path2 = [1, 4, 5, 6]
        self.correct_dist2 = 12

        self.G3 = {1: {2: 1, 4: 10}, 2: {3: 15}, 3: {}, 4: {5: 1}, 5: {}, 6: {}}
        self.correct_path3 = []
        self.correct_dist3 = float("inf")

        self.G4 = {1: {2: 1, 4: 10}, 2: {3: 15}, 3: {6: 5}, 4: {5: 1}, 5: {6: 1}, 6: {}}
        self.correct_path4 = [1, 4, 5]
        self.correct_dist4 = 11

    def test_emptygraph(self):
        path_to_take, distance = dijkstra(self.G1, 0, 1)
        self.assertEqual(distance, self.correct_dist1)
        self.assertEqual(path_to_take, self.correct_path1)

    def test_simplegraph(self):
        path_to_take, distance = dijkstra(self.G2, 1, 6)
        self.assertEqual(distance, self.correct_dist2)
        self.assertEqual(path_to_take, self.correct_path2)

    def test_no_path_exists(self):
        path_to_take, distance = dijkstra(self.G3, 1, 6)
        self.assertEqual(distance, self.correct_dist3)
        self.assertEqual(path_to_take, self.correct_path3)

    def test_not_endpoint(self):
        path_to_take, distance = dijkstra(self.G4, 1, 5)
        self.assertEqual(distance, self.correct_dist4)
        self.assertEqual(path_to_take, self.correct_path4)


if __name__ == "__main__":
    print("Running Djikstra tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/graphtheory_tests/bellman_ford_test.py
================================================
# Import folder where sorting algorithms
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/graphtheory/bellman-ford")

# If run from local:
# sys.path.append('../../Algorithms/graphtheory/bellman-ford')

from bellman_ford import bellman_ford


class test_BellmanFord(unittest.TestCase):
    def test_negativecycle(self):
        # Because of negative cycles, we shall denote the shortest path for these
        # as -infinity.
        G = {1: {2: 5, 3: 20}, 2: {4: 10}, 3: {5: 10}, 4: {}, 5: {6: 5}, 6: {3: -20}}

        correct_shortest_dist = {
            1: 0,
            2: 5,
            3: -float("inf"),
            4: 15,
            5: -float("inf"),
            6: -float("inf"),
        }
        shortest_dist, _ = bellman_ford(G, 1)

        self.assertEqual(shortest_dist, correct_shortest_dist)

    def test_shortestdist(self):
        G = {1: {2: 100, 3: 5}, 2: {4: 20}, 3: {2: 10}, 4: {}}

        start_node = 1
        shortest_dist, _ = bellman_ford(G, start_node)

        # Test distance to starting node should be 0
        self.assertEqual(shortest_dist[start_node], 0)

        # Test shortest distances from graph
        self.assertEqual(shortest_dist[2], 15)
        self.assertEqual(shortest_dist[3], 5)
        self.assertEqual(shortest_dist[4], 35)

    def test_run_emptygraph(self):
        G = {}
        start_node = 1

        # Cant run an empty graph without returning error
        with self.assertRaises(ValueError):
            shortest_dist, _ = bellman_ford(G, start_node)


if __name__ == "__main__":
    print("Running bellman ford tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/graphtheory_tests/kahn_topological_ordering_test.py
================================================
# Import folder where sorting algorithms
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/graphtheory/kahns-toposort/")

# If run from local:
# sys.path.append('../../Algorithms/graphtheory/kahns-toposort')

from kahn_topological_ordering import topological_ordering
from collections import defaultdict


class test_TopologicalOrdering(unittest.TestCase):
    def setUp(self):
        self.G1 = {}
        self.degree_incoming1 = defaultdict(int, {})
        self.correct_isDAG1 = False
        self.correct_path1 = []

        self.G2 = {"1": ["2"], "2": ["3"], "3": ["4"], "4": ["5"], "5": []}
        self.degree_incoming2 = defaultdict(int, {"2": 1, "3": 1, "4": 1, "5": 1})
        self.correct_isDAG2 = True
        self.correct_path2 = ["1", "2", "3", "4", "5"]

        self.G3 = {
            "1": ["2", "3", "4", "5"],
            "2": ["3", "4", "5"],
            "3": ["4", "5"],
            "4": ["5"],
            "5": [],
        }
        self.degree_incoming3 = defaultdict(int, {"2": 1, "3": 2, "4": 3, "5": 4})
        self.correct_isDAG3 = True
        self.correct_path3 = ["1", "2", "3", "4", "5"]

        self.G4 = {
            "1": ["2", "3", "4", "5"],
            "2": ["3", "4", "5"],
            "3": ["2", "4", "5"],
            "4": ["5"],
            "5": [],
        }
        self.degree_incoming4 = defaultdict(int, {"2": 2, "3": 2, "4": 3, "5": 4})
        self.correct_isDAG4 = False
        self.correct_path4 = []

    def test_emptygraph(self):
        path_to_take, is_DAG = topological_ordering(self.G1, self.degree_incoming1)
        self.assertEqual(path_to_take, self.correct_path1)
        self.assertEqual(is_DAG, self.correct_isDAG1)

    def test_clear_ordering(self):
        path_to_take, is_DAG = topological_ordering(self.G2, self.degree_incoming2)
        self.assertEqual(path_to_take, self.correct_path2)
        self.assertEqual(is_DAG, self.correct_isDAG2)

    def test_more_complicated_graph(self):
        path_to_take, is_DAG = topological_ordering(self.G3, self.degree_incoming3)
        self.assertEqual(path_to_take, self.correct_path3)
        self.assertEqual(is_DAG, self.correct_isDAG3)

    def test_no_topological_ordering(self):
        path_to_take, is_DAG = topological_ordering(self.G4, self.degree_incoming4)
        self.assertEqual(path_to_take, self.correct_path4)
        self.assertEqual(is_DAG, self.correct_isDAG4)


if __name__ == "__main__":
    print("Running Topological Ordering tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/graphtheory_tests/kruskal_unionfind_test.py
================================================
# Import folder where sorting algorithms
import sys
import unittest
from unionfind import unionfind

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/graphtheory/kruskal/")

# If run from local:
# sys.path.append('../../Algorithms/graphtheory/kruskal/')
from kruskal_unionfind import kruskal


class test_Kruskal(unittest.TestCase):
    def setUp(self):
        # self.G1 = {1:[(10, 2, 1)], 2:[(10, 1, 2), (10, 3, 2)], 3:[(10, 2, 3)]}
        self.G1 = [(10, 2, 1), (10, 1, 2), (10, 3, 2), (10, 2, 3)]
        self.num_nodes1 = 3
        self.correct_cost1 = 20
        self.correct_MST1 = [(1, 2, 10), (2, 3, 10)]

        self.G2 = [
            (10, 2, 1),
            (10, 3, 1),
            (10, 1, 2),
            (100, 3, 2),
            (10, 1, 3),
            (100, 2, 3),
        ]
        self.num_nodes2 = 3
        self.correct_cost2 = 20
        self.correct_MST2 = [(1, 2, 10), (1, 3, 10)]

        self.G3 = [
            (1, 2, 1),
            (1, 1, 2),
            (1, 3, 2),
            (1, 4, 3),
            (5, 5, 3),
            (1, 3, 4),
            (1, 5, 4),
            (5, 3, 5),
            (1, 4, 5),
        ]
        self.num_nodes3 = 5
        self.correct_cost3 = 4
        self.correct_MST3 = [(1, 2, 1), (2, 3, 1), (3, 4, 1), (4, 5, 1)]

        self.G4 = [(1, 2, 1), (1, 1, 2), (1, 4, 3), (1, 3, 4)]
        self.num_nodes4 = 4
        self.correct_cost4 = 2
        self.correct_MST4 = [(1, 2, 1), (3, 4, 1)]

        self.G5 = {}
        self.num_nodes5 = 0
        self.correct_cost5 = 0
        self.correct_MST5 = []

        # Takes as input G which will have {node1: [(cost, to_node, node1), ...], node2:[(...)] }

    def test_linear_graph(self):
        MST, cost = kruskal(sorted(self.G1, key=lambda tup: tup[0]), self.num_nodes1)
        self.assertEqual(MST, self.correct_MST1)
        self.assertEqual(cost, self.correct_cost1)

    def test_triangle_graph(self):
        MST, cost = kruskal(sorted(self.G2, key=lambda tup: tup[0]), self.num_nodes2)
        self.assertEqual(MST, self.correct_MST2)
        self.assertEqual(cost, self.correct_cost2)

    def test_trickier_mst(self):
        MST, cost = kruskal(sorted(self.G3, key=lambda tup: tup[0]), self.num_nodes3)
        self.assertEqual(MST, self.correct_MST3)
        self.assertEqual(cost, self.correct_cost3)

    def test_disconnected_graph(self):
        MST, cost = kruskal(sorted(self.G4, key=lambda tup: tup[0]), self.num_nodes4)
        self.assertEqual(MST, self.correct_MST4)
        self.assertEqual(cost, self.correct_cost4)

    def test_empty_graph(self):
        MST, cost = kruskal(self.G5, self.num_nodes5)
        self.assertEqual(MST, self.correct_MST5)
        self.assertEqual(cost, self.correct_cost5)


if __name__ == "__main__":
    print("Running Kruskal tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/graphtheory_tests/prims_algorithm_test.py
================================================
# Import folder where sorting algorithms
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/graphtheory/prims/")

# If run from local:
# sys.path.append('../../Algorithms/graphtheory/prims/')
from prim_heap import prims_algo


class test_primsHeap(unittest.TestCase):
    def setUp(self):
        # How I've decided to construct the graph is confusing, but the reason is because we're using a min heap and
        # want first element in the tuple to be the cost of the edge. However when I return the MST, we want it to be
        # returned as: from_node, to_node, edge_cost, rather than the reverse for constructing the graph.

        self.G1 = {1: [(10, 2, 1)], 2: [(10, 1, 2), (10, 3, 2)], 3: [(10, 2, 3)]}
        self.correct_cost1 = 20
        self.correct_MST1 = [(1, 2, 10), (2, 3, 10)]

        self.G2 = {
            1: [(10, 2, 1), (10, 3, 1)],
            2: [(10, 1, 2), (100, 3, 2)],
            3: [(10, 1, 3), (100, 2, 3)],
        }
        self.correct_cost2 = 20
        self.correct_MST2 = [(1, 2, 10), (1, 3, 10)]

        self.G3 = {
            1: [(1, 2, 1)],
            2: [(1, 1, 2), (1, 3, 2)],
            3: [(1, 4, 3), (5, 5, 3)],
            4: [(1, 3, 4), (1, 5, 4)],
            5: [(5, 3, 5), (1, 4, 5)],
        }
        self.correct_cost3 = 4
        self.correct_MST3 = [(1, 2, 1), (2, 3, 1), (3, 4, 1), (4, 5, 1)]

        self.G4 = {1: [(1, 2, 1)], 2: [(1, 1, 2)], 3: [(1, 4, 3)], 4: [(1, 3, 4)]}
        self.correct_cost4 = 1
        self.correct_MST4 = [(1, 2, 1)]

        self.G5 = {}
        self.correct_cost5 = 0
        self.correct_MST5 = []

        # Takes as input G which will have {node1: [(cost, to_node, node1), ...], node2:[(...)] }

    def test_linear_graph(self):
        MST, cost = prims_algo(self.G1, start=1)
        self.assertEqual(MST, self.correct_MST1)
        self.assertEqual(cost, self.correct_cost1)

    def test_triangle_graph(self):
        MST, cost = prims_algo(self.G2, start=1)
        self.assertEqual(MST, self.correct_MST2)
        self.assertEqual(cost, self.correct_cost2)

    def test_trickier_mst(self):
        MST, cost = prims_algo(self.G3, start=1)
        self.assertEqual(MST, self.correct_MST3)
        self.assertEqual(cost, self.correct_cost3)

    def test_disconnected_graph(self):
        MST, cost = prims_algo(self.G4, start=1)
        self.assertEqual(MST, self.correct_MST4)
        self.assertEqual(cost, self.correct_cost4)

    def test_empty_graph(self):
        MST, cost = prims_algo(self.G5, start=1)
        self.assertEqual(MST, self.correct_MST5)
        self.assertEqual(cost, self.correct_cost5)


if __name__ == "__main__":
    print("Running Prims Heap tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/graphtheory_tests/test_NN.py
================================================
import unittest
import sys

# Import from different folder
sys.path.append("Algorithms/graphtheory/nearest-neighbor-tsp/")

import NearestNeighborTSP


class TestNN(unittest.TestCase):
    def setUp(self):
        self.G1 = [[0,3,-1],[3,0,1],[-1,1,0]]
        self.correct_path1 = [0,1,2,0]

        # No possible solution for this one so its a dead end
        self.G2 = [[0, 2, -1,-1,-1], [2, 0,5,1,-1], [-1, 5, 0, -1, -1],[-1, 1, -1, 0, 3], [-1, -1, -1, 3, 0]]
        self.correct_path2 = [0,1,3,4]

        # No possible solution for this one so its a dead end
        self.G3 = [[0, 2, -1,-1,-1], [2, 0,5,1,-1], [-1, 5, 0, -1, -1],[-1, 1, -1, 0, -1], [-1, -1, -1, -1, 0]]
        self.correct_path3 = [0, 1, 3]

        # Multiple possible solutions
        self.G4 = [[0,1,1,1],[1,0,1,1],[1,1,0,1],[1,1,1,0]]
        self.correct_path4 = [0, 1, 2, 3, 0]


    # adjacency matrix of a graph for testing
    adjMatrix = [[0,2,5,-1,3],[2,0,2,4,-1],[5,2,0,5,5],[-1,4,5,0,2],[3,-1,5,2,0]]
    # correct rank of each node's neighbors
    correctNeighbors = [[1,4,2],[0,2,3],[1,0,3,4],[4,1,2],[3,0,2]]


    def test_0_rankNeighbors(self):
        for i in range(0,4):
            self.assertEqual(NearestNeighborTSP.rankNeighbors(i, self.adjMatrix), self.correctNeighbors[i], "Check if order is different.")


    def test_1_nnTSP(self):
        path=NearestNeighborTSP.nnTSP(self.adjMatrix)
        # Test if path is null
        self.assertIsNotNone(path,"Output is empty")
        # Test if path is not complete
        self.assertEqual(len(path),len(self.adjMatrix)+1,"Path in incomplete")


    def test_linear_graph(self):
        #print(NearestNeighbor.nnTSP(self.G2))
        path = NearestNeighborTSP.nnTSP(self.G1)
        self.assertEqual(path,self.correct_path1)


    def test_simple_graph(self):
        path = NearestNeighborTSP.nnTSP(self.G2)
        self.assertEqual(path,self.correct_path2)


    def test_disconnected_graph(self):
        path = NearestNeighborTSP.nnTSP(self.G3)
        self.assertEqual(path, self.correct_path3)


    def test_complete_graph(self):
        path = NearestNeighborTSP.nnTSP(self.G4)
        self.assertEqual(path, self.correct_path4)

if __name__ == '__main__':
    print("Running Nearest Neighbor TSP solver tests:")
    unittest.main()

================================================
FILE: Algorithm_tests/graphtheory_tests/test_graph.txt
================================================
1 2,5 3,10
2 4,-5
3 4,15

================================================
FILE: Algorithm_tests/math_tests/intersection_test.py
================================================
# Import folder where sorting algorithms
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/math/intersection_of_two_sets")

# If run from local:
# sys.path.append('../../Algorithms/math/intersection_of_two_sets')

from intersection_of_two_sets import intersection


class test_intersection(unittest.TestCase):
    def setUp(self):
        # test cases we wish to run
        self.L1 = [1, 3, 5, 7, 9, 10]
        self.L2 = [2, 4, 6, 11, 12]
        self.L1L2_correct = []

        self.L3 = [1, 3, 5, 10]
        self.L4 = [2, 4, 6, 10]
        self.L3L4_correct = [10]

        self.L5 = [1, 3, 5, 10]
        self.L6 = [1, 4, 6, 11]
        self.L5L6_correct = [1]

        self.L7 = [1, 2, 3, 4, 5, 6, 7]
        self.L8 = [1, 2, 3, 4, 5, 6, 7]
        self.L7L8_correct = [1, 2, 3, 4, 5, 6, 7]

        self.L9 = []
        self.L10 = []
        self.L9L10_correct = []

    def test_intersection_none(self):
        L1L2_output = intersection(self.L1, self.L2)
        self.assertEqual(L1L2_output, self.L1L2_correct)

    def test_intersection_lastelement(self):
        L3L4_output = intersection(self.L3, self.L4)
        self.assertEqual(L3L4_output, self.L3L4_correct)

    def test_intersection_firstelement(self):
        L5L6_output = intersection(self.L5, self.L6)
        self.assertEqual(L5L6_output, self.L5L6_correct)

    def test_intersection_allequal(self):
        L7L8_output = intersection(self.L7, self.L8)
        self.assertEqual(L7L8_output, self.L7L8_correct)

    def test_intersection_both_empty(self):
        L9L10_output = intersection(self.L9, self.L10)
        self.assertEqual(L9L10_output, self.L9L10_correct)


if __name__ == "__main__":
    print("Running sorting tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/math_tests/union_test.py
================================================
# Import folder where sorting algorithms
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/math/union_of_two_sets")

# If run from local:
# sys.path.append('../../Algorithms/math/union_of_two_sets')

from union_of_two_sets import union


class test_union(unittest.TestCase):
    def setUp(self):
        # test cases we wish to run
        self.L1 = [1, 3, 5, 7, 9, 10]
        self.L2 = [2, 4, 6, 11, 12]
        self.L1L2_correct = [1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12]

        self.L3 = [1, 3, 5, 10]
        self.L4 = [2, 4, 6, 10]
        self.L3L4_correct = [1, 2, 3, 4, 5, 6, 10]

        self.L5 = [1, 3, 5, 10]
        self.L6 = [1, 4, 6, 11]
        self.L5L6_correct = [1, 3, 4, 5, 6, 10, 11]

        self.L7 = [1, 2, 3, 4, 5, 6, 7]
        self.L8 = [1, 2, 3, 4, 5, 6, 7]
        self.L7L8_correct = [1, 2, 3, 4, 5, 6, 7]

        self.L9 = []
        self.L10 = []
        self.L9L10_correct = []

    def test_union_all(self):
        L1L2_output = union(self.L1, self.L2)
        self.assertEqual(L1L2_output, self.L1L2_correct)

    def test_union_lastequal(self):
        L3L4_output = union(self.L3, self.L4)
        self.assertEqual(L3L4_output, self.L3L4_correct)

    def test_union_firstequal(self):
        L5L6_output = union(self.L5, self.L6)
        self.assertEqual(L5L6_output, self.L5L6_correct)

    def test_union_samelist(self):
        L7L8_output = union(self.L7, self.L8)
        self.assertEqual(L7L8_output, self.L7L8_correct)

    def test_union_both_empty(self):
        L9L10_output = union(self.L9, self.L10)
        self.assertEqual(L9L10_output, self.L9L10_correct)


if __name__ == "__main__":
    print("Running sorting tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/other_tests/test_binarysearch.py
================================================
# Import folder where sorting algorithms
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/other")

# If run from local:
# sys.path.append('../../Algorithms/other')

from binarysearch import binarysearch_iterative, binarysearch_recursive


class test_binarysearch(unittest.TestCase):
    def setUp(self):
        # test cases we wish to run
        self.L1 = [1, 3, 5, 8, 10, 12]
        self.L1_target = 5
        self.L1_correct = True, 2

        self.L2 = [1, 3, 5, 8, 10, 12]
        self.L2_target = 6
        self.L2_correct = False, None

        self.L3 = [1, 1, 1, 1, 1, 1, 1, 1]
        self.L3_target = 1
        self.L3_correct = True, (0 + len(self.L3) - 1) // 2

        self.L4 = [1, 3, 6, 11, 16, 21, 25, 27]
        self.L4_target = 27
        self.L4_correct = True, len(self.L4) - 1

        self.L5 = [1, 3, 6, 11, 16, 21, 27]
        self.L5_target = 1
        self.L5_correct = True, 0

        self.L6 = []
        self.L6_target = 10
        self.L6_correct = False, None

        self.L7 = [11, 12, 15, 19, 23, 41, 173, 298]
        self.L7_target = 12
        self.L7_correct = True, 1

    def test_binarysearch_basic(self):
        L1_result_iterative = binarysearch_iterative(self.L1, self.L1_target)
        L1_result_recursive = binarysearch_recursive(
            self.L1, self.L1_target, 0, len(self.L1) - 1
        )

        self.assertEqual(L1_result_iterative, self.L1_correct)
        self.assertEqual(L1_result_recursive, self.L1_correct)

    def test_binarysearch_nonexistant(self):
        L2_result_iterative = binarysearch_iterative(self.L2, self.L2_target)
        L2_result_recursive = binarysearch_recursive(
            self.L2, self.L2_target, 0, len(self.L1) - 1
        )

        self.assertEqual(L2_result_iterative, self.L2_correct)
        self.assertEqual(L2_result_recursive, self.L2_correct)

    def test_binarysearch_identical(self):
        L3_result_iterative = binarysearch_iterative(self.L3, self.L3_target)
        L3_result_recursive = binarysearch_recursive(
            self.L3, self.L3_target, 0, len(self.L3) - 1
        )

        self.assertEqual(L3_result_iterative, self.L3_correct)
        self.assertEqual(L3_result_recursive, self.L3_correct)

    def test_binarysearch_lastvalue(self):
        L4_result_iterative = binarysearch_iterative(self.L4, self.L4_target)
        L4_result_recursive = binarysearch_recursive(
            self.L4, self.L4_target, 0, len(self.L4) - 1
        )

        self.assertEqual(L4_result_iterative, self.L4_correct)
        self.assertEqual(L4_result_recursive, self.L4_correct)

    def test_binarysearch_firstvalue(self):
        L5_result_iterative = binarysearch_iterative(self.L5, self.L5_target)
        L5_result_recursive = binarysearch_recursive(
            self.L5, self.L5_target, 0, len(self.L5) - 1
        )

        self.assertEqual(L5_result_iterative, self.L5_correct)
        self.assertEqual(L5_result_recursive, self.L5_correct)

    def test_binarysearch_empty(self):
        L6_result_iterative = binarysearch_iterative(self.L6, self.L6_target)
        L6_result_recursive = binarysearch_recursive(
            self.L6, self.L6_target, 0, len(self.L6) - 1
        )

        self.assertEqual(L6_result_iterative, self.L6_correct)
        self.assertEqual(L6_result_recursive, self.L6_correct)

    def test_binarysearch_standard(self):
        L7_result_iterative = binarysearch_iterative(self.L7, self.L7_target)
        L7_result_recursive = binarysearch_recursive(
            self.L7, self.L7_target, 0, len(self.L7) - 1
        )

        self.assertEqual(L7_result_iterative, self.L7_correct)
        self.assertEqual(L7_result_recursive, self.L7_correct)


if __name__ == "__main__":
    print("Running sorting tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/other_tests/test_intervalscheduling.py
================================================
# Import folder where sorting algorithms
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/other")

# If run from local:
# sys.path.append('../../Algorithms/other')

from interval_scheduling import interval_scheduling


class test_intervalscheduling(unittest.TestCase):
    def setUp(self):
        # test cases we wish to run
        self.R1 = [(0, 5), (3, 6), (5, 10)]
        self.R1_correct = [(0, 5), (5, 10)]

        self.R2 = []
        self.R2_correct = []

        self.R3 = [(0, 3), (3, 6), (6, 9), (9, 10)]
        self.R3_correct = [(0, 3), (3, 6), (6, 9), (9, 10)]

        self.R4 = [(1, 3), (0, 2), (1, 4), (2, 5)]
        self.R4_correct = [(0, 2), (2, 5)]

        self.R5 = [(0, 3)]
        self.R5_correct = [(0, 3)]

    def test_intervalscheduling_basic(self):
        O = []
        O = interval_scheduling(self.R1, O)
        self.assertEqual(O, self.R1_correct)

    def test_intervalscheduling_empty(self):
        O = []
        O = interval_scheduling(self.R2, O)
        self.assertEqual(O, self.R2_correct)

    def test_intervalscheduling_take_all(self):
        O = []
        O = interval_scheduling(self.R3, O)
        self.assertEqual(O, self.R3_correct)

    def test_intervalscheduling_unsorted(self):
        O = []
        O = interval_scheduling(self.R4, O)
        self.assertEqual(O, self.R4_correct)

    def test_intervalscheduling_one_element(self):
        O = []
        O = interval_scheduling(self.R5, O)
        self.assertEqual(O, self.R5_correct)


if __name__ == "__main__":
    print("Running Interval Scheduling tests:")
    unittest.main()


================================================
FILE: Algorithm_tests/other_tests/test_medianmaintenance.py
================================================
# Import packages
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/other")

# If run from local:
# sys.path.append('../../Algorithms/other')

from median_maintenance import Maintain_Median


class MyTestCase(unittest.TestCase):
    def setUp(self):
        self.data1 = [1, 3, 8, 5, 10]
        self.correct1 = 5

        self.data2 = []
        self.correct2 = []

        self.data3 = [10]
        self.correct3 = 10

        self.data4 = [1, 2, 3, 4]
        self.correct4 = 2.5

        self.data5 = [1, 10, 2, 9, 11, 4, 6, 5, 3, 8, 7]
        self.correct5 = 6

    def test_basic(self):
        maintain_median = Maintain_Median()
        median = maintain_median.main(self.data1)
        self.assertEqual(median, self.correct1)

    def test_empty(self):
        maintain_median = Maintain_Median()
        median = maintain_median.main(self.data2)
        self.assertEqual(median, self.correct2)

    def test_single(self):
        maintain_median = Maintain_Median()
        median = maintain_median.main(self.data3)
        self.assertEqual(median, self.correct3)

    def test_even(self):
        maintain_median = Maintain_Median()
        median = maintain_median.main(self.data4)
        self.assertEqual(median, self.correct4)

    def test_longer_example(self):
        maintain_median = Maintain_Median()
        median = maintain_median.main(self.data5)
        self.assertEqual(median, self.correct5)


if __name__ == "__main__":
    unittest.main()


================================================
FILE: Algorithm_tests/sorting_tests/test_sorting.py
================================================
# Import folder where sorting algorithms
import sys
import unittest

# For importing from different folders
# OBS: This is supposed to be done with automated testing, hence relative to folder we want to import from
sys.path.append("Algorithms/sorting")

# If run from local:
# sys.path.append('../../Algorithms/sorting')

from bubblesort import bubblesort
from insertionsort import insertionsort
from mergesort import merge_sort, merge
from quicksort import quicksort_firstpivot, quicksort_lastpivot
from randomized_quicksort import quicksort_randomized
from selectionsort import selectionsort

# Test cases we wish to run
L1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
L1_sorted = [1, 2, 3, 4, 5, 6, 7, 8, 9]

L2 = [9, 8, 7, 6, 5, 4, 3, 2, 1]
L2_sorted = [1, 2, 3, 4, 5, 6, 7, 8, 9]

L3 = [1, 1, 1, 1, 1, 1, 1, 1, 1]
L3_sorted = [1, 1, 1, 1, 1, 1, 1, 1, 1]

L4 = [6, 7, 3, 5, 1, 3]
L4_sorted = [1, 3, 3, 5, 6, 7]

L5 = []
L5_sorted = []

L6 = [-1, -2, -3]
L6_sorted = [-3, -2, -1]

L7 = [-5, -7, -1, -3, -4]
L7_sorted = [-7, -5, -4, -3, -1]


class test_sorting(unittest.TestCase):
    def test_bubblesort(self):
        self.assertEqual(bubblesort(L1), L1_sorted)
        self.assertEqual(bubblesort(L2), L2_sorted)
        self.assertEqual(bubblesort(L3), L3_sorted)
        self.assertEqual(bubblesort(L4), L4_sorted)
        self.assertEqual(bubblesort(L5), L5_sorted)
        self.assertEqual(bubblesort(L6), L6_sorted)
        self.assertEqual(bubblesort(L7), L7_sorted)
        self.assertEqual(bubblesort(L7), L7_sorted)

    def test_insertionsort(self):
        self.assertEqual(insertionsort(L1), L1_sorted)
        self.assertEqual(insertionsort(L2), L2_sorted)
        self.assertEqual(insertionsort(L3), L3_sorted)
        self.assertEqual(insertionsort(L4), L4_sorted)
        self.assertEqual(insertionsort(L5), L5_sorted)
        self.assertEqual(insertionsort(L6), L6_sorted)
        self.assertEqual(insertionsort(L7), L7_sorted)

    def test_mergesort(self):
        self.assertEqual(merge_sort(L1), L1_sorted)
        self.assertEqual(merge_sort(L2), L2_sorted)
        self.assertEqual(merge_sort(L3), L3_sorted)
        self.assertEqual(merge_sort(L4), L4_sorted)
        self.assertEqual(merge_sort(L5), L5_sorted)
        self.assertEqual(merge_sort(L6), L6_sorted)
        self.assertEqual(merge_sort(L7), L7_sorted)

    def test_quicksort(self):
        self.assertEqual(quicksort_firstpivot(L1), L1_sorted)
        self.assertEqual(quicksort_firstpivot(L2), L2_sorted)
        self.assertEqual(quicksort_firstpivot(L3), L3_sorted)
        self.assertEqual(quicksort_firstpivot(L4), L4_sorted)
        self.assertEqual(quicksort_firstpivot(L5), L5_sorted)
        self.assertEqual(quicksort_firstpivot(L6), L6_sorted)
        self.assertEqual(quicksort_firstpivot(L7), L7_sorted)

        self.assertEqual(quicksort_lastpivot(L1), L1_sorted)
        self.assertEqual(quicksort_lastpivot(L2), L2_sorted)
        self.assertEqual(quicksort_lastpivot(L3), L3_sorted)
        self.assertEqual(quicksort_lastpivot(L4), L4_sorted)
        self.assertEqual(quicksort_lastpivot(L5), L5_sorted)
        self.assertEqual(quicksort_lastpivot(L6), L6_sorted)
        self.assertEqual(quicksort_lastpivot(L7), L7_sorted)

    def test_selectionsort(self):
        self.assertEqual(selectionsort(L1), L1_sorted)
        self.assertEqual(selectionsort(L2), L2_sorted)
        self.assertEqual(selectionsort(L3), L3_sorted)
        self.assertEqual(selectionsort(L4), L4_sorted)
        self.assertEqual(selectionsort(L5), L5_sorted)
        self.assertEqual(selectionsort(L6), L6_sorted)
        self.assertEqual(selectionsort(L7), L7_sorted)

    def test_quicksort_randomized(self):
        self.assertEqual(quicksort_randomized(L1), L1_sorted)
        self.assertEqual(quicksort_randomized(L2), L2_sorted)
        self.assertEqual(quicksort_randomized(L3), L3_sorted)
        self.assertEqual(quicksort_randomized(L4), L4_sorted)
        self.assertEqual(quicksort_randomized(L5), L5_sorted)
        self.assertEqual(quicksort_randomized(L6), L6_sorted)
        self.assertEqual(quicksort_randomized(L7), L7_sorted)


if __name__ == "__main__":
    print("Running sorting tests:")
    unittest.main()


================================================
FILE: Algorithms/cryptology/RSA_algorithm/RSA.py
================================================
"""
Purpose of the RSA cryptosystem is to have a secure way of transmitting data

Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
*   2019-08-26 Initial programming

"""

from math import gcd
from sympy import isprime
import random
from euclid_gcd import extended_euclidean


def generate_pq(bits):
    # Randomly generate two primes p,q
    p = random.getrandbits(bits)
    q = random.getrandbits(bits)

    # Check if p,q is prime
    p_isprime = isprime(p)
    q_isprime = isprime(q)

    # Keep generating until both are primes
    while not (p_isprime and q_isprime):
        if not p_isprime:
            p = random.getrandbits(bits)
        if not q_isprime:
            q = random.getrandbits(bits)

        p_isprime = isprime(p)
        q_isprime = isprime(q)

    return p, q


def generate_e(totient):
    # Generate e such that 1 < e < phi(n)
    # phi(n) in this case is totient

    while True:
        # Should be (2,totient) so if it is stuck in infinite loop then restart or replace 80000 -> totient
        # Reason why I want e to be a low value is to make encryption faster
        e = random.randint(2, 50000)

        if gcd(e, totient) == 1:
            return e


def generate_d(e, totient):
    _, e_inverse, _ = extended_euclidean(e, totient)
    d = e_inverse % totient

    return d


def generate_all_values():
    num_bits = 1024
    p, q = generate_pq(num_bits)
    totient = (p - 1) * (q - 1)
    e = generate_e(totient)
    d = generate_d(e, totient)

    print("Generated value n: " + str(p * q))
    print("Generated e and d: " + str(e) + " and " + str(d))

    return p * q, e, d


def encrypt(message, n, e):
    encrypted = ""
    for letter in message:
        pad = 3 - len(str(ord(letter)))

        if pad > 0:
            new_letter = "0" * pad + str(ord(letter))
        else:
            new_letter = ord(letter)

        encrypted += str(new_letter)

    encrypted = pow(int(encrypted), e, n)
    return encrypted


def decrypt(encrypted, n, d):
    decrypted_message = ""
    decrypted_code = str(pow(encrypted, d, n))

    if len(decrypted_code) % 3 != 0:
        decrypted_code = "0" + decrypted_code

    while len(decrypted_code):
        decrypted_message += chr(int(decrypted_code[0:3]))
        decrypted_code = decrypted_code[3:]

    return decrypted_message


def example():
    # An example of a test case where we generate all necessary primes, encrypt and then decrypt the message.
    # Only to show how all parts of the code is working. This is not how it's going to be used in practice.
    hidden_message = "i really love peanuts"
    n, e, d = generate_all_values()
    encrypted_message = encrypt(hidden_message, n, e)
    decrypted_message = decrypt(encrypted_message, n, d)

    print("\n")
    print("Original message: " + hidden_message)
    print("Encrypted message: " + str(encrypted_message))
    print("Decrypted message: " + decrypted_message)


def main():
    # Write the values of your RSA encryption (Note: Never give the 'd' to someone that doesn't want it)
    n = 354089397494626050014776605732143027269473328409397973403863001639624332101789181044818951483060155060788030618162673282176493895463414816015601230408140046833172059490430968956729878861381343553446553025440156523477822105773362480000716985478565013956749662865189691539813391686696182702224364834273144673717742246537383454469146642154754778836797926780437490677663302034284308892191362266103193070200405420180296005388479418941723827243187899338980201782128797489464650981164232057548015010630986959083998487019465357524040595865260220030689502065850060761344148196291328192760801074939658292752592564874822996765430361631210613041006858858506787439506504448316606509551260553919757840169593791152166515571202450662850988377002989153080277915454500432640601643512909764636398157415600050468972065216354878984114648007494687081718749734915103155014825420081658864982423629447913147575382146725524407739875786801876011026010419782863232303861065841801863420557617962438178979549855959377311548527613240676904989886382444381261628076009466895878852398923237601309285642954207693266358989851324012643315688180744573155217352955083176785543099571257338683938756048920161738393295253775030232399282686809347027784971441882883201432807953
    e = 9361
    # d =

    enc_or_dec = input(
        "Would you like to encrypt or decrypt a message (input: 'enc' or 'dec'): "
    )

    if enc_or_dec.lower() == "enc":
        hidden_message = input("What is your hidden message?: ")
        print("Encrypted message: " + str(encrypt(hidden_message, n, e)))

    elif enc_or_dec.lower() == "dec":
        encrypted = input("What is your encrypted message?: ")
        print(encrypted)
        print("Decrypted message: " + str(decrypt(int(encrypted), n, d)))

    else:
        print("Not sure what you typed")


main()


================================================
FILE: Algorithms/cryptology/RSA_algorithm/euclid_gcd.py
================================================
"""


"""

import sys

sys.setrecursionlimit(100000)


def extended_euclidean(a, b):
    if a == 0:
        return (b, 0, 1)

    else:
        gcd, x, y = extended_euclidean(b % a, a)
        return (gcd, y - (b // a) * x, x)


if __name__ == "__main__":
    print(extended_euclidean(5, -2772))
    # print(extended_euclidean(13, 2640))


================================================
FILE: Algorithms/cryptology/ceasar_shifting_cipher/ceasar_shift_cipher.py
================================================
"""
The Ceasar cipher is one of the simplest and one of the earliest known ciphers.
It is a type of substitution cipher that 'shifts' a letter by a fixed amount in the alphabet.

For example with a shift = 3:
a -> d
b -> e
.
.
.
z -> c

Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
*   2019-11-07 Initial programming

"""

# This alphabet is of 27 letters since I included a space, but normally it is of 26 letters.
# If you wish to include more letters you need to expand the alphabet used. For example you cannot use '!', '@' now.
alphabet = "abcdefghijklmnopqrstuvwxyz "
letter_to_index = dict(zip(alphabet, range(len(alphabet))))
index_to_letter = dict(zip(range(len(alphabet)), alphabet))


def encrypt(message, shift=3):
    cipher = ""

    for letter in message:
        number = (letter_to_index[letter] + shift) % len(letter_to_index)
        letter = index_to_letter[number]
        cipher += letter

    return cipher


def decrypt(cipher, shift=3):
    decrypted = ""

    for letter in cipher:
        number = (letter_to_index[letter] - shift) % len(letter_to_index)
        letter = index_to_letter[number]
        decrypted += letter

    return decrypted


# def main():
#     message = 'attackatnoon'
#     cipher = encrypt(message, shift=3)
#     decrypted = decrypt(cipher, shift=3)
#
#     print('Original message: ' + message)
#     print('Encrypted message: ' + cipher)
#     print('Decrypted message: ' + decrypted)
#
# main()


================================================
FILE: Algorithms/cryptology/hill_cipher/hill_cipher.py
================================================
"""
Implementation of Hill Cipher!

Important notation:
K = Matrix which is our 'Secret Key'
P = Vector of plaintext (that has been mapped to numbers)
C = Vector of Ciphered text (in numbers)

C = E(K,P) = K*P (mod X) -- X is length of alphabet used
P = D(K,C) = inv(K)*C (mod X)  -- X is length of alphabet used

Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
*  2019-11-09 Initial programming
"""

import numpy as np
from egcd import egcd  # pip install egcd

alphabet = "abcdefghijklmnopqrstuvwxyz"

letter_to_index = dict(zip(alphabet, range(len(alphabet))))
index_to_letter = dict(zip(range(len(alphabet)), alphabet))


def matrix_mod_inv(matrix, modulus):
    """We find the matrix modulus inverse by
    Step 1) Find determinant
    Step 2) Find determinant value in a specific modulus (usually length of alphabet)
    Step 3) Take that det_inv times the det*inverted matrix (this will then be the adjoint) in mod 26
    """

    det = int(np.round(np.linalg.det(matrix)))  # Step 1)
    det_inv = egcd(det, modulus)[1] % modulus  # Step 2)
    matrix_modulus_inv = (
        det_inv * np.round(det * np.linalg.inv(matrix)).astype(int) % modulus
    )  # Step 3)

    return matrix_modulus_inv


def encrypt(message, K):
    encrypted = ""
    message_in_numbers = []

    for letter in message:
        message_in_numbers.append(letter_to_index[letter])

    split_P = [
        message_in_numbers[i : i + int(K.shape[0])]
        for i in range(0, len(message_in_numbers), int(K.shape[0]))
    ]

    for P in split_P:
        P = np.transpose(np.asarray(P))[:, np.newaxis]

        while P.shape[0] != K.shape[0]:
            P = np.append(P, letter_to_index[" "])[:, np.newaxis]

        numbers = np.dot(K, P) % len(alphabet)
        n = numbers.shape[0]  # length of encrypted message (in numbers)

        # Map back to get encrypted text
        for idx in range(n):
            number = int(numbers[idx, 0])
            encrypted += index_to_letter[number]

    return encrypted


def decrypt(cipher, Kinv):
    decrypted = ""
    cipher_in_numbers = []

    for letter in cipher:
        cipher_in_numbers.append(letter_to_index[letter])

    split_C = [
        cipher_in_numbers[i : i + int(Kinv.shape[0])]
        for i in range(0, len(cipher_in_numbers), int(Kinv.shape[0]))
    ]

    for C in split_C:
        C = np.transpose(np.asarray(C))[:, np.newaxis]
        numbers = np.dot(Kinv, C) % len(alphabet)
        n = numbers.shape[0]

        for idx in range(n):
            number = int(numbers[idx, 0])
            decrypted += index_to_letter[number]

    return decrypted


def main():
    # message = 'my life is potato'
    message = "help"

    K = np.matrix([[3, 3], [2, 5]])
    # K = np.matrix([[6, 24, 1], [13,16,10], [20,17,15]]) # for length of alphabet = 26
    # K = np.matrix([[3,10,20],[20,19,17], [23,78,17]]) # for length of alphabet = 27
    Kinv = matrix_mod_inv(K, len(alphabet))

    encrypted_message = encrypt(message, K)
    decrypted_message = decrypt(encrypted_message, Kinv)

    print("Original message: " + message)
    print("Encrypted message: " + encrypted_message)
    print("Decrypted message: " + decrypted_message)


main()


================================================
FILE: Algorithms/cryptology/one_time_pad/one_time_pad.py
================================================
"""
Implementation of the famous one time pad / Vernam Cipher

In practice we need a way to generate random keys which I havn't included.

Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
*  2019-11-12 Initial programming

"""


def xor(s1, s2):
    xor_result = []

    for i in range(min(len(s1), len(s2))):
        xor_result.append(int(s1[i]) ^ int(s2[i]))  # xor

    return xor_result


def encrypt(message, key):
    binary_message = ""
    binary_key = ""
    ciphered_text = ""

    for letter in message:
        binary_message += format(ord(letter), "b")

    for letter in key:
        binary_key += format(ord(letter), "b")

    cipher_binary = xor(binary_message, binary_key)

    return "".join(str(e) for e in cipher_binary)


def decrypt(cipher_text, key):
    binary_key = ""
    decrypted_text = ""

    for letter in key:
        binary_key += format(ord(letter), "b")

    binary_message = xor(cipher_text, binary_key)

    for i in range(0, len(binary_message), 7):
        letter = "".join(str(e) for e in binary_message[i : i + 7])
        decrypted_text += chr(int(letter, 2))

    return decrypted_text


def main():
    message = "cheesecake"  # 'secret' message
    key = "randomrandomrandom"  #'random' key

    encrypted = encrypt(message, key)
    decrypted = decrypt(encrypted, key)

    print("Original message: " + str(message))
    print("Encrypted message (in binary): " + str(encrypted))
    print("Decrypted message: " + str(decrypted))


if __name__ == "__main__":
    main()


================================================
FILE: Algorithms/cryptology/vigenere_cipher/vigenere.py
================================================
"""
Vigenère cipher is one of the simplest that employs a form of polyalphabetic substitution (each letter is assigned
more than one substitute).

It was first described in 1553 but took an entire three centuries to break it in 1863.

Weakness: If someone finds key length then this can be broken.

Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
*  2019-11-07 Initial programming

"""


alphabet = "abcdefghijklmnopqrstuvwxyz "

letter_to_index = dict(zip(alphabet, range(len(alphabet))))
index_to_letter = dict(zip(range(len(alphabet)), alphabet))


def encrypt(message, key):
    encrypted = ""
    split_message = [
        message[i : i + len(key)] for i in range(0, len(message), len(key))
    ]

    for each_split in split_message:
        i = 0
        for letter in each_split:
            number = (letter_to_index[letter] + letter_to_index[key[i]]) % len(alphabet)
            encrypted += index_to_letter[number]
            i += 1

    return encrypted


def decrypt(cipher, key):
    decrypted = ""
    split_encrypted = [
        cipher[i : i + len(key)] for i in range(0, len(cipher), len(key))
    ]

    for each_split in split_encrypted:
        i = 0
        for letter in each_split:
            number = (letter_to_index[letter] - letter_to_index[key[i]]) % len(alphabet)
            decrypted += index_to_letter[number]
            i += 1

    return decrypted


def main():
    message = "i loove peanuts"
    key = "banana"
    encrypted_message = encrypt(message, key)
    decrypted_message = decrypt(encrypted_message, key)

    print("Original message: " + message)
    print("Encrypted message: " + encrypted_message)
    print("Decrypted message: " + decrypted_message)


main()


================================================
FILE: Algorithms/dynamic_programming/knapsack/knapsack_bottomup.py
================================================
"""
Purpose is if having a bunch of items with a weight and corresponding value to each object.
Which collection of objects should we choose such that we maximize the value restricted to
a specific capacity of weight. Bottom up implementation of Knapsack (using loops)

Time Complexity: O(nC), pseudo-polynomial

Programmed by Aladdin Persson <aladdin dot persson at hotmail dot com>
  2020-02-15 Initial programming
"""


def find_opt(i, c, M, values, items, weights):
    if i <= 0 or c <= 0:
        return items

    if (M[i - 1][c] >= (values[i - 1] + M[i - 1][c - weights[i - 1]])) or (
        c - weights[i - 1]
    ) < 0:
        find_opt(i - 1, c, M, values, items, weights)

    else:
        items.append(i - 1)
        find_opt(i - 1, c - weights[i - 1], M, values, items, weights)


def knapsack(n, C, weights, values):
    # Initialization of matrix of size (n*W)
    M = [[None for i in range(C + 1)] for j in range(len(values) + 1)]

    for c in range(C + 1):
        M[0][c] = 0

    for i in range(len(weights) + 1):
        M[i][0] = 0

    for i in range(1, n + 1):
        for c in range(1, C + 1):
            # If current weight exceeds capacity then we cannot take it
            if weights[i - 1] > c:
                M[i][c] = M[i - 1][c]

            # Else we can take it, then find what gives us the optimal value, either
            # taking it or not taking it and we consider what gives us max value of those
            else:
                M[i][c] = max(M[i - 1][c], values[i - 1] + M[i - 1][c - weights[i - 1]])
    items = []

    find_opt(n, C, M, values, items, weights)

    return M[n][C], items[::-1]


# if __name__ == '__main__':
#    # Run small example
#    weights = [1,2,4,2,5]
#    values = [5,3,5,3,2]
#    n = len(weights)
#    capacity = 3
#    total_value, items = knapsack(n, capacity, weights, values)
#    print('Items at the end: ' + str(items))
#    print('With total value: ' + str(total_value))


================================================
FILE: Algorithms/dynamic_programming/knapsack/knapsack_memoization_recursive_topdown.py
================================================
# Memoization implementation Knapsack

# Purpose is if having a bunch of items with a weight and corresponding value to each object.
# Which collection of objects should we choose such that we maximize the value restricted to
# a specific capacity of weight

# Programmed by Aladdin Persson <aladdin dot persson at hotmail dot com>
#   2019-02-28 Initial programming
#   2019-03-04 Made code cleaner and included a tracking of which items to choose


def knapsack(n, C, W, v, items, arr):
    # if n == 0 we cannot index further (since we look at n-1), further if we have no more capacity
    # then we cannot obtain more objects
    if n == 0 or C == 0:
        return 0, []

    elif arr[n - 1][C - 1] != None:
        return arr[n - 1][C - 1], items

    # If the weight is higher than our capacity then we can't pick it
    elif W[n - 1] > C:
        result, items = knapsack(n - 1, C, W, v, items, arr)

    # Recursively search through all choices
    else:
        tmp1, items1 = knapsack(n - 1, C, W, v, items, arr)  # exclude item
        tmp2, items2 = knapsack(n - 1, C - W[n - 1], W, v, items, arr)  # include item

        items = items2 + [n - 1] if (tmp2 + v[n - 1] > tmp1) else items1

        result = max(tmp1, tmp2 + v[n - 1])

    arr[n - 1][C - 1] = result

    return result, items


if __name__ == "__main__":
    # Run a small example
    weight = [1, 2, 4, 2, 5]
    value = [5, 3, 5, 3, 2]
    num_objects = len(weight)
    capacity = 3

    arr = [[None for i in range(capacity)] for j in range(num_objects)]

    total_val_and_items = knapsack(num_objects, capacity, weight, value, [])
    print(total_val_and_items)


================================================
FILE: Algorithms/dynamic_programming/knapsack/knapsack_naive_recursive.py
================================================
# "Naive" Implementation of the knapsack problem

# Purpose is if having a bunch of items with a weight and corresponding value to each object.
# Which collection of objects should we choose such that we maximize the value restricted to
# a specific capacity of weight?

# Programmed by Aladdin Persson <aladdin dot persson at hotmail dot com>
#   2019-02-28 Initial programming
#   2019-03-04 Cleaned up code and included a tracking of which items to choose


def knapsack(n, C, W, v, items):
    # if n == 0 we cannot index further (since we look at n-1), further if we have no more capacity
    # then we cannot obtain more objects
    if n == 0 or C == 0:
        return 0, []

    # If the weight is higher than our capacity then we can't pick it
    elif W[n - 1] > C:
        result, items = knapsack(n - 1, C, W, v, items)

    # Recursively search through all choices
    else:
        tmp1, items1 = knapsack(n - 1, C, W, v, items)  # exclude item
        tmp2, items2 = knapsack(n - 1, C - W[n - 1], W, v, items)  # include item

        items = items2 + [n - 1] if (tmp2 + v[n - 1] > tmp1) else items1

        result = max(tmp1, tmp2 + v[n - 1])

    return result, items


if __name__ == "__main__":
    # Run small example
    weight = [1, 2, 4, 2, 5]
    value = [5, 3, 5, 3, 2]
    num_objects = len(weight)
    capacity = 3

    arr = [[None for i in range(capacity)] for j in range(num_objects)]

    total_val_and_items = knapsack(num_objects, capacity, weight, value, [])
    print(total_val_and_items)  # items = []


================================================
FILE: Algorithms/dynamic_programming/longest_increasing_subsequence.py
================================================
"""
O(n^2) algorithm, can be faster and done in O(nlogn), but this works ok.
To do: Create extensive test cases before adding to algorithm list.

"""


def longest_increasing_subsequence(nums):
    if len(nums) == 0:
        return 0

    OPT = [1 for i in range(len(nums))]

    for i in range(1, len(nums)):
        for j in range(0, i):
            if nums[j] < nums[i] and OPT[j] + 1 > OPT[i]:
                OPT[i] = OPT[j] + 1

    return max(OPT)


if __name__ == "__main__":
    # test1 = [1,5,-2,10, 50, -10, 10, 1,2,3,4]
    test2 = [10, 1, 2, 11, 3, 5]
    # test3 = [10,9,8,5,3,2,1,2,3]
    # test4 = [1,5,2,3,4,5,6]
    test5 = []

    print(test2)
    print(longest_increasing_subsequence(test2))


================================================
FILE: Algorithms/dynamic_programming/sequence_alignment.py
================================================
"""
Algorithm for solving sequence alignment
Input strings x,y of len(x) = m, len(y) = n and find minimum number of
edit steps and the specific steps to transform x into y.

Time Complexity: O(nm)

Video of algorithm explanation: https://youtu.be/bQ7kRW6zo9Y
Video of code explanation: https://youtu.be/XmyxiSc3LKg

Programmed by Aladdin Persson <aladdin dot persson at hotmail dot com>
  2020-02-15 Initial coding
  2020-02-16 Improved find_solution and made code cleaner
  2020-03-13 There was an error in the code in function find_solution,
             I was working with list indexing as if it was a matrix.
             Should be working now. Extensive testing would be good.

  2020-03-28 Cleaned up code by making SequenceAlignment into class
"""


class SequenceAlignment(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.solution = []

    delta = lambda self, x, y, i, j: 1 if x[i] != y[j] else 0

    def find_solution(self, OPT, m, n):
        if m == 0 and n == 0:
            return

        # We can only do insert if n != 0, align if there are element in both x, y, etc.
        insert = OPT[m][n - 1] + 1 if n != 0 else float("inf")
        align = (
            OPT[m - 1][n - 1] + self.delta(self.x, self.y, m - 1, n - 1)
            if m != 0 and n != 0
            else float("inf")
        )
        delete = OPT[m - 1][n] + 1 if m != 0 else float("inf")

        best_choice = min(insert, align, delete)

        if best_choice == insert:
            self.solution.append("insert_" + str(self.y[n - 1]))
            return self.find_solution(OPT, m, n - 1)

        elif best_choice == align:
            self.solution.append("align_" + str(self.y[n - 1]))
            return self.find_solution(OPT, m - 1, n - 1)

        elif best_choice == delete:
            self.solution.append("remove_" + str(self.x[m - 1]))
            return self.find_solution(OPT, m - 1, n)

    def alignment(self):
        n = len(self.y)
        m = len(self.x)
        OPT = [[0 for i in range(n + 1)] for j in range(m + 1)]

        for i in range(1, m + 1):
            OPT[i][0] = i

        for j in range(1, n + 1):
            OPT[0][j] = j

        for i in range(1, m + 1):
            for j in range(1, n + 1):
                OPT[i][j] = min(
                    OPT[i - 1][j - 1] + self.delta(self.x, self.y, i - 1, j - 1),
                    OPT[i - 1][j] + 1,
                    OPT[i][j - 1] + 1,
                )  # align, delete, insert respectively

        self.find_solution(OPT, m, n)

        return (OPT[m][n], self.solution[::-1])


# if __name__ == '__main__':
#     x = 'TGACGTGC'
#     y = 'TCGACGTCA'
#     print('We we want to transform: ' + x + ' to: ' + y)
#     sqalign = SequenceAlignment(x, y)
#     min_edit, steps = sqalign.alignment()
#     print('Minimum amount of edit steps are: ' + str(min_edit))
#     print('And the way to do it is: ' + str(steps))


================================================
FILE: Algorithms/dynamic_programming/weighted_interval_scheduling.py
================================================
"""
Weighted Interval Scheduling
Explained YouTube video: https://www.youtube.com/watch?v=iIX1YvbLbvc
Implementation walkthrough video: https://www.youtube.com/watch?v=dU-coYsd7zw

Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
  2020-02-13 Initial programming
  2020-03-28 Cleaned up code by making WeightedIntervalScheduling class

Time complexity: O(nlogn)
"""

import bisect


class WeightedIntervalScheduling(object):
    def __init__(self, I):
        self.I = sorted(I, key=lambda tup: tup[1])  # (key = lambda tup : tup[1])
        self.OPT = []
        self.solution = []

    def previous_intervals(self):
        start = [task[0] for task in self.I]
        finish = [task[1] for task in self.I]
        p = []

        for i in range(len(self.I)):
            # finds idx for which to input start[i] in finish times to still be sorted
            idx = bisect.bisect(finish, start[i]) - 1
            p.append(idx)

        return p

    def find_solution(self, j):
        if j == -1:
            return

        else:
            if (self.I[j][2] + self.compute_opt(self.p[j])) > self.compute_opt(j - 1):
                self.solution.append(self.I[j])
                self.find_solution(self.p[j])

            else:
                self.find_solution(j - 1)

    def compute_opt(self, j):
        if j == -1:
            return 0

        elif (0 <= j) and (j < len(self.OPT)):
            return self.OPT[j]

        else:
            return max(
                self.I[j][2] + self.compute_opt(self.p[j]), self.compute_opt(j - 1)
            )

    def weighted_interval(self):
        if len(self.I) == 0:
            return 0, self.solution

        self.p = self.previous_intervals()

        for j in range(len(self.I)):
            opt_j = self.compute_opt(j)
            self.OPT.append(opt_j)

        self.find_solution(len(self.I) - 1)

        return self.OPT[-1], self.solution[::-1]


# Small Example
# if __name__ == '__main__':
#     # They are labeled as:  (start, end, weight)
#     t1 = (0,3,3)
#     t2 = (1,4,2)
#     t3 = (0,5,4)
#     t4 = (3,6,1)
#     t5 = (4,7,2)
#     t6 = (3,9,5)
#     t7 = (5,10,2)
#     t8 = (8,10,1)
#     I = [t1,t2,t3,t4,t5,t6,t7,t8]
#     weightedinterval = WeightedIntervalScheduling(I)
#     max_weight, best_intervals = weightedinterval.weighted_interval()
#     print('Maximum weight: ' + str(max_weight))
#     print('The best items to take are: ' + str(best_intervals))


================================================
FILE: Algorithms/graphtheory/bellman-ford/bellman_ford.py
================================================
"""
Purpose is to find the shortest path between one source node to all other nodes using Bellman-Ford Algorithm.
The difference between Dijkstra and this is that this can handle negative edges. We do pay for this as it is
a lot slower than Dijkstra.

Time Complexity: O(mn)

Programmed by Aladdin Persson <aladdin dot persson at hotmail dot com>
  2019-03-04 Initial programming
"""


def bellman_ford(G, start):
    """
    :param G: {from_node1: {to_node1, cost1, to_node2, cost2}, from_node2: {etc}}
    :param start: node to start from
    """

    if len(G) == 0:
        raise ValueError("There should be something in the graph")

    # step1: initialize by setting to infinity etc.
    shortest_distance = {}
    predecessor = {}
    infinity = float("inf")

    for node in G:
        shortest_distance[node] = infinity

    shortest_distance[start] = 0
    num_vertices = len(G)

    # step2: relax edges
    for _ in range(num_vertices - 1):
        for from_node in G:
            for to_node, weight in G[from_node].items():
                if shortest_distance[from_node] + weight < shortest_distance[to_node]:
                    shortest_distance[to_node] = shortest_distance[from_node] + weight
                    predecessor[to_node] = from_node

    # step3: check neg. cycles
    for from_node in G:
        for to_node, weight in G[from_node].items():
            if shortest_distance[from_node] + weight < shortest_distance[to_node]:
                shortest_distance[to_node] = -infinity

    return shortest_distance, predecessor


# if __name__ == '__main__':
#     G = {1: {2: -10, 3: 20},
#          2: {4: 40},
#          3: {4: 5},
#          4: {}}
#
#     print(f'Current graph is: {G}')
#     shortest, predecessor = bellman_ford(G, 1)
#     print(shortest)


================================================
FILE: Algorithms/graphtheory/bellman-ford/data.txt
================================================
1	80,982	163,8164	170,2620	145,648	200,8021	173,2069	92,647	26,4122	140,546	11,1913	160,6461	27,7905	40,9047	150,2183	61,9146	159,7420	198,1724	114,508	104,6647	30,4612	99,2367	138,7896	169,8700	49,2437	125,2909	117,2597	55,6399	
2	42,1689	127,9365	5,8026	170,9342	131,7005	172,1438	34,315	30,2455	26,2328	6,8847	11,1873	17,5409	157,8643	159,1397	142,7731	182,7908	93,8177	
3	57,1239	101,3381	43,7313	41,7212	91,2483	31,3031	167,3877	106,6521	76,7729	122,9640	144,285	44,2165	6,9006	177,7097	119,7711	
4	162,3924	70,5285	195,2490	72,6508	126,2625	121,7639	31,399	118,3626	90,9446	127,6808	135,7582	159,6133	106,4769	52,9267	190,7536	78,8058	75,7044	116,6771	49,619	107,4383	89,6363	54,313	
5	200,4009	112,1522	25,3496	23,9432	64,7836	56,8262	120,1862	2,8026	90,8919	142,1195	81,2469	182,8806	17,2514	83,8407	146,5308	147,1087	51,22	
6	141,8200	98,5594	66,6627	159,9500	143,3110	129,8525	118,8547	88,2039	83,4949	165,6473	162,6897	184,8021	123,13	176,3512	195,2233	42,7265	47,274	132,1514	2,8847	171,3722	3,9006	
7	156,7027	187,9522	87,4976	121,8739	56,6616	10,2904	71,8206	53,179	146,4823	165,6019	125,5670	27,4888	63,9920	150,9031	84,4061	
8	152,1257	189,2780	58,4708	26,8342	199,1918	31,3987	35,3160	71,5829	27,3483	69,8815	130,55	168,2076	122,5338	73,4528	28,9996	17,3535	40,3193	72,7308	24,8434	87,2833	25,3949	175,1022	177,8508	
9	152,1087	115,7827	17,7002	72,794	150,4539	190,3613	95,9480	36,5284	166,8702	63,1753	199,70	131,700	76,9340	70,2	139,8701	140,4163	180,5995	
10	57,9988	78,3771	62,4816	137,5273	7,2904	187,4786	184,3207	96,807	31,1184	88,2539	135,4650	168,9495	164,3866	11,8988	116,1493	51,5578	171,2029	
11	1,1913	185,2045	77,815	22,8425	181,8448	47,8727	81,7299	150,4802	178,1696	28,2275	183,594	131,833	157,8497	25,5057	59,3203	10,8988	2,1873	134,294	83,4211	124,6180	
12	78,5753	17,4602	62,5676	16,8068	60,5933	67,371	71,6734	53,7001	72,3626	34,6690	59,761	18,1520	128,7542	38,6699	57,9416	
13	144,9987	59,9801	97,7026	50,758	43,5400	163,3870	178,4194	151,9629	45,1794	105,6821	29,2784	172,2070	57,6850	77,8638	135,861	
14	149,4352	187,4874	26,3841	128,9662	155,4446	118,373	123,2733	106,7912	169,4333	53,9197	161,4275	126,9602	73,4106	160,7860	131,358	141,4477	119,960	43,3199	47,7898	175,6718	177,6741	60,2464	127,5682	31,1945	143,5848	94,3551	82,3283	
15	42,1789	22,3571	25,7019	163,818	56,2334	100,809	143,1041	107,4589	190,6854	169,7485	94,9606	34,7961	54,8983	157,2136	24,8040	
16	200,2848	198,2223	92,2896	18,8663	27,8673	75,4116	150,1680	36,1555	41,2747	90,4558	68,5894	12,8068	42,2596	185,6280	171,3482	109,1469	127,9807	178,1714	35,839	56,9828	134,5203	55,6680	110,4252	
17	26,1275	45,5114	142,8016	83,4615	140,6440	8,3535	69,3610	153,8545	9,7002	12,4602	173,7312	114,8915	108,1942	54,3115	66,6176	190,7000	70,3899	5,2514	178,7464	166,4762	2,5409	146,5362	117,6266	
18	57,4216	80,5252	86,7517	62,1926	120,44	173,7256	133,2702	148,589	167,7625	16,8663	170,4989	118,6388	142,332	95,6122	99,5717	154,453	150,5150	149,2664	146,9000	171,4403	111,785	12,1520	
19	33,6938	77,7013	187,107	109,8397	88,2002	95,8691	132,3157	195,5038	154,4320	23,8560	152,9751	185,5896	119,7406	160,3997	80,62	
20	66,2667	173,2676	43,8105	135,6434	33,6387	74,6183	106,8785	75,2484	130,9048	56,7194	50,9507	88,3014	124,392	61,2580	90,7372	92,1704	87,2639	154,2398	41,4203	85,1435	169,5990	166,6086	28,2234	145,8099	
21	23,5183	40,2199	31,2556	71,4986	165,2151	193,494	154,1845	111,3060	85,2880	101,2775	182,2447	80,9884	87,2681	102,6643	131,3748	
22	92,5592	64,4257	11,8425	24,594	15,3571	42,3783	41,1374	114,9960	144,9362	146,3620	71,3243	143,8603	131,6075	192,4606	108,9656	168,4356	177,8713	132,1560	
23	143,7543	161,6863	45,8074	165,208	21,5183	118,5079	40,8336	27,9054	112,3201	135,4560	167,2133	188,4236	166,8077	195,3179	48,4485	137,7591	99,6485	5,9432	71,3316	96,2431	125,922	19,8560	
24	141,6862	197,9337	66,5879	59,6941	70,4670	55,4106	103,8083	61,7906	48,7959	151,784	177,393	102,8731	199,2838	73,3509	8,8434	187,9327	22,594	150,5669	164,7312	157,9540	15,8040	
25	115,9233	197,3875	185,3573	72,2332	104,4899	137,5378	8,3949	5,3496	77,2729	136,9251	143,108	83,9569	15,7019	48,3214	155,3242	153,2477	129,3005	132,219	11,5057	37,1591	68,4188	
26	14,3841	8,8342	1,4122	147,5759	113,5553	157,7	65,9434	116,4221	66,2747	138,7027	145,6697	130,5706	60,701	127,9896	136,7200	17,1275	120,5788	175,6165	70,9252	95,36	106,6940	2,2328	96,425	51,9329	183,4842	196,6754	
27	23,9054	78,3066	8,3483	1,7905	152,2124	108,9929	63,3896	151,5915	111,3101	34,8912	182,6234	133,7749	16,8673	192,5344	114,714	168,1578	175,210	138,5918	7,4888	122,84	
28	8,9996	188,3816	116,2638	132,5604	20,2234	178,3642	76,3705	122,9165	184,4164	198,366	161,9217	160,9059	56,5375	120,8874	11,2275	111,4495	193,9441	157,6880	48,2803	
29	78,8190	144,6452	114,9478	156,5083	62,9692	121,4537	184,9797	109,6873	153,5446	67,3449	172,5830	111,1005	100,1642	148,3252	13,2784	
30	78,5469	119,7372	144,1616	130,1356	59,4458	40,9818	79,503	43,6233	148,4760	42,263	1,4612	57,5668	185,3846	101,6979	94,6976	106,7819	2,2455	71,9294	
31	4,399	8,3987	50,2598	75,7688	47,7840	99,8583	190,5055	112,5231	114,7617	118,6949	180,3598	21,2556	199,5564	14,1945	3,3031	35,9855	10,1184	146,2837	51,3739	83,6588	46,5964	
32	136,3823	77,1689	92,3395	121,1615	85,7494	173,9631	177,6902	88,8129	36,7329	116,6065	61,3332	68,7352	119,1914	82,8571	70,9909	
33	144,4841	173,5949	170,3648	113,652	110,1986	82,3577	61,1837	97,5671	55,1252	19,6938	48,914	74,3642	125,67	89,3089	176,3258	20,6387	138,6960	153,6574	171,3913	
34	86,6435	156,8641	72,2540	181,5267	27,8912	58,8824	179,8528	62,9864	70,2348	57,5471	53,236	168,3923	101,3383	142,7791	55,7174	2,315	147,9758	15,7961	199,8196	12,6690	
35	57,3693	8,3160	144,3087	114,490	65,8910	178,5774	172,992	16,839	118,8640	41,6749	31,9855	39,853	64,6071	166,2816	184,7437	49,3098	182,7369	110,4985	93,8775	
36	80,2032	130,7589	123,6226	16,1555	150,116	88,7759	100,8612	9,5284	198,6280	49,953	143,5111	42,4917	134,979	159,6043	32,7329	67,2380	148,9550	48,7266	
37	197,9188	119,9313	187,4105	191,3573	109,2135	75,751	200,7541	139,8208	155,609	142,6433	25,1591	132,821	156,7714	107,1144	99,7757	
38	91,7087	88,502	132,6092	126,5441	147,8391	12,6699	130,5227	146,4400	108,8712	100,1369	134,4730	87,2975	99,6169	183,5213	109,4945	
39	200,4319	98,3993	130,2414	40,2489	196,9267	133,8145	82,3528	44,9175	42,5464	127,6103	93,6132	180,9506	192,7454	119,1376	115,983	81,7400	35,853	
40	23,8336	1,9047	120,7760	101,2885	21,2199	144,7772	96,5739	136,4658	184,4306	189,4263	30,9818	39,2489	108,8883	8,3193	80,9657	181,2338	162,3056	71,2826	68,5800	
41	200,2622	78,63	66,4654	198,7215	59,284	75,7333	22,1374	181,5235	16,2747	154,901	150,7278	3,7212	103,7917	163,5256	20,4203	91,7776	35,6749	147,1858	165,3741	107,8116	
42	160,2382	156,6539	6,7265	15,1789	61,8096	164,347	194,6498	172,5383	104,2726	124,3496	161,4792	159,5951	117,7074	2,1689	186,9391	62,3249	79,9404	39,5464	187,3075	22,3783	30,263	16,2596	137,4572	163,1278	60,6663	70,9396	36,4917	73,9154	
43	200,8943	159,9621	97,3906	20,8105	164,6849	13,5400	3,7313	133,8488	108,8964	30,6233	79,5052	131,8231	167,8120	14,3199	130,2685	138,7965	177,9544	143,1171	65,5805	118,8008	140,4482	93,8479	
44	197,4900	144,2276	198,2619	39,9175	87,7875	191,8130	166,6953	170,6940	163,18	79,9988	145,2888	173,5518	57,9979	82,3134	54,4113	3,2165	
45	57,4630	23,8074	112,9496	130,4994	86,8207	17,5114	120,5279	169,662	162,3436	170,8060	118,5918	124,3290	110,8317	13,1794	167,1163	
46	57,2413	152,9550	86,7512	123,132	138,2860	195,8206	176,9923	119,2687	54,9328	196,9632	73,5109	31,5964	173,2969	193,199	80,7968	194,2429	
47	57,9584	114,9480	145,9483	190,5892	182,8382	31,7840	129,9533	142,5297	58,1229	146,2959	6,274	14,7898	189,5939	11,8727	76,2138	70,2236	
48	152,5835	23,4485	33,914	24,7959	25,3214	135,8869	53,3578	162,201	28,2803	141,7941	36,7266	85,2792	86,3588	124,2593	130,7921	
49	160,8648	154,2962	109,7520	36,953	178,9747	192,3113	112,2935	35,3098	71,3441	4,619	96,9901	171,9736	163,4688	1,2437	133,5167	117,2896	105,9278	
50	152,5767	112,6454	185,3968	77,5220	20,9507	165,2667	98,990	187,2485	198,3798	13,758	128,2987	189,7031	52,9931	127,3622	31,2598	179,2502	191,5026	153,4905	
51	80,7589	72,4882	137,1096	138,8755	109,662	67,4225	181,158	132,6107	189,8899	159,3017	5,22	10,5578	31,3739	120,5675	26,9329	176,1625	
52	4,9267	115,4973	159,7816	185,8925	188,7805	97,9063	50,9931	137,9846	91,424	150,634	56,2416	107,3647	68,7601	168,1134	179,3504	
53	14,9197	114,7352	156,4662	62,153	85,1227	177,9852	34,236	7,179	12,7001	48,3578	71,9285	86,7353	150,662	183,5304	125,8054	54,8361	
54	197,2223	66,2906	136,1794	188,4883	17,3115	109,7832	44,4113	182,438	15,8983	200,4899	112,2279	169,2296	4,313	53,8361	138,6261	46,9328	
55	33,1252	188,5181	101,6050	24,4106	169,7795	149,3088	34,7174	193,8583	1,6399	145,3342	105,8477	166,3686	121,44	16,6680	82,3547	
56	101,3516	20,7194	179,5284	127,3031	5,8262	161,9811	16,9828	15,2334	52,2416	7,6616	77,7923	182,7267	88,3375	61,1315	117,1934	28,5375	124,552	100,361	
57	18,4216	94,558	186,8815	3,1239	85,6678	45,4630	46,2413	35,3693	84,6563	185,9772	67,8012	47,9584	155,893	64,810	10,9988	80,8722	160,2058	59,2689	79,2330	30,5668	184,7592	44,9979	162,6483	116,656	34,5471	106,4868	131,6342	183,9093	13,6850	12,9416	
58	152,5877	98,3677	8,4708	130,7020	59,5735	121,8818	47,1229	102,6906	150,4857	90,7141	86,5989	175,3675	79,2365	34,8824	186,8993	125,1050	74,7934	147,2267	193,6166	
59	86,1293	147,2651	149,2405	141,9126	112,4585	58,5735	74,4470	24,6941	199,8958	57,2689	13,9801	162,391	30,4458	180,2435	41,284	72,7154	101,1804	87,4628	168,4170	99,671	70,8055	11,3203	12,761	
60	200,3269	98,2073	26,701	185,6670	120,2231	14,2464	127,1402	12,5933	42,6663	189,4415	107,52	146,2317	112,2570	154,6667	177,5345	172,2781	
61	1,9146	159,49	33,1837	42,8096	20,2580	24,7906	87,9053	163,448	190,9775	155,5301	173,4803	115,3324	196,5577	171,6888	32,3332	56,1315	131,6924	195,8928	
62	97,9163	53,153	120,3851	18,1926	154,3238	12,5676	88,9007	152,7404	29,9692	161,4144	10,4816	105,2736	42,3249	107,5324	115,1913	121,4145	116,7419	34,9864	193,6610	103,8383	
63	141,5607	77,5873	27,3896	169,5160	95,5264	69,2323	125,1315	158,5709	102,5806	9,1753	103,9314	71,3007	131,5257	92,9006	96,5638	7,9920	
64	57,810	98,3909	97,2201	22,4257	120,2385	177,7660	83,2716	81,9744	111,2663	145,2685	130,2493	148,6419	106,256	141,158	86,414	87,9403	121,771	102,4635	5,7836	67,2090	35,6071	131,4631	182,4701	110,6711	
65	152,3595	66,6930	26,9434	97,6170	123,9599	175,7920	155,5533	102,1652	77,4069	198,3575	81,3054	199,11	95,6605	35,8910	43,5805	71,439	134,9956	74,6617	165,3705	140,5376	
66	80,2902	68,8312	142,777	156,2965	41,4654	6,6627	84,7710	102,3328	65,6930	54,2906	24,5879	112,2271	93,5873	94,3424	20,2667	26,2747	130,5826	17,6176	69,824	89,3012	
67	57,8012	102,5417	175,5048	153,6204	12,371	137,1414	133,3802	64,2090	98,980	200,475	171,1394	36,2380	29,3449	124,1880	51,4225	195,5737	100,6216	103,1468	
68	141,3540	197,8223	78,7924	66,8312	144,2277	174,7082	16,5894	163,4920	146,3895	52,7601	140,9624	40,5800	25,4188	32,7352	186,2528	
69	8,8815	198,6284	17,3610	156,9959	75,3354	168,2357	102,1172	190,8022	139,9030	161,6171	96,4815	189,5215	66,824	94,1427	63,2323	
70	4,5285	24,4670	148,7231	26,9252	17,3899	59,8055	47,2236	42,9396	175,3256	149,2366	92,96	153,6532	178,3394	168,1295	156,4830	34,2348	9,2	124,9089	32,9909	183,5332	
71	8,5829	22,3243	138,1229	81,1711	170,1539	49,3441	23,3316	134,7485	12,6734	30,9294	21,4986	142,6038	65,439	7,8206	40,2826	145,6127	53,9285	63,3007	186,7143	171,6702	
72	4,6508	78,5839	119,6215	114,8350	9,794	8,7308	113,8782	102,3377	34,2540	25,2332	59,7154	172,3153	89,4836	178,5128	51,4882	120,2287	174,2019	153,541	96,859	146,4264	171,8573	157,604	12,3626	
73	14,4106	8,4528	159,4969	97,6534	77,2438	24,3509	174,2581	150,8061	139,4428	149,5233	42,9154	90,5133	78,212	194,8521	172,2239	46,5109	
74	159,8960	33,3642	59,4470	20,6183	99,7031	179,1223	93,5576	164,8627	58,7934	65,6617	110,6731	108,8251	165,2602	121,1468	182,1873	176,8129	
75	115,9140	141,9237	80,2187	86,259	20,2484	92,6095	97,1883	41,7333	87,3244	69,3354	120,6892	131,5902	31,7688	108,5943	4,7044	16,4116	191,1403	81,2609	37,751	
76	115,7291	185,3674	181,3275	47,2138	143,1079	28,3705	125,1865	178,8433	3,7729	114,9690	100,1793	200,4623	199,6878	138,5683	141,1969	126,9595	9,9340	83,4424	89,6942	
77	112,3500	160,105	189,5702	191,5135	124,8896	198,5081	19,7013	73,2438	63,5873	129,2337	11,815	133,2481	192,561	32,1689	50,5220	87,7040	25,2729	65,4069	106,9161	153,4483	56,7923	172,4771	13,8638	
78	10,3771	68,7924	12,5753	30,5469	158,6367	122,6207	27,3066	116,2732	41,63	72,5839	161,6310	4,8058	104,1377	83,3955	29,8190	98,6603	154,8423	137,1910	135,6919	73,212	145,7244	
79	141,7918	101,3205	165,3768	96,3059	119,4117	152,6519	57,2330	42,9404	166,8726	161,8395	30,503	89,5169	134,5792	117,9043	129,7314	43,5052	109,9677	58,2365	44,9988	167,820	193,7737	194,5784	
80	36,2032	84,4645	1,982	115,1417	151,6728	112,5208	51,7589	152,9606	113,917	18,5252	121,2257	75,2187	57,8722	133,7217	179,7729	119,108	66,2902	40,9657	97,7213	172,7715	89,7224	19,62	46,7968	21,9884	
81	115,2608	197,5540	97,8866	101,4493	64,9744	11,7299	71,1711	109,2519	136,1409	39,7400	75,2609	142,424	141,4032	183,3061	184,4485	95,7627	5,2469	143,9810	65,3054	89,6124	
82	33,3577	130,3349	156,4691	39,3528	173,591	177,7882	44,3134	116,8491	132,4162	135,519	131,3457	128,6834	32,8571	55,3547	14,3283	
83	78,3955	6,4949	185,9306	17,4615	64,2716	25,9569	149,6823	5,8407	167,8200	117,8516	165,1555	151,162	31,6588	76,4424	11,4211	
84	57,6563	80,4645	119,6417	66,7710	198,5999	136,4270	86,195	104,5330	154,5421	137,4367	95,3812	159,8763	170,2436	107,2954	85,9888	134,9312	7,4061	
85	57,6678	160,3613	156,6669	168,6193	136,6221	180,5525	32,7494	118,1102	192,544	129,517	93,2349	87,7478	189,1147	53,1227	20,1435	167,8110	133,836	84,9888	132,3873	128,4644	110,6060	21,2880	48,2792	
86	115,4291	197,9714	144,8808	59,1293	126,937	189,1115	18,7517	45,8207	46,7512	177,7010	180,4604	75,259	157,4447	84,195	34,6435	120,5230	64,414	184,801	58,5989	142,1663	53,7353	117,4220	48,3588	
87	160,8712	119,518	75,3244	94,9647	59,4628	61,9053	44,7875	168,9716	64,9403	164,3629	20,2639	8,2833	77,7040	7,4976	159,19	85,7478	191,6921	88,8011	167,1022	158,4081	110,1219	21,2681	38,2975	
88	6,2039	62,9007	20,3014	113,7322	136,9026	32,8129	38,502	151,2295	150,6770	183,5547	36,7759	87,8011	94,4629	115,6611	19,2002	161,1726	56,3375	10,2539	125,5012	89,6267	
89	33,3089	72,4836	123,1723	79,5169	174,858	76,6942	4,6363	199,2446	105,2736	66,3012	180,6612	80,7224	163,4055	88,6267	81,6124	
90	152,4427	4,9446	115,1117	119,928	185,7284	20,7372	16,4558	108,9076	179,3149	139,7846	58,7141	5,8919	73,5133	144,6223	174,6914	
91	160,383	181,5060	174,3418	113,4626	95,1806	3,2483	192,6625	52,424	115,1105	137,4129	142,9164	41,7776	158,5553	38,7087	200,1988	
92	1,647	130,4320	108,1844	134,610	194,426	177,3182	75,6095	20,1704	94,6085	128,556	22,5592	16,2896	186,7980	32,3395	139,6763	121,3819	138,8080	70,96	63,9006	
93	66,5873	39,6132	181,4071	154,4073	85,2349	106,7477	74,5576	150,9213	98,6617	147,7807	43,8479	152,6543	35,8775	167,5670	2,8177	
94	57,558	66,3424	92,6085	120,2733	87,9647	30,6976	191,8318	139,7116	109,1299	88,4629	170,9318	69,1427	14,3551	115,3350	171,9959	15,9606	
95	119,8126	112,555	120,1104	18,6122	91,1806	173,4092	196,231	26,36	147,1278	19,8691	125,2917	9,9480	63,5264	81,7627	84,3812	65,6605	105,6026	
96	40,5739	79,3059	104,9639	113,712	162,3737	155,1251	10,807	49,9901	151,5643	23,2431	72,859	26,425	69,4815	143,9274	183,5939	63,5638	147,6736	193,8831	
97	33,5671	185,7065	52,9063	64,2201	188,4695	192,6411	43,3906	73,6534	13,7026	112,7969	81,8866	80,7213	62,9163	65,6170	140,6527	75,1883	137,4667	
98	115,5825	131,4614	64,3909	155,5515	139,1235	39,3993	102,8330	60,2073	200,2690	166,2364	78,6603	162,6139	58,3677	117,9545	6,5594	144,7198	50,990	150,2093	143,4300	67,980	93,6617	
99	104,9140	18,5717	174,5675	157,6818	132,6234	182,2897	151,4990	183,3577	59,671	133,2090	23,6485	153,4560	31,8583	74,7031	1,2367	127,1408	37,7757	193,4566	194,5832	38,6169	
100	159,6567	137,7178	163,9709	190,6674	36,8612	142,2994	76,1793	67,6216	29,1642	56,361	144,6605	128,2584	153,9522	145,5512	15,809	38,1369	
101	188,8531	40,2885	157,1393	171,4083	55,6050	144,3619	3,3381	113,5024	81,4493	163,6033	56,3516	129,8821	184,9591	59,1804	79,3205	30,6979	138,2902	143,4042	34,3383	21,2775	
102	98,8330	66,3328	144,7884	72,3377	24,8731	181,3585	137,6814	172,6572	58,6906	64,4635	117,2689	177,4462	67,5417	183,9634	69,1172	65,1652	178,1334	161,8230	63,5806	140,6370	21,6643	
103	200,6851	123,8756	24,8083	41,7917	191,9683	63,9314	112,7409	110,491	131,2920	196,696	186,9654	62,8383	113,5248	67,1468	114,1318	
104	141,8162	78,1377	42,2726	123,9213	1,6647	126,8615	200,7083	197,4174	84,5330	192,4219	142,6236	99,9140	96,9639	25,4899	172,561	179,8827	169,3712	
105	185,1033	62,2736	113,3388	116,7899	89,2736	164,4661	183,7722	55,8477	190,2518	180,341	95,6026	119,9930	120,9333	13,6821	49,9278	
106	14,7912	4,4769	115,9598	141,674	112,4854	20,8785	64,256	181,5332	190,3305	3,6521	30,7819	93,7477	26,6940	77,9161	57,4868	111,6460	
107	114,2032	123,4581	62,5324	187,2610	60,52	116,9864	84,2954	182,8313	37,1144	169,668	52,3647	4,4383	41,8116	146,7862	112,7448	15,4589	176,6806	
108	200,9976	185,8699	17,1942	40,8883	156,7039	92,1844	75,5943	22,9656	43,8964	27,9929	174,5669	90,9076	145,521	143,972	113,4342	74,8251	126,525	38,8712	
109	152,2743	136,8658	81,2519	169,382	51,662	49,7520	129,2464	79,9677	54,7832	37,2135	94,1299	185,6644	29,6873	19,8397	16,1469	38,4945	
110	197,751	33,1986	145,6099	118,9403	74,6731	126,1073	103,491	35,4985	137,8848	165,4097	85,6060	87,1219	45,8317	64,6711	16,4252	
111	197,4083	144,5456	114,2027	64,2663	27,3101	191,5723	162,8771	152,1940	28,4495	106,6460	29,1005	130,9137	133,6767	18,785	160,9702	21,3060	
112	23,3201	141,130	80,5208	181,2524	95,555	77,3500	183,9037	164,1492	155,7915	106,4854	50,6454	133,9083	5,1522	45,9496	173,7338	66,2271	59,4585	97,7969	60,2570	31,5231	149,8736	49,2935	158,383	128,7645	107,7448	103,7409	54,2279	196,5663	
113	80,917	33,652	26,5553	72,8782	101,5024	108,4342	132,5383	116,8036	184,4999	88,7322	105,3388	187,6332	190,697	136,1984	96,712	91,4626	103,5248	
114	29,9478	180,8490	189,3102	111,2027	192,6813	141,6388	72,8350	115,3112	152,9627	53,7352	129,168	107,2032	1,508	47,9480	35,490	17,8915	22,9960	27,714	31,7617	76,9690	117,7876	193,4000	103,1318	194,949	
115	152,4383	176,8236	75,9140	25,9233	9,7827	98,5825	52,4973	146,9828	81,2608	128,9072	86,4291	76,7291	90,1117	106,9598	144,3825	80,1417	114,3112	62,1913	39,983	91,1105	88,6611	129,7465	166,3001	61,3324	117,1399	94,3350	
116	78,2732	26,4221	113,8036	179,8099	32,6065	105,7899	62,7419	107,9864	82,8491	186,8639	176,4512	192,5906	57,656	4,6771	28,2638	10,1493	
117	98,9545	198,3936	42,7074	79,9043	102,2689	56,1934	114,7876	83,8516	86,4220	196,3366	1,2597	49,2896	138,7762	17,6266	115,1399	
118	14,373	23,5079	4,3626	6,8547	123,2088	181,8129	18,6388	85,1102	31,6949	166,3979	35,8640	43,8008	45,5918	177,8279	110,9403	128,6289	
119	80,108	154,741	130,730	84,6417	72,6215	30,7372	170,275	168,1890	157,9158	90,928	121,6261	37,9313	95,8126	14,960	87,518	79,4117	39,1376	163,5189	169,3511	195,617	3,7711	32,1914	19,7406	46,2687	196,2824	105,9930	
120	40,7760	62,3851	72,2287	94,2733	86,5230	95,1104	164,5926	26,5788	18,44	155,6822	60,2231	185,556	45,5279	179,3327	159,5811	75,6892	64,2385	5,1862	178,8906	28,8874	51,5675	105,9333	
121	4,7639	80,2257	197,6502	119,6261	136,1320	156,195	29,4537	7,8739	58,8818	32,1615	168,7186	62,4145	92,3819	173,2976	64,771	175,8821	191,8606	162,1977	132,3867	74,1468	165,7147	148,8115	55,44	
122	78,6207	8,5338	174,8205	168,1574	162,3518	166,6712	135,6345	28,9165	192,1494	128,7247	189,2017	3,9640	148,3230	27,84	179,7377	
123	14,2733	198,3493	6,13	104,9213	107,4581	89,1723	118,2088	128,1602	155,3251	46,132	36,6226	184,2832	103,8756	65,9599	124,6490	145,8804	193,7460	
124	141,168	159,6580	42,3496	123,6490	77,8896	20,392	67,1880	158,1870	147,9014	165,9797	136,7388	56,552	11,6180	70,9089	45,3290	48,2593	
125	33,67	174,9048	95,2917	53,8054	1,2909	63,1315	76,1865	88,5012	58,1050	23,922	173,2615	188,230	172,8515	196,4519	138,9932	183,9920	7,5670	
126	14,9602	4,2625	159,2980	86,937	181,8920	104,8615	179,7436	191,3989	161,4512	108,525	155,307	110,1073	134,5002	38,5441	76,9595	180,7176	
127	4,6808	160,7534	26,9896	39,6103	50,3622	137,4069	60,1402	156,6372	2,9365	16,9807	56,3031	139,2526	14,5682	99,1408	167,3756	135,1752	161,6643	146,8151	
128	14,9662	115,9072	123,1602	92,556	50,2987	190,2968	118,6289	157,6815	132,2789	184,6339	198,1860	112,7645	122,7247	85,4644	82,6834	100,2584	196,1760	12,7542	
129	6,8525	114,168	101,8821	77,2337	79,7314	47,9533	85,517	175,7121	184,5623	109,2464	143,8021	167,5370	25,3005	159,6895	115,7465	
130	119,730	8,55	26,5706	45,4994	36,7589	30,1356	184,8488	178,615	92,4320	58,7020	82,3349	174,4481	66,5826	39,2414	194,9429	156,2264	20,9048	64,2493	43,2685	137,5926	190,3429	147,9251	111,9137	48,7921	38,5227	
131	14,358	98,4614	159,4355	75,5902	22,6075	43,8231	163,8625	11,833	57,6342	61,6924	82,3457	64,4631	134,6293	167,6269	2,7005	63,5257	9,700	103,2920	21,3748	
132	198,2393	113,5383	99,6234	138,5667	28,5604	19,3157	38,6092	85,3873	82,4162	25,219	182,6433	22,1560	147,2847	6,1514	121,3867	128,2789	51,6107	37,821	
133	80,7217	112,9083	136,3739	77,2481	39,8145	43,8488	18,2702	27,7749	168,899	99,2090	190,9958	139,4719	182,8241	191,4296	85,836	153,8437	67,3802	49,5167	111,6767	
134	197,6225	198,4071	92,610	79,5792	175,4489	36,979	131,6293	71,7485	146,9556	158,119	11,294	65,9956	135,276	16,5203	84,9312	126,5002	38,4730	
135	23,4560	4,7582	20,6434	174,6977	150,9732	190,1431	173,5664	144,6396	127,1752	122,6345	48,8869	82,519	158,8348	184,7629	78,6919	10,4650	134,276	194,5726	13,861	
136	161,3866	195,4279	32,3823	84,4270	168,9519	54,1794	170,1529	197,9068	121,1320	194,2496	109,8658	199,7783	133,3739	145,1769	179,6711	26,7200	40,4658	174,5711	85,6221	113,1984	25,9251	184,6682	81,1409	88,9026	178,2752	124,7388	
137	188,9117	100,7178	42,4572	51,1096	52,9846	97,4667	25,5378	102,6814	130,5926	84,4367	141,7872	23,7591	127,4069	157,5286	78,1910	91,4129	155,5736	67,1414	10,5273	110,8848	
138	200,678	160,9902	26,7027	101,2902	51,8755	132,5667	43,7965	92,8080	1,7896	173,8555	33,6960	71,1229	46,2860	27,5918	188,892	169,7498	178,6589	125,9932	76,5683	117,7762	54,6261	140,5446	
139	197,1386	98,1235	92,6763	181,5456	176,8186	182,2354	133,4719	158,3451	196,3988	73,4428	90,7846	155,2100	194,6966	69,9030	94,7116	127,2526	162,4510	9,8701	37,8208	
140	1,546	17,6440	97,6527	158,4029	151,5289	68,9624	138,5446	43,4482	169,2230	9,4163	155,5001	188,6223	102,6370	166,9829	65,5376	
141	154,3188	68,3540	106,674	79,7918	104,8162	24,6862	63,5607	6,8200	75,9237	150,2634	124,168	14,4477	112,130	164,6499	198,2621	114,6388	185,6820	59,9126	64,158	137,7872	81,4032	76,1969	48,7941	
142	66,777	17,8016	104,6236	18,332	47,5297	81,424	91,9164	150,2598	5,1195	34,7791	155,6613	169,7506	86,1663	100,2994	190,8070	2,7731	71,6038	145,5378	37,6433	
143	23,7543	6,3110	22,8603	108,972	25,108	81,9810	43,1171	186,8430	14,5848	129,8021	101,4042	76,1079	98,4300	155,2442	177,3884	36,5111	153,9940	96,9274	15,1041	176,5062	
144	115,3825	173,8693	29,6452	98,7198	68,2277	195,652	102,7884	30,1616	111,5456	33,4841	13,9987	44,2276	86,8808	148,3617	35,3087	40,7772	101,3619	22,9362	184,5222	135,6396	90,6223	3,285	100,6605	
145	200,2753	1,648	136,1769	26,6697	64,2685	174,7252	47,9483	108,521	44,2888	123,8804	71,6127	142,5378	20,8099	78,7244	110,6099	100,5512	55,3342	
146	115,9828	22,3620	47,2959	60,2317	5,5308	127,8151	7,4823	134,9556	18,9000	31,2837	17,5362	68,3895	72,4264	188,5715	167,52	107,7862	38,4400	
147	26,5759	59,2651	163,7221	95,1278	132,2847	124,9014	5,1087	34,9758	96,6736	38,8391	41,1858	167,5546	130,9251	149,6379	58,2267	93,7807	
148	160,3995	144,3617	185,2814	64,6419	18,589	30,4760	173,6725	179,6374	70,7231	155,6603	122,3230	192,4834	36,9550	121,8115	29,3252	
149	14,4352	59,2405	188,1003	163,9897	70,2366	83,6823	187,9580	174,2824	73,5233	112,8736	55,3088	18,2664	176,2255	190,3755	180,3407	147,6379	
150	141,2634	1,2183	16,1680	41,7278	36,116	135,9732	11,4802	98,2093	58,4857	142,2598	73,8061	9,4539	18,5150	24,5669	52,634	190,5243	88,6770	53,662	7,9031	93,9213	
151	80,6728	156,6169	24,784	27,5915	174,1846	168,9216	99,4990	88,2295	178,5979	96,5643	83,162	13,9629	140,5289	189,9732	163,3624	
152	161,6939	58,5877	48,5835	9,1087	8,1257	46,9550	189,8140	199,2697	109,2743	65,3595	186,2075	115,4383	50,5767	193,5444	90,4427	80,9606	114,9627	62,7404	79,6519	27,2124	111,1940	19,9751	93,6543	
153	17,8545	99,4560	70,6532	164,8748	29,5446	25,2477	72,541	143,9940	173,7613	77,4483	50,4905	165,897	133,8437	33,6574	67,6204	100,9522	
154	141,3188	119,741	198,5078	156,8062	62,3238	20,2398	18,453	49,2962	187,1808	168,6317	200,229	185,1448	93,4073	78,8423	84,5421	41,901	60,6667	170,5971	19,4320	21,1845	199,5786	
155	57,893	14,4446	98,5515	112,7915	123,3251	120,6822	25,3242	139,2100	143,2442	65,5533	142,6613	96,1251	137,5736	148,6603	61,5301	126,307	37,609	140,5001	194,6768	
156	66,2965	42,6539	82,4691	53,4662	151,6169	7,7027	85,6669	29,5083	154,8062	130,2264	108,7039	34,8641	121,195	175,2205	69,9959	70,4830	127,6372	37,7714	
157	119,9158	26,7	86,4447	101,1393	187,7184	137,5286	99,6818	11,8497	2,8643	158,1881	128,6815	175,1597	72,604	24,9540	28,6880	15,2136	
158	78,6367	187,6714	91,5553	139,3451	169,1709	135,8348	63,5709	195,4912	140,4029	157,1881	124,1870	181,969	112,383	87,4081	134,119	
159	4,6133	160,4243	61,49	180,5757	6,9500	194,9391	43,9621	100,6567	126,2980	73,4969	131,4355	124,6580	1,7420	52,7816	74,8960	198,8330	42,5951	120,5811	87,19	36,6043	84,8763	129,6895	2,1397	51,3017	193,3786	
160	14,7860	138,9902	127,7534	49,8648	85,3613	189,1530	57,2058	159,4243	183,9293	148,3995	87,8712	180,624	179,2542	91,383	42,2382	1,6461	77,105	28,9059	111,9702	19,3997	
161	152,6939	14,4275	23,6863	78,6310	136,3866	42,4792	62,4144	79,8395	127,6643	69,6171	126,4512	56,9811	196,9729	102,8230	88,1726	28,9217	
162	4,3924	98,6139	6,6897	59,391	194,1483	122,3518	57,6483	121,1977	179,9718	139,4510	199,7749	40,3056	111,8771	96,3737	45,3436	186,6114	48,201	
163	1,8164	101,6033	41,5256	173,5799	15,818	13,3870	149,9897	131,8625	181,5593	119,5189	61,448	42,1278	68,4920	100,9709	147,7221	44,18	49,4688	192,2762	151,3624	89,4055	
164	141,6499	112,1492	42,347	120,5926	43,6849	87,3629	184,9774	170,328	153,8748	10,3866	172,9550	74,8627	195,9730	105,4661	24,7312	183,615	176,8681	
165	23,208	6,6473	79,3768	187,1291	50,2667	153,897	166,4221	74,2602	21,2151	121,7147	124,9797	83,1555	65,3705	7,6019	41,3741	110,4097	
166	23,8077	98,2364	79,8726	173,6917	44,6953	167,7080	118,3979	165,4221	168,4399	17,4762	9,8702	122,6712	20,6086	169,5530	115,3001	35,2816	55,3686	140,9829	
167	23,2133	188,6549	187,9538	43,8120	18,7625	127,3756	180,6183	87,1022	79,820	83,8200	3,3877	129,5370	85,8110	193,8116	166,7080	131,6269	146,52	147,5546	45,1163	199,2001	93,5670	
168	119,1890	8,2076	136,9519	87,9716	154,6317	121,7186	133,899	122,1574	85,6193	173,3859	59,4170	27,1578	69,2357	151,9216	22,4356	70,1295	34,3923	166,4399	10,9495	52,1134	
169	14,4333	175,9164	177,2274	45,662	20,5990	63,5160	119,3511	104,3712	187,9225	192,8603	109,382	158,1709	55,7795	1,8700	138,7498	142,7506	166,5530	107,668	15,7485	54,2296	140,2230	
170	119,275	1,2620	198,8089	136,1529	33,3648	18,4989	177,2774	44,6940	84,2436	2,9342	154,5971	164,328	45,8060	71,1539	94,9318	
171	188,6981	101,4083	16,3482	67,1394	61,6888	49,9736	182,4704	94,9959	10,2029	33,3913	185,5113	71,6702	6,3722	18,4403	72,8573	
172	200,6888	42,5383	72,3153	104,561	174,3433	102,6572	175,5353	35,992	73,2239	164,9550	29,5830	80,7715	77,4771	2,1438	60,2781	125,8515	13,2070	
173	112,7338	1,2069	144,8693	33,5949	17,7312	20,2676	18,7256	121,2976	168,3859	32,9631	148,6725	82,591	163,5799	192,2550	166,6917	179,4234	138,8555	44,5518	95,4092	153,7613	135,5664	61,4803	125,2615	193,4808	46,2969	
174	130,4481	89,858	73,2581	135,6977	68,7082	136,5711	91,3418	125,9048	122,8205	145,7252	72,2019	151,1846	172,3433	108,5669	99,5675	179,1886	149,2824	90,6914	
175	156,2205	187,2864	27,210	199,3779	67,5048	121,8821	169,9164	134,4489	65,7920	26,6165	172,5353	197,5909	8,1022	129,7121	14,6718	184,9107	70,3256	58,3675	157,1597	
176	200,1709	115,8236	6,3512	33,3258	187,1128	191,3352	139,8186	149,2255	116,4512	46,9923	143,5062	51,1625	164,8681	107,6806	74,8129	
177	86,7010	92,3182	24,393	64,7660	102,4462	43,9544	22,8713	190,1332	14,6741	8,8508	170,2774	82,7882	169,2274	32,6902	53,9852	60,5345	143,3884	178,7547	118,8279	3,7097	
178	130,615	72,5128	70,3394	13,4194	120,8906	11,1696	151,5979	16,1714	138,6589	102,1334	17,7464	49,9747	177,7547	35,5774	136,2752	28,3642	76,8433	
179	80,7729	160,2542	136,6711	120,3327	56,5284	50,2502	186,9993	180,664	104,8827	90,3149	74,1223	148,6374	174,1886	126,7436	173,4234	162,9718	116,8099	34,8528	52,3504	122,7377	
180	160,624	159,5757	114,8490	59,2435	86,4604	39,9506	85,5525	179,664	191,6312	31,3598	149,3407	167,6183	89,6612	9,5995	126,7176	105,341	
181	112,2524	187,7956	41,5235	118,8129	185,9712	139,5456	76,3275	40,2338	11,8448	34,5267	102,3585	126,8920	106,5332	93,4071	91,5060	191,4844	163,5593	158,969	51,158	
182	27,6234	47,8382	99,2897	139,2354	5,8806	133,8241	132,6433	56,7267	74,1873	35,7369	64,4701	107,8313	54,438	171,4704	2,7908	21,2447	
183	160,9293	112,9037	102,9634	99,3577	81,3061	88,5547	11,594	96,5939	53,5304	105,7722	26,4842	57,9093	70,5332	125,9920	164,615	38,5213	
184	6,8021	130,8488	188,198	40,4306	123,2832	101,9591	113,4999	129,5623	144,5222	175,9107	136,6682	164,9774	86,801	57,7592	29,9797	81,4485	35,7437	135,7629	28,4164	10,3207	128,6339	
185	57,9772	105,1033	90,7284	52,8925	83,9306	97,7065	148,2814	25,3573	197,3140	50,3968	11,2045	141,6820	76,3674	108,8699	60,6670	188,700	120,556	181,9712	154,1448	30,3846	16,6280	109,6644	171,5113	19,5896	196,1339	
186	57,8815	152,2075	197,1324	42,9391	188,5027	92,7980	179,9993	191,8255	58,8993	143,8430	116,8639	162,6114	71,7143	189,8128	195,2099	68,2528	103,9654	
187	14,4874	200,6767	176,1128	37,4105	7,9522	175,2864	19,107	107,2610	167,9538	157,7184	24,9327	181,7956	42,3075	158,6714	165,1291	50,2485	154,1808	113,6332	169,9225	149,9580	10,4786	
188	23,4236	198,9114	137,9117	184,198	101,8531	167,6549	54,4883	149,1003	28,3816	196,88	52,7805	55,5181	185,700	186,5027	171,6981	97,4695	138,892	125,230	146,5715	140,6223	
189	152,8140	160,1530	8,2780	114,3102	86,1115	40,4263	77,5702	50,7031	47,5939	85,1147	60,4415	69,5215	186,8128	198,9430	122,2017	51,8899	151,9732	193,2375	
190	4,7536	200,5999	47,5892	113,697	130,3429	135,1431	150,5243	61,9775	69,8022	133,9958	128,2968	100,6674	17,7000	106,3305	9,3613	177,1332	31,5055	149,3755	142,8070	15,6854	105,2518	
191	77,5135	126,3989	176,3352	94,8318	186,8255	121,8606	87,6921	44,8130	103,9683	75,1403	181,4844	50,5026	180,6312	111,5723	37,3573	133,4296	
192	114,6813	97,6411	77,561	39,7454	22,4606	104,4219	27,5344	85,544	173,2550	91,6625	169,8603	116,5906	49,3113	163,2762	122,1494	148,4834	
193	152,5444	167,8116	114,4000	55,8583	58,6166	189,2375	159,3786	96,8831	79,7737	21,494	28,9441	62,6610	123,7460	99,4566	173,4808	46,199	
194	200,2915	159,9391	136,2496	130,9429	42,6498	92,426	139,6966	162,1483	73,8521	99,5832	155,6768	114,949	46,2429	79,5784	135,5726	
195	23,3179	4,2490	197,5337	144,652	136,4279	6,2233	158,4912	186,2099	200,8114	61,8928	46,8206	164,9730	119,617	19,5038	67,5737	
196	188,88	39,9267	139,3988	95,231	61,5577	161,9729	125,4519	117,3366	103,696	46,9632	26,6754	112,5663	128,1760	119,2824	185,1339	
197	54,2223	186,1324	121,6502	134,6225	68,8223	24,9337	25,3875	139,1386	81,5540	44,4900	195,5337	37,9188	111,4083	86,9714	110,751	136,9068	185,3140	104,4174	175,5909	
198	141,2621	170,8089	44,2619	188,9114	41,7215	1,1724	154,5078	84,5999	16,2223	117,3936	123,3493	159,8330	69,6284	132,2393	134,4071	77,5081	50,3798	65,3575	36,6280	28,366	128,1860	189,9430	
199	152,2697	8,1918	136,7783	59,8958	24,2838	175,3779	31,5564	162,7749	65,11	76,6878	9,70	89,2446	34,8196	167,2001	154,5786	
200	108,9976	103,6851	145,2753	41,2622	187,6767	190,5999	16,2848	194,2915	5,4009	172,6888	39,4319	176,1709	60,3269	138,678	43,8943	98,2690	1,8021	104,7083	154,229	91,1988	67,475	76,4623	195,8114	37,7541	54,4899	


================================================
FILE: Algorithms/graphtheory/breadth-first-search/BFS_queue_iterative.py
================================================
"""
Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
    2019-02-17 Initial programming
    2020-03-29 Cleaned up code, removed load graph, I think a small example is sufficient
               and instead only have the BFS function.
"""

from collections import deque


def BFS(G, start_node=1):
    """
    :param G: Graph with G = {from_node1:[to_node1, to_node2], from_node2: [to_node,] etc}
    :param start_node: starting node to run BFS from
    :return: returns visited boolean array and path in which order it visited them
    """
    visited = [False for i in range(1, len(G) + 1)]

    Q = deque()
    Q.append(start_node)

    path = []

    while Q:
        curr_node = Q.popleft()
        path.append(curr_node)

        if not visited[curr_node - 1]:
            visited[curr_node - 1] = True

            for connected_node in G[curr_node]:
                if not visited[connected_node - 1]:
                    Q.append(connected_node)

    return visited, path


# Small Example Run
# if __name__ == '__main__':
#     G = {1:[2,3], 2:[1,4], 3:[1,4],4:[]}
#     visited, path = BFS(G)
#
#     if all(visited) == True:
#         print("Return: This graph is connected!")

#     else:
#         print("Not all nodes were reachable, i.e the graph is not connected.")


================================================
FILE: Algorithms/graphtheory/breadth-first-search/exgraph.txt
================================================
1	37	79	164	155	32	87	39	113	15	18	78	175	140	200	4	160	97	191	100	91	20	69	198	196	
2	123	134	10	141	13	12	43	47	3	177	101	179	77	182	117	116	36	103	51	154	162	128	30	
3	48	123	134	109	41	17	159	49	136	16	130	141	29	176	2	190	66	153	157	70	114	65	173	104	194	54	
4	91	171	118	125	158	76	107	18	73	140	42	193	127	100	84	121	60	81	99	80	150	55	1	35	23	93	
5	193	156	102	118	175	39	124	119	19	99	160	75	20	112	37	23	145	135	146	73	35	
6	155	56	52	120	131	160	124	119	14	196	144	25	75	76	166	35	87	26	20	32	23	
7	156	185	178	79	27	52	144	107	78	22	71	26	31	15	56	76	112	39	8	113	93	
8	185	155	171	178	108	64	164	53	140	25	100	133	9	52	191	46	20	150	144	39	62	131	42	119	127	31	7	
9	91	155	8	160	107	132	195	26	20	133	39	76	100	78	122	127	38	156	191	196	115	
10	190	184	154	49	2	182	173	170	161	47	189	101	153	50	30	109	177	148	179	16	163	116	13	90	185	
11	123	134	163	41	12	28	130	13	101	83	77	109	114	21	82	88	74	24	94	48	33	
12	161	109	169	21	24	36	65	50	2	101	159	148	54	192	88	47	11	142	43	70	182	177	179	189	194	33	
13	161	141	157	44	83	90	181	41	2	176	10	29	116	134	182	170	165	173	190	159	47	82	111	142	72	154	110	21	103	130	11	33	138	152	
14	91	156	58	122	62	113	107	73	137	25	19	40	6	139	150	46	37	76	39	127	
15	149	58	68	52	39	67	121	191	1	45	100	18	118	174	40	85	196	122	42	193	119	139	26	127	145	135	57	38	7	
16	48	10	36	187	43	3	114	173	111	142	129	88	189	117	128	147	141	194	180	106	167	179	66	74	136	51	59	
17	48	123	134	36	163	3	44	117	167	161	152	95	170	83	180	77	65	72	109	47	43	88	159	197	28	194	181	49	
18	193	149	56	62	15	160	67	191	140	52	178	96	107	132	1	145	89	198	4	26	73	151	126	34	115	
19	156	80	178	164	108	84	71	174	40	62	113	22	89	45	91	126	195	144	5	14	172	
20	185	122	171	56	8	52	73	191	67	126	9	119	1	89	79	107	96	31	75	55	5	6	34	23	
21	188	187	12	173	180	197	138	167	63	111	95	13	192	116	94	114	105	49	177	51	130	90	11	50	66	157	176	
22	156	27	32	131	7	56	53	81	149	23	100	146	115	26	175	121	96	75	57	39	119	71	132	19	150	140	93	
23	91	122	124	22	200	195	145	5	69	125	55	68	156	20	58	191	4	57	149	6	
24	123	134	161	163	169	72	116	167	30	33	77	162	143	159	187	63	184	130	28	50	153	12	148	11	53	
25	193	185	79	108	8	158	87	73	81	115	39	64	178	132	27	68	127	84	14	52	200	97	6	93	
26	193	58	27	108	52	144	160	18	84	81	22	75	139	166	15	107	198	131	7	9	133	6	
27	156	139	144	166	112	100	26	174	31	42	75	158	122	81	22	7	58	73	89	115	39	25	200	69	169	
28	134	188	24	184	159	29	72	114	152	116	169	173	141	17	111	61	192	90	11	177	179	77	33	66	83	136	
29	48	134	188	13	47	88	3	82	92	28	194	50	192	189	123	199	177	147	43	106	148	197	77	103	129	181	
30	165	123	10	24	41	187	47	168	92	148	197	101	50	2	179	111	130	77	153	199	70	
31	27	171	56	131	146	139	191	89	20	108	38	71	75	69	196	149	97	8	86	98	7	
32	156	149	171	62	22	185	35	124	56	38	158	97	53	121	160	1	191	58	89	127	87	120	39	99	84	60	151	174	6	
33	48	161	109	141	24	187	47	88	168	183	110	103	95	116	28	12	11	13	83	134	63	
34	37	122	171	118	76	131	166	137	40	46	97	87	80	164	127	18	62	52	20	139	
35	79	164	125	32	107	137	75	121	85	55	69	45	193	132	4	5	200	135	76	139	198	6	
36	165	188	17	106	88	16	177	110	147	154	159	179	136	41	50	141	66	162	152	168	184	12	43	72	180	190	77	2	170	61	122	
37	193	149	39	121	191	115	146	52	127	79	198	58	125	38	34	1	76	89	164	97	86	178	108	87	84	124	98	174	195	14	5	57	196	186	
38	193	37	86	32	76	107	73	85	127	100	46	89	31	57	96	158	99	160	45	15	9	
39	193	37	122	102	8	158	32	87	85	81	200	60	5	27	155	1	58	150	15	113	76	84	22	25	151	139	100	14	145	9	7	
40	91	156	122	79	118	125	52	175	87	15	81	166	132	121	19	14	160	34	78	71	
41	36	169	184	116	163	106	189	11	104	61	30	123	129	111	3	47	49	154	161	152	13	153	65	92	183	177	162	95	54	70	108	
42	178	79	27	53	171	164	102	52	87	113	15	191	131	91	62	193	8	122	89	56	4	127	145	112	
43	165	161	12	70	199	54	17	190	16	153	141	36	47	44	194	110	82	189	2	148	183	29	130	94	170	51	61	59	
44	188	163	169	17	13	43	114	173	142	154	103	129	181	105	157	148	182	101	110	66	176	49	
45	156	80	149	58	178	53	108	68	56	125	15	93	75	135	174	198	81	166	113	100	19	89	35	97	38	
46	193	58	86	122	155	8	175	160	99	127	67	14	150	144	126	146	34	131	55	38	196	
47	123	10	109	41	17	12	43	116	59	33	13	2	187	165	88	117	29	30	176	147	180	101	130	194	50	94	152	70	
48	180	128	188	197	105	51	94	190	116	29	183	114	153	33	16	49	3	63	184	17	141	168	179	162	11	66	83	193	
49	48	123	10	186	141	41	168	3	148	142	179	21	136	109	44	117	17	103	187	74	
50	165	123	10	188	36	169	24	187	12	65	29	167	47	21	134	130	111	168	77	116	138	106	66	30	
51	165	48	109	141	163	159	92	190	143	2	21	138	43	59	192	117	16	184	104	169	
52	37	178	8	6	15	200	133	80	102	96	40	119	164	166	127	151	20	42	7	26	76	18	73	99	78	25	132	139	191	150	34	
53	156	122	102	193	137	133	42	62	45	64	60	78	160	132	155	56	144	131	196	178	125	8	32	113	22	98	121	198	24	
54	123	187	12	43	168	65	129	130	147	95	41	61	59	141	3	138	114	199	66	110	
55	68	56	125	113	73	78	200	46	131	85	107	89	185	60	84	4	35	99	171	71	20	23	
56	193	122	53	108	45	55	18	125	86	171	79	6	85	133	80	140	96	31	107	20	32	87	120	42	73	84	22	112	196	7	
57	79	155	158	76	84	22	75	121	85	191	100	97	15	37	102	69	38	64	195	145	23	
58	15	146	107	193	140	84	144	86	14	150	26	60	46	166	80	87	139	195	126	45	37	27	102	62	32	175	39	124	23	93	188	
59	186	163	187	47	168	92	143	147	157	54	51	61	199	43	103	63	184	16	188	197	
60	58	86	178	53	171	125	39	144	146	73	124	4	93	32	99	158	132	80	91	96	75	174	55	196	
61	188	116	41	114	183	28	77	54	36	163	187	147	179	65	63	190	43	186	59	189	
62	193	185	79	53	171	102	146	84	198	14	58	137	8	166	175	32	113	18	115	196	42	200	132	121	19	112	133	172	34	
63	48	24	116	183	111	167	21	162	90	181	147	105	106	101	33	123	153	184	128	168	61	59	
64	91	149	122	53	8	120	113	124	119	25	132	131	193	121	144	68	185	108	175	107	57	
65	186	17	12	114	82	3	66	159	167	197	50	101	176	94	54	134	41	165	157	194	180	77	103	74	61	
66	188	36	116	3	65	183	72	180	77	16	136	177	82	159	28	95	48	50	187	21	44	54	176	
67	91	156	102	68	175	131	144	15	18	146	119	20	200	46	112	139	75	80	86	137	
68	122	171	55	78	175	96	75	71	93	118	195	115	67	79	45	158	15	120	155	193	87	146	81	25	64	23	
69	91	108	125	131	81	75	85	174	145	89	27	200	35	156	1	98	86	23	191	127	31	57	
70	165	123	163	153	12	43	168	3	114	82	148	190	129	74	176	47	110	181	41	30	
71	193	79	171	68	124	98	120	73	75	93	151	108	89	155	19	96	22	119	7	125	85	127	40	55	140	31	
72	109	169	24	116	17	114	182	190	141	186	192	28	104	13	66	165	162	36	159	77	110	129	130	181	
73	91	80	27	160	4	20	100	56	193	60	38	18	25	172	76	14	55	52	149	96	78	71	195	127	5	112	97	93	
74	88	104	197	111	130	95	11	138	123	77	159	65	179	94	165	70	141	16	153	136	83	49	
75	91	79	27	171	68	158	87	81	22	119	71	166	57	60	35	160	69	175	26	193	45	127	67	126	89	20	5	31	198	6	
76	37	178	175	120	122	57	52	34	4	156	98	115	133	131	171	149	85	38	174	39	73	99	14	140	35	135	172	9	7	6	
77	24	116	17	72	190	110	36	173	143	94	65	29	61	154	2	161	90	66	159	28	128	117	11	50	138	74	30	
78	156	80	53	164	68	131	144	107	73	195	55	175	1	126	7	149	171	81	91	52	124	40	9	
79	80	37	158	40	75	108	198	25	62	42	7	86	57	102	122	145	175	71	1	35	164	68	118	56	144	200	139	20	112	135	172	163	
80	91	144	100	118	45	78	139	112	149	98	113	87	195	124	85	73	119	19	79	99	58	56	52	146	81	4	60	137	67	126	145	97	34	134	
81	86	27	120	39	131	40	132	25	69	96	26	127	108	75	68	135	98	80	115	149	78	22	4	45	172	
82	161	186	109	153	43	159	114	101	104	70	29	197	192	116	148	65	152	184	13	154	92	110	130	11	147	66	176	
83	17	13	153	88	111	90	117	95	11	33	147	28	109	199	48	74	167	182	154	101	
84	149	58	86	178	171	62	175	113	26	135	96	198	39	19	57	144	37	118	32	56	119	4	98	25	200	150	55	
85	156	80	185	155	102	56	158	39	76	15	69	38	150	175	118	137	71	35	120	57	55	135	
86	58	84	120	81	112	37	60	46	185	193	38	125	118	175	149	99	108	126	133	102	79	56	144	67	69	31	109	
87	80	149	58	118	25	75	126	115	68	178	37	200	32	40	164	56	42	193	107	1	39	113	145	89	172	6	34	93	
88	36	116	12	47	165	168	29	83	159	154	74	148	92	176	180	33	110	194	167	17	114	173	16	11	
89	37	27	102	32	42	18	99	71	151	19	55	75	98	131	69	45	31	38	195	87	20	135	115	
90	163	116	13	173	28	110	190	77	129	117	130	10	179	92	134	194	21	63	83	157	94	152	199	
91	126	14	75	135	107	80	102	67	160	158	144	23	64	155	4	198	40	9	73	69	193	185	149	164	42	78	60	98	19	1	165	
92	161	109	163	187	88	186	141	51	117	197	59	173	192	82	29	143	116	41	30	111	148	129	90	194	152	170	
93	68	99	71	60	45	150	145	98	25	87	122	178	185	7	144	4	22	73	58	112	
94	48	163	65	173	182	154	77	21	117	11	147	74	189	43	114	47	177	192	104	90	
95	123	141	169	17	168	114	179	21	33	165	167	177	41	103	83	199	129	182	188	74	66	157	152	54	176	
96	171	164	68	56	52	18	73	84	81	124	22	71	60	126	150	20	97	38	149	158	196	115	
97	185	149	37	178	122	108	118	32	131	1	31	140	73	34	45	25	80	133	57	96	
98	80	171	164	158	120	76	99	81	71	37	91	151	144	172	140	150	160	121	84	53	139	89	69	31	133	93	
99	80	86	178	122	118	125	52	193	32	174	46	113	98	93	89	150	102	76	100	124	4	60	55	5	38	196	
100	80	185	149	27	8	113	131	15	73	99	22	4	200	45	102	172	57	164	38	39	1	112	9	
101	165	10	188	109	141	163	187	12	168	82	65	148	180	47	167	2	162	169	192	30	179	11	44	83	170	63	
102	91	86	79	53	171	155	67	113	39	137	158	196	166	120	42	89	58	5	119	85	62	52	146	99	121	100	57	
103	161	188	186	184	153	159	167	189	2	168	13	29	104	142	33	65	197	117	148	44	95	181	59	49	
104	134	188	186	141	184	41	187	168	114	82	148	192	194	154	74	3	190	161	105	163	72	103	94	170	51	
105	165	48	161	116	159	104	21	129	63	44	169	106	142	190	181	143	179	157	173	188	199	176	
106	36	163	169	184	41	159	29	197	111	16	179	162	105	138	148	50	165	63	173	109	
107	91	58	56	125	158	87	191	133	9	38	122	164	175	135	4	35	14	7	185	78	18	146	151	26	64	126	55	20	112	198	172	
108	86	178	79	164	37	25	195	144	120	198	26	56	19	132	69	193	115	45	172	97	155	8	81	71	166	139	174	64	31	41	
109	10	47	116	12	128	51	167	180	179	33	123	101	142	92	143	199	154	3	72	82	141	17	168	114	173	183	148	189	11	181	106	83	152	49	86	
110	165	186	36	163	169	43	88	168	33	138	147	13	167	189	184	134	72	90	188	82	77	44	54	70	
111	41	92	114	162	188	129	187	170	152	83	142	74	157	16	13	138	186	106	63	184	28	21	50	30	192	
112	193	80	86	27	137	174	67	5	79	198	132	127	42	131	100	73	107	56	135	62	7	93	
113	156	80	149	171	102	62	39	133	84	87	198	1	53	64	55	172	122	100	42	14	160	99	124	137	45	19	145	7	
114	48	104	136	16	61	72	181	128	82	88	138	109	129	70	192	3	153	65	95	44	111	28	21	11	94	54	
115	185	37	27	108	68	62	87	120	76	81	22	25	151	139	191	140	9	89	96	18	
116	48	188	109	24	157	61	41	181	128	66	88	63	152	189	168	90	105	72	77	10	13	47	82	173	92	142	28	180	2	21	117	50	33	136	164	
117	17	47	92	16	179	2	103	90	194	189	192	94	143	170	162	83	116	129	184	77	138	152	51	49	
118	193	156	80	86	155	68	196	145	40	4	97	79	5	99	87	149	174	34	137	166	131	15	160	84	121	85	
119	80	178	102	52	160	124	84	185	6	22	67	174	8	121	133	5	75	64	15	150	71	151	145	20	
120	185	86	171	108	102	68	200	193	126	64	160	32	150	6	115	98	81	56	191	76	124	71	139	85	195	135	
121	156	185	37	32	15	146	22	119	4	98	151	57	62	126	53	139	40	102	35	118	64	135	133	
122	156	146	23	99	196	46	14	56	53	175	164	20	68	39	195	126	97	40	34	64	79	27	155	113	76	131	15	42	107	166	151	9	93	36	
123	165	194	50	70	95	11	153	30	24	17	49	47	54	2	189	147	199	3	188	197	186	109	41	29	129	130	128	74	136	63	156	
124	193	80	125	32	146	99	23	5	60	113	120	191	6	58	64	119	71	37	78	96	137	
125	37	86	56	4	133	69	178	132	53	172	45	60	151	40	198	55	35	107	99	124	71	137	127	23	
126	91	58	86	122	155	87	120	146	78	200	121	19	80	20	137	75	96	107	18	156	46	135	
127	37	178	32	52	131	160	81	4	25	191	125	38	71	15	8	42	75	46	174	73	14	69	112	172	9	34	
128	48	134	161	109	116	187	114	183	16	179	189	130	181	142	123	138	2	136	77	152	63	
129	165	184	41	153	114	148	111	177	16	180	44	29	123	54	173	72	92	70	199	105	90	117	95	157	
130	186	169	24	3	154	189	21	136	72	82	74	190	11	47	13	173	54	181	43	123	90	128	50	138	30	176	
131	193	53	76	78	22	69	97	118	178	122	140	81	34	164	8	100	127	67	31	6	42	146	200	195	26	64	46	55	89	112	
132	185	149	53	171	108	125	18	81	60	25	139	191	178	64	52	9	62	22	40	164	35	112	
133	86	53	56	125	8	52	113	76	107	119	195	97	156	98	121	62	140	26	175	9	
134	153	11	17	182	165	197	138	173	24	28	104	128	29	2	167	152	183	3	162	154	186	13	65	142	110	90	50	33	157	80	
135	91	171	164	107	84	81	45	5	35	112	120	15	151	85	76	79	178	121	126	89	
136	165	36	187	3	114	173	190	130	128	66	74	152	123	154	116	28	49	153	16	169	
137	156	185	53	155	102	118	62	166	175	200	151	112	113	14	124	80	146	35	125	34	85	67	126	145	172	
138	134	186	153	114	111	142	110	179	21	128	130	117	197	169	77	13	74	51	180	50	106	54	
139	80	58	27	164	132	121	108	115	140	31	79	98	15	160	52	26	171	39	195	120	67	14	35	196	34	
140	185	58	56	8	175	131	144	18	4	166	98	139	1	195	22	156	71	76	178	115	97	133	
141	109	104	184	2	143	188	51	49	33	197	48	176	95	159	148	101	154	13	170	190	36	43	3	92	72	16	28	167	180	147	74	54	178	
142	161	109	169	12	183	111	163	187	162	180	16	165	116	184	138	44	13	49	134	143	177	103	128	181	105	192	
143	165	161	109	141	24	184	168	92	142	154	180	51	147	179	176	183	189	59	159	167	77	117	105	152	
144	91	80	58	178	27	53	164	108	8	158	60	79	67	155	78	140	7	86	26	174	84	98	64	19	46	145	6	93	
145	178	79	155	118	18	151	69	39	113	42	119	93	80	144	87	15	137	23	158	166	5	57	172	
146	149	58	37	122	62	60	68	107	31	67	172	195	121	131	102	185	174	124	126	80	22	137	46	5	
147	123	186	36	47	183	29	182	197	16	167	110	143	168	83	82	141	63	94	54	59	157	170	61	
148	10	188	186	141	163	12	43	88	82	109	192	70	161	30	129	24	92	49	177	29	104	197	154	101	103	162	181	106	44	176	
149	156	80	200	146	15	185	87	91	100	45	37	178	18	32	64	132	97	84	150	113	86	118	76	73	81	78	22	31	96	23	161	
150	149	58	8	175	120	39	99	119	166	98	200	85	14	4	46	96	84	22	93	52	
151	125	52	160	71	166	98	137	145	122	171	119	193	175	32	121	107	115	18	39	89	135	196	
152	134	161	36	116	41	17	82	111	28	128	157	13	92	47	143	117	109	90	95	136	170	
153	165	48	123	134	10	186	138	187	103	82	70	163	129	188	170	173	24	83	167	41	43	3	114	154	180	74	136	63	30	
154	134	10	109	141	36	41	88	159	82	104	143	148	197	44	13	94	130	162	177	153	167	77	2	83	136	170	
155	91	185	53	164	108	145	171	200	6	122	8	9	85	57	1	137	126	102	118	46	68	158	39	144	160	71	172	
156	7	53	113	45	14	193	122	40	67	19	121	22	118	78	5	137	166	149	32	85	178	27	158	76	126	140	69	133	9	23	123	
157	184	116	13	3	65	111	90	105	187	147	152	134	59	95	186	197	44	170	129	21	
158	91	193	79	27	102	68	32	75	156	107	185	144	4	57	39	155	98	171	85	25	175	60	145	38	96	
159	188	141	36	24	13	12	88	103	105	179	177	17	3	182	51	82	28	161	154	106	65	183	72	143	77	66	74	
160	91	185	53	32	120	155	6	9	18	127	171	118	113	119	151	26	46	195	200	73	98	75	139	40	1	5	198	38	
161	165	10	24	173	142	182	162	92	13	152	33	82	189	43	143	128	103	186	105	12	188	184	41	17	159	148	104	180	77	194	170	149	
162	134	161	188	186	36	24	173	182	111	142	72	154	101	48	148	2	179	106	63	41	117	
163	177	92	10	148	101	44	169	59	110	188	17	51	90	186	94	11	24	70	106	182	41	153	187	104	142	190	61	79	
164	185	37	122	175	139	144	91	35	19	96	98	78	155	1	108	198	42	135	79	195	8	52	87	131	107	166	132	100	34	116	
165	30	105	36	101	167	183	43	50	70	189	181	190	161	123	136	51	143	129	153	110	134	169	13	47	88	65	142	72	95	106	74	91	
166	156	58	27	102	118	62	52	191	140	164	40	122	151	108	75	174	137	196	150	34	200	45	26	145	6	
167	165	134	109	24	17	153	187	88	168	65	182	177	154	16	194	141	103	50	147	63	110	101	179	143	21	95	83	
168	36	169	116	88	48	70	30	33	101	104	109	110	143	181	167	54	199	49	59	95	177	180	103	50	147	63	
169	163	50	184	12	176	106	41	194	173	168	110	142	44	95	130	24	165	182	72	177	197	28	101	138	105	136	51	27	
170	10	186	141	17	13	153	111	117	157	92	161	152	147	104	179	154	43	101	36	199	
171	34	60	68	31	20	42	62	4	120	71	32	135	113	175	84	102	132	96	98	75	155	56	8	158	76	160	78	151	139	55	184	
172	185	108	125	113	146	73	98	174	100	155	81	79	76	127	87	137	107	19	62	145	
173	134	10	161	169	13	153	109	162	44	21	88	182	3	190	179	136	90	16	116	94	92	28	77	129	130	105	106	
174	27	118	175	76	144	15	146	99	119	166	45	32	19	172	191	60	108	37	69	112	127	
175	86	122	79	171	164	68	62	84	140	5	40	196	46	174	150	67	58	76	193	158	107	78	22	137	75	151	85	195	64	1	133	
176	141	169	13	47	88	3	65	183	177	143	148	82	105	130	66	181	44	21	182	95	70	
177	10	36	163	169	159	29	148	190	12	199	167	176	180	2	192	168	142	41	179	129	154	28	21	95	66	94	
178	149	76	19	52	127	108	45	156	60	198	99	37	144	7	97	145	84	119	42	191	53	125	8	87	131	18	25	132	195	140	135	93	141	
179	10	109	36	159	173	177	49	117	12	48	101	189	2	138	128	95	106	28	167	16	143	162	90	105	74	170	199	30	61	
180	48	109	17	88	142	177	16	65	194	36	153	116	161	66	143	141	129	47	168	21	101	181	138	
181	165	188	184	116	13	168	114	182	130	128	44	103	148	63	29	142	180	17	109	72	105	176	70	
182	134	10	161	163	169	184	13	159	173	183	147	189	162	181	12	72	167	94	199	192	2	95	44	83	176	
183	165	48	134	188	186	63	33	147	43	61	109	142	159	66	41	128	182	176	190	184	143	189	
184	48	10	141	169	24	143	41	161	181	36	129	197	104	186	182	28	106	157	103	199	82	183	111	142	110	117	63	51	59	171	
185	193	140	8	97	7	121	160	155	85	172	91	100	164	132	25	120	20	62	137	115	149	86	32	158	107	146	119	64	55	93	10	
186	161	104	199	162	148	110	138	183	153	103	192	82	130	123	59	49	147	134	65	170	163	184	187	92	197	111	72	157	61	37	
187	24	153	186	92	189	54	33	59	21	167	163	101	136	50	197	16	104	128	192	30	47	111	142	66	157	61	49	
188	48	123	50	104	36	101	148	66	161	44	28	21	162	116	183	103	159	181	61	29	141	163	153	111	110	190	95	105	59	58	
189	165	123	10	161	116	41	187	43	29	182	197	16	110	179	143	12	183	103	199	109	130	128	194	117	94	61	
190	165	48	10	141	13	43	3	173	183	104	177	72	36	77	188	90	136	51	163	70	130	105	61	
191	193	37	178	8	32	120	15	42	107	18	124	166	132	174	20	52	57	31	115	127	1	69	9	23	
192	186	187	12	114	82	92	29	148	104	182	177	72	28	101	21	117	94	51	111	142	
193	26	112	191	62	195	25	91	39	71	158	131	46	5	38	37	185	18	118	124	56	156	58	86	53	108	68	175	87	120	15	42	73	99	4	75	151	64	35	48	
194	123	169	43	88	65	29	104	16	167	180	90	189	161	199	47	92	3	12	17	117	
195	193	80	58	122	164	108	68	160	146	78	139	23	120	178	133	73	175	37	131	9	19	89	140	57	
196	122	53	102	118	62	175	15	166	31	9	37	6	99	151	56	139	46	1	96	60	
197	48	123	134	141	184	187	82	65	92	106	148	147	199	29	17	30	189	186	74	169	154	21	103	138	157	59	
198	91	37	178	79	164	108	125	62	113	18	84	45	26	112	35	107	160	53	1	75	
199	123	186	109	184	43	168	29	182	197	177	189	129	194	95	83	170	54	105	90	179	30	59	
200	149	155	52	87	120	39	160	137	27	79	131	100	25	55	23	126	84	166	150	62	67	1	69	35	


================================================
FILE: Algorithms/graphtheory/depth-first-search/DFS_recursive.py
================================================
# Purpose of Depth first search is (mainly from my understanding) to find if a graph G is connected.
# Identify all nodes that are reachable from a given starting node.

# Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
#   2019-02-16 Initial programming


def DFS(G, curr_node, visited):
    """
    :param G: G = {from_node1:[to_node1, to_node2], from_node2: [to_node,] etc}
    :param curr_node: Node currently at, run from beginning this is the starting node
    :param visited: since it is recursive, visited is updated and needs to be sent in on recursive call
    :return: visited is initialized outside of DFS and updates this boolean array with which nodes has been visited
    """
    if visited[curr_node - 1]:
        return

    visited[curr_node - 1] = True

    neighbours = G[curr_node]

    for next_node in neighbours:
        DFS(G, next_node, visited)


# Small Eaxmple
# if __name__ == '__main__':
#      G = {1: [2], 2: [1, 3, 4], 3: [2], 4: [2, 5], 5: [4]}
#
#     visited = [False for i in range(1, len(G) + 1)]
#     start_node = 1
#
#     DFS(G, start_node, visited)
#
#     if any(visited) == False:
#         print("Result: This graph is connected!")


================================================
FILE: Algorithms/graphtheory/depth-first-search/DFS_stack_iterative.py
================================================
"""
Depth first search has many applications,for example finding if a graph G is connected.
Identify all nodes that are reachable from a given starting node.

Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
    2019-02-17 Initial programming
    2020-03-29 Cleaned up code, made test cases
"""


def DFS(G, start_node):
    """
    :param G: Graph with G = {from_node1:[to_node1, to_node2], from_node2: [to_node,] etc}
    :param start_node: starting node to run BFS from
    :return: returns visited boolean array and path in which order it visited them
    """
    visited = [False for i in range(1, len(G) + 1)]
    path = [start_node]
    stack = []
    stack.append(start_node)

    while stack:
        v = stack.pop()
        if not visited[v - 1]:
            visited[v - 1] = True

            for connected_node in G[v]:
                if not visited[connected_node - 1]:
                    stack.append(connected_node)
                    path.append(connected_node)

    return visited, path


# if __name__ == '__main__':
#     G = {1: [2, 3], 2: [1, 4], 3: [1, 4], 4: []}
#     start_node = 1
#     visited = DFS(G, start_node)
#
#     if all(visited) == True:
#         print("Return: This graph is connected!")
#     else:
#         print("Not all nodes were reachable, i.e the graph is not connected.")


================================================
FILE: Algorithms/graphtheory/depth-first-search/exgraph.txt
================================================
1	37	79	164	155	32	87	39	113	15	18	78	175	140	200	4	160	97	191	100	91	20	69	198	196	
2	123	134	10	141	13	12	43	47	3	177	101	179	77	182	117	116	36	103	51	154	162	128	30	
3	48	123	134	109	41	17	159	49	136	16	130	141	29	176	2	190	66	153	157	70	114	65	173	104	194	54	
4	91	171	118	125	158	76	107	18	73	140	42	193	127	100	84	121	60	81	99	80	150	55	1	35	23	93	
5	193	156	102	118	175	39	124	119	19	99	160	75	20	112	37	23	145	135	146	73	35	
6	155	56	52	120	131	160	124	119	14	196	144	25	75	76	166	35	87	26	20	32	23	
7	156	185	178	79	27	52	144	107	78	22	71	26	31	15	56	76	112	39	8	113	93	
8	185	155	171	178	108	64	164	53	140	25	100	133	9	52	191	46	20	150	144	39	62	131	42	119	127	31	7	
9	91	155	8	160	107	132	195	26	20	133	39	76	100	78	122	127	38	156	191	196	115	
10	190	184	154	49	2	182	173	170	161	47	189	101	153	50	30	109	177	148	179	16	163	116	13	90	185	
11	123	134	163	41	12	28	130	13	101	83	77	109	114	21	82	88	74	24	94	48	33	
12	161	109	169	21	24	36	65	50	2	101	159	148	54	192	88	47	11	142	43	70	182	177	179	189	194	33	
13	161	141	157	44	83	90	181	41	2	176	10	29	116	134	182	170	165	173	190	159	47	82	111	142	72	154	110	21	103	130	11	33	138	152	
14	91	156	58	122	62	113	107	73	137	25	19	40	6	139	150	46	37	76	39	127	
15	149	58	68	52	39	67	121	191	1	45	100	18	118	174	40	85	196	122	42	193	119	139	26	127	145	135	57	38	7	
16	48	10	36	187	43	3	114	173	111	142	129	88	189	117	128	147	141	194	180	106	167	179	66	74	136	51	59	
17	48	123	134	36	163	3	44	117	167	161	152	95	170	83	180	77	65	72	109	47	43	88	159	197	28	194	181	49	
18	193	149	56	62	15	160	67	191	140	52	178	96	107	132	1	145	89	198	4	26	73	151	126	34	115	
19	156	80	178	164	108	84	71	174	40	62	113	22	89	45	91	126	195	144	5	14	172	
20	185	122	171	56	8	52	73	191	67	126	9	119	1	89	79	107	96	31	75	55	5	6	34	23	
21	188	187	12	173	180	197	138	167	63	111	95	13	192	116	94	114	105	49	177	51	130	90	11	50	66	157	176	
22	156	27	32	131	7	56	53	81	149	23	100	146	115	26	175	121	96	75	57	39	119	71	132	19	150	140	93	
23	91	122	124	22	200	195	145	5	69	125	55	68	156	20	58	191	4	57	149	6	
24	123	134	161	163	169	72	116	167	30	33	77	162	143	159	187	63	184	130	28	50	153	12	148	11	53	
25	193	185	79	108	8	158	87	73	81	115	39	64	178	132	27	68	127	84	14	52	200	97	6	93	
26	193	58	27	108	52	144	160	18	84	81	22	75	139	166	15	107	198	131	7	9	133	6	
27	156	139	144	166	112	100	26	174	31	42	75	158	122	81	22	7	58	73	89	115	39	25	200	69	169	
28	134	188	24	184	159	29	72	114	152	116	169	173	141	17	111	61	192	90	11	177	179	77	33	66	83	136	
29	48	134	188	13	47	88	3	82	92	28	194	50	192	189	123	199	177	147	43	106	148	197	77	103	129	181	
30	165	123	10	24	41	187	47	168	92	148	197	101	50	2	179	111	130	77	153	199	70	
31	27	171	56	131	146	139	191	89	20	108	38	71	75	69	196	149	97	8	86	98	7	
32	156	149	171	62	22	185	35	124	56	38	158	97	53	121	160	1	191	58	89	127	87	120	39	99	84	60	151	174	6	
33	48	161	109	141	24	187	47	88	168	183	110	103	95	116	28	12	11	13	83	134	63	
34	37	122	171	118	76	131	166	137	40	46	97	87	80	164	127	18	62	52	20	139	
35	79	164	125	32	107	137	75	121	85	55	69	45	193	132	4	5	200	135	76	139	198	6	
36	165	188	17	106	88	16	177	110	147	154	159	179	136	41	50	141	66	162	152	168	184	12	43	72	180	190	77	2	170	61	122	
37	193	149	39	121	191	115	146	52	127	79	198	58	125	38	34	1	76	89	164	97	86	178	108	87	84	124	98	174	195	14	5	57	196	186	
38	193	37	86	32	76	107	73	85	127	100	46	89	31	57	96	158	99	160	45	15	9	
39	193	37	122	102	8	158	32	87	85	81	200	60	5	27	155	1	58	150	15	113	76	84	22	25	151	139	100	14	145	9	7	
40	91	156	122	79	118	125	52	175	87	15	81	166	132	121	19	14	160	34	78	71	
41	36	169	184	116	163	106	189	11	104	61	30	123	129	111	3	47	49	154	161	152	13	153	65	92	183	177	162	95	54	70	108	
42	178	79	27	53	171	164	102	52	87	113	15	191	131	91	62	193	8	122	89	56	4	127	145	112	
43	165	161	12	70	199	54	17	190	16	153	141	36	47	44	194	110	82	189	2	148	183	29	130	94	170	51	61	59	
44	188	163	169	17	13	43	114	173	142	154	103	129	181	105	157	148	182	101	110	66	176	49	
45	156	80	149	58	178	53	108	68	56	125	15	93	75	135	174	198	81	166	113	100	19	89	35	97	38	
46	193	58	86	122	155	8	175	160	99	127	67	14	150	144	126	146	34	131	55	38	196	
47	123	10	109	41	17	12	43	116	59	33	13	2	187	165	88	117	29	30	176	147	180	101	130	194	50	94	152	70	
48	180	128	188	197	105	51	94	190	116	29	183	114	153	33	16	49	3	63	184	17	141	168	179	162	11	66	83	193	
49	48	123	10	186	141	41	168	3	148	142	179	21	136	109	44	117	17	103	187	74	
50	165	123	10	188	36	169	24	187	12	65	29	167	47	21	134	130	111	168	77	116	138	106	66	30	
51	165	48	109	141	163	159	92	190	143	2	21	138	43	59	192	117	16	184	104	169	
52	37	178	8	6	15	200	133	80	102	96	40	119	164	166	127	151	20	42	7	26	76	18	73	99	78	25	132	139	191	150	34	
53	156	122	102	193	137	133	42	62	45	64	60	78	160	132	155	56	144	131	196	178	125	8	32	113	22	98	121	198	24	
54	123	187	12	43	168	65	129	130	147	95	41	61	59	141	3	138	114	199	66	110	
55	68	56	125	113	73	78	200	46	131	85	107	89	185	60	84	4	35	99	171	71	20	23	
56	193	122	53	108	45	55	18	125	86	171	79	6	85	133	80	140	96	31	107	20	32	87	120	42	73	84	22	112	196	7	
57	79	155	158	76	84	22	75	121	85	191	100	97	15	37	102	69	38	64	195	145	23	
58	15	146	107	193	140	84	144	86	14	150	26	60	46	166	80	87	139	195	126	45	37	27	102	62	32	175	39	124	23	93	188	
59	186	163	187	47	168	92	143	147	157	54	51	61	199	43	103	63	184	16	188	197	
60	58	86	178	53	171	125	39	144	146	73	124	4	93	32	99	158	132	80	91	96	75	174	55	196	
61	188	116	41	114	183	28	77	54	36	163	187	147	179	65	63	190	43	186	59	189	
62	193	185	79	53	171	102	146	84	198	14	58	137	8	166	175	32	113	18	115	196	42	200	132	121	19	112	133	172	34	
63	48	24	116	183	111	167	21	162	90	181	147	105	106	101	33	123	153	184	128	168	61	59	
64	91	149	122	53	8	120	113	124	119	25	132	131	193	121	144	68	185	108	175	107	57	
65	186	17	12	114	82	3	66	159	167	197	50	101	176	94	54	134	41	165	157	194	180	77	103	74	61	
66	188	36	116	3	65	183	72	180	77	16	136	177	82	159	28	95	48	50	187	21	44	54	176	
67	91	156	102	68	175	131	144	15	18	146	119	20	200	46	112	139	75	80	86	137	
68	122	171	55	78	175	96	75	71	93	118	195	115	67	79	45	158	15	120	155	193	87	146	81	25	64	23	
69	91	108	125	131	81	75	85	174	145	89	27	200	35	156	1	98	86	23	191	127	31	57	
70	165	123	163	153	12	43	168	3	114	82	148	190	129	74	176	47	110	181	41	30	
71	193	79	171	68	124	98	120	73	75	93	151	108	89	155	19	96	22	119	7	125	85	127	40	55	140	31	
72	109	169	24	116	17	114	182	190	141	186	192	28	104	13	66	165	162	36	159	77	110	129	130	181	
73	91	80	27	160	4	20	100	56	193	60	38	18	25	172	76	14	55	52	149	96	78	71	195	127	5	112	97	93	
74	88	104	197	111	130	95	11	138	123	77	159	65	179	94	165	70	141	16	153	136	83	49	
75	91	79	27	171	68	158	87	81	22	119	71	166	57	60	35	160	69	175	26	193	45	127	67	126	89	20	5	31	198	6	
76	37	178	175	120	122	57	52	34	4	156	98	115	133	131	171	149	85	38	174	39	73	99	14	140	35	135	172	9	7	6	
77	24	116	17	72	190	110	36	173	143	94	65	29	61	154	2	161	90	66	159	28	128	117	11	50	138	74	30	
78	156	80	53	164	68	131	144	107	73	195	55	175	1	126	7	149	171	81	91	52	124	40	9	
79	80	37	158	40	75	108	198	25	62	42	7	86	57	102	122	145	175	71	1	35	164	68	118	56	144	200	139	20	112	135	172	163	
80	91	144	100	118	45	78	139	112	149	98	113	87	195	124	85	73	119	19	79	99	58	56	52	146	81	4	60	137	67	126	145	97	34	134	
81	86	27	120	39	131	40	132	25	69	96	26	127	108	75	68	135	98	80	115	149	78	22	4	45	172	
82	161	186	109	153	43	159	114	101	104	70	29	197	192	116	148	65	152	184	13	154	92	110	130	11	147	66	176	
83	17	13	153	88	111	90	117	95	11	33	147	28	109	199	48	74	167	182	154	101	
84	149	58	86	178	171	62	175	113	26	135	96	198	39	19	57	144	37	118	32	56	119	4	98	25	200	150	55	
85	156	80	185	155	102	56	158	39	76	15	69	38	150	175	118	137	71	35	120	57	55	135	
86	58	84	120	81	112	37	60	46	185	193	38	125	118	175	149	99	108	126	133	102	79	56	144	67	69	31	109	
87	80	149	58	118	25	75	126	115	68	178	37	200	32	40	164	56	42	193	107	1	39	113	145	89	172	6	34	93	
88	36	116	12	47	165	168	29	83	159	154	74	148	92	176	180	33	110	194	167	17	114	173	16	11	
89	37	27	102	32	42	18	99	71	151	19	55	75	98	131	69	45	31	38	195	87	20	135	115	
90	163	116	13	173	28	110	190	77	129	117	130	10	179	92	134	194	21	63	83	157	94	152	199	
91	126	14	75	135	107	80	102	67	160	158	144	23	64	155	4	198	40	9	73	69	193	185	149	164	42	78	60	98	19	1	165	
92	161	109	163	187	88	186	141	51	117	197	59	173	192	82	29	143	116	41	30	111	148	129	90	194	152	170	
93	68	99	71	60	45	150	145	98	25	87	122	178	185	7	144	4	22	73	58	112	
94	48	163	65	173	182	154	77	21	117	11	147	74	189	43	114	47	177	192	104	90	
95	123	141	169	17	168	114	179	21	33	165	167	177	41	103	83	199	129	182	188	74	66	157	152	54	176	
96	171	164	68	56	52	18	73	84	81	124	22	71	60	126	150	20	97	38	149	158	196	115	
97	185	149	37	178	122	108	118	32	131	1	31	140	73	34	45	25	80	133	57	96	
98	80	171	164	158	120	76	99	81	71	37	91	151	144	172	140	150	160	121	84	53	139	89	69	31	133	93	
99	80	86	178	122	118	125	52	193	32	174	46	113	98	93	89	150	102	76	100	124	4	60	55	5	38	196	
100	80	185	149	27	8	113	131	15	73	99	22	4	200	45	102	172	57	164	38	39	1	112	9	
101	165	10	188	109	141	163	187	12	168	82	65	148	180	47	167	2	162	169	192	30	179	11	44	83	170	63	
102	91	86	79	53	171	155	67	113	39	137	158	196	166	120	42	89	58	5	119	85	62	52	146	99	121	100	57	
103	161	188	186	184	153	159	167	189	2	168	13	29	104	142	33	65	197	117	148	44	95	181	59	49	
104	134	188	186	141	184	41	187	168	114	82	148	192	194	154	74	3	190	161	105	163	72	103	94	170	51	
105	165	48	161	116	159	104	21	129	63	44	169	106	142	190	181	143	179	157	173	188	199	176	
106	36	163	169	184	41	159	29	197	111	16	179	162	105	138	148	50	165	63	173	109	
107	91	58	56	125	158	87	191	133	9	38	122	164	175	135	4	35	14	7	185	78	18	146	151	26	64	126	55	20	112	198	172	
108	86	178	79	164	37	25	195	144	120	198	26	56	19	132	69	193	115	45	172	97	155	8	81	71	166	139	174	64	31	41	
109	10	47	116	12	128	51	167	180	179	33	123	101	142	92	143	199	154	3	72	82	141	17	168	114	173	183	148	189	11	181	106	83	152	49	86	
110	165	186	36	163	169	43	88	168	33	138	147	13	167	189	184	134	72	90	188	82	77	44	54	70	
111	41	92	114	162	188	129	187	170	152	83	142	74	157	16	13	138	186	106	63	184	28	21	50	30	192	
112	193	80	86	27	137	174	67	5	79	198	132	127	42	131	100	73	107	56	135	62	7	93	
113	156	80	149	171	102	62	39	133	84	87	198	1	53	64	55	172	122	100	42	14	160	99	124	137	45	19	145	7	
114	48	104	136	16	61	72	181	128	82	88	138	109	129	70	192	3	153	65	95	44	111	28	21	11	94	54	
115	185	37	27	108	68	62	87	120	76	81	22	25	151	139	191	140	9	89	96	18	
116	48	188	109	24	157	61	41	181	128	66	88	63	152	189	168	90	105	72	77	10	13	47	82	173	92	142	28	180	2	21	117	50	33	136	164	
117	17	47	92	16	179	2	103	90	194	189	192	94	143	170	162	83	116	129	184	77	138	152	51	49	
118	193	156	80	86	155	68	196	145	40	4	97	79	5	99	87	149	174	34	137	166	131	15	160	84	121	85	
119	80	178	102	52	160	124	84	185	6	22	67	174	8	121	133	5	75	64	15	150	71	151	145	20	
120	185	86	171	108	102	68	200	193	126	64	160	32	150	6	115	98	81	56	191	76	124	71	139	85	195	135	
121	156	185	37	32	15	146	22	119	4	98	151	57	62	126	53	139	40	102	35	118	64	135	133	
122	156	146	23	99	196	46	14	56	53	175	164	20	68	39	195	126	97	40	34	64	79	27	155	113	76	131	15	42	107	166	151	9	93	36	
123	165	194	50	70	95	11	153	30	24	17	49	47	54	2	189	147	199	3	188	197	186	109	41	29	129	130	128	74	136	63	156	
124	193	80	125	32	146	99	23	5	60	113	120	191	6	58	64	119	71	37	78	96	137	
125	37	86	56	4	133	69	178	132	53	172	45	60	151	40	198	55	35	107	99	124	71	137	127	23	
126	91	58	86	122	155	87	120	146	78	200	121	19	80	20	137	75	96	107	18	156	46	135	
127	37	178	32	52	131	160	81	4	25	191	125	38	71	15	8	42	75	46	174	73	14	69	112	172	9	34	
128	48	134	161	109	116	187	114	183	16	179	189	130	181	142	123	138	2	136	77	152	63	
129	165	184	41	153	114	148	111	177	16	180	44	29	123	54	173	72	92	70	199	105	90	117	95	157	
130	186	169	24	3	154	189	21	136	72	82	74	190	11	47	13	173	54	181	43	123	90	128	50	138	30	176	
131	193	53	76	78	22	69	97	118	178	122	140	81	34	164	8	100	127	67	31	6	42	146	200	195	26	64	46	55	89	112	
132	185	149	53	171	108	125	18	81	60	25	139	191	178	64	52	9	62	22	40	164	35	112	
133	86	53	56	125	8	52	113	76	107	119	195	97	156	98	121	62	140	26	175	9	
134	153	11	17	182	165	197	138	173	24	28	104	128	29	2	167	152	183	3	162	154	186	13	65	142	110	90	50	33	157	80	
135	91	171	164	107	84	81	45	5	35	112	120	15	151	85	76	79	178	121	126	89	
136	165	36	187	3	114	173	190	130	128	66	74	152	123	154	116	28	49	153	16	169	
137	156	185	53	155	102	118	62	166	175	200	151	112	113	14	124	80	146	35	125	34	85	67	126	145	172	
138	134	186	153	114	111	142	110	179	21	128	130	117	197	169	77	13	74	51	180	50	106	54	
139	80	58	27	164	132	121	108	115	140	31	79	98	15	160	52	26	171	39	195	120	67	14	35	196	34	
140	185	58	56	8	175	131	144	18	4	166	98	139	1	195	22	156	71	76	178	115	97	133	
141	109	104	184	2	143	188	51	49	33	197	48	176	95	159	148	101	154	13	170	190	36	43	3	92	72	16	28	167	180	147	74	54	178	
142	161	109	169	12	183	111	163	187	162	180	16	165	116	184	138	44	13	49	134	143	177	103	128	181	105	192	
143	165	161	109	141	24	184	168	92	142	154	180	51	147	179	176	183	189	59	159	167	77	117	105	152	
144	91	80	58	178	27	53	164	108	8	158	60	79	67	155	78	140	7	86	26	174	84	98	64	19	46	145	6	93	
145	178	79	155	118	18	151	69	39	113	42	119	93	80	144	87	15	137	23	158	166	5	57	172	
146	149	58	37	122	62	60	68	107	31	67	172	195	121	131	102	185	174	124	126	80	22	137	46	5	
147	123	186	36	47	183	29	182	197	16	167	110	143	168	83	82	141	63	94	54	59	157	170	61	
148	10	188	186	141	163	12	43	88	82	109	192	70	161	30	129	24	92	49	177	29	104	197	154	101	103	162	181	106	44	176	
149	156	80	200	146	15	185	87	91	100	45	37	178	18	32	64	132	97	84	150	113	86	118	76	73	81	78	22	31	96	23	161	
150	149	58	8	175	120	39	99	119	166	98	200	85	14	4	46	96	84	22	93	52	
151	125	52	160	71	166	98	137	145	122	171	119	193	175	32	121	107	115	18	39	89	135	196	
152	134	161	36	116	41	17	82	111	28	128	157	13	92	47	143	117	109	90	95	136	170	
153	165	48	123	134	10	186	138	187	103	82	70	163	129	188	170	173	24	83	167	41	43	3	114	154	180	74	136	63	30	
154	134	10	109	141	36	41	88	159	82	104	143	148	197	44	13	94	130	162	177	153	167	77	2	83	136	170	
155	91	185	53	164	108	145	171	200	6	122	8	9	85	57	1	137	126	102	118	46	68	158	39	144	160	71	172	
156	7	53	113	45	14	193	122	40	67	19	121	22	118	78	5	137	166	149	32	85	178	27	158	76	126	140	69	133	9	23	123	
157	184	116	13	3	65	111	90	105	187	147	152	134	59	95	186	197	44	170	129	21	
158	91	193	79	27	102	68	32	75	156	107	185	144	4	57	39	155	98	171	85	25	175	60	145	38	96	
159	188	141	36	24	13	12	88	103	105	179	177	17	3	182	51	82	28	161	154	106	65	183	72	143	77	66	74	
160	91	185	53	32	120	155	6	9	18	127	171	118	113	119	151	26	46	195	200	73	98	75	139	40	1	5	198	38	
161	165	10	24	173	142	182	162	92	13	152	33	82	189	43	143	128	103	186	105	12	188	184	41	17	159	148	104	180	77	194	170	149	
162	134	161	188	186	36	24	173	182	111	142	72	154	101	48	148	2	179	106	63	41	117	
163	177	92	10	148	101	44	169	59	110	188	17	51	90	186	94	11	24	70	106	182	41	153	187	104	142	190	61	79	
164	185	37	122	175	139	144	91	35	19	96	98	78	155	1	108	198	42	135	79	195	8	52	87	131	107	166	132	100	34	116	
165	30	105	36	101	167	183	43	50	70	189	181	190	161	123	136	51	143	129	153	110	134	169	13	47	88	65	142	72	95	106	74	91	
166	156	58	27	102	118	62	52	191	140	164	40	122	151	108	75	174	137	196	150	34	200	45	26	145	6	
167	165	134	109	24	17	153	187	88	168	65	182	177	154	16	194	141	103	50	147	63	110	101	179	143	21	95	83	
168	36	169	116	88	48	70	30	33	101	104	109	110	143	181	167	54	199	49	59	95	177	180	103	50	147	63	
169	163	50	184	12	176	106	41	194	173	168	110	142	44	95	130	24	165	182	72	177	197	28	101	138	105	136	51	27	
170	10	186	141	17	13	153	111	117	157	92	161	152	147	104	179	154	43	101	36	199	
171	34	60	68	31	20	42	62	4	120	71	32	135	113	175	84	102	132	96	98	75	155	56	8	158	76	160	78	151	139	55	184	
172	185	108	125	113	146	73	98	174	100	155	81	79	76	127	87	137	107	19	62	145	
173	134	10	161	169	13	153	109	162	44	21	88	182	3	190	179	136	90	16	116	94	92	28	77	129	130	105	106	
174	27	118	175	76	144	15	146	99	119	166	45	32	19	172	191	60	108	37	69	112	127	
175	86	122	79	171	164	68	62	84	140	5	40	196	46	174	150	67	58	76	193	158	107	78	22	137	75	151	85	195	64	1	133	
176	141	169	13	47	88	3	65	183	177	143	148	82	105	130	66	181	44	21	182	95	70	
177	10	36	163	169	159	29	148	190	12	199	167	176	180	2	192	168	142	41	179	129	154	28	21	95	66	94	
178	149	76	19	52	127	108	45	156	60	198	99	37	144	7	97	145	84	119	42	191	53	125	8	87	131	18	25	132	195	140	135	93	141	
179	10	109	36	159	173	177	49	117	12	48	101	189	2	138	128	95	106	28	167	16	143	162	90	105	74	170	199	30	61	
180	48	109	17	88	142	177	16	65	194	36	153	116	161	66	143	141	129	47	168	21	101	181	138	
181	165	188	184	116	13	168	114	182	130	128	44	103	148	63	29	142	180	17	109	72	105	176	70	
182	134	10	161	163	169	184	13	159	173	183	147	189	162	181	12	72	167	94	199	192	2	95	44	83	176	
183	165	48	134	188	186	63	33	147	43	61	109	142	159	66	41	128	182	176	190	184	143	189	
184	48	10	141	169	24	143	41	161	181	36	129	197	104	186	182	28	106	157	103	199	82	183	111	142	110	117	63	51	59	171	
185	193	140	8	97	7	121	160	155	85	172	91	100	164	132	25	120	20	62	137	115	149	86	32	158	107	146	119	64	55	93	10	
186	161	104	199	162	148	110	138	183	153	103	192	82	130	123	59	49	147	134	65	170	163	184	187	92	197	111	72	157	61	37	
187	24	153	186	92	189	54	33	59	21	167	163	101	136	50	197	16	104	128	192	30	47	111	142	66	157	61	49	
188	48	123	50	104	36	101	148	66	161	44	28	21	162	116	183	103	159	181	61	29	141	163	153	111	110	190	95	105	59	58	
189	165	123	10	161	116	41	187	43	29	182	197	16	110	179	143	12	183	103	199	109	130	128	194	117	94	61	
190	165	48	10	141	13	43	3	173	183	104	177	72	36	77	188	90	136	51	163	70	130	105	61	
191	193	37	178	8	32	120	15	42	107	18	124	166	132	174	20	52	57	31	115	127	1	69	9	23	
192	186	187	12	114	82	92	29	148	104	182	177	72	28	101	21	117	94	51	111	142	
193	26	112	191	62	195	25	91	39	71	158	131	46	5	38	37	185	18	118	124	56	156	58	86	53	108	68	175	87	120	15	42	73	99	4	75	151	64	35	48	
194	123	169	43	88	65	29	104	16	167	180	90	189	161	199	47	92	3	12	17	117	
195	193	80	58	122	164	108	68	160	146	78	139	23	120	178	133	73	175	37	131	9	19	89	140	57	
196	122	53	102	118	62	175	15	166	31	9	37	6	99	151	56	139	46	1	96	60	
197	48	123	134	141	184	187	82	65	92	106	148	147	199	29	17	30	189	186	74	169	154	21	103	138	157	59	
198	91	37	178	79	164	108	125	62	113	18	84	45	26	112	35	107	160	53	1	75	
199	123	186	109	184	43	168	29	182	197	177	189	129	194	95	83	170	54	105	90	179	30	59	
200	149	155	52	87	120	39	160	137	27	79	131	100	25	55	23	126	84	166	150	62	67	1	69	35	


================================================
FILE: Algorithms/graphtheory/dijkstra/dijkstra.py
================================================
"""
Dijkstra's algorithm for finding the shortest path in a graph, this implementation
is a naive implementation, check my Heap implementation for a more efficient algorithm

Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
    2019-01-28 Initial programming
    2020-03-28 Cleaned up code
"""


def dijkstra(G, start, end):
    """
    :param G: {from_node1: {to_node1:cost1, to_node2:cost2}, from_node2 : {.., etc.}, ...}
    :param start: starting node
    :param end: ending node where we want to find path to
    :return: path from starting node to end node and the cost to get between them
    """

    if start not in G or end not in G:
        return [], float("inf")

    shortest_distance = {}
    predecessor = {}
    unseenNodes = G
    infinity = float("inf")
    path = []

    for node in unseenNodes:
        shortest_distance[node] = infinity

    shortest_distance[start] = 0

    while unseenNodes:
        minNode = None

        for node in unseenNodes:
            if minNode is None:
                minNode = node
            elif shortest_distance[node] < shortest_distance[minNode]:
                minNode = node

        for childNode, weight in G[minNode].items():
            if weight + shortest_distance[minNode] < shortest_distance[childNode]:
                shortest_distance[childNode] = weight + shortest_distance[minNode]
                predecessor[childNode] = minNode

        unseenNodes.pop(minNode)

    # Find path from start node s to end node t
    currentNode = end

    while currentNode != start:
        try:
            path.insert(0, currentNode)
            currentNode = predecessor[currentNode]
        except KeyError:
            return [], float("inf")

    path.insert(0, start)

    return path, shortest_distance[end]


if __name__ == "__main__":
    G = {1: {2: 10, 3: 20}, 2: {4: 40}, 3: {4: 5}, 4: {}}

    print(f"Current graph is: {G}")
    path, shortest = dijkstra(G, 1, 4)

    print(path)
    print(shortest)


================================================
FILE: Algorithms/graphtheory/dijkstra/dijkstraData.txt
================================================
1	80,982	163,8164	170,2620	145,648	200,8021	173,2069	92,647	26,4122	140,546	11,1913	160,6461	27,7905	40,9047	150,2183	61,9146	159,7420	198,1724	114,508	104,6647	30,4612	99,2367	138,7896	169,8700	49,2437	125,2909	117,2597	55,6399	
2	42,1689	127,9365	5,8026	170,9342	131,7005	172,1438	34,315	30,2455	26,2328	6,8847	11,1873	17,5409	157,8643	159,1397	142,7731	182,7908	93,8177	
3	57,1239	101,3381	43,7313	41,7212	91,2483	31,3031	167,3877	106,6521	76,7729	122,9640	144,285	44,2165	6,9006	177,7097	119,7711	
4	162,3924	70,5285	195,2490	72,6508	126,2625	121,7639	31,399	118,3626	90,9446	127,6808	135,7582	159,6133	106,4769	52,9267	190,7536	78,8058	75,7044	116,6771	49,619	107,4383	89,6363	54,313	
5	200,4009	112,1522	25,3496	23,9432	64,7836	56,8262	120,1862	2,8026	90,8919	142,1195	81,2469	182,8806	17,2514	83,8407	146,5308	147,1087	51,22	
6	141,8200	98,5594	66,6627	159,9500	143,3110	129,8525	118,8547	88,2039	83,4949	165,6473	162,6897	184,8021	123,13	176,3512	195,2233	42,7265	47,274	132,1514	2,8847	171,3722	3,9006	
7	156,7027	187,9522	87,4976	121,8739	56,6616	10,2904	71,8206	53,179	146,4823	165,6019	125,5670	27,4888	63,9920	150,9031	84,4061	
8	152,1257	189,2780	58,4708	26,8342	199,1918	31,3987	35,3160	71,5829	27,3483	69,8815	130,55	168,2076	122,5338	73,4528	28,9996	17,3535	40,3193	72,7308	24,8434	87,2833	25,3949	175,1022	177,8508	
9	152,1087	115,7827	17,7002	72,794	150,4539	190,3613	95,9480	36,5284	166,8702	63,1753	199,70	131,700	76,9340	70,2	139,8701	140,4163	180,5995	
10	57,9988	78,3771	62,4816	137,5273	7,2904	187,4786	184,3207	96,807	31,1184	88,2539	135,4650	168,9495	164,3866	11,8988	116,1493	51,5578	171,2029	
11	1,1913	185,2045	77,815	22,8425	181,8448	47,8727	81,7299	150,4802	178,1696	28,2275	183,594	131,833	157,8497	25,5057	59,3203	10,8988	2,1873	134,294	83,4211	124,6180	
12	78,5753	17,4602	62,5676	16,8068	60,5933	67,371	71,6734	53,7001	72,3626	34,6690	59,761	18,1520	128,7542	38,6699	57,9416	
13	144,9987	59,9801	97,7026	50,758	43,5400	163,3870	178,4194	151,9629	45,1794	105,6821	29,2784	172,2070	57,6850	77,8638	135,861	
14	149,4352	187,4874	26,3841	128,9662	155,4446	118,373	123,2733	106,7912	169,4333	53,9197	161,4275	126,9602	73,4106	160,7860	131,358	141,4477	119,960	43,3199	47,7898	175,6718	177,6741	60,2464	127,5682	31,1945	143,5848	94,3551	82,3283	
15	42,1789	22,3571	25,7019	163,818	56,2334	100,809	143,1041	107,4589	190,6854	169,7485	94,9606	34,7961	54,8983	157,2136	24,8040	
16	200,2848	198,2223	92,2896	18,8663	27,8673	75,4116	150,1680	36,1555	41,2747	90,4558	68,5894	12,8068	42,2596	185,6280	171,3482	109,1469	127,9807	178,1714	35,839	56,9828	134,5203	55,6680	110,4252	
17	26,1275	45,5114	142,8016	83,4615	140,6440	8,3535	69,3610	153,8545	9,7002	12,4602	173,7312	114,8915	108,1942	54,3115	66,6176	190,7000	70,3899	5,2514	178,7464	166,4762	2,5409	146,5362	117,6266	
18	57,4216	80,5252	86,7517	62,1926	120,44	173,7256	133,2702	148,589	167,7625	16,8663	170,4989	118,6388	142,332	95,6122	99,5717	154,453	150,5150	149,2664	146,9000	171,4403	111,785	12,1520	
19	33,6938	77,7013	187,107	109,8397	88,2002	95,8691	132,3157	195,5038	154,4320	23,8560	152,9751	185,5896	119,7406	160,3997	80,62	
20	66,2667	173,2676	43,8105	135,6434	33,6387	74,6183	106,8785	75,2484	130,9048	56,7194	50,9507	88,3014	124,392	61,2580	90,7372	92,1704	87,2639	154,2398	41,4203	85,1435	169,5990	166,6086	28,2234	145,8099	
21	23,5183	40,2199	31,2556	71,4986	165,2151	193,494	154,1845	111,3060	85,2880	101,2775	182,2447	80,9884	87,2681	102,6643	131,3748	
22	92,5592	64,4257	11,8425	24,594	15,3571	42,3783	41,1374	114,9960	144,9362	146,3620	71,3243	143,8603	131,6075	192,4606	108,9656	168,4356	177,8713	132,1560	
23	143,7543	161,6863	45,8074	165,208	21,5183	118,5079	40,8336	27,9054	112,3201	135,4560	167,2133	188,4236	166,8077	195,3179	48,4485	137,7591	99,6485	5,9432	71,3316	96,2431	125,922	19,8560	
24	141,6862	197,9337	66,5879	59,6941	70,4670	55,4106	103,8083	61,7906	48,7959	151,784	177,393	102,8731	199,2838	73,3509	8,8434	187,9327	22,594	150,5669	164,7312	157,9540	15,8040	
25	115,9233	197,3875	185,3573	72,2332	104,4899	137,5378	8,3949	5,3496	77,2729	136,9251	143,108	83,9569	15,7019	48,3214	155,3242	153,2477	129,3005	132,219	11,5057	37,1591	68,4188	
26	14,3841	8,8342	1,4122	147,5759	113,5553	157,7	65,9434	116,4221	66,2747	138,7027	145,6697	130,5706	60,701	127,9896	136,7200	17,1275	120,5788	175,6165	70,9252	95,36	106,6940	2,2328	96,425	51,9329	183,4842	196,6754	
27	23,9054	78,3066	8,3483	1,7905	152,2124	108,9929	63,3896	151,5915	111,3101	34,8912	182,6234	133,7749	16,8673	192,5344	114,714	168,1578	175,210	138,5918	7,4888	122,84	
28	8,9996	188,3816	116,2638	132,5604	20,2234	178,3642	76,3705	122,9165	184,4164	198,366	161,9217	160,9059	56,5375	120,8874	11,2275	111,4495	193,9441	157,6880	48,2803	
29	78,8190	144,6452	114,9478	156,5083	62,9692	121,4537	184,9797	109,6873	153,5446	67,3449	172,5830	111,1005	100,1642	148,3252	13,2784	
30	78,5469	119,7372	144,1616	130,1356	59,4458	40,9818	79,503	43,6233	148,4760	42,263	1,4612	57,5668	185,3846	101,6979	94,6976	106,7819	2,2455	71,9294	
31	4,399	8,3987	50,2598	75,7688	47,7840	99,8583	190,5055	112,5231	114,7617	118,6949	180,3598	21,2556	199,5564	14,1945	3,3031	35,9855	10,1184	146,2837	51,3739	83,6588	46,5964	
32	136,3823	77,1689	92,3395	121,1615	85,7494	173,9631	177,6902	88,8129	36,7329	116,6065	61,3332	68,7352	119,1914	82,8571	70,9909	
33	144,4841	173,5949	170,3648	113,652	110,1986	82,3577	61,1837	97,5671	55,1252	19,6938	48,914	74,3642	125,67	89,3089	176,3258	20,6387	138,6960	153,6574	171,3913	
34	86,6435	156,8641	72,2540	181,5267	27,8912	58,8824	179,8528	62,9864	70,2348	57,5471	53,236	168,3923	101,3383	142,7791	55,7174	2,315	147,9758	15,7961	199,8196	12,6690	
35	57,3693	8,3160	144,3087	114,490	65,8910	178,5774	172,992	16,839	118,8640	41,6749	31,9855	39,853	64,6071	166,2816	184,7437	49,3098	182,7369	110,4985	93,8775	
36	80,2032	130,7589	123,6226	16,1555	150,116	88,7759	100,8612	9,5284	198,6280	49,953	143,5111	42,4917	134,979	159,6043	32,7329	67,2380	148,9550	48,7266	
37	197,9188	119,9313	187,4105	191,3573	109,2135	75,751	200,7541	139,8208	155,609	142,6433	25,1591	132,821	156,7714	107,1144	99,7757	
38	91,7087	88,502	132,6092	126,5441	147,8391	12,6699	130,5227	146,4400	108,8712	100,1369	134,4730	87,2975	99,6169	183,5213	109,4945	
39	200,4319	98,3993	130,2414	40,2489	196,9267	133,8145	82,3528	44,9175	42,5464	127,6103	93,6132	180,9506	192,7454	119,1376	115,983	81,7400	35,853	
40	23,8336	1,9047	120,7760	101,2885	21,2199	144,7772	96,5739	136,4658	184,4306	189,4263	30,9818	39,2489	108,8883	8,3193	80,9657	181,2338	162,3056	71,2826	68,5800	
41	200,2622	78,63	66,4654	198,7215	59,284	75,7333	22,1374	181,5235	16,2747	154,901	150,7278	3,7212	103,7917	163,5256	20,4203	91,7776	35,6749	147,1858	165,3741	107,8116	
42	160,2382	156,6539	6,7265	15,1789	61,8096	164,347	194,6498	172,5383	104,2726	124,3496	161,4792	159,5951	117,7074	2,1689	186,9391	62,3249	79,9404	39,5464	187,3075	22,3783	30,263	16,2596	137,4572	163,1278	60,6663	70,9396	36,4917	73,9154	
43	200,8943	159,9621	97,3906	20,8105	164,6849	13,5400	3,7313	133,8488	108,8964	30,6233	79,5052	131,8231	167,8120	14,3199	130,2685	138,7965	177,9544	143,1171	65,5805	118,8008	140,4482	93,8479	
44	197,4900	144,2276	198,2619	39,9175	87,7875	191,8130	166,6953	170,6940	163,18	79,9988	145,2888	173,5518	57,9979	82,3134	54,4113	3,2165	
45	57,4630	23,8074	112,9496	130,4994	86,8207	17,5114	120,5279	169,662	162,3436	170,8060	118,5918	124,3290	110,8317	13,1794	167,1163	
46	57,2413	152,9550	86,7512	123,132	138,2860	195,8206	176,9923	119,2687	54,9328	196,9632	73,5109	31,5964	173,2969	193,199	80,7968	194,2429	
47	57,9584	114,9480	145,9483	190,5892	182,8382	31,7840	129,9533	142,5297	58,1229	146,2959	6,274	14,7898	189,5939	11,8727	76,2138	70,2236	
48	152,5835	23,4485	33,914	24,7959	25,3214	135,8869	53,3578	162,201	28,2803	141,7941	36,7266	85,2792	86,3588	124,2593	130,7921	
49	160,8648	154,2962	109,7520	36,953	178,9747	192,3113	112,2935	35,3098	71,3441	4,619	96,9901	171,9736	163,4688	1,2437	133,5167	117,2896	105,9278	
50	152,5767	112,6454	185,3968	77,5220	20,9507	165,2667	98,990	187,2485	198,3798	13,758	128,2987	189,7031	52,9931	127,3622	31,2598	179,2502	191,5026	153,4905	
51	80,7589	72,4882	137,1096	138,8755	109,662	67,4225	181,158	132,6107	189,8899	159,3017	5,22	10,5578	31,3739	120,5675	26,9329	176,1625	
52	4,9267	115,4973	159,7816	185,8925	188,7805	97,9063	50,9931	137,9846	91,424	150,634	56,2416	107,3647	68,7601	168,1134	179,3504	
53	14,9197	114,7352	156,4662	62,153	85,1227	177,9852	34,236	7,179	12,7001	48,3578	71,9285	86,7353	150,662	183,5304	125,8054	54,8361	
54	197,2223	66,2906	136,1794	188,4883	17,3115	109,7832	44,4113	182,438	15,8983	200,4899	112,2279	169,2296	4,313	53,8361	138,6261	46,9328	
55	33,1252	188,5181	101,6050	24,4106	169,7795	149,3088	34,7174	193,8583	1,6399	145,3342	105,8477	166,3686	121,44	16,6680	82,3547	
56	101,3516	20,7194	179,5284	127,3031	5,8262	161,9811	16,9828	15,2334	52,2416	7,6616	77,7923	182,7267	88,3375	61,1315	117,1934	28,5375	124,552	100,361	
57	18,4216	94,558	186,8815	3,1239	85,6678	45,4630	46,2413	35,3693	84,6563	185,9772	67,8012	47,9584	155,893	64,810	10,9988	80,8722	160,2058	59,2689	79,2330	30,5668	184,7592	44,9979	162,6483	116,656	34,5471	106,4868	131,6342	183,9093	13,6850	12,9416	
58	152,5877	98,3677	8,4708	130,7020	59,5735	121,8818	47,1229	102,6906	150,4857	90,7141	86,5989	175,3675	79,2365	34,8824	186,8993	125,1050	74,7934	147,2267	193,6166	
59	86,1293	147,2651	149,2405	141,9126	112,4585	58,5735	74,4470	24,6941	199,8958	57,2689	13,9801	162,391	30,4458	180,2435	41,284	72,7154	101,1804	87,4628	168,4170	99,671	70,8055	11,3203	12,761	
60	200,3269	98,2073	26,701	185,6670	120,2231	14,2464	127,1402	12,5933	42,6663	189,4415	107,52	146,2317	112,2570	154,6667	177,5345	172,2781	
61	1,9146	159,49	33,1837	42,8096	20,2580	24,7906	87,9053	163,448	190,9775	155,5301	173,4803	115,3324	196,5577	171,6888	32,3332	56,1315	131,6924	195,8928	
62	97,9163	53,153	120,3851	18,1926	154,3238	12,5676	88,9007	152,7404	29,9692	161,4144	10,4816	105,2736	42,3249	107,5324	115,1913	121,4145	116,7419	34,9864	193,6610	103,8383	
63	141,5607	77,5873	27,3896	169,5160	95,5264	69,2323	125,1315	158,5709	102,5806	9,1753	103,9314	71,3007	131,5257	92,9006	96,5638	7,9920	
64	57,810	98,3909	97,2201	22,4257	120,2385	177,7660	83,2716	81,9744	111,2663	145,2685	130,2493	148,6419	106,256	141,158	86,414	87,9403	121,771	102,4635	5,7836	67,2090	35,6071	131,4631	182,4701	110,6711	
65	152,3595	66,6930	26,9434	97,6170	123,9599	175,7920	155,5533	102,1652	77,4069	198,3575	81,3054	199,11	95,6605	35,8910	43,5805	71,439	134,9956	74,6617	165,3705	140,5376	
66	80,2902	68,8312	142,777	156,2965	41,4654	6,6627	84,7710	102,3328	65,6930	54,2906	24,5879	112,2271	93,5873	94,3424	20,2667	26,2747	130,5826	17,6176	69,824	89,3012	
67	57,8012	102,5417	175,5048	153,6204	12,371	137,1414	133,3802	64,2090	98,980	200,475	171,1394	36,2380	29,3449	124,1880	51,4225	195,5737	100,6216	103,1468	
68	141,3540	197,8223	78,7924	66,8312	144,2277	174,7082	16,5894	163,4920	146,3895	52,7601	140,9624	40,5800	25,4188	32,7352	186,2528	
69	8,8815	198,6284	17,3610	156,9959	75,3354	168,2357	102,1172	190,8022	139,9030	161,6171	96,4815	189,5215	66,824	94,1427	63,2323	
70	4,5285	24,4670	148,7231	26,9252	17,3899	59,8055	47,2236	42,9396	175,3256	149,2366	92,96	153,6532	178,3394	168,1295	156,4830	34,2348	9,2	124,9089	32,9909	183,5332	
71	8,5829	22,3243	138,1229	81,1711	170,1539	49,3441	23,3316	134,7485	12,6734	30,9294	21,4986	142,6038	65,439	7,8206	40,2826	145,6127	53,9285	63,3007	186,7143	171,6702	
72	4,6508	78,5839	119,6215	114,8350	9,794	8,7308	113,8782	102,3377	34,2540	25,2332	59,7154	172,3153	89,4836	178,5128	51,4882	120,2287	174,2019	153,541	96,859	146,4264	171,8573	157,604	12,3626	
73	14,4106	8,4528	159,4969	97,6534	77,2438	24,3509	174,2581	150,8061	139,4428	149,5233	42,9154	90,5133	78,212	194,8521	172,2239	46,5109	
74	159,8960	33,3642	59,4470	20,6183	99,7031	179,1223	93,5576	164,8627	58,7934	65,6617	110,6731	108,8251	165,2602	121,1468	182,1873	176,8129	
75	115,9140	141,9237	80,2187	86,259	20,2484	92,6095	97,1883	41,7333	87,3244	69,3354	120,6892	131,5902	31,7688	108,5943	4,7044	16,4116	191,1403	81,2609	37,751	
76	115,7291	185,3674	181,3275	47,2138	143,1079	28,3705	125,1865	178,8433	3,7729	114,9690	100,1793	200,4623	199,6878	138,5683	141,1969	126,9595	9,9340	83,4424	89,6942	
77	112,3500	160,105	189,5702	191,5135	124,8896	198,5081	19,7013	73,2438	63,5873	129,2337	11,815	133,2481	192,561	32,1689	50,5220	87,7040	25,2729	65,4069	106,9161	153,4483	56,7923	172,4771	13,8638	
78	10,3771	68,7924	12,5753	30,5469	158,6367	122,6207	27,3066	116,2732	41,63	72,5839	161,6310	4,8058	104,1377	83,3955	29,8190	98,6603	154,8423	137,1910	135,6919	73,212	145,7244	
79	141,7918	101,3205	165,3768	96,3059	119,4117	152,6519	57,2330	42,9404	166,8726	161,8395	30,503	89,5169	134,5792	117,9043	129,7314	43,5052	109,9677	58,2365	44,9988	167,820	193,7737	194,5784	
80	36,2032	84,4645	1,982	115,1417	151,6728	112,5208	51,7589	152,9606	113,917	18,5252	121,2257	75,2187	57,8722	133,7217	179,7729	119,108	66,2902	40,9657	97,7213	172,7715	89,7224	19,62	46,7968	21,9884	
81	115,2608	197,5540	97,8866	101,4493	64,9744	11,7299	71,1711	109,2519	136,1409	39,7400	75,2609	142,424	141,4032	183,3061	184,4485	95,7627	5,2469	143,9810	65,3054	89,6124	
82	33,3577	130,3349	156,4691	39,3528	173,591	177,7882	44,3134	116,8491	132,4162	135,519	131,3457	128,6834	32,8571	55,3547	14,3283	
83	78,3955	6,4949	185,9306	17,4615	64,2716	25,9569	149,6823	5,8407	167,8200	117,8516	165,1555	151,162	31,6588	76,4424	11,4211	
84	57,6563	80,4645	119,6417	66,7710	198,5999	136,4270	86,195	104,5330	154,5421	137,4367	95,3812	159,8763	170,2436	107,2954	85,9888	134,9312	7,4061	
85	57,6678	160,3613	156,6669	168,6193	136,6221	180,5525	32,7494	118,1102	192,544	129,517	93,2349	87,7478	189,1147	53,1227	20,1435	167,8110	133,836	84,9888	132,3873	128,4644	110,6060	21,2880	48,2792	
86	115,4291	197,9714	144,8808	59,1293	126,937	189,1115	18,7517	45,8207	46,7512	177,7010	180,4604	75,259	157,4447	84,195	34,6435	120,5230	64,414	184,801	58,5989	142,1663	53,7353	117,4220	48,3588	
87	160,8712	119,518	75,3244	94,9647	59,4628	61,9053	44,7875	168,9716	64,9403	164,3629	20,2639	8,2833	77,7040	7,4976	159,19	85,7478	191,6921	88,8011	167,1022	158,4081	110,1219	21,2681	38,2975	
88	6,2039	62,9007	20,3014	113,7322	136,9026	32,8129	38,502	151,2295	150,6770	183,5547	36,7759	87,8011	94,4629	115,6611	19,2002	161,1726	56,3375	10,2539	125,5012	89,6267	
89	33,3089	72,4836	123,1723	79,5169	174,858	76,6942	4,6363	199,2446	105,2736	66,3012	180,6612	80,7224	163,4055	88,6267	81,6124	
90	152,4427	4,9446	115,1117	119,928	185,7284	20,7372	16,4558	108,9076	179,3149	139,7846	58,7141	5,8919	73,5133	144,6223	174,6914	
91	160,383	181,5060	174,3418	113,4626	95,1806	3,2483	192,6625	52,424	115,1105	137,4129	142,9164	41,7776	158,5553	38,7087	200,1988	
92	1,647	130,4320	108,1844	134,610	194,426	177,3182	75,6095	20,1704	94,6085	128,556	22,5592	16,2896	186,7980	32,3395	139,6763	121,3819	138,8080	70,96	63,9006	
93	66,5873	39,6132	181,4071	154,4073	85,2349	106,7477	74,5576	150,9213	98,6617	147,7807	43,8479	152,6543	35,8775	167,5670	2,8177	
94	57,558	66,3424	92,6085	120,2733	87,9647	30,6976	191,8318	139,7116	109,1299	88,4629	170,9318	69,1427	14,3551	115,3350	171,9959	15,9606	
95	119,8126	112,555	120,1104	18,6122	91,1806	173,4092	196,231	26,36	147,1278	19,8691	125,2917	9,9480	63,5264	81,7627	84,3812	65,6605	105,6026	
96	40,5739	79,3059	104,9639	113,712	162,3737	155,1251	10,807	49,9901	151,5643	23,2431	72,859	26,425	69,4815	143,9274	183,5939	63,5638	147,6736	193,8831	
97	33,5671	185,7065	52,9063	64,2201	188,4695	192,6411	43,3906	73,6534	13,7026	112,7969	81,8866	80,7213	62,9163	65,6170	140,6527	75,1883	137,4667	
98	115,5825	131,4614	64,3909	155,5515	139,1235	39,3993	102,8330	60,2073	200,2690	166,2364	78,6603	162,6139	58,3677	117,9545	6,5594	144,7198	50,990	150,2093	143,4300	67,980	93,6617	
99	104,9140	18,5717	174,5675	157,6818	132,6234	182,2897	151,4990	183,3577	59,671	133,2090	23,6485	153,4560	31,8583	74,7031	1,2367	127,1408	37,7757	193,4566	194,5832	38,6169	
100	159,6567	137,7178	163,9709	190,6674	36,8612	142,2994	76,1793	67,6216	29,1642	56,361	144,6605	128,2584	153,9522	145,5512	15,809	38,1369	
101	188,8531	40,2885	157,1393	171,4083	55,6050	144,3619	3,3381	113,5024	81,4493	163,6033	56,3516	129,8821	184,9591	59,1804	79,3205	30,6979	138,2902	143,4042	34,3383	21,2775	
102	98,8330	66,3328	144,7884	72,3377	24,8731	181,3585	137,6814	172,6572	58,6906	64,4635	117,2689	177,4462	67,5417	183,9634	69,1172	65,1652	178,1334	161,8230	63,5806	140,6370	21,6643	
103	200,6851	123,8756	24,8083	41,7917	191,9683	63,9314	112,7409	110,491	131,2920	196,696	186,9654	62,8383	113,5248	67,1468	114,1318	
104	141,8162	78,1377	42,2726	123,9213	1,6647	126,8615	200,7083	197,4174	84,5330	192,4219	142,6236	99,9140	96,9639	25,4899	172,561	179,8827	169,3712	
105	185,1033	62,2736	113,3388	116,7899	89,2736	164,4661	183,7722	55,8477	190,2518	180,341	95,6026	119,9930	120,9333	13,6821	49,9278	
106	14,7912	4,4769	115,9598	141,674	112,4854	20,8785	64,256	181,5332	190,3305	3,6521	30,7819	93,7477	26,6940	77,9161	57,4868	111,6460	
107	114,2032	123,4581	62,5324	187,2610	60,52	116,9864	84,2954	182,8313	37,1144	169,668	52,3647	4,4383	41,8116	146,7862	112,7448	15,4589	176,6806	
108	200,9976	185,8699	17,1942	40,8883	156,7039	92,1844	75,5943	22,9656	43,8964	27,9929	174,5669	90,9076	145,521	143,972	113,4342	74,8251	126,525	38,8712	
109	152,2743	136,8658	81,2519	169,382	51,662	49,7520	129,2464	79,9677	54,7832	37,2135	94,1299	185,6644	29,6873	19,8397	16,1469	38,4945	
110	197,751	33,1986	145,6099	118,9403	74,6731	126,1073	103,491	35,4985	137,8848	165,4097	85,6060	87,1219	45,8317	64,6711	16,4252	
111	197,4083	144,5456	114,2027	64,2663	27,3101	191,5723	162,8771	152,1940	28,4495	106,6460	29,1005	130,9137	133,6767	18,785	160,9702	21,3060	
112	23,3201	141,130	80,5208	181,2524	95,555	77,3500	183,9037	164,1492	155,7915	106,4854	50,6454	133,9083	5,1522	45,9496	173,7338	66,2271	59,4585	97,7969	60,2570	31,5231	149,8736	49,2935	158,383	128,7645	107,7448	103,7409	54,2279	196,5663	
113	80,917	33,652	26,5553	72,8782	101,5024	108,4342	132,5383	116,8036	184,4999	88,7322	105,3388	187,6332	190,697	136,1984	96,712	91,4626	103,5248	
114	29,9478	180,8490	189,3102	111,2027	192,6813	141,6388	72,8350	115,3112	152,9627	53,7352	129,168	107,2032	1,508	47,9480	35,490	17,8915	22,9960	27,714	31,7617	76,9690	117,7876	193,4000	103,1318	194,949	
115	152,4383	176,8236	75,9140	25,9233	9,7827	98,5825	52,4973	146,9828	81,2608	128,9072	86,4291	76,7291	90,1117	106,9598	144,3825	80,1417	114,3112	62,1913	39,983	91,1105	88,6611	129,7465	166,3001	61,3324	117,1399	94,3350	
116	78,2732	26,4221	113,8036	179,8099	32,6065	105,7899	62,7419	107,9864	82,8491	186,8639	176,4512	192,5906	57,656	4,6771	28,2638	10,1493	
117	98,9545	198,3936	42,7074	79,9043	102,2689	56,1934	114,7876	83,8516	86,4220	196,3366	1,2597	49,2896	138,7762	17,6266	115,1399	
118	14,373	23,5079	4,3626	6,8547	123,2088	181,8129	18,6388	85,1102	31,6949	166,3979	35,8640	43,8008	45,5918	177,8279	110,9403	128,6289	
119	80,108	154,741	130,730	84,6417	72,6215	30,7372	170,275	168,1890	157,9158	90,928	121,6261	37,9313	95,8126	14,960	87,518	79,4117	39,1376	163,5189	169,3511	195,617	3,7711	32,1914	19,7406	46,2687	196,2824	105,9930	
120	40,7760	62,3851	72,2287	94,2733	86,5230	95,1104	164,5926	26,5788	18,44	155,6822	60,2231	185,556	45,5279	179,3327	159,5811	75,6892	64,2385	5,1862	178,8906	28,8874	51,5675	105,9333	
121	4,7639	80,2257	197,6502	119,6261	136,1320	156,195	29,4537	7,8739	58,8818	32,1615	168,7186	62,4145	92,3819	173,2976	64,771	175,8821	191,8606	162,1977	132,3867	74,1468	165,7147	148,8115	55,44	
122	78,6207	8,5338	174,8205	168,1574	162,3518	166,6712	135,6345	28,9165	192,1494	128,7247	189,2017	3,9640	148,3230	27,84	179,7377	
123	14,2733	198,3493	6,13	104,9213	107,4581	89,1723	118,2088	128,1602	155,3251	46,132	36,6226	184,2832	103,8756	65,9599	124,6490	145,8804	193,7460	
124	141,168	159,6580	42,3496	123,6490	77,8896	20,392	67,1880	158,1870	147,9014	165,9797	136,7388	56,552	11,6180	70,9089	45,3290	48,2593	
125	33,67	174,9048	95,2917	53,8054	1,2909	63,1315	76,1865	88,5012	58,1050	23,922	173,2615	188,230	172,8515	196,4519	138,9932	183,9920	7,5670	
126	14,9602	4,2625	159,2980	86,937	181,8920	104,8615	179,7436	191,3989	161,4512	108,525	155,307	110,1073	134,5002	38,5441	76,9595	180,7176	
127	4,6808	160,7534	26,9896	39,6103	50,3622	137,4069	60,1402	156,6372	2,9365	16,9807	56,3031	139,2526	14,5682	99,1408	167,3756	135,1752	161,6643	146,8151	
128	14,9662	115,9072	123,1602	92,556	50,2987	190,2968	118,6289	157,6815	132,2789	184,6339	198,1860	112,7645	122,7247	85,4644	82,6834	100,2584	196,1760	12,7542	
129	6,8525	114,168	101,8821	77,2337	79,7314	47,9533	85,517	175,7121	184,5623	109,2464	143,8021	167,5370	25,3005	159,6895	115,7465	
130	119,730	8,55	26,5706	45,4994	36,7589	30,1356	184,8488	178,615	92,4320	58,7020	82,3349	174,4481	66,5826	39,2414	194,9429	156,2264	20,9048	64,2493	43,2685	137,5926	190,3429	147,9251	111,9137	48,7921	38,5227	
131	14,358	98,4614	159,4355	75,5902	22,6075	43,8231	163,8625	11,833	57,6342	61,6924	82,3457	64,4631	134,6293	167,6269	2,7005	63,5257	9,700	103,2920	21,3748	
132	198,2393	113,5383	99,6234	138,5667	28,5604	19,3157	38,6092	85,3873	82,4162	25,219	182,6433	22,1560	147,2847	6,1514	121,3867	128,2789	51,6107	37,821	
133	80,7217	112,9083	136,3739	77,2481	39,8145	43,8488	18,2702	27,7749	168,899	99,2090	190,9958	139,4719	182,8241	191,4296	85,836	153,8437	67,3802	49,5167	111,6767	
134	197,6225	198,4071	92,610	79,5792	175,4489	36,979	131,6293	71,7485	146,9556	158,119	11,294	65,9956	135,276	16,5203	84,9312	126,5002	38,4730	
135	23,4560	4,7582	20,6434	174,6977	150,9732	190,1431	173,5664	144,6396	127,1752	122,6345	48,8869	82,519	158,8348	184,7629	78,6919	10,4650	134,276	194,5726	13,861	
136	161,3866	195,4279	32,3823	84,4270	168,9519	54,1794	170,1529	197,9068	121,1320	194,2496	109,8658	199,7783	133,3739	145,1769	179,6711	26,7200	40,4658	174,5711	85,6221	113,1984	25,9251	184,6682	81,1409	88,9026	178,2752	124,7388	
137	188,9117	100,7178	42,4572	51,1096	52,9846	97,4667	25,5378	102,6814	130,5926	84,4367	141,7872	23,7591	127,4069	157,5286	78,1910	91,4129	155,5736	67,1414	10,5273	110,8848	
138	200,678	160,9902	26,7027	101,2902	51,8755	132,5667	43,7965	92,8080	1,7896	173,8555	33,6960	71,1229	46,2860	27,5918	188,892	169,7498	178,6589	125,9932	76,5683	117,7762	54,6261	140,5446	
139	197,1386	98,1235	92,6763	181,5456	176,8186	182,2354	133,4719	158,3451	196,3988	73,4428	90,7846	155,2100	194,6966	69,9030	94,7116	127,2526	162,4510	9,8701	37,8208	
140	1,546	17,6440	97,6527	158,4029	151,5289	68,9624	138,5446	43,4482	169,2230	9,4163	155,5001	188,6223	102,6370	166,9829	65,5376	
141	154,3188	68,3540	106,674	79,7918	104,8162	24,6862	63,5607	6,8200	75,9237	150,2634	124,168	14,4477	112,130	164,6499	198,2621	114,6388	185,6820	59,9126	64,158	137,7872	81,4032	76,1969	48,7941	
142	66,777	17,8016	104,6236	18,332	47,5297	81,424	91,9164	150,2598	5,1195	34,7791	155,6613	169,7506	86,1663	100,2994	190,8070	2,7731	71,6038	145,5378	37,6433	
143	23,7543	6,3110	22,8603	108,972	25,108	81,9810	43,1171	186,8430	14,5848	129,8021	101,4042	76,1079	98,4300	155,2442	177,3884	36,5111	153,9940	96,9274	15,1041	176,5062	
144	115,3825	173,8693	29,6452	98,7198	68,2277	195,652	102,7884	30,1616	111,5456	33,4841	13,9987	44,2276	86,8808	148,3617	35,3087	40,7772	101,3619	22,9362	184,5222	135,6396	90,6223	3,285	100,6605	
145	200,2753	1,648	136,1769	26,6697	64,2685	174,7252	47,9483	108,521	44,2888	123,8804	71,6127	142,5378	20,8099	78,7244	110,6099	100,5512	55,3342	
146	115,9828	22,3620	47,2959	60,2317	5,5308	127,8151	7,4823	134,9556	18,9000	31,2837	17,5362	68,3895	72,4264	188,5715	167,52	107,7862	38,4400	
147	26,5759	59,2651	163,7221	95,1278	132,2847	124,9014	5,1087	34,9758	96,6736	38,8391	41,1858	167,5546	130,9251	149,6379	58,2267	93,7807	
148	160,3995	144,3617	185,2814	64,6419	18,589	30,4760	173,6725	179,6374	70,7231	155,6603	122,3230	192,4834	36,9550	121,8115	29,3252	
149	14,4352	59,2405	188,1003	163,9897	70,2366	83,6823	187,9580	174,2824	73,5233	112,8736	55,3088	18,2664	176,2255	190,3755	180,3407	147,6379	
150	141,2634	1,2183	16,1680	41,7278	36,116	135,9732	11,4802	98,2093	58,4857	142,2598	73,8061	9,4539	18,5150	24,5669	52,634	190,5243	88,6770	53,662	7,9031	93,9213	
151	80,6728	156,6169	24,784	27,5915	174,1846	168,9216	99,4990	88,2295	178,5979	96,5643	83,162	13,9629	140,5289	189,9732	163,3624	
152	161,6939	58,5877	48,5835	9,1087	8,1257	46,9550	189,8140	199,2697	109,2743	65,3595	186,2075	115,4383	50,5767	193,5444	90,4427	80,9606	114,9627	62,7404	79,6519	27,2124	111,1940	19,9751	93,6543	
153	17,8545	99,4560	70,6532	164,8748	29,5446	25,2477	72,541	143,9940	173,7613	77,4483	50,4905	165,897	133,8437	33,6574	67,6204	100,9522	
154	141,3188	119,741	198,5078	156,8062	62,3238	20,2398	18,453	49,2962	187,1808	168,6317	200,229	185,1448	93,4073	78,8423	84,5421	41,901	60,6667	170,5971	19,4320	21,1845	199,5786	
155	57,893	14,4446	98,5515	112,7915	123,3251	120,6822	25,3242	139,2100	143,2442	65,5533	142,6613	96,1251	137,5736	148,6603	61,5301	126,307	37,609	140,5001	194,6768	
156	66,2965	42,6539	82,4691	53,4662	151,6169	7,7027	85,6669	29,5083	154,8062	130,2264	108,7039	34,8641	121,195	175,2205	69,9959	70,4830	127,6372	37,7714	
157	119,9158	26,7	86,4447	101,1393	187,7184	137,5286	99,6818	11,8497	2,8643	158,1881	128,6815	175,1597	72,604	24,9540	28,6880	15,2136	
158	78,6367	187,6714	91,5553	139,3451	169,1709	135,8348	63,5709	195,4912	140,4029	157,1881	124,1870	181,969	112,383	87,4081	134,119	
159	4,6133	160,4243	61,49	180,5757	6,9500	194,9391	43,9621	100,6567	126,2980	73,4969	131,4355	124,6580	1,7420	52,7816	74,8960	198,8330	42,5951	120,5811	87,19	36,6043	84,8763	129,6895	2,1397	51,3017	193,3786	
160	14,7860	138,9902	127,7534	49,8648	85,3613	189,1530	57,2058	159,4243	183,9293	148,3995	87,8712	180,624	179,2542	91,383	42,2382	1,6461	77,105	28,9059	111,9702	19,3997	
161	152,6939	14,4275	23,6863	78,6310	136,3866	42,4792	62,4144	79,8395	127,6643	69,6171	126,4512	56,9811	196,9729	102,8230	88,1726	28,9217	
162	4,3924	98,6139	6,6897	59,391	194,1483	122,3518	57,6483	121,1977	179,9718	139,4510	199,7749	40,3056	111,8771	96,3737	45,3436	186,6114	48,201	
163	1,8164	101,6033	41,5256	173,5799	15,818	13,3870	149,9897	131,8625	181,5593	119,5189	61,448	42,1278	68,4920	100,9709	147,7221	44,18	49,4688	192,2762	151,3624	89,4055	
164	141,6499	112,1492	42,347	120,5926	43,6849	87,3629	184,9774	170,328	153,8748	10,3866	172,9550	74,8627	195,9730	105,4661	24,7312	183,615	176,8681	
165	23,208	6,6473	79,3768	187,1291	50,2667	153,897	166,4221	74,2602	21,2151	121,7147	124,9797	83,1555	65,3705	7,6019	41,3741	110,4097	
166	23,8077	98,2364	79,8726	173,6917	44,6953	167,7080	118,3979	165,4221	168,4399	17,4762	9,8702	122,6712	20,6086	169,5530	115,3001	35,2816	55,3686	140,9829	
167	23,2133	188,6549	187,9538	43,8120	18,7625	127,3756	180,6183	87,1022	79,820	83,8200	3,3877	129,5370	85,8110	193,8116	166,7080	131,6269	146,52	147,5546	45,1163	199,2001	93,5670	
168	119,1890	8,2076	136,9519	87,9716	154,6317	121,7186	133,899	122,1574	85,6193	173,3859	59,4170	27,1578	69,2357	151,9216	22,4356	70,1295	34,3923	166,4399	10,9495	52,1134	
169	14,4333	175,9164	177,2274	45,662	20,5990	63,5160	119,3511	104,3712	187,9225	192,8603	109,382	158,1709	55,7795	1,8700	138,7498	142,7506	166,5530	107,668	15,7485	54,2296	140,2230	
170	119,275	1,2620	198,8089	136,1529	33,3648	18,4989	177,2774	44,6940	84,2436	2,9342	154,5971	164,328	45,8060	71,1539	94,9318	
171	188,6981	101,4083	16,3482	67,1394	61,6888	49,9736	182,4704	94,9959	10,2029	33,3913	185,5113	71,6702	6,3722	18,4403	72,8573	
172	200,6888	42,5383	72,3153	104,561	174,3433	102,6572	175,5353	35,992	73,2239	164,9550	29,5830	80,7715	77,4771	2,1438	60,2781	125,8515	13,2070	
173	112,7338	1,2069	144,8693	33,5949	17,7312	20,2676	18,7256	121,2976	168,3859	32,9631	148,6725	82,591	163,5799	192,2550	166,6917	179,4234	138,8555	44,5518	95,4092	153,7613	135,5664	61,4803	125,2615	193,4808	46,2969	
174	130,4481	89,858	73,2581	135,6977	68,7082	136,5711	91,3418	125,9048	122,8205	145,7252	72,2019	151,1846	172,3433	108,5669	99,5675	179,1886	149,2824	90,6914	
175	156,2205	187,2864	27,210	199,3779	67,5048	121,8821	169,9164	134,4489	65,7920	26,6165	172,5353	197,5909	8,1022	129,7121	14,6718	184,9107	70,3256	58,3675	157,1597	
176	200,1709	115,8236	6,3512	33,3258	187,1128	191,3352	139,8186	149,2255	116,4512	46,9923	143,5062	51,1625	164,8681	107,6806	74,8129	
177	86,7010	92,3182	24,393	64,7660	102,4462	43,9544	22,8713	190,1332	14,6741	8,8508	170,2774	82,7882	169,2274	32,6902	53,9852	60,5345	143,3884	178,7547	118,8279	3,7097	
178	130,615	72,5128	70,3394	13,4194	120,8906	11,1696	151,5979	16,1714	138,6589	102,1334	17,7464	49,9747	177,7547	35,5774	136,2752	28,3642	76,8433	
179	80,7729	160,2542	136,6711	120,3327	56,5284	50,2502	186,9993	180,664	104,8827	90,3149	74,1223	148,6374	174,1886	126,7436	173,4234	162,9718	116,8099	34,8528	52,3504	122,7377	
180	160,624	159,5757	114,8490	59,2435	86,4604	39,9506	85,5525	179,664	191,6312	31,3598	149,3407	167,6183	89,6612	9,5995	126,7176	105,341	
181	112,2524	187,7956	41,5235	118,8129	185,9712	139,5456	76,3275	40,2338	11,8448	34,5267	102,3585	126,8920	106,5332	93,4071	91,5060	191,4844	163,5593	158,969	51,158	
182	27,6234	47,8382	99,2897	139,2354	5,8806	133,8241	132,6433	56,7267	74,1873	35,7369	64,4701	107,8313	54,438	171,4704	2,7908	21,2447	
183	160,9293	112,9037	102,9634	99,3577	81,3061	88,5547	11,594	96,5939	53,5304	105,7722	26,4842	57,9093	70,5332	125,9920	164,615	38,5213	
184	6,8021	130,8488	188,198	40,4306	123,2832	101,9591	113,4999	129,5623	144,5222	175,9107	136,6682	164,9774	86,801	57,7592	29,9797	81,4485	35,7437	135,7629	28,4164	10,3207	128,6339	
185	57,9772	105,1033	90,7284	52,8925	83,9306	97,7065	148,2814	25,3573	197,3140	50,3968	11,2045	141,6820	76,3674	108,8699	60,6670	188,700	120,556	181,9712	154,1448	30,3846	16,6280	109,6644	171,5113	19,5896	196,1339	
186	57,8815	152,2075	197,1324	42,9391	188,5027	92,7980	179,9993	191,8255	58,8993	143,8430	116,8639	162,6114	71,7143	189,8128	195,2099	68,2528	103,9654	
187	14,4874	200,6767	176,1128	37,4105	7,9522	175,2864	19,107	107,2610	167,9538	157,7184	24,9327	181,7956	42,3075	158,6714	165,1291	50,2485	154,1808	113,6332	169,9225	149,9580	10,4786	
188	23,4236	198,9114	137,9117	184,198	101,8531	167,6549	54,4883	149,1003	28,3816	196,88	52,7805	55,5181	185,700	186,5027	171,6981	97,4695	138,892	125,230	146,5715	140,6223	
189	152,8140	160,1530	8,2780	114,3102	86,1115	40,4263	77,5702	50,7031	47,5939	85,1147	60,4415	69,5215	186,8128	198,9430	122,2017	51,8899	151,9732	193,2375	
190	4,7536	200,5999	47,5892	113,697	130,3429	135,1431	150,5243	61,9775	69,8022	133,9958	128,2968	100,6674	17,7000	106,3305	9,3613	177,1332	31,5055	149,3755	142,8070	15,6854	105,2518	
191	77,5135	126,3989	176,3352	94,8318	186,8255	121,8606	87,6921	44,8130	103,9683	75,1403	181,4844	50,5026	180,6312	111,5723	37,3573	133,4296	
192	114,6813	97,6411	77,561	39,7454	22,4606	104,4219	27,5344	85,544	173,2550	91,6625	169,8603	116,5906	49,3113	163,2762	122,1494	148,4834	
193	152,5444	167,8116	114,4000	55,8583	58,6166	189,2375	159,3786	96,8831	79,7737	21,494	28,9441	62,6610	123,7460	99,4566	173,4808	46,199	
194	200,2915	159,9391	136,2496	130,9429	42,6498	92,426	139,6966	162,1483	73,8521	99,5832	155,6768	114,949	46,2429	79,5784	135,5726	
195	23,3179	4,2490	197,5337	144,652	136,4279	6,2233	158,4912	186,2099	200,8114	61,8928	46,8206	164,9730	119,617	19,5038	67,5737	
196	188,88	39,9267	139,3988	95,231	61,5577	161,9729	125,4519	117,3366	103,696	46,9632	26,6754	112,5663	128,1760	119,2824	185,1339	
197	54,2223	186,1324	121,6502	134,6225	68,8223	24,9337	25,3875	139,1386	81,5540	44,4900	195,5337	37,9188	111,4083	86,9714	110,751	136,9068	185,3140	104,4174	175,5909	
198	141,2621	170,8089	44,2619	188,9114	41,7215	1,1724	154,5078	84,5999	16,2223	117,3936	123,3493	159,8330	69,6284	132,2393	134,4071	77,5081	50,3798	65,3575	36,6280	28,366	128,1860	189,9430	
199	152,2697	8,1918	136,7783	59,8958	24,2838	175,3779	31,5564	162,7749	65,11	76,6878	9,70	89,2446	34,8196	167,2001	154,5786	
200	108,9976	103,6851	145,2753	41,2622	187,6767	190,5999	16,2848	194,2915	5,4009	172,6888	39,4319	176,1709	60,3269	138,678	43,8943	98,2690	1,8021	104,7083	154,229	91,1988	67,475	76,4623	195,8114	37,7541	54,4899	


================================================
FILE: Algorithms/graphtheory/dijkstra/heapdijkstra.py
================================================
"""
Dijkstra's algorithm for finding the shortest path.
Improved version with the usage of heaps.

Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
  2019-02-15 Initial coding
  2020-03-28 Small code changes, fixed for edge cases not covered

"""

import heapq


def make_graph(file):
    try:
        f = open(file, "r")
    except IOError:
        raise ("File does not exist!")

    line_list = f.readlines()

    # Kinda messy graph loading
    G = {
        int(line.split()[0]): {
            (int(tup.split(",")[0])): int(tup.split(",")[1])
            for tup in line.split()[1:]
            if tup
        }
        for line in line_list
        if line
    }
    f.close()
    return G


def dijkstra(G, start, end=None):
    if start not in G or (end != None and end not in G):
        return [], {end: float("inf")}

    distance, visited, history, heap, path = {}, {}, {}, [], []

    for node in G.keys():
        distance[node] = float("inf")
        visited[node] = False

    distance[start], visited[start] = 0, True
    heapq.heappush(heap, (0, start))

    while heap:
        (d, node) = heapq.heappop(heap)
        visited[node] = True

        for child_node, weight in G[node].items():
            if (not visited[child_node]) and (d + weight < distance[child_node]):
                history[child_node] = node
                distance[child_node] = d + weight
                heapq.heappush(heap, (distance[child_node], child_node))

    if end != None:
        current_node = end

        while current_node != start:
            try:
                path.insert(0, current_node)
                current_node = history[current_node]

            except KeyError:
                return [], distance

        path.insert(0, start)

    return path, distance


if __name__ == "__main__":
    # start, end = 1, 160
    # print(f'Goal is to find the path from node {start} to node {end}')
    # G = make_graph('dijkstraData.txt')

    G = {1: {2: 10, 3: 20}, 2: {4: 40}, 3: {4: 5}, 4: {}}
    start = 1
    end = 2

    path, dist = dijkstra(G, start, end)
    print(f"Path found: {path}")
    print(dist)


================================================
FILE: Algorithms/graphtheory/floyd-warshall/floyd-warshall.py
================================================
"""
Purpose is to the find shortest path from all nodes to all other nodes, O(n^3).
Can be used with negative weights, however to check if it has negative cycles, bellman ford should prob. be used first.

Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>
*   2019-03-08 Initial programming

"""


def load_graph(file_name):
    try:
        with open(file_name) as file:
            line_list = file.readlines()
            file.close()

    except IOError:
        raise IOError("File does not exist")

    G = {
        int(line.split()[0]): {
            (int(tup.split(",")[0])): int(tup.split(",")[1])
            for tup in line.split()[1:]
            if tup
        }
        for line in line_list
        if line
    }

    # If we have path set path else make value infinity
    adjacency_matrix = [
        [
            G[i][j] if (i in G and j in G[i]) else float("inf")
            for j in range(1, len(G) + 1)
        ]
        for i in range(1, len(G) + 1)
    ]

    # Make diagonal values all 0
    for i in range(len(G)):
        adjacency_matrix[i][i] = 0

    # next will be matrix showing which path to take for the shortest path
    next = [
        [j if adjacency_matrix[i][j] != float("inf") else None for j in range(len(G))]
        for i in range(len(G))
    ]

    return adjacency_matrix, next


def floyd_warshall(adj_matrix, next):
    n = len(adj_matrix)
    # make a copy of adj_matrix, dp will contain APSP (All-Path-Shortest-Path) solutions,
    APSP = adj_matrix.copy()

    # Can we get a better path by going through node k?
    for k in range(n):
        # Goal is to find path from i to j
        for i in range(n):
            for j in range(n):
                # if distance from  i to k, then k to j is less than distance i to j
                if APSP[i][k] + APSP[k][j] < APSP[i][j]:
                    APSP[i][j] = APSP[i][k] + APSP[k][j]
                    next[i][j] = next[i][k]

    # return APSP (All-Path-Shortest-Path) matrix
    return APSP, next


def construct_path_to_take(next, start, end):
    go_through = start
    path = [start]

    while next[go_through][end] != end:
        go_through = next[go_through][end]
        path.append(go_through)

    path.append(end)

    return path


if __name__ == "__main__":
    adj_matrix, next = load_graph("test_graph.txt")
    APSP, next = floyd_warshall(adj_matrix, next)

    print(f"The shortest paths are {APSP}")
    print(f"The path to take is given by {next}")

    path_to_take = construct_path_to_take(next, 0, 3)
    print(path_to_take)


================================================
FILE: Algorithms/graphtheory/floyd-warshall/test_graph.txt
================================================
1 2,5 3,10
2 4,-3
3 4,20
4

================================================
FILE: Algorithms/graphtheory/kahns-toposort/example.txt
================================================
Step C must be finished before step A can begin.
Step C must be finished before step F can begin.
Step A must be finished before step B can begin.
Step A must be finished before step D can begin.
Step B must be finished before step E can begin.
Step D must be finished before step E can begin.
Step F must be finished before step E can begin.

================================================
FILE: Algorithms/graphtheory/kahns-toposort/kahn_topological_ordering.py
================================================
"""
Purpose of this algorithm is finding a path that is in topological ordering for a directed acyclic graph (DAG).
If the graph is not a DAG and includes cycles it will return is_DAG = 'False' meaning it has cycles.

Time Complexity: O(n + m), n = |V|, m = |E|

Programmed by Aladdin Persson <aladdin.persson at hotmail.com>
*   2019-03-17 Intitial programming
*   2020-03-28 Removed load graph function, just having topological sort seems to make more sense
               The loading of the graph is so varying depending on input, doesn't make much sense to include it

"""

from collections import defaultdict, deque


def topological_ordering(graph, degree_incoming):
    if len(graph) == 0:
        return [], False

    curr_accessible_nodes = deque()

    for node in graph:
        if degree_incoming[node] == 0:
            curr_accessible_nodes.append(node)

    path = []

    while curr_accessible_nodes:
        node_topological = curr_accessible_nodes.popleft()
        path.append(node_topological)

        for connected_node in graph[node_topological]:
            degree_incoming[connected_node] -= 1

            if degree_incoming[connected_node] == 0:
                curr_accessible_nodes.append(connected_node)

    # Check if there are still incoming edges (meaning it will have cycles)
    is_DAG = True

    for val in degree_incoming.values():
        if val != 0:
            is_DAG = False
            path = []

    return path, is_DAG


if __name__ == "__main__":
    G = {"A": ["B"], "B": ["C", "D"], "C": ["D"], "D": []}
    degree_incoming = defaultdict(int, {"B": 1, "C": 1, "D": 2})

    print("The graph to check is : " + str(G))
    print("Which has incoming edges: " + str(degree_incoming))
    print("\n")
    path_to_take, is_DAG = topological_ordering(G, degree_incoming)
    print("The graph has a topological ordering <--> G is a DAG: " + str(is_DAG))
    print(f'One path to take that is a topological ordering is {"".join(path_to_take)}')


================================================
FILE: Algorithms/graphtheory/kargers/kargermincut.py
================================================
# Purpose of Karger's algorithm is to compute the mi
Download .txt
gitextract_4q2tk5k2/

├── .gitignore
├── .travis.yml
├── Algorithm_tests/
│   ├── cryptology_tests/
│   │   └── ceasar_test.py
│   ├── dynamic_programming_tests/
│   │   ├── knapsack_tests/
│   │   │   └── knapsack_bottomup_test.py
│   │   ├── sequence_alignment/
│   │   │   └── sequence_alignment_test.py
│   │   └── weighted_interval_scheduling/
│   │       └── weighted_interval_scheduling_test.py
│   ├── graphtheory_tests/
│   │   ├── BFS_test.py
│   │   ├── DFS_test.py
│   │   ├── Djikstra/
│   │   │   ├── djikstra_heap_test.py
│   │   │   └── djikstra_naive_test.py
│   │   ├── bellman_ford_test.py
│   │   ├── kahn_topological_ordering_test.py
│   │   ├── kruskal_unionfind_test.py
│   │   ├── prims_algorithm_test.py
│   │   ├── test_NN.py
│   │   └── test_graph.txt
│   ├── math_tests/
│   │   ├── intersection_test.py
│   │   └── union_test.py
│   ├── other_tests/
│   │   ├── test_binarysearch.py
│   │   ├── test_intervalscheduling.py
│   │   └── test_medianmaintenance.py
│   └── sorting_tests/
│       └── test_sorting.py
├── Algorithms/
│   ├── cryptology/
│   │   ├── RSA_algorithm/
│   │   │   ├── RSA.py
│   │   │   └── euclid_gcd.py
│   │   ├── ceasar_shifting_cipher/
│   │   │   └── ceasar_shift_cipher.py
│   │   ├── hill_cipher/
│   │   │   └── hill_cipher.py
│   │   ├── one_time_pad/
│   │   │   └── one_time_pad.py
│   │   └── vigenere_cipher/
│   │       └── vigenere.py
│   ├── dynamic_programming/
│   │   ├── knapsack/
│   │   │   ├── knapsack_bottomup.py
│   │   │   ├── knapsack_memoization_recursive_topdown.py
│   │   │   └── knapsack_naive_recursive.py
│   │   ├── longest_increasing_subsequence.py
│   │   ├── sequence_alignment.py
│   │   └── weighted_interval_scheduling.py
│   ├── graphtheory/
│   │   ├── bellman-ford/
│   │   │   ├── bellman_ford.py
│   │   │   └── data.txt
│   │   ├── breadth-first-search/
│   │   │   ├── BFS_queue_iterative.py
│   │   │   └── exgraph.txt
│   │   ├── depth-first-search/
│   │   │   ├── DFS_recursive.py
│   │   │   ├── DFS_stack_iterative.py
│   │   │   └── exgraph.txt
│   │   ├── dijkstra/
│   │   │   ├── dijkstra.py
│   │   │   ├── dijkstraData.txt
│   │   │   └── heapdijkstra.py
│   │   ├── floyd-warshall/
│   │   │   ├── floyd-warshall.py
│   │   │   └── test_graph.txt
│   │   ├── kahns-toposort/
│   │   │   ├── example.txt
│   │   │   └── kahn_topological_ordering.py
│   │   ├── kargers/
│   │   │   ├── kargermincut.py
│   │   │   └── kargermincutdata.txt
│   │   ├── kruskal/
│   │   │   ├── edges.txt
│   │   │   ├── kruskal.py
│   │   │   ├── kruskal_unionfind.py
│   │   │   └── testedges.txt
│   │   ├── nearest-neighbor-tsp/
│   │   │   ├── NearestNeighborTSP.py
│   │   │   └── graph.txt
│   │   └── prims/
│   │       ├── edges.txt
│   │       ├── prim_heap.py
│   │       └── prim_naive.py
│   ├── math/
│   │   ├── euclid_gcd/
│   │   │   └── euclid_gcd.py
│   │   ├── extended_euclidean_algorithm/
│   │   │   └── euclid_gcd.py
│   │   ├── intersection_of_two_sets/
│   │   │   └── intersection_of_two_sets.py
│   │   ├── karatsuba/
│   │   │   └── karatsuba.py
│   │   ├── pollard_p1/
│   │   │   └── pollard_p1.py
│   │   ├── prime_factorization/
│   │   │   └── primefactorization.py
│   │   ├── sieve_of_eratosthenes/
│   │   │   └── sieve_eratosthenes.py
│   │   └── union_of_two_sets/
│   │       └── union_of_two_sets.py
│   ├── numerical_methods/
│   │   ├── bisection.py
│   │   └── fixpoint.py
│   ├── other/
│   │   ├── Huffman/
│   │   │   ├── Huffman.py
│   │   │   ├── huffman.txt
│   │   │   └── test.txt
│   │   ├── Kadanes_algorithm.py
│   │   ├── binarysearch.py
│   │   ├── counting_inversions.py
│   │   ├── interval_scheduling.py
│   │   └── median_maintenance.py
│   └── sorting/
│       ├── bubblesort.py
│       ├── hopesort.py
│       ├── insertionsort.py
│       ├── mergesort.py
│       ├── quicksort.py
│       ├── randomized_quicksort.py
│       └── selectionsort.py
├── LICENSE
├── README.md
├── requirements.txt
└── setup.py
Download .txt
SYMBOL INDEX (245 symbols across 68 files)

FILE: Algorithm_tests/cryptology_tests/ceasar_test.py
  class test_ceasar_cipher (line 16) | class test_ceasar_cipher(unittest.TestCase):
    method setUp (line 17) | def setUp(self):
    method test_encryption_message1 (line 27) | def test_encryption_message1(self):
    method test_decryption_message1 (line 31) | def test_decryption_message1(self):
    method test_encryption_message2 (line 35) | def test_encryption_message2(self):
    method test_decryption_message2 (line 39) | def test_decryption_message2(self):

FILE: Algorithm_tests/dynamic_programming_tests/knapsack_tests/knapsack_bottomup_test.py
  class test_KnapSack (line 13) | class test_KnapSack(unittest.TestCase):
    method setUp (line 14) | def setUp(self):
    method test_noitems (line 39) | def test_noitems(self):
    method test_singleitem_value (line 46) | def test_singleitem_value(self):
    method test_negativevalues (line 53) | def test_negativevalues(self):
    method test_simpleexample (line 60) | def test_simpleexample(self):
    method test_weight_too_heavy (line 67) | def test_weight_too_heavy(self):

FILE: Algorithm_tests/dynamic_programming_tests/sequence_alignment/sequence_alignment_test.py
  class test_sequence_alignment (line 13) | class test_sequence_alignment(unittest.TestCase):
    method setUp (line 14) | def setUp(self):
    method test_simplecase (line 59) | def test_simplecase(self):
    method test_remove (line 64) | def test_remove(self):
    method test_remove_to_empty (line 69) | def test_remove_to_empty(self):
    method test_insert_elements (line 74) | def test_insert_elements(self):
    method test_remove_insert_align (line 79) | def test_remove_insert_align(self):
    method test_x_longer_than_y (line 84) | def test_x_longer_than_y(self):
    method test_y_longer_than_x (line 89) | def test_y_longer_than_x(self):
    method test_more_complicated_example (line 94) | def test_more_complicated_example(self):
    method test_findsolution_simplecase (line 99) | def test_findsolution_simplecase(self):
    method test_findsolution_empty_y (line 104) | def test_findsolution_empty_y(self):
    method test_findsolution_empty_x (line 109) | def test_findsolution_empty_x(self):

FILE: Algorithm_tests/dynamic_programming_tests/weighted_interval_scheduling/weighted_interval_scheduling_test.py
  class test_weighted_interval_scheduling (line 13) | class test_weighted_interval_scheduling(unittest.TestCase):
    method setUp (line 14) | def setUp(self):
    method test_empty_interval (line 51) | def test_empty_interval(self):
    method test_single_interval (line 57) | def test_single_interval(self):
    method test_overlapping_intervals (line 63) | def test_overlapping_intervals(self):
    method test_no_overlapping_intervals (line 69) | def test_no_overlapping_intervals(self):
    method test_negative_weights (line 75) | def test_negative_weights(self):
    method test_interval_contained_in_all_intervals (line 81) | def test_interval_contained_in_all_intervals(self):
    method test_all_intervals_same (line 87) | def test_all_intervals_same(self):
    method test_earliest_finish_time (line 93) | def test_earliest_finish_time(self):
    method test_earliest_finish_time_not_best (line 99) | def test_earliest_finish_time_not_best(self):

FILE: Algorithm_tests/graphtheory_tests/BFS_test.py
  class test_BFS (line 15) | class test_BFS(unittest.TestCase):
    method setUp (line 16) | def setUp(self):
    method test_linear_graph (line 41) | def test_linear_graph(self):
    method test_simple_graph (line 46) | def test_simple_graph(self):
    method test_disconnected_graph (line 51) | def test_disconnected_graph(self):
    method test_complete_graph (line 55) | def test_complete_graph(self):
    method test_breadth_before_depth (line 59) | def test_breadth_before_depth(self):

FILE: Algorithm_tests/graphtheory_tests/DFS_test.py
  class test_DFS (line 16) | class test_DFS(unittest.TestCase):
    method setUp (line 17) | def setUp(self):
    method test_linear_graph (line 35) | def test_linear_graph(self):
    method test_simple_graph (line 43) | def test_simple_graph(self):
    method test_disconnected_graph (line 50) | def test_disconnected_graph(self):
    method test_complete_graph (line 57) | def test_complete_graph(self):

FILE: Algorithm_tests/graphtheory_tests/Djikstra/djikstra_heap_test.py
  class test_Dijkstra (line 15) | class test_Dijkstra(unittest.TestCase):
    method setUp (line 16) | def setUp(self):
    method test_emptygraph (line 33) | def test_emptygraph(self):
    method test_simplegraph (line 38) | def test_simplegraph(self):
    method test_no_path_exists (line 43) | def test_no_path_exists(self):
    method test_not_endpoint (line 48) | def test_not_endpoint(self):

FILE: Algorithm_tests/graphtheory_tests/Djikstra/djikstra_naive_test.py
  class test_Dijkstra (line 15) | class test_Dijkstra(unittest.TestCase):
    method setUp (line 16) | def setUp(self):
    method test_emptygraph (line 33) | def test_emptygraph(self):
    method test_simplegraph (line 38) | def test_simplegraph(self):
    method test_no_path_exists (line 43) | def test_no_path_exists(self):
    method test_not_endpoint (line 48) | def test_not_endpoint(self):

FILE: Algorithm_tests/graphtheory_tests/bellman_ford_test.py
  class test_BellmanFord (line 15) | class test_BellmanFord(unittest.TestCase):
    method test_negativecycle (line 16) | def test_negativecycle(self):
    method test_shortestdist (line 33) | def test_shortestdist(self):
    method test_run_emptygraph (line 47) | def test_run_emptygraph(self):

FILE: Algorithm_tests/graphtheory_tests/kahn_topological_ordering_test.py
  class test_TopologicalOrdering (line 16) | class test_TopologicalOrdering(unittest.TestCase):
    method setUp (line 17) | def setUp(self):
    method test_emptygraph (line 50) | def test_emptygraph(self):
    method test_clear_ordering (line 55) | def test_clear_ordering(self):
    method test_more_complicated_graph (line 60) | def test_more_complicated_graph(self):
    method test_no_topological_ordering (line 65) | def test_no_topological_ordering(self):

FILE: Algorithm_tests/graphtheory_tests/kruskal_unionfind_test.py
  class test_Kruskal (line 15) | class test_Kruskal(unittest.TestCase):
    method setUp (line 16) | def setUp(self):
    method test_linear_graph (line 62) | def test_linear_graph(self):
    method test_triangle_graph (line 67) | def test_triangle_graph(self):
    method test_trickier_mst (line 72) | def test_trickier_mst(self):
    method test_disconnected_graph (line 77) | def test_disconnected_graph(self):
    method test_empty_graph (line 82) | def test_empty_graph(self):

FILE: Algorithm_tests/graphtheory_tests/prims_algorithm_test.py
  class test_primsHeap (line 14) | class test_primsHeap(unittest.TestCase):
    method setUp (line 15) | def setUp(self):
    method test_linear_graph (line 52) | def test_linear_graph(self):
    method test_triangle_graph (line 57) | def test_triangle_graph(self):
    method test_trickier_mst (line 62) | def test_trickier_mst(self):
    method test_disconnected_graph (line 67) | def test_disconnected_graph(self):
    method test_empty_graph (line 72) | def test_empty_graph(self):

FILE: Algorithm_tests/graphtheory_tests/test_NN.py
  class TestNN (line 10) | class TestNN(unittest.TestCase):
    method setUp (line 11) | def setUp(self):
    method test_0_rankNeighbors (line 34) | def test_0_rankNeighbors(self):
    method test_1_nnTSP (line 39) | def test_1_nnTSP(self):
    method test_linear_graph (line 47) | def test_linear_graph(self):
    method test_simple_graph (line 53) | def test_simple_graph(self):
    method test_disconnected_graph (line 58) | def test_disconnected_graph(self):
    method test_complete_graph (line 63) | def test_complete_graph(self):

FILE: Algorithm_tests/math_tests/intersection_test.py
  class test_intersection (line 15) | class test_intersection(unittest.TestCase):
    method setUp (line 16) | def setUp(self):
    method test_intersection_none (line 38) | def test_intersection_none(self):
    method test_intersection_lastelement (line 42) | def test_intersection_lastelement(self):
    method test_intersection_firstelement (line 46) | def test_intersection_firstelement(self):
    method test_intersection_allequal (line 50) | def test_intersection_allequal(self):
    method test_intersection_both_empty (line 54) | def test_intersection_both_empty(self):

FILE: Algorithm_tests/math_tests/union_test.py
  class test_union (line 15) | class test_union(unittest.TestCase):
    method setUp (line 16) | def setUp(self):
    method test_union_all (line 38) | def test_union_all(self):
    method test_union_lastequal (line 42) | def test_union_lastequal(self):
    method test_union_firstequal (line 46) | def test_union_firstequal(self):
    method test_union_samelist (line 50) | def test_union_samelist(self):
    method test_union_both_empty (line 54) | def test_union_both_empty(self):

FILE: Algorithm_tests/other_tests/test_binarysearch.py
  class test_binarysearch (line 15) | class test_binarysearch(unittest.TestCase):
    method setUp (line 16) | def setUp(self):
    method test_binarysearch_basic (line 46) | def test_binarysearch_basic(self):
    method test_binarysearch_nonexistant (line 55) | def test_binarysearch_nonexistant(self):
    method test_binarysearch_identical (line 64) | def test_binarysearch_identical(self):
    method test_binarysearch_lastvalue (line 73) | def test_binarysearch_lastvalue(self):
    method test_binarysearch_firstvalue (line 82) | def test_binarysearch_firstvalue(self):
    method test_binarysearch_empty (line 91) | def test_binarysearch_empty(self):
    method test_binarysearch_standard (line 100) | def test_binarysearch_standard(self):

FILE: Algorithm_tests/other_tests/test_intervalscheduling.py
  class test_intervalscheduling (line 15) | class test_intervalscheduling(unittest.TestCase):
    method setUp (line 16) | def setUp(self):
    method test_intervalscheduling_basic (line 33) | def test_intervalscheduling_basic(self):
    method test_intervalscheduling_empty (line 38) | def test_intervalscheduling_empty(self):
    method test_intervalscheduling_take_all (line 43) | def test_intervalscheduling_take_all(self):
    method test_intervalscheduling_unsorted (line 48) | def test_intervalscheduling_unsorted(self):
    method test_intervalscheduling_one_element (line 53) | def test_intervalscheduling_one_element(self):

FILE: Algorithm_tests/other_tests/test_medianmaintenance.py
  class MyTestCase (line 15) | class MyTestCase(unittest.TestCase):
    method setUp (line 16) | def setUp(self):
    method test_basic (line 32) | def test_basic(self):
    method test_empty (line 37) | def test_empty(self):
    method test_single (line 42) | def test_single(self):
    method test_even (line 47) | def test_even(self):
    method test_longer_example (line 52) | def test_longer_example(self):

FILE: Algorithm_tests/sorting_tests/test_sorting.py
  class test_sorting (line 42) | class test_sorting(unittest.TestCase):
    method test_bubblesort (line 43) | def test_bubblesort(self):
    method test_insertionsort (line 53) | def test_insertionsort(self):
    method test_mergesort (line 62) | def test_mergesort(self):
    method test_quicksort (line 71) | def test_quicksort(self):
    method test_selectionsort (line 88) | def test_selectionsort(self):
    method test_quicksort_randomized (line 97) | def test_quicksort_randomized(self):

FILE: Algorithms/cryptology/RSA_algorithm/RSA.py
  function generate_pq (line 15) | def generate_pq(bits):
  function generate_e (line 37) | def generate_e(totient):
  function generate_d (line 50) | def generate_d(e, totient):
  function generate_all_values (line 57) | def generate_all_values():
  function encrypt (line 70) | def encrypt(message, n, e):
  function decrypt (line 86) | def decrypt(encrypted, n, d):
  function example (line 100) | def example():
  function main (line 114) | def main():

FILE: Algorithms/cryptology/RSA_algorithm/euclid_gcd.py
  function extended_euclidean (line 11) | def extended_euclidean(a, b):

FILE: Algorithms/cryptology/ceasar_shifting_cipher/ceasar_shift_cipher.py
  function encrypt (line 25) | def encrypt(message, shift=3):
  function decrypt (line 36) | def decrypt(cipher, shift=3):

FILE: Algorithms/cryptology/hill_cipher/hill_cipher.py
  function matrix_mod_inv (line 25) | def matrix_mod_inv(matrix, modulus):
  function encrypt (line 41) | def encrypt(message, K):
  function decrypt (line 70) | def decrypt(cipher, Kinv):
  function main (line 94) | def main():

FILE: Algorithms/cryptology/one_time_pad/one_time_pad.py
  function xor (line 12) | def xor(s1, s2):
  function encrypt (line 21) | def encrypt(message, key):
  function decrypt (line 37) | def decrypt(cipher_text, key):
  function main (line 53) | def main():

FILE: Algorithms/cryptology/vigenere_cipher/vigenere.py
  function encrypt (line 21) | def encrypt(message, key):
  function decrypt (line 37) | def decrypt(cipher, key):
  function main (line 53) | def main():

FILE: Algorithms/dynamic_programming/knapsack/knapsack_bottomup.py
  function find_opt (line 13) | def find_opt(i, c, M, values, items, weights):
  function knapsack (line 27) | def knapsack(n, C, weights, values):

FILE: Algorithms/dynamic_programming/knapsack/knapsack_memoization_recursive_topdown.py
  function knapsack (line 12) | def knapsack(n, C, W, v, items, arr):

FILE: Algorithms/dynamic_programming/knapsack/knapsack_naive_recursive.py
  function knapsack (line 12) | def knapsack(n, C, W, v, items):

FILE: Algorithms/dynamic_programming/longest_increasing_subsequence.py
  function longest_increasing_subsequence (line 8) | def longest_increasing_subsequence(nums):

FILE: Algorithms/dynamic_programming/sequence_alignment.py
  class SequenceAlignment (line 22) | class SequenceAlignment(object):
    method __init__ (line 23) | def __init__(self, x, y):
    method find_solution (line 30) | def find_solution(self, OPT, m, n):
    method alignment (line 57) | def alignment(self):

FILE: Algorithms/dynamic_programming/weighted_interval_scheduling.py
  class WeightedIntervalScheduling (line 16) | class WeightedIntervalScheduling(object):
    method __init__ (line 17) | def __init__(self, I):
    method previous_intervals (line 22) | def previous_intervals(self):
    method find_solution (line 34) | def find_solution(self, j):
    method compute_opt (line 46) | def compute_opt(self, j):
    method weighted_interval (line 58) | def weighted_interval(self):

FILE: Algorithms/graphtheory/bellman-ford/bellman_ford.py
  function bellman_ford (line 13) | def bellman_ford(G, start):

FILE: Algorithms/graphtheory/breadth-first-search/BFS_queue_iterative.py
  function BFS (line 11) | def BFS(G, start_node=1):

FILE: Algorithms/graphtheory/depth-first-search/DFS_recursive.py
  function DFS (line 8) | def DFS(G, curr_node, visited):

FILE: Algorithms/graphtheory/depth-first-search/DFS_stack_iterative.py
  function DFS (line 11) | def DFS(G, start_node):

FILE: Algorithms/graphtheory/dijkstra/dijkstra.py
  function dijkstra (line 11) | def dijkstra(G, start, end):

FILE: Algorithms/graphtheory/dijkstra/heapdijkstra.py
  function make_graph (line 14) | def make_graph(file):
  function dijkstra (line 36) | def dijkstra(G, start, end=None):

FILE: Algorithms/graphtheory/floyd-warshall/floyd-warshall.py
  function load_graph (line 11) | def load_graph(file_name):
  function floyd_warshall (line 52) | def floyd_warshall(adj_matrix, next):
  function construct_path_to_take (line 71) | def construct_path_to_take(next, start, end):

FILE: Algorithms/graphtheory/kahns-toposort/kahn_topological_ordering.py
  function topological_ordering (line 17) | def topological_ordering(graph, degree_incoming):

FILE: Algorithms/graphtheory/kargers/kargermincut.py
  function load_graph (line 17) | def load_graph():
  function get_random_edge (line 28) | def get_random_edge(G):
  function karger_contraction (line 34) | def karger_contraction(G):
  function main (line 57) | def main():

FILE: Algorithms/graphtheory/kruskal/kruskal.py
  function load_graph (line 15) | def load_graph(file="edges.txt"):
  function kruskal (line 33) | def kruskal(G, num_nodes):

FILE: Algorithms/graphtheory/kruskal/kruskal_unionfind.py
  function load_graph (line 9) | def load_graph(file="edges.txt"):
  function kruskal (line 27) | def kruskal(G, num_nodes):

FILE: Algorithms/graphtheory/nearest-neighbor-tsp/NearestNeighborTSP.py
  function parseGraph (line 25) | def parseGraph(path):
  function rankNeighbors (line 45) | def rankNeighbors(node,adj):
  function nnTSP (line 63) | def nnTSP(adj):

FILE: Algorithms/graphtheory/prims/prim_heap.py
  function load_graph (line 15) | def load_graph(file="edges.txt"):
  function prims_algo (line 41) | def prims_algo(G, start=1):

FILE: Algorithms/graphtheory/prims/prim_naive.py
  function load_graph (line 11) | def load_graph(path="edges.txt"):
  function prims_algo (line 25) | def prims_algo(edge_list, num_nodes):

FILE: Algorithms/math/euclid_gcd/euclid_gcd.py
  function gcd_recursive (line 10) | def gcd_recursive(a, b):
  function gcd_iterative (line 17) | def gcd_iterative(a, b):

FILE: Algorithms/math/extended_euclidean_algorithm/euclid_gcd.py
  function extended_euclidean (line 11) | def extended_euclidean(a, b):

FILE: Algorithms/math/intersection_of_two_sets/intersection_of_two_sets.py
  function intersection (line 13) | def intersection(A, B):

FILE: Algorithms/math/karatsuba/karatsuba.py
  function karatsuba (line 9) | def karatsuba(x, y):

FILE: Algorithms/math/pollard_p1/pollard_p1.py
  function pollard_p1 (line 14) | def pollard_p1(n):

FILE: Algorithms/math/prime_factorization/primefactorization.py
  function primefactorization (line 14) | def primefactorization(n):

FILE: Algorithms/math/sieve_of_eratosthenes/sieve_eratosthenes.py
  function eratosthenes (line 7) | def eratosthenes(n):

FILE: Algorithms/math/union_of_two_sets/union_of_two_sets.py
  function union (line 13) | def union(A, B):

FILE: Algorithms/numerical_methods/bisection.py
  function function (line 10) | def function(x):
  function bisection (line 15) | def bisection(a0, b0, eps, delta, maxit):
  function main (line 57) | def main():

FILE: Algorithms/numerical_methods/fixpoint.py
  function function (line 10) | def function(x):
  function fixpoint (line 14) | def fixpoint(x0, tol):
  function main (line 25) | def main():

FILE: Algorithms/other/Huffman/Huffman.py
  class Node (line 5) | class Node(object):
    method __init__ (line 6) | def __init__(self, ch, freq, left=None, right=None):
    method __lt__ (line 12) | def __lt__(self, other):
  function make_frequency_dict (line 16) | def make_frequency_dict(file="huffman.txt"):
  function make_heap (line 32) | def make_heap(freq):
  function build_tree (line 41) | def build_tree(heap):
  function create_mapping (line 54) | def create_mapping(root, map={}, binarytext=""):
  function decode (line 70) | def decode(binarystring, root):
  function main (line 96) | def main():

FILE: Algorithms/other/Kadanes_algorithm.py
  function kadane_algorithm (line 12) | def kadane_algorithm(array):

FILE: Algorithms/other/binarysearch.py
  function binarysearch_iterative (line 11) | def binarysearch_iterative(L, target):
  function binarysearch_recursive (line 30) | def binarysearch_recursive(L, target, low, high):

FILE: Algorithms/other/counting_inversions.py
  function merge_sort (line 1) | def merge_sort(array):
  function merge_and_count (line 15) | def merge_and_count(left, right):

FILE: Algorithms/other/interval_scheduling.py
  function interval_scheduling (line 11) | def interval_scheduling(R, O):

FILE: Algorithms/other/median_maintenance.py
  class Maintain_Median (line 18) | class Maintain_Median(object):
    method __init__ (line 19) | def __init__(self):
    method medmain_insert (line 23) | def medmain_insert(self, x):
    method main (line 49) | def main(self, data):

FILE: Algorithms/sorting/bubblesort.py
  function bubblesort (line 11) | def bubblesort(L):

FILE: Algorithms/sorting/hopesort.py
  function hopesort (line 11) | def hopesort(L):

FILE: Algorithms/sorting/insertionsort.py
  function insertionsort (line 10) | def insertionsort(L):

FILE: Algorithms/sorting/mergesort.py
  function merge_sort (line 1) | def merge_sort(array):
  function merge (line 13) | def merge(left, right):

FILE: Algorithms/sorting/quicksort.py
  function quicksort_firstpivot (line 4) | def quicksort_firstpivot(L):
  function quicksort_lastpivot (line 27) | def quicksort_lastpivot(x):

FILE: Algorithms/sorting/randomized_quicksort.py
  function quicksort_randomized (line 14) | def quicksort_randomized(L):

FILE: Algorithms/sorting/selectionsort.py
  function selectionsort_intuitive (line 10) | def selectionsort_intuitive(L):
  function selectionsort (line 25) | def selectionsort(L):
Condensed preview — 88 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,649K chars).
[
  {
    "path": ".gitignore",
    "chars": 18,
    "preview": "plot_complexity.py"
  },
  {
    "path": ".travis.yml",
    "chars": 2223,
    "preview": "language: python\n\n# Default Python version is usually 2.7\npython: 3.7\n\n# Install ruby to get gem command\nbefore_install:"
  },
  {
    "path": "Algorithm_tests/cryptology_tests/ceasar_test.py",
    "chars": 1648,
    "preview": "# Import folder where sorting algorithms\nimport sys\nimport unittest\n\n# For importing from different folders\n# OBS: This "
  },
  {
    "path": "Algorithm_tests/dynamic_programming_tests/knapsack_tests/knapsack_bottomup_test.py",
    "chars": 2732,
    "preview": "import sys\nimport unittest\n\n# For importing from different folders\n# OBS: This is supposed to be done with automated tes"
  },
  {
    "path": "Algorithm_tests/dynamic_programming_tests/sequence_alignment/sequence_alignment_test.py",
    "chars": 3841,
    "preview": "import sys\nimport unittest\n\n# For importing from different folders\n# OBS: This is supposed to be done with automated tes"
  },
  {
    "path": "Algorithm_tests/dynamic_programming_tests/weighted_interval_scheduling/weighted_interval_scheduling_test.py",
    "chars": 4598,
    "preview": "import sys\nimport unittest\n\n# For importing from different folders\n# OBS: This is supposed to be done with automated tes"
  },
  {
    "path": "Algorithm_tests/graphtheory_tests/BFS_test.py",
    "chars": 2658,
    "preview": "# Import folder where sorting algorithms\nimport sys\nimport unittest\nfrom collections import deque\n\n# For importing from "
  },
  {
    "path": "Algorithm_tests/graphtheory_tests/DFS_test.py",
    "chars": 2628,
    "preview": "# Import folder where sorting algorithms\nimport sys\nimport unittest\nfrom collections import deque\n\n# For importing from "
  },
  {
    "path": "Algorithm_tests/graphtheory_tests/Djikstra/djikstra_heap_test.py",
    "chars": 1951,
    "preview": "# Import folder where sorting algorithms\nimport sys\nimport unittest\n\n# For importing from different folders\n# OBS: This "
  },
  {
    "path": "Algorithm_tests/graphtheory_tests/Djikstra/djikstra_naive_test.py",
    "chars": 1927,
    "preview": "# Import folder where sorting algorithms\nimport sys\nimport unittest\n\n# For importing from different folders\n# OBS: This "
  },
  {
    "path": "Algorithm_tests/graphtheory_tests/bellman_ford_test.py",
    "chars": 1762,
    "preview": "# Import folder where sorting algorithms\nimport sys\nimport unittest\n\n# For importing from different folders\n# OBS: This "
  },
  {
    "path": "Algorithm_tests/graphtheory_tests/kahn_topological_ordering_test.py",
    "chars": 2650,
    "preview": "# Import folder where sorting algorithms\nimport sys\nimport unittest\n\n# For importing from different folders\n# OBS: This "
  },
  {
    "path": "Algorithm_tests/graphtheory_tests/kruskal_unionfind_test.py",
    "chars": 2945,
    "preview": "# Import folder where sorting algorithms\nimport sys\nimport unittest\nfrom unionfind import unionfind\n\n# For importing fro"
  },
  {
    "path": "Algorithm_tests/graphtheory_tests/prims_algorithm_test.py",
    "chars": 2857,
    "preview": "# Import folder where sorting algorithms\nimport sys\nimport unittest\n\n# For importing from different folders\n# OBS: This "
  },
  {
    "path": "Algorithm_tests/graphtheory_tests/test_NN.py",
    "chars": 2291,
    "preview": "import unittest\nimport sys\n\n# Import from different folder\nsys.path.append(\"Algorithms/graphtheory/nearest-neighbor-tsp/"
  },
  {
    "path": "Algorithm_tests/graphtheory_tests/test_graph.txt",
    "chars": 24,
    "preview": "1 2,5 3,10\n2 4,-5\n3 4,15"
  },
  {
    "path": "Algorithm_tests/math_tests/intersection_test.py",
    "chars": 1885,
    "preview": "# Import folder where sorting algorithms\nimport sys\nimport unittest\n\n# For importing from different folders\n# OBS: This "
  },
  {
    "path": "Algorithm_tests/math_tests/union_test.py",
    "chars": 1847,
    "preview": "# Import folder where sorting algorithms\nimport sys\nimport unittest\n\n# For importing from different folders\n# OBS: This "
  },
  {
    "path": "Algorithm_tests/other_tests/test_binarysearch.py",
    "chars": 3934,
    "preview": "# Import folder where sorting algorithms\nimport sys\nimport unittest\n\n# For importing from different folders\n# OBS: This "
  },
  {
    "path": "Algorithm_tests/other_tests/test_intervalscheduling.py",
    "chars": 1809,
    "preview": "# Import folder where sorting algorithms\r\nimport sys\r\nimport unittest\r\n\r\n# For importing from different folders\r\n# OBS: "
  },
  {
    "path": "Algorithm_tests/other_tests/test_medianmaintenance.py",
    "chars": 1681,
    "preview": "# Import packages\r\nimport sys\r\nimport unittest\r\n\r\n# For importing from different folders\r\n# OBS: This is supposed to be "
  },
  {
    "path": "Algorithm_tests/sorting_tests/test_sorting.py",
    "chars": 4205,
    "preview": "# Import folder where sorting algorithms\nimport sys\nimport unittest\n\n# For importing from different folders\n# OBS: This "
  },
  {
    "path": "Algorithms/cryptology/RSA_algorithm/RSA.py",
    "chars": 4875,
    "preview": "\"\"\"\nPurpose of the RSA cryptosystem is to have a secure way of transmitting data\n\nProgrammed by Aladdin Persson <aladdin"
  },
  {
    "path": "Algorithms/cryptology/RSA_algorithm/euclid_gcd.py",
    "chars": 338,
    "preview": "\"\"\"\n\n\n\"\"\"\n\nimport sys\n\nsys.setrecursionlimit(100000)\n\n\ndef extended_euclidean(a, b):\n    if a == 0:\n        return (b, 0"
  },
  {
    "path": "Algorithms/cryptology/ceasar_shifting_cipher/ceasar_shift_cipher.py",
    "chars": 1474,
    "preview": "\"\"\"\nThe Ceasar cipher is one of the simplest and one of the earliest known ciphers.\nIt is a type of substitution cipher "
  },
  {
    "path": "Algorithms/cryptology/hill_cipher/hill_cipher.py",
    "chars": 3208,
    "preview": "\"\"\"\nImplementation of Hill Cipher!\n\nImportant notation:\nK = Matrix which is our 'Secret Key'\nP = Vector of plaintext (th"
  },
  {
    "path": "Algorithms/cryptology/one_time_pad/one_time_pad.py",
    "chars": 1533,
    "preview": "\"\"\"\nImplementation of the famous one time pad / Vernam Cipher\n\nIn practice we need a way to generate random keys which I"
  },
  {
    "path": "Algorithms/cryptology/vigenere_cipher/vigenere.py",
    "chars": 1729,
    "preview": "\"\"\"\nVigenère cipher is one of the simplest that employs a form of polyalphabetic substitution (each letter is assigned\nm"
  },
  {
    "path": "Algorithms/dynamic_programming/knapsack/knapsack_bottomup.py",
    "chars": 1957,
    "preview": "\"\"\"\nPurpose is if having a bunch of items with a weight and corresponding value to each object.\nWhich collection of obje"
  },
  {
    "path": "Algorithms/dynamic_programming/knapsack/knapsack_memoization_recursive_topdown.py",
    "chars": 1645,
    "preview": "# Memoization implementation Knapsack\n\n# Purpose is if having a bunch of items with a weight and corresponding value to "
  },
  {
    "path": "Algorithms/dynamic_programming/knapsack/knapsack_naive_recursive.py",
    "chars": 1538,
    "preview": "# \"Naive\" Implementation of the knapsack problem\n\n# Purpose is if having a bunch of items with a weight and correspondin"
  },
  {
    "path": "Algorithms/dynamic_programming/longest_increasing_subsequence.py",
    "chars": 712,
    "preview": "\"\"\"\nO(n^2) algorithm, can be faster and done in O(nlogn), but this works ok.\nTo do: Create extensive test cases before a"
  },
  {
    "path": "Algorithms/dynamic_programming/sequence_alignment.py",
    "chars": 2940,
    "preview": "\"\"\"\nAlgorithm for solving sequence alignment\nInput strings x,y of len(x) = m, len(y) = n and find minimum number of\nedit"
  },
  {
    "path": "Algorithms/dynamic_programming/weighted_interval_scheduling.py",
    "chars": 2464,
    "preview": "\"\"\"\nWeighted Interval Scheduling\nExplained YouTube video: https://www.youtube.com/watch?v=iIX1YvbLbvc\nImplementation wal"
  },
  {
    "path": "Algorithms/graphtheory/bellman-ford/bellman_ford.py",
    "chars": 1791,
    "preview": "\"\"\"\nPurpose is to find the shortest path between one source node to all other nodes using Bellman-Ford Algorithm.\nThe di"
  },
  {
    "path": "Algorithms/graphtheory/bellman-ford/data.txt",
    "chars": 32037,
    "preview": "1\t80,982\t163,8164\t170,2620\t145,648\t200,8021\t173,2069\t92,647\t26,4122\t140,546\t11,1913\t160,6461\t27,7905\t40,9047\t150,2183\t61"
  },
  {
    "path": "Algorithms/graphtheory/breadth-first-search/BFS_queue_iterative.py",
    "chars": 1299,
    "preview": "\"\"\"\nProgrammed by Aladdin Persson <aladdin.persson at hotmail dot com>\n    2019-02-17 Initial programming\n    2020-03-29"
  },
  {
    "path": "Algorithms/graphtheory/breadth-first-search/exgraph.txt",
    "chars": 18370,
    "preview": "1\t37\t79\t164\t155\t32\t87\t39\t113\t15\t18\t78\t175\t140\t200\t4\t160\t97\t191\t100\t91\t20\t69\t198\t196\t\n2\t123\t134\t10\t141\t13\t12\t43\t47\t3\t177\t"
  },
  {
    "path": "Algorithms/graphtheory/depth-first-search/DFS_recursive.py",
    "chars": 1198,
    "preview": "# Purpose of Depth first search is (mainly from my understanding) to find if a graph G is connected.\n# Identify all node"
  },
  {
    "path": "Algorithms/graphtheory/depth-first-search/DFS_stack_iterative.py",
    "chars": 1341,
    "preview": "\"\"\"\nDepth first search has many applications,for example finding if a graph G is connected.\nIdentify all nodes that are "
  },
  {
    "path": "Algorithms/graphtheory/depth-first-search/exgraph.txt",
    "chars": 18370,
    "preview": "1\t37\t79\t164\t155\t32\t87\t39\t113\t15\t18\t78\t175\t140\t200\t4\t160\t97\t191\t100\t91\t20\t69\t198\t196\t\n2\t123\t134\t10\t141\t13\t12\t43\t47\t3\t177\t"
  },
  {
    "path": "Algorithms/graphtheory/dijkstra/dijkstra.py",
    "chars": 1998,
    "preview": "\"\"\"\nDijkstra's algorithm for finding the shortest path in a graph, this implementation\nis a naive implementation, check "
  },
  {
    "path": "Algorithms/graphtheory/dijkstra/dijkstraData.txt",
    "chars": 32037,
    "preview": "1\t80,982\t163,8164\t170,2620\t145,648\t200,8021\t173,2069\t92,647\t26,4122\t140,546\t11,1913\t160,6461\t27,7905\t40,9047\t150,2183\t61"
  },
  {
    "path": "Algorithms/graphtheory/dijkstra/heapdijkstra.py",
    "chars": 2146,
    "preview": "\"\"\"\nDijkstra's algorithm for finding the shortest path.\nImproved version with the usage of heaps.\n\nProgrammed by Aladdin"
  },
  {
    "path": "Algorithms/graphtheory/floyd-warshall/floyd-warshall.py",
    "chars": 2572,
    "preview": "\"\"\"\nPurpose is to the find shortest path from all nodes to all other nodes, O(n^3).\nCan be used with negative weights, h"
  },
  {
    "path": "Algorithms/graphtheory/floyd-warshall/test_graph.txt",
    "chars": 26,
    "preview": "1 2,5 3,10\n2 4,-3\n3 4,20\n4"
  },
  {
    "path": "Algorithms/graphtheory/kahns-toposort/example.txt",
    "chars": 342,
    "preview": "Step C must be finished before step A can begin.\nStep C must be finished before step F can begin.\nStep A must be finishe"
  },
  {
    "path": "Algorithms/graphtheory/kahns-toposort/kahn_topological_ordering.py",
    "chars": 1986,
    "preview": "\"\"\"\nPurpose of this algorithm is finding a path that is in topological ordering for a directed acyclic graph (DAG).\nIf t"
  },
  {
    "path": "Algorithms/graphtheory/kargers/kargermincut.py",
    "chars": 1411,
    "preview": "# Purpose of Karger's algorithm is to compute the minimum cut of a connected graph.\n# If you have nodes connected to edg"
  },
  {
    "path": "Algorithms/graphtheory/kargers/kargermincutdata.txt",
    "chars": 18370,
    "preview": "1\t37\t79\t164\t155\t32\t87\t39\t113\t15\t18\t78\t175\t140\t200\t4\t160\t97\t191\t100\t91\t20\t69\t198\t196\t\n2\t123\t134\t10\t141\t13\t12\t43\t47\t3\t177\t"
  },
  {
    "path": "Algorithms/graphtheory/kruskal/edges.txt",
    "chars": 28291,
    "preview": "500 2184\n1 2 6807\n2 3 -8874\n3 4 -1055\n4 5 4414\n5 6 1728\n6 7 -2237\n7 8 -7507\n8 9 7990\n9 10 -5012\n10 11 7353\n11 12 -6736\n1"
  },
  {
    "path": "Algorithms/graphtheory/kruskal/kruskal.py",
    "chars": 1568,
    "preview": "\"\"\"\nKruskal's algorithm for finding minimal spanning tree (MST) of a graph.\n\nAladdin Persson <aladdin.persson at hotmail"
  },
  {
    "path": "Algorithms/graphtheory/kruskal/kruskal_unionfind.py",
    "chars": 1312,
    "preview": "# Kruskal's algorithm for finding minimal spanning tree (MST) of a graph. Using Union find datastructure\n\n# Aladdin Pers"
  },
  {
    "path": "Algorithms/graphtheory/kruskal/testedges.txt",
    "chars": 62,
    "preview": "7 8\n1 2 20\n1 3 10\n2 4 50\n3 5 25\n3 6 70\n5 6 100\n5 7 150\n6 5 100"
  },
  {
    "path": "Algorithms/graphtheory/nearest-neighbor-tsp/NearestNeighborTSP.py",
    "chars": 3564,
    "preview": "\"\"\"\nAuthor: Philip Andreadis\ne-mail: philip_andreadis@hotmail.com\n\n    This script implements a simple heuristic solver "
  },
  {
    "path": "Algorithms/graphtheory/nearest-neighbor-tsp/graph.txt",
    "chars": 49,
    "preview": "5\n0 1 2\n0 2 5\n0 4 3\n1 2 2\n1 3 4\n2 3 5\n2 4 5\n3 4 2"
  },
  {
    "path": "Algorithms/graphtheory/prims/edges.txt",
    "chars": 28291,
    "preview": "500 2184\n1 2 6807\n2 3 -8874\n3 4 -1055\n4 5 4414\n5 6 1728\n6 7 -2237\n7 8 -7507\n8 9 7990\n9 10 -5012\n10 11 7353\n11 12 -6736\n1"
  },
  {
    "path": "Algorithms/graphtheory/prims/prim_heap.py",
    "chars": 2528,
    "preview": "\"\"\"\nPrims algorithm for finding minimal spanning tree (MST) of a graph. Optimized version using Heaps!\nIf there is no MS"
  },
  {
    "path": "Algorithms/graphtheory/prims/prim_naive.py",
    "chars": 1797,
    "preview": "# Prims algorithm for finding minimal spanning tree (MST) of a graph\n\n# With this straightforward implementation: O(m * "
  },
  {
    "path": "Algorithms/math/euclid_gcd/euclid_gcd.py",
    "chars": 497,
    "preview": "# \"Euclidean algorithm is one of the oldest algorithms in common use\".\n# The purpose is to find the greatest common divi"
  },
  {
    "path": "Algorithms/math/extended_euclidean_algorithm/euclid_gcd.py",
    "chars": 337,
    "preview": "\"\"\"\n\n\n\"\"\"\n\nimport sys\n\nsys.setrecursionlimit(100000)\n\n\ndef extended_euclidean(a, b):\n    if a == 0:\n        return (b, 0"
  },
  {
    "path": "Algorithms/math/intersection_of_two_sets/intersection_of_two_sets.py",
    "chars": 971,
    "preview": "\"\"\"\nPurpose is given two sets A,B find the intersection of them. I know there must be more efficients ways than what I,\n"
  },
  {
    "path": "Algorithms/math/karatsuba/karatsuba.py",
    "chars": 1929,
    "preview": "# Purpose is to implement karatsuba multiplication, a way of computing\n# x * y which is faster than the normal method ta"
  },
  {
    "path": "Algorithms/math/pollard_p1/pollard_p1.py",
    "chars": 588,
    "preview": "\"\"\"\nPurpose is given a number write it only as a factorization of primes.\n\nTime complexity:\n\nProgrammed by Aladdin Perss"
  },
  {
    "path": "Algorithms/math/prime_factorization/primefactorization.py",
    "chars": 1235,
    "preview": "\"\"\"\nPurpose is given a number write it only as a factorization of primes.\n\nTime complexity: O(sqrt(n)) PSEUDO-POLYNOMIAL"
  },
  {
    "path": "Algorithms/math/sieve_of_eratosthenes/sieve_eratosthenes.py",
    "chars": 658,
    "preview": "# Purpose of this is to find primes from [2,n]\n\n# Programmed by Aladdin Persson <aladdin.persson at hotmail dot com>\n#  "
  },
  {
    "path": "Algorithms/math/union_of_two_sets/union_of_two_sets.py",
    "chars": 1038,
    "preview": "\"\"\"\nPurpose is given two sets A,B find the union of them. I know there must be more efficients ways than what I,\nam doin"
  },
  {
    "path": "Algorithms/numerical_methods/bisection.py",
    "chars": 1581,
    "preview": "\"\"\"\n# Purpose of the bisection method is to find an interval where there exists a root\n\n# Programmed by Aladdin Persson\n"
  },
  {
    "path": "Algorithms/numerical_methods/fixpoint.py",
    "chars": 526,
    "preview": "\"\"\"\n# Purpose of the fixpoint method is to solve equations of the form x = g(x)\n# Note that many equations can be rewrit"
  },
  {
    "path": "Algorithms/other/Huffman/Huffman.py",
    "chars": 2643,
    "preview": "import heapq\nfrom bitarray import bitarray\n\n\nclass Node(object):\n    def __init__(self, ch, freq, left=None, right=None)"
  },
  {
    "path": "Algorithms/other/Huffman/huffman.txt",
    "chars": 1269419,
    "preview": "The Project Gutenberg EBook of The Adventures of Sherlock Holmes\nby Sir Arthur Conan Doyle\n(#15 in our series by Sir Art"
  },
  {
    "path": "Algorithms/other/Huffman/test.txt",
    "chars": 9,
    "preview": "aaabbbcdd"
  },
  {
    "path": "Algorithms/other/Kadanes_algorithm.py",
    "chars": 599,
    "preview": "\"\"\"\nPurpose of the Kadane's Algorithm is to the find the sum of the maximum \ncontigous subarray of an array. Ex: [-2,1,-"
  },
  {
    "path": "Algorithms/other/binarysearch.py",
    "chars": 1371,
    "preview": "\"\"\"\nPurpose of this is to find a target element in an already sorted list L.\nWe use the fact that it is already sorted a"
  },
  {
    "path": "Algorithms/other/counting_inversions.py",
    "chars": 1230,
    "preview": "def merge_sort(array):\n    total_inversions = 0\n    if len(array) <= 1:\n        return (array, 0)\n\n    midpoint = int(le"
  },
  {
    "path": "Algorithms/other/interval_scheduling.py",
    "chars": 1349,
    "preview": "# Interval Scheduling, we have a set of requests R and we wish to choose\n# the maximum amount of non-overlapping interva"
  },
  {
    "path": "Algorithms/other/median_maintenance.py",
    "chars": 1739,
    "preview": "# Purpose of median_maintenance is given numbers, x then y, w, etc, maintain the median.\n\n# Programmed by Aladdin Persso"
  },
  {
    "path": "Algorithms/sorting/bubblesort.py",
    "chars": 631,
    "preview": "\"\"\"\nBubblesort sorting algorithm. This is not a very efficient sorting algorithm, T(n) = O(n^2).\n\nProgrammed by Aladdin "
  },
  {
    "path": "Algorithms/sorting/hopesort.py",
    "chars": 397,
    "preview": "\"\"\"\nHopesort algorithm. If it works, then it works in constant time.\nUse at own risk :)\n\nProgrammed by Aladdin Persson <"
  },
  {
    "path": "Algorithms/sorting/insertionsort.py",
    "chars": 681,
    "preview": "\"\"\"\nInsertion sort algorithm O(n^2).\n\nProgrammed by Aladdin Persson <aladdin.persson at hotmail dot com>\n*    2019-01-23"
  },
  {
    "path": "Algorithms/sorting/mergesort.py",
    "chars": 863,
    "preview": "def merge_sort(array):\n\n    if len(array) <= 1:\n        return array\n\n    midpoint = int(len(array) / 2)\n\n    left, righ"
  },
  {
    "path": "Algorithms/sorting/quicksort.py",
    "chars": 935,
    "preview": "# Quicksort with pivot always using first index as pivot\n\n\ndef quicksort_firstpivot(L):\n    if len(L) <= 1:\n        retu"
  },
  {
    "path": "Algorithms/sorting/randomized_quicksort.py",
    "chars": 1191,
    "preview": "\"\"\"\nPurpose is to sort a list. The reason why randomizing is better is that on average, regardless on the input\nrandomiz"
  },
  {
    "path": "Algorithms/sorting/selectionsort.py",
    "chars": 1047,
    "preview": "\"\"\"\nSelection sort algorithm. T(n) = O(n^2)\n\nProgrammed by Aladdin Persson <aladdin.persson at hotmail dot com>\n*    201"
  },
  {
    "path": "LICENSE",
    "chars": 1071,
    "preview": "MIT License\n\nCopyright (c) 2019 Aladdin Perzon\n\nPermission is hereby granted, free of charge, to any person obtaining a "
  },
  {
    "path": "README.md",
    "chars": 9109,
    "preview": "[![Build Status](https://travis-ci.com/AladdinPersson/Algorithms-Collection-Python.svg?branch=master)](https://travis-ci"
  },
  {
    "path": "requirements.txt",
    "chars": 75,
    "preview": "unionfind==0.0.10\nnumpy==1.18.1\nbitarray==1.2.1\negcd==0.0.1.1\nsympy==1.5.1\n"
  },
  {
    "path": "setup.py",
    "chars": 242,
    "preview": "from distutils.core import setup\n\nsetup(\n    name=\"Algorithms\",\n    packages=[\"Algorithm_test\"],\n    version=\"0.0.7\",\n  "
  }
]

About this extraction

This page contains the full source code of the aladdinpersson/Algorithms-Collection-Python GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 88 files (1.5 MB), approximately 425.1k tokens, and a symbol index with 245 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!