main ac7202880a53 cached
755 files
93.1 MB
16.4M tokens
1132 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (65,395K chars total). Download the full file to get everything.
Repository: dvklopfenstein/PrincetonAlgorithms
Branch: main
Commit: ac7202880a53
Files: 755
Total size: 93.1 MB

Directory structure:
gitextract__qej4jrm/

├── .gitignore
├── AlgsSedgewickWayne/
│   ├── .gitignore
│   ├── AcyclicLP.py
│   ├── AcyclicSP.py
│   ├── BST.py
│   ├── BST_utils.py
│   ├── BTree.py
│   ├── Bag.py
│   ├── BaseComp.py
│   ├── BellmanFordSP.py
│   ├── BinarySearch.py
│   ├── BoyerMoore.py
│   ├── BreadthFirstPaths.py
│   ├── CC.py
│   ├── CPM.py
│   ├── CollisionSystem.py
│   ├── Date.py
│   ├── DepthFirstDirectedPaths.py
│   ├── DepthFirstOrder.py
│   ├── DepthFirstPaths.py
│   ├── DepthFirstSearch.py
│   ├── Digraph.py
│   ├── DijkstraSP.py
│   ├── DirectedDFS.py
│   ├── DirectedEdge.py
│   ├── Edge.py
│   ├── EdgeWeightedDigraph.py
│   ├── EdgeWeightedDirectedCycle.py
│   ├── EdgeWeightedGraph.py
│   ├── FileIndex.py
│   ├── FlowEdge.py
│   ├── FlowNetwork.py
│   ├── FordFulkerson.py
│   ├── FrequencyCounter.py
│   ├── GREP.py
│   ├── GabowSCC.py
│   ├── GrahamScan.py
│   ├── Graph.py
│   ├── HTree.py
│   ├── Heap.py
│   ├── Insertion.py
│   ├── Interval1D.py
│   ├── KMP.py
│   ├── KosarajuSharirSCC.py
│   ├── KruskalMST.py
│   ├── LSD.py
│   ├── LazyPrimMST.py
│   ├── LinearProbingHashST.py
│   ├── LinearProgramming.py
│   ├── LinkedBag.py
│   ├── LinkedQueue.py
│   ├── LinkedStack.py
│   ├── LookupCSV.py
│   ├── MSD.py
│   ├── MST_check.py
│   ├── MaxPQ.py
│   ├── Merge.py
│   ├── MergeBU.py
│   ├── MergeX.py
│   ├── MinPQ.py
│   ├── NFA.py
│   ├── Particle.py
│   ├── Point2D.py
│   ├── PowerLaw.py
│   ├── PrimMST.py
│   ├── Queue.py
│   ├── Quick.py
│   ├── Quick3way.py
│   ├── QuickFindUF.py
│   ├── QuickUnionUF.py
│   ├── QuickX.py
│   ├── RabinKarp.py
│   ├── RedBlackBST.py
│   ├── ResizingArrayBag.py
│   ├── ResizingArrayQueue.py
│   ├── ResizingArrayStack.py
│   ├── SET.py
│   ├── ST.py
│   ├── Selection.py
│   ├── SeparateChainingHashST.py
│   ├── SequentialSearchST.py
│   ├── Shell.py
│   ├── SparseVector.py
│   ├── Stack.py
│   ├── StdIn.py
│   ├── TST.py
│   ├── TarjanSCC.py
│   ├── ThreeSum.py
│   ├── ThreeSumFast.py
│   ├── TopM.py
│   ├── Topological.py
│   ├── TopologicalX.py
│   ├── Transaction.py
│   ├── TrieST.py
│   ├── UnorderedArrayMaxPQ.py
│   ├── WeightedQuickUnionPlusUF.py
│   ├── WeightedQuickUnionUF.py
│   ├── Whitelist.py
│   ├── __init__.py
│   ├── digraph_dvk.py
│   ├── directed_dfs.py
│   ├── knuth_shuffle.py
│   ├── makefile
│   ├── nfa_dvk.py
│   ├── notes_Search_Problems.txt
│   ├── plt_regex_graph.py
│   ├── pylintrc
│   ├── substrsrc_bruteforce.py
│   ├── substrsrc_bruteforce_alt.py
│   ├── testcode/
│   │   ├── ArrayHistory.py
│   │   ├── InputArgs.py
│   │   ├── __init__.py
│   │   ├── binary_heaps.py
│   │   ├── chaining_table.py
│   │   ├── order.py
│   │   └── utils.py
│   └── utils.py
├── LICENSE
├── README.md
├── doc/
│   ├── README.md
│   ├── README_Analysis_of_Algorithms.md
│   ├── README_BST.md
│   ├── README_BST_geom.md
│   ├── README_Data_Compression.md
│   ├── README_Directed_Graphs.md
│   ├── README_ElemSymbolTbls.md
│   ├── README_Elementary_Sorts.md
│   ├── README_HashTables.md
│   ├── README_Intractability.md
│   ├── README_Intractability_details.md
│   ├── README_Linear_Programming.md
│   ├── README_Maximum_Flow_and_Minimum_Cut.md
│   ├── README_Mergesort.md
│   ├── README_Minimum_Spanning_Trees.md
│   ├── README_PriorityQueues.md
│   ├── README_Quicksort.md
│   ├── README_Radix_Sorts.md
│   ├── README_Reductions.md
│   ├── README_Regular_Expressions.md
│   ├── README_Shortest_Paths.md
│   ├── README_StacksQueues.md
│   ├── README_Substring_Search.md
│   ├── README_Tries.md
│   ├── README_Undirected_Graphs.md
│   ├── README_Union_Find.md
│   ├── README_analysis_summary.md
│   ├── discussions.txt
│   ├── scratchpad/
│   │   ├── Interview_Questions.txt
│   │   ├── PQ_doc.txt
│   │   ├── lec10.txt
│   │   ├── lecture_week3_Sorting_Complexity.txt
│   │   ├── notes
│   │   ├── notes.txt
│   │   ├── oog1.py
│   │   ├── wk1_ex_AnalysisOfAlgorithms_Q2.py
│   │   ├── wk1_ex_q2.py
│   │   └── wk2.txt
│   ├── video_toc.md
│   ├── wk1_ex_mem.txt
│   └── wk1_memory
├── makefile
├── notebooks/
│   ├── .gitignore
│   ├── ElemSymbolTbls.ipynb
│   └── makefile
├── py/
│   └── UnorderedMaxPQ.py
├── setup.py
├── tests/
│   ├── 1Kints.txt
│   ├── 2Kints.txt
│   ├── 4Kints.txt
│   ├── 8Kints.txt
│   ├── __init__.py
│   ├── brownian.txt
│   ├── diffusion.txt
│   ├── images/
│   │   └── README_figs.md
│   ├── largeW.txt
│   ├── makefile
│   ├── mediumG.txt
│   ├── plot_graphs.py
│   ├── shellsST.txt
│   ├── test_AcyclicSP.py
│   ├── test_BST.py
│   ├── test_BST_sortinput.py
│   ├── test_Bag.py
│   ├── test_BellmanFordSP.py
│   ├── test_BoyerMoore.py
│   ├── test_BreadthFirstPaths.py
│   ├── test_CC.py
│   ├── test_Date.py
│   ├── test_DepthFirstDirectedPaths.py
│   ├── test_DepthFirstPaths.py
│   ├── test_DepthFirstSearch.py
│   ├── test_Deque.py
│   ├── test_Digraph.py
│   ├── test_DijkstraSP.py
│   ├── test_DirectedDFS.py
│   ├── test_DirectedEdge.py
│   ├── test_Edge.py
│   ├── test_EdgeWeightedDigraph.py
│   ├── test_EdgeWeightedDirectedCycle.py
│   ├── test_EdgeWeightedGraph.py
│   ├── test_FlowEdge.py
│   ├── test_FlowNetwork.py
│   ├── test_FordFulkerson.py
│   ├── test_GREP.py
│   ├── test_Graph.py
│   ├── test_Heap.py
│   ├── test_Insertion.py
│   ├── test_Interval1D.py
│   ├── test_KMP.py
│   ├── test_KruskalMST.py
│   ├── test_LSD.py
│   ├── test_LazyPrimMST.py
│   ├── test_LinearProbingHashST.py
│   ├── test_LinearProgramming.py
│   ├── test_MSD.py
│   ├── test_MaxPQ.py
│   ├── test_Merge.py
│   ├── test_MergeBU.py
│   ├── test_MergeX.py
│   ├── test_MinPQ.py
│   ├── test_NFA.py
│   ├── test_Point2D.py
│   ├── test_PowerLaw.py
│   ├── test_PrimMST.py
│   ├── test_Queue.py
│   ├── test_Quick.py
│   ├── test_Quick3way.py
│   ├── test_QuickFindUF.py
│   ├── test_QuickUnionUF.py
│   ├── test_QuickX.py
│   ├── test_Quick_partition.py
│   ├── test_RabinKarp.py
│   ├── test_RandomizedQueue.py
│   ├── test_RandomizedQueueOrdered.py
│   ├── test_RedBlackBST.py
│   ├── test_ResizingArrayQueue.py
│   ├── test_ResizingArrayStack.py
│   ├── test_ST.py
│   ├── test_Selection.py
│   ├── test_SeparateChainingHashST.py
│   ├── test_SequentialSearchST.py
│   ├── test_Shell.py
│   ├── test_Sorting.py
│   ├── test_Stack.py
│   ├── test_TST.py
│   ├── test_Transaction.py
│   ├── test_TrieST.py
│   ├── test_UnorderedArrayMaxPQ.py
│   ├── test_WeightedQUF_state_pics.py
│   ├── test_WeightedQuickUnionPlusUF.py
│   ├── test_WeightedQuickUnionUF.py
│   ├── test_adjtxtblk2arr.py
│   ├── test_knuth_shuffle.py
│   ├── test_nfa_dvk.py
│   ├── test_quickfinduf_01a_03_11.py
│   ├── test_regex_is_exponential.py
│   ├── test_substr_search.py
│   ├── tinyBatch.txt
│   ├── tinyCG.txt
│   ├── tinyDAG.txt
│   ├── tinyDG.txt
│   ├── tinyDG2.txt
│   ├── tinyEWG.txt
│   ├── tinyG.txt
│   ├── tinyST.txt
│   ├── tinyT.txt
│   ├── tinyTale.txt
│   ├── tinyW.txt
│   ├── utils.py
│   ├── visualize_blktxt.py
│   └── words3.txt
└── thirdparty/
    ├── .gitignore
    ├── BouncingBalls.java
    ├── EvaluatePostfix.java
    ├── FileSorter.java
    ├── HelloWorld.java
    ├── README.md
    ├── UnorderedArrayMaxPQ.java
    ├── a2_hw1/
    │   ├── COS_226_Programming_Assignment_1_WordNet.html
    │   ├── Programming_Assignment_1_Checklist_WordNet.html
    │   └── wordnet/
    │       ├── digraph-ambiguous-ancestor.txt
    │       ├── digraph-wordnet.txt
    │       ├── digraph1.txt
    │       ├── digraph2.txt
    │       ├── digraph3.txt
    │       ├── digraph4.txt
    │       ├── digraph5.txt
    │       ├── digraph6.txt
    │       ├── digraph9.txt
    │       ├── hypernyms.txt
    │       ├── hypernyms100-subgraph.txt
    │       ├── hypernyms1000-subgraph.txt
    │       ├── hypernyms10000-subgraph.txt
    │       ├── hypernyms100K.txt
    │       ├── hypernyms11AmbiguousAncestor.txt
    │       ├── hypernyms11ManyPathsOneAncestor.txt
    │       ├── hypernyms15Path.txt
    │       ├── hypernyms15Tree.txt
    │       ├── hypernyms200K.txt
    │       ├── hypernyms300K.txt
    │       ├── hypernyms3InvalidCycle.txt
    │       ├── hypernyms3InvalidTwoRoots.txt
    │       ├── hypernyms500-subgraph.txt
    │       ├── hypernyms5000-subgraph.txt
    │       ├── hypernyms50000-subgraph.txt
    │       ├── hypernyms6InvalidCycle+Path.txt
    │       ├── hypernyms6InvalidCycle.txt
    │       ├── hypernyms6InvalidTwoRoots.txt
    │       ├── hypernyms6TwoAncestors.txt
    │       ├── hypernyms8ManyAncestors.txt
    │       ├── hypernyms8WrongBFS.txt
    │       ├── hypernymsManyPathsOneAncestor.txt
    │       ├── outcast10.txt
    │       ├── outcast10a.txt
    │       ├── outcast11.txt
    │       ├── outcast12.txt
    │       ├── outcast12a.txt
    │       ├── outcast17.txt
    │       ├── outcast2.txt
    │       ├── outcast20.txt
    │       ├── outcast29.txt
    │       ├── outcast3.txt
    │       ├── outcast4.txt
    │       ├── outcast5.txt
    │       ├── outcast5a.txt
    │       ├── outcast7.txt
    │       ├── outcast8.txt
    │       ├── outcast8a.txt
    │       ├── outcast8b.txt
    │       ├── outcast8c.txt
    │       ├── outcast9.txt
    │       ├── outcast9a.txt
    │       ├── synsets.txt
    │       ├── synsets100-subgraph.txt
    │       ├── synsets1000-subgraph.txt
    │       ├── synsets10000-subgraph.txt
    │       ├── synsets11.txt
    │       ├── synsets15.txt
    │       ├── synsets3.txt
    │       ├── synsets500-subgraph.txt
    │       ├── synsets5000-subgraph.txt
    │       ├── synsets50000-subgraph.txt
    │       ├── synsets6.txt
    │       └── synsets8.txt
    ├── a2_hw2/
    │   ├── Programming_Assignment_2_Checklist_Seam_Carving.html
    │   ├── Programming_Assignment_2_Seam_Carving.html
    │   └── seamCarving/
    │       ├── 10x10.printseams.txt
    │       ├── 10x12.printseams.txt
    │       ├── 12x10.printseams.txt
    │       ├── 3x4.printseams.txt
    │       ├── 3x7.printseams.txt
    │       ├── 4x6.printseams.txt
    │       ├── 5x6.printseams.txt
    │       ├── 6x5.printseams.txt
    │       ├── 7x10.printseams.txt
    │       ├── 7x3.printseams.txt
    │       ├── PrintEnergy.java
    │       ├── PrintSeams.java
    │       ├── ResizeDemo.java
    │       ├── SCUtility.java
    │       ├── ShowEnergy.java
    │       ├── ShowSeams.java
    │       ├── diagonals.printseams.txt
    │       └── stripes.printseams.txt
    ├── a2_hw3/
    │   ├── Programming_Assignment_3_Baseball_Elimination.html
    │   ├── Programming_Assignment_Checklist_Baseball_Elimination.html
    │   └── baseball/
    │       ├── readme.txt
    │       ├── teams1.txt
    │       ├── teams10.txt
    │       ├── teams12-allgames.txt
    │       ├── teams12.txt
    │       ├── teams24.txt
    │       ├── teams29.txt
    │       ├── teams30.txt
    │       ├── teams32.txt
    │       ├── teams36.txt
    │       ├── teams4.txt
    │       ├── teams42.txt
    │       ├── teams48.txt
    │       ├── teams4a.txt
    │       ├── teams4b.txt
    │       ├── teams5.txt
    │       ├── teams50.txt
    │       ├── teams54.txt
    │       ├── teams5a.txt
    │       ├── teams5b.txt
    │       ├── teams5c.txt
    │       ├── teams60.txt
    │       ├── teams7.txt
    │       └── teams8.txt
    ├── a2_hw4/
    │   ├── Programming_Assignment_4_Boggle.html
    │   ├── Programming_Assignment_Checklist_Boggle.html
    │   └── boggle/
    │       ├── BoggleBoard.java
    │       ├── BoggleGame.java
    │       ├── board-16q.txt
    │       ├── board-antidisestablishmentarianisms.txt
    │       ├── board-aqua.txt
    │       ├── board-couscous.txt
    │       ├── board-diagonal.txt
    │       ├── board-dichlorodiphenyltrichloroethanes.txt
    │       ├── board-dodo.txt
    │       ├── board-estrangers.txt
    │       ├── board-horizontal.txt
    │       ├── board-inconsequentially.txt
    │       ├── board-noon.txt
    │       ├── board-pneumonoultramicroscopicsilicovolcanoconiosis.txt
    │       ├── board-points0.txt
    │       ├── board-points1.txt
    │       ├── board-points100.txt
    │       ├── board-points1000.txt
    │       ├── board-points1111.txt
    │       ├── board-points1250.txt
    │       ├── board-points13464.txt
    │       ├── board-points1500.txt
    │       ├── board-points2.txt
    │       ├── board-points200.txt
    │       ├── board-points2000.txt
    │       ├── board-points26539.txt
    │       ├── board-points3.txt
    │       ├── board-points300.txt
    │       ├── board-points4.txt
    │       ├── board-points400.txt
    │       ├── board-points4410.txt
    │       ├── board-points4527.txt
    │       ├── board-points4540.txt
    │       ├── board-points5.txt
    │       ├── board-points500.txt
    │       ├── board-points750.txt
    │       ├── board-points777.txt
    │       ├── board-q.txt
    │       ├── board-quinquevalencies.txt
    │       ├── board-qwerty.txt
    │       ├── board-rotavator.txt
    │       ├── board-vertical.txt
    │       ├── board4x4.txt
    │       ├── dictionary-16q.txt
    │       ├── dictionary-2letters.txt
    │       ├── dictionary-algs4.txt
    │       ├── dictionary-common.txt
    │       ├── dictionary-enable2k.txt
    │       ├── dictionary-nursery.txt
    │       ├── dictionary-shakespeare.txt
    │       ├── dictionary-sowpods.txt
    │       ├── dictionary-twl06.txt
    │       ├── dictionary-yawl.txt
    │       └── dictionary-zingarelli2005.txt
    ├── a2_hw5/
    │   ├── Programming_Assignment_5_Burrows_Wheeler_Data_Compression_Algorithm.html
    │   ├── Programming_Assignment_Checklist_Burrows_Wheeler_Data_Compression.html
    │   └── burrows/
    │       ├── a.txt
    │       ├── abra.txt
    │       ├── abra.txt.bwt
    │       ├── abra.txt.bwt.mtf.huf
    │       ├── abra.txt.huf
    │       ├── abra.txt.mtf
    │       ├── aesop.txt
    │       ├── aesop.txt.bwt
    │       ├── aesop.txt.bwt.mtf.huf
    │       ├── aesop.txt.huf
    │       ├── aesop.txt.mtf
    │       ├── alphanum.txt
    │       ├── amendments.txt
    │       ├── cadabra.txt
    │       ├── couscous.txt
    │       ├── encodedSecretMessage.txt
    │       ├── stars.txt
    │       ├── us.gif.bwt
    │       ├── us.gif.bwt.mtf.huf
    │       ├── us.gif.huf
    │       ├── us.gif.mtf
    │       └── zebra.txt
    ├── algs4.jar
    ├── hw1/
    │   ├── Programming_Assignment_1_Checklist_Percolation.html
    │   ├── Programming_Assignment_1_Percolation.html
    │   └── percolation/
    │       ├── CREDITS
    │       ├── InteractivePercolationVisualizer.java
    │       ├── PercolationVisualizer.java
    │       ├── greeting57.txt
    │       ├── heart25.txt
    │       ├── input1-no.txt
    │       ├── input1.txt
    │       ├── input10-no.txt
    │       ├── input10.txt
    │       ├── input2-no.txt
    │       ├── input2.txt
    │       ├── input20.txt
    │       ├── input3.txt
    │       ├── input4.txt
    │       ├── input5.txt
    │       ├── input50.txt
    │       ├── input6.txt
    │       ├── input7.txt
    │       ├── input8-no.txt
    │       ├── input8.txt
    │       ├── jerry47.txt
    │       ├── sedgewick60.txt
    │       └── wayne98.txt
    ├── hw2/
    │   ├── Programming_Assignment_2_Checklist_Randomized_Queues_and_Dequeues.html
    │   └── Programming_Assignment_2_Randomized_Queues_and_Deques.html
    ├── hw3/
    │   ├── Programming_Assignment_3_Checklist_Pattern_Recognition.html
    │   ├── Programming_Assignment_3_Pattern_Recognition_Assignment.html
    │   └── collinear/
    │       ├── LineSegment.java
    │       ├── equidistant.txt
    │       ├── grid4x4.txt
    │       ├── grid5x5.txt
    │       ├── grid6x6.txt
    │       ├── horizontal100.txt
    │       ├── horizontal25.txt
    │       ├── horizontal5.txt
    │       ├── horizontal50.txt
    │       ├── horizontal75.txt
    │       ├── inarow.txt
    │       ├── input1.txt
    │       ├── input10.txt
    │       ├── input100.txt
    │       ├── input1000.txt
    │       ├── input10000.txt
    │       ├── input150.txt
    │       ├── input2.txt
    │       ├── input20.txt
    │       ├── input200.txt
    │       ├── input2000.txt
    │       ├── input250.txt
    │       ├── input299.txt
    │       ├── input3.txt
    │       ├── input300.txt
    │       ├── input3000.txt
    │       ├── input350.txt
    │       ├── input40.txt
    │       ├── input400.txt
    │       ├── input4000.txt
    │       ├── input48.txt
    │       ├── input50.txt
    │       ├── input5000.txt
    │       ├── input56.txt
    │       ├── input6.txt
    │       ├── input6000.txt
    │       ├── input8.txt
    │       ├── input80.txt
    │       ├── input8000.txt
    │       ├── input9.txt
    │       ├── kw1260.txt
    │       ├── mystery10089.txt
    │       ├── random152.txt
    │       ├── random23.txt
    │       ├── random38.txt
    │       ├── random91.txt
    │       ├── rs1423.txt
    │       ├── vertical100.txt
    │       ├── vertical25.txt
    │       ├── vertical5.txt
    │       ├── vertical50.txt
    │       └── vertical75.txt
    ├── hw4/
    │   ├── 8-Puzzle_Programming_Assignment.html
    │   ├── 8puzzle/
    │   │   ├── PuzzleChecker.java
    │   │   ├── puzzle00.txt
    │   │   ├── puzzle01.txt
    │   │   ├── puzzle02.txt
    │   │   ├── puzzle03.txt
    │   │   ├── puzzle04.txt
    │   │   ├── puzzle04_goal.txt
    │   │   ├── puzzle05.txt
    │   │   ├── puzzle06.txt
    │   │   ├── puzzle07.txt
    │   │   ├── puzzle08.txt
    │   │   ├── puzzle09.txt
    │   │   ├── puzzle10.txt
    │   │   ├── puzzle11.txt
    │   │   ├── puzzle12.txt
    │   │   ├── puzzle13.txt
    │   │   ├── puzzle14.txt
    │   │   ├── puzzle15.txt
    │   │   ├── puzzle16.txt
    │   │   ├── puzzle17.txt
    │   │   ├── puzzle18.txt
    │   │   ├── puzzle19.txt
    │   │   ├── puzzle20.txt
    │   │   ├── puzzle21.txt
    │   │   ├── puzzle22.txt
    │   │   ├── puzzle23.txt
    │   │   ├── puzzle24.txt
    │   │   ├── puzzle25.txt
    │   │   ├── puzzle26.txt
    │   │   ├── puzzle27.txt
    │   │   ├── puzzle28.txt
    │   │   ├── puzzle29.txt
    │   │   ├── puzzle2x2-00.txt
    │   │   ├── puzzle2x2-01.txt
    │   │   ├── puzzle2x2-02.txt
    │   │   ├── puzzle2x2-03.txt
    │   │   ├── puzzle2x2-04.txt
    │   │   ├── puzzle2x2-05.txt
    │   │   ├── puzzle2x2-06.txt
    │   │   ├── puzzle2x2-unsolvable1.txt
    │   │   ├── puzzle2x2-unsolvable2.txt
    │   │   ├── puzzle2x2-unsolvable3.txt
    │   │   ├── puzzle30.txt
    │   │   ├── puzzle31.txt
    │   │   ├── puzzle32.txt
    │   │   ├── puzzle33.txt
    │   │   ├── puzzle34.txt
    │   │   ├── puzzle35.txt
    │   │   ├── puzzle36.txt
    │   │   ├── puzzle37.txt
    │   │   ├── puzzle38.txt
    │   │   ├── puzzle39.txt
    │   │   ├── puzzle3x3-00.txt
    │   │   ├── puzzle3x3-01.txt
    │   │   ├── puzzle3x3-02.txt
    │   │   ├── puzzle3x3-03.txt
    │   │   ├── puzzle3x3-04.txt
    │   │   ├── puzzle3x3-05.txt
    │   │   ├── puzzle3x3-06.txt
    │   │   ├── puzzle3x3-07.txt
    │   │   ├── puzzle3x3-08.txt
    │   │   ├── puzzle3x3-09.txt
    │   │   ├── puzzle3x3-10.txt
    │   │   ├── puzzle3x3-11.txt
    │   │   ├── puzzle3x3-12.txt
    │   │   ├── puzzle3x3-13.txt
    │   │   ├── puzzle3x3-14.txt
    │   │   ├── puzzle3x3-15.txt
    │   │   ├── puzzle3x3-16.txt
    │   │   ├── puzzle3x3-17.txt
    │   │   ├── puzzle3x3-18.txt
    │   │   ├── puzzle3x3-19.txt
    │   │   ├── puzzle3x3-20.txt
    │   │   ├── puzzle3x3-21.txt
    │   │   ├── puzzle3x3-22.txt
    │   │   ├── puzzle3x3-23.txt
    │   │   ├── puzzle3x3-24.txt
    │   │   ├── puzzle3x3-25.txt
    │   │   ├── puzzle3x3-26.txt
    │   │   ├── puzzle3x3-27.txt
    │   │   ├── puzzle3x3-28.txt
    │   │   ├── puzzle3x3-29.txt
    │   │   ├── puzzle3x3-30.txt
    │   │   ├── puzzle3x3-31.txt
    │   │   ├── puzzle3x3-unsolvable.txt
    │   │   ├── puzzle3x3-unsolvable1.txt
    │   │   ├── puzzle3x3-unsolvable2.txt
    │   │   ├── puzzle40.txt
    │   │   ├── puzzle41.txt
    │   │   ├── puzzle42.txt
    │   │   ├── puzzle43.txt
    │   │   ├── puzzle44.txt
    │   │   ├── puzzle45.txt
    │   │   ├── puzzle46.txt
    │   │   ├── puzzle47.txt
    │   │   ├── puzzle48.txt
    │   │   ├── puzzle49.txt
    │   │   ├── puzzle4x4-00.txt
    │   │   ├── puzzle4x4-01.txt
    │   │   ├── puzzle4x4-02.txt
    │   │   ├── puzzle4x4-03.txt
    │   │   ├── puzzle4x4-04.txt
    │   │   ├── puzzle4x4-05.txt
    │   │   ├── puzzle4x4-06.txt
    │   │   ├── puzzle4x4-07.txt
    │   │   ├── puzzle4x4-08.txt
    │   │   ├── puzzle4x4-09.txt
    │   │   ├── puzzle4x4-10.txt
    │   │   ├── puzzle4x4-11.txt
    │   │   ├── puzzle4x4-12.txt
    │   │   ├── puzzle4x4-13.txt
    │   │   ├── puzzle4x4-14.txt
    │   │   ├── puzzle4x4-15.txt
    │   │   ├── puzzle4x4-16.txt
    │   │   ├── puzzle4x4-17.txt
    │   │   ├── puzzle4x4-18.txt
    │   │   ├── puzzle4x4-19.txt
    │   │   ├── puzzle4x4-20.txt
    │   │   ├── puzzle4x4-21.txt
    │   │   ├── puzzle4x4-22.txt
    │   │   ├── puzzle4x4-23.txt
    │   │   ├── puzzle4x4-24.txt
    │   │   ├── puzzle4x4-25.txt
    │   │   ├── puzzle4x4-26.txt
    │   │   ├── puzzle4x4-27.txt
    │   │   ├── puzzle4x4-28.txt
    │   │   ├── puzzle4x4-29.txt
    │   │   ├── puzzle4x4-30.txt
    │   │   ├── puzzle4x4-31.txt
    │   │   ├── puzzle4x4-32.txt
    │   │   ├── puzzle4x4-33.txt
    │   │   ├── puzzle4x4-34.txt
    │   │   ├── puzzle4x4-35.txt
    │   │   ├── puzzle4x4-36.txt
    │   │   ├── puzzle4x4-37.txt
    │   │   ├── puzzle4x4-38.txt
    │   │   ├── puzzle4x4-39.txt
    │   │   ├── puzzle4x4-40.txt
    │   │   ├── puzzle4x4-41.txt
    │   │   ├── puzzle4x4-42.txt
    │   │   ├── puzzle4x4-43.txt
    │   │   ├── puzzle4x4-44.txt
    │   │   ├── puzzle4x4-45.txt
    │   │   ├── puzzle4x4-46.txt
    │   │   ├── puzzle4x4-47.txt
    │   │   ├── puzzle4x4-48.txt
    │   │   ├── puzzle4x4-49.txt
    │   │   ├── puzzle4x4-50.txt
    │   │   ├── puzzle4x4-78.txt
    │   │   ├── puzzle4x4-80.txt
    │   │   ├── puzzle4x4-unsolvable.txt
    │   │   └── puzzle50.txt
    │   └── Programming_Assignment_4_Checklist_8_Puzzle.html
    ├── hw5/
    │   ├── NearestNeighborVisualizer.java
    │   ├── Programming_Assignment_5_Checklist_Kd-Trees.html
    │   ├── Programming_Assignment_5_Kd-Trees.html
    │   ├── RangeSearchVisualizer.java
    │   └── kdtree/
    │       ├── KdTreeGenerator.java
    │       ├── KdTreeVisualizer.java
    │       ├── NearestNeighborVisualizer.java
    │       ├── RangeSearchVisualizer.java
    │       ├── circle10.txt
    │       ├── circle100.txt
    │       ├── circle1000.txt
    │       ├── circle10000.txt
    │       ├── circle10k.txt
    │       ├── circle4.txt
    │       ├── horizontal8.txt
    │       ├── input100K.txt
    │       ├── input10K.txt
    │       ├── input1M.txt
    │       ├── input200K.txt
    │       ├── input20K.txt
    │       ├── input400K.txt
    │       ├── input40K.txt
    │       ├── input800K.txt
    │       ├── input80K.txt
    │       └── vertical7.txt
    ├── java2tmp.py
    ├── makefile
    ├── test/
    │   └── percolation/
    │       ├── CREDITS
    │       ├── greeting57.txt
    │       ├── heart25.txt
    │       ├── input1-no.txt
    │       ├── input1.txt
    │       ├── input10-no.txt
    │       ├── input10.txt
    │       ├── input2-no.txt
    │       ├── input2.txt
    │       ├── input20.txt
    │       ├── input3.txt
    │       ├── input4.txt
    │       ├── input5.txt
    │       ├── input50.txt
    │       ├── input6.txt
    │       ├── input7.txt
    │       ├── input8-no.txt
    │       ├── input8.txt
    │       ├── jerry47.txt
    │       ├── sedgewick60.txt
    │       └── wayne98.txt
    └── test_RandomizedQueue.java

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

================================================
FILE: .gitignore
================================================
/*.png

thirdparty/percolation.zip
thirdparty/PercolationStats.java
thirdparty/Percolation.java
py/AlgsSedgewickWayne/Percolation.py
py/AlgsSedgewickWayne/PercolationStats.py

# Programming Assignment 1.2
thirdparty/queues.zip
thirdparty/Deque.java
thirdparty/RandomizedQueue.java
thirdparty/Subset.java
py/AlgsSedgewickWayne/Deque.py
py/AlgsSedgewickWayne/RandomizedQueue.py
py/AlgsSedgewickWayne/Subset.py

# Programming Assignment 1.3
thirdparty/collinear.zip
thirdparth/Point.java
thirdparth/Brute.java
thirdparth/Fast.java
py/AlgsSedgewickWayne/Point.py
py/AlgsSedgewickWayne/Brute.py
py/AlgsSedgewickWayne/Fast.py

# Programming Assignment 1.4
thirdparty/8puzzle.zip
thirdparty/Board.java
thirdparty/Solver.java
py/AlgsSedgewickWayne/Board.py
py/AlgsSedgewickWayne/Solver.py

# Programming Assignment 1.5
thirdparty/kdtree.zip
thirdparty/PointSET.java
thirdparty/KdTree.java
py/AlgsSedgewickWayne/PointSET.py
py/AlgsSedgewickWayne/KdTree.py

# Programming Assignment 2.1: WordNet
thirdparty/wordnet.zip
thirdparty/SAP.java
thirdparty/WordNet.java
thirdparty/Outcast.java
py/AlgsSedgewickWayne/SAP.py
py/AlgsSedgewickWayne/WordNet.py
py/AlgsSedgewickWayne/Outcast.py

# Programming Assignment 2.2: Content-Aware Resizing
thirdparty/seamCarving.zip
thirdparty/SeamCarver.java
py/AlgsSedgewickWayne/SeamCarver.py

# Programming Assignment 2.3: Baseball Elimination
thirdparty/baseball.zip
thirdparty/BaseballElimination.java
py/AlgsSedgewickWayne/BaseballElimination.py

# Programming Assignment 2.4: Boggle
thirdparty/boggle.zip
thirdparty/BoggleSolver.java
py/AlgsSedgewickWayne/BoggleSolver.py

# Programming Assignment 2.5: BurrowsWheeler
thirdparty/burrows.zip
thirdparty/MoveToFront.java
thirdparty/BurrowsWheeler.java
thirdparty/CircularSuffixArrag.java
py/AlgsSedgewickWayne/MoveToFront.py
py/AlgsSedgewickWayne/BurrowsWheeler.py
py/AlgsSedgewickWayne/CircularSuffixArrag.py

# Temporary files
tmp*

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

# C extensions
*.so

# Distribution / packaging
.Python
env/
bin/
build/
develop-eggs/
dist/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

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

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml

# Translations
*.mo

# Mr Developer
.mr.developer.cfg
.project
.pydevproject

# Rope
.ropeproject

# Django stuff:
*.log
*.pot

# Sphinx documentation
docs/_build/



================================================
FILE: AlgsSedgewickWayne/.gitignore
================================================
tmp*

# Algs 1, wk1
Percolation.py
PercolationStats.py

# Algs 1, wk2
Deque.py 
RandomizedQueue.py 
Subset.py

# Algs 1, wk3
Point.py
BruteCollinearPoints.py
FastCollinearPoints.py

# Algs 1, week 4
Board.py
Solver.py

# Algs 1, week 5
PointSET.py
KdTree.py



================================================
FILE: AlgsSedgewickWayne/AcyclicLP.py
================================================
#*****************************************************************************
 #  Compilation:  javac AcyclicLP.java
 #  Execution:    java AcyclicP V E
 #  Dependencies: EdgeWeightedDigraph.java DirectedEdge.java Topological.java
 #  Data files:   http://algs4.cs.princeton.edu/44sp/tinyEWDAG.txt
 #  
 #  Computes longeset paths in an edge-weighted acyclic digraph.
 #
 #  Remark: should probably check that graph is a DAG before running
 #
 #  % java AcyclicLP tinyEWDAG.txt 5
 #  5 to 0 (2.44)  5->1  0.32   1->3  0.29   3->6  0.52   6->4  0.93   4->0  0.38   
 #  5 to 1 (0.32)  5->1  0.32   
 #  5 to 2 (2.77)  5->1  0.32   1->3  0.29   3->6  0.52   6->4  0.93   4->7  0.37   7->2  0.34   
 #  5 to 3 (0.61)  5->1  0.32   1->3  0.29   
 #  5 to 4 (2.06)  5->1  0.32   1->3  0.29   3->6  0.52   6->4  0.93   
 #  5 to 5 (0.00)  
 #  5 to 6 (1.13)  5->1  0.32   1->3  0.29   3->6  0.52   
 #  5 to 7 (2.43)  5->1  0.32   1->3  0.29   3->6  0.52   6->4  0.93   4->7  0.37   
 #
 #*****************************************************************************/

package edu.princeton.cs.algs4

#*
 #  The <tt>AcyclicLP</tt> class represents a data type for solving the
 #  single-source longest paths problem in edge-weighted directed
 #  acyclic graphs (DAGs). The edge weights can be positive, negative, or zero.
 #  <p>
 #  This implementation uses a topological-sort based algorithm.
 #  The constructor takes time proportional to <em>V</em> + <em>E</em>,
 #  where <em>V</em> is the number of vertices and <em>E</em> is the number of edges.
 #  Afterwards, the <tt>distTo()</tt> and <tt>hasPathTo()</tt> methods take
 #  constant time and the <tt>pathTo()</tt> method takes time proportional to the
 #  number of edges in the longest path returned.
 #  <p>
 #  For additional documentation,   
 #  see <a href="http://algs4.cs.princeton.edu/44sp">Section 4.4</a> of   
 #  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 #
 #  @author Robert Sedgewick
 #  @author Kevin Wayne
 #/
public class AcyclicLP:
  private double[] distTo;          # distTo[v] = distance  of longest s->v path
  private DirectedEdge[] edgeTo;    # edgeTo[v] = last edge on longest s->v path

    #*
     # Computes a longest paths tree from <tt>s</tt> to every other vertex in
     # the directed acyclic graph <tt>G</tt>.
     # @param G the acyclic digraph
     # @param s the source vertex
     # @throws IllegalArgumentException if the digraph is not acyclic
     # @throws IllegalArgumentException unless 0 &le; <tt>s</tt> &le; <tt>V</tt> - 1
     #/
  public AcyclicLP(EdgeWeightedDigraph G, s):
      distTo = new double[G.V()]
      edgeTo = new DirectedEdge[G.V()]
      for (int v = 0; v < G.V(); v += 1)
          distTo[v] = Double.NEGATIVE_INFINITY
      distTo[s] = 0.0

      # relax vertices in toplogical order
      Topological topological = new Topological(G)
      if !topological.hasOrder())
          raise new IllegalArgumentException("Digraph is not acyclic.")
      for (int v : topological.order()):
          for (DirectedEdge e : G.adj(v))
              relax(e)

  # relax edge e, but update if you find a *longer* path
  def _relax(DirectedEdge e):
      v = e.from(), w = e.to()
      if distTo[w] < distTo[v] + e.weight()):
          distTo[w] = distTo[v] + e.weight()
          edgeTo[w] = e

    #*
     # Returns the length of a longest path from the source vertex <tt>s</tt> to vertex <tt>v</tt>.
     # @param v the destination vertex
     # @return the length of a longest path from the source vertex <tt>s</tt> to vertex <tt>v</tt>;
     #    <tt>Double.NEGATIVE_INFINITY</tt> if no such path
     #/
  def distTo(int v):
      return distTo[v]

    #*
     # Is there a path from the source vertex <tt>s</tt> to vertex <tt>v</tt>?
     # @param v the destination vertex
     # @return <tt>true</tt> if there is a path from the source vertex
     #    <tt>s</tt> to vertex <tt>v</tt>, and <tt>false</tt> otherwise
     #/
  def hasPathTo(int v):
      return distTo[v] > Double.NEGATIVE_INFINITY

    #*
     # Returns a longest path from the source vertex <tt>s</tt> to vertex <tt>v</tt>.
     # @param v the destination vertex
     # @return a longest path from the source vertex <tt>s</tt> to vertex <tt>v</tt>
     #    as an iterable of edges, and <tt>null</tt> if no such path
     #/
  def pathTo(int v):
      if !hasPathTo(v)) return None
      Stack<DirectedEdge> path = new Stack<DirectedEdge>()
      for (DirectedEdge e = edgeTo[v]; e is not None; e = edgeTo[e.from()]):
          path.push(e)
      return path



    #*
     # Unit tests the <tt>AcyclicLP</tt> data type.
     #/
  def main(String[] args):
      In in = new In(args[0])
      s = Integer.parseInt(args[1])
      EdgeWeightedDigraph G = new EdgeWeightedDigraph(in)

      AcyclicLP lp = new AcyclicLP(G, s)

      for (int v = 0; v < G.V(); v += 1):
          if lp.hasPathTo(v)):
              StdOut.printf("%d to %d (%.2f)  ", s, v, lp.distTo(v))
              for (DirectedEdge e : lp.pathTo(v)):
                  StdOut.print(e + "   ")
              prt.write()
          else:
              StdOut.printf("%d to %d         no path\n", s, v)

#*****************************************************************************
 #  Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
 #
 #  This file is part of algs4.jar, which accompanies the textbook
 #
 #      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 #      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 #      http://algs4.cs.princeton.edu
 #
 #
 #  algs4.jar is free software: you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
 #  the Free Software Foundation, either version 3 of the License, or
 #  (at your option) any later version.
 #
 #  algs4.jar is distributed in the hope that it will be useful,
 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #  GNU General Public License for more details.
 #
 #  You should have received a copy of the GNU General Public License
 #  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 #*****************************************************************************/


================================================
FILE: AlgsSedgewickWayne/AcyclicSP.py
================================================
"""Solve single-source shortest paths problem in edge-weighted DAG"""
# TBD: Finish Python port

from AlgsSedgewickWayne.DirectedEdge import DirectedEdge
from AlgsSedgewickWayne.Topological import Topological

class AcyclicSP(object):
  """Computes a shortest paths tree from s to every other vertex in the DAG G."""
  Inf = float('Inf')

  def __init__(self, G, s): # G=DAG, v=source vertex O(V+E)
    self._distTo = [self.Inf for i in range(G.V())]  # distance  of shortest s->v path
    self._edgeTo = [None for i in range(G.V())] # last edge on shortest s->v path
    self._distTo[s] = 0.0

    # visit vertices in toplogical order
    topological = Topological(G)
    if not topological.hasOrder():
      raise Exception("Digraph is not acyclic.")
    for v in topological.order():
      for e in G.adj(v):
        self.relax(e)

  def _relax(self, e):
    """Relax an edge e from v to w"""
    v, w = e.get_from_to()
    if self._distTo[w] > (self._distTo[v] + e.weight()):
       self._distTo[w] =  self._distTo[v] + e.weight() # New shorter dist
       self._edgeTo[w] = e # Set better way to get to w

  def distTo(self, v): # O(K)
    """Returns the length of a shortest path from the source vertex s to vertex v."""
    return self._distTo[v]

  def hasPathTo(self, v): # O(K)
    """Is there a path from the source vertex s to vertex v?"""
    return self._distTo[v] < self.Inf

  def pathTo(self, v): # O(E in shortest path)
    """Returns a shortest path from the source vertex s to vertex v."""
    if not self.hasPathTo(v): return None
    path = [] # new Stack<DirectedEdge>()
    e = self._edgeTo[v] 
    while e is not None: 
      path.append(e) # push(e)
      e = self._edgeTo[e.get_from()]
    return path

# Shortest Paths APIs (10:51)
#
# QUESTION: Which version of the shortest path problem does the SP API represent?
#     Single-source and single-sink: find the shortest path from s to t
#  -> Single-source: find the shortest paths from s to every vertex
#     Single-sink: find the shortest paths from every vertex to t
#     All-pairs: find the shortest paths between every ordered pair of vertices.
# EXPLANATION: The API requires the algorithm to compute the shortest path 
# from s to every other vertex.
# The single-source single-sink problem is a special case. If you reverse the
# digraph, you can solve the single-sink version of the problem (by interchanging
# the roles of s and t). The all-pairs problem is a generalization where you solve
# the single-source version of the problem for every vertex.

# Shortest Path Properties (14:46)
# 
# SHORTEST-PATHS OPTIMALITY CONDITIONS
# To prove shortest paths are found, prove S-P OPT. COND. hold
#
# QUESTION: Let e = v->w be an edge with weight 17.0. Suppose that during the 
# generic shortest paths algorithm, distTo[v] = Inf and distTo[w] = 15.0. 
# What will distTo[w] be after calling relax(e)?
# ANSWER: 15
# EXPLANATION: If distTo[v] is Inf, then relaxing any edge pointing from v
# will have no effect since in Java (and IEEE floating point), Inf + x = Inf
# unless x is -Inf or Nan.

# QUESTION: The topological sort algorithm computes the shortest-paths tree in 
# an edge-weighted DAG in time proportional to ...
# ANSWER: E + V
# EXPLANATION: It process the V vertices in topological order;
# It relaxes each of teh E edges exactly once.

# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python port


================================================
FILE: AlgsSedgewickWayne/BST.py
================================================
"""A symbol table implemented with a binary search tree (BST)."""

# It also provides a **keys** method for iterating over all of the keys.
# A symbol table implements the **associative array** abstraction:
# when associating a value with a key that is already in the symbol table,
# the convention is to replace the old value with the new value.
# Unlike:@link java.util.Map}, self class uses the convention that
# values cannot be <tt>None</tt>&mdash;setting the
# value associated with a key to <tt>None</tt> is equivalent to deleting the key
# from the symbol table.
# <p>
# This implementation uses an (unbalanced) binary search tree. It requires that
# the key type implements the <tt>Comparable</tt> interface and calls the
# <tt>compareTo()</tt> and method to compare two keys. It does not call either
# <tt>equals()</tt> or <tt>hashCode()</tt>.
# The <em>put</em>, <em>contains</em>, <em>remove</em>, <em>minimum</em>,
# <em>maximum</em>, <em>ceiling</em>, <em>floor</em>, <em>select</em>, and
# <em>rank</em>  operations each take
# linear time in the worst case, if the tree becomes unbalanced.

# For other implementations, see 
# {@link ST},:@link BinarySearchST},
# {@link SequentialSearchST},:@link RedBlackBST},
# {@link SeparateChainingHashST}, and:@link LinearProbingHashST},
# <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.

import collections as cx
import sys

class BST(object):
    """Represents an ordered symbol table of generic key-value pairs.

       Supports: put, get, contains, delete, size, isEmpty
           get_min, get_max, floor, select, ceiling
    """

    class _Node(object):

        def __init__(self, key, val, N): 
            self.key = key # Key:   sorted by key
            self.val = val # Value: associated data
            self.N = N     # int:   number of nodes in subtree
            self.left = None  # left subtrees
            self.right = None # right subtrees

        def __str__(self):
            return "{K}\nv={V} N={N}".format(
                K=self.key, V=self.val, N=self.N)

    def __init__(self, keyvals=None):
        """Initializes an empty symbol table."""
        self.log = sys.stdout
        self._root = None       # root of BST
        if keyvals is not None:
            for key, val in keyvals:
                self.put(key, val)

    # Return True if self symbol table is empty; False otherwise. $ = K
    def isEmpty(self): return self.size() == 0

    # Returns the number of key-value pairs in self symbol table. $ = K
    def size(self): return self._size(self._root)

    # return number of key-value pairs in BST self._rooted at x. $ = K
    def _size(self, node_x): return node_x.N if node_x is not None else 0

    def contains(self, key):
        """Does self symbol table contain the given key?"""
        if key is None: raise Exception("argument to contains() is None")
        return self.get(key) is not None

    def get(self, key): # $ = 1 + depth
        """Returns the value associated with the given key or None."""
        return self._get(self._root, key)

    def _get(self, node_x, key):
        """Recursive method returns the value associated with the given key or None."""
        if node_x is None: return None
        if   key == node_x.key: return node_x.val
        elif key  < node_x.key: return self._get(node_x.left,  key)
        else:                   return self._get(node_x.right, key)
    
    # Inserts the specified key-value pair into the symbol table, overwriting the old 
    # value with the new value if the symbol table already contains the specified key.
    # Deletes the specified key (and its associated value) from self symbol table
    # if the specified value is None.
    def put(self, key, val):
        """Client method to add or update a key-value pair in a BST."""
        if key is None: raise Exception("first argument to put() is None")
        if val is None:
            self.delete(key)
            return
        self._root = self._put(self._root, key, val)
        assert self.check()

    def _put(self, node_x, key, val):
        """Recursive method to add or update a key-value pair in a BST."""
        if node_x is None: return self._Node(key, val, N=1)
        if   key == node_x.key: node_x.val   = val
        elif key  < node_x.key: node_x.left  = self._put(node_x.left,  key, val)
        else:                   node_x.right = self._put(node_x.right, key, val)
        node_x.N = 1 + self._size(node_x.left) + self._size(node_x.right)
        return node_x

    def deleteMin(self):
        """Removes the smallest key and associated value from the symbol table."""
        if self.isEmpty(): raise Exception("Symbol table underflow")
        self._root = self._deleteMin(self._root)
        assert self.check()

    def _deleteMin(self, node_x):
        if node_x.left is None: return node_x.right
        node_x.left = self._deleteMin(node_x.left)
        node_x.N = self._size(node_x.left) + self._size(node_x.right) + 1
        return node_x

    def deleteMax(self):
        """Removes the largest key and associated value from the symbol table."""
        if self.isEmpty(): raise Exception("Symbol table underflow")
        self._root = self._deleteMax(self._root)
        assert self.check()

    def _deleteMax(self, node_x):
        if node_x.right is None: return node_x.left
        node_x.right = self._deleteMax(node_x.right)
        node_x.N = self._size(node_x.left) + self._size(node_x.right) + 1
        return node_x

    def delete(self, key):
        """Removes the specified key and its associated value from self symbol table"""
        if key is None: raise Exception("argument to delete() is None")
        self._root = self._delete(self._root, key)
        assert self.check()

    def _delete(self, node_x, key):
        if node_x is None: return None
        if   key  < node_x.key: node_x.left = self._delete(node_x.left, key)
        elif key == node_x.key:
            if node_x.right is None: return node_x.left
            if node_x.left  is None: return node_x.right
            node_t = node_x
            node_x = self._get_min(node_t.right)
            node_x.right = self._deleteMin(node_t.right)
            node_x.left = node_t.left
        else: node_x.right = self._delete(node_x.right, key)
        node_x.self.N = self._size(node_x.left) + self._size(node_x.right) + 1
        return node_x


    # Returns the smallest key in the symbol table.
    def get_min(self): return self.get_min_node().key

    def _get_min_node(self, node_x):
        return node_x if node_x.left is None else self._get_min_node(node_x.left)

    # Returns the largest key in the symbol table.
    def get_max(self): return self.get_max_node().key

    def _get_max_node(self, node_x):
        return node_x if node_x.right is None else self._get_max_node(node_x.right)

    def get_min_node(self):
        """Returns the node with the smallest key in the symbol table."""
        if self.isEmpty(): raise Exception("called min() with empty symbol table")
        return self._get_min_node(self._root)

    def get_max_node(self):
        """Returns the node with the largest key in the symbol table."""
        if self.isEmpty(): raise Exception("called max() with empty symbol table")
        return self._get_max_node(self._root)


    def floor(self, key):
        """Returns the largest key in the symbol table less than or equal to key."""
        if key is None: raise Exception("argument to floor() is None")
        if self.isEmpty(): raise Exception("called floor() with empty symbol table")
        node_x = self._floor(self._root, key)
        return node_x.key if node_x is not None else None

    def _floor(self, node_x, key):
        if node_x is None: return None
        if key == node_x.key: return node_x
        if key  < node_x.key: return self._floor(node_x.left, key)
        node_tree = self._floor(node_x.right, key)
        return node_tree if node_tree is not None else node_x

    def ceiling(self, key):
        """Returns the smallest key in the symbol table greater than or equal to key."""
        if key is None:    raise Exception("argument to ceiling() is None")
        if self.isEmpty(): raise Exception("called ceiling() with empty symbol table")
        node_x = self._ceiling(self._root, key)
        return node_x.key if node_x is not None else None

    def _ceiling(self, node_x, key):
        if node_x is None: return None
        if key == node_x.key: return node_x
        if key  < node_x.key:
            node_t = self._ceiling(node_x.left, key)
            return node_t if node_t is not None else node_x
        return self._ceiling(node_x.right, key)

    def select(self, rank_k):
        """Return the kth smallest key in the symbol table."""
        if rank_k < 0 or rank_k >= self.size(): raise Exception("OUT OF RANGE: 0 to N")
        node_x = self._select(self._root, rank_k)
        return node_x.key

    def _select(self, node_x, rank_k):
        """Return key of rank k."""
        if node_x is None: return None
        sz_left = self._size(node_x.left)
        if   sz_left == rank_k: return node_x
        elif sz_left  < rank_k: return self._select(node_x.right, rank_k-sz_left-1)
        else:                   return self._select(node_x.left,  rank_k)

    def rank(self, key):
        """Return the number of keys in the symbol table strictly less than key."""
        if key is None: raise Exception("argument to rank() is None")
        return self._rank(key, self._root)

    def _rank(self, key, node_x):
        """Number of keys in the subtree less than key."""
        if node_x is None: return 0
        if   key == node_x.key: return self._size(node_x.left)
        elif key  < node_x.key: return self._rank(key, node_x.left)
        else:                   return 1 + self._size(node_x.left) + self._rank(key, node_x.right)


    def keys(self): 
        """return all keys in the symbol table."""
        return [n.key for n in self.nodes()]

    def nodes(self): return self._nodes_lohi(self.get_min(), self.get_max())

    def _nodes_lohi(self, lo_key, hi_key):
        """return all nodes in the symbol table between lo_key (inclusive) and hi_key (exclusive)"""
        if lo_key is None: raise Exception("first argument to nodes() is None")
        if hi_key is None: raise Exception("second argument to nodes() is None")
        queue = cx.deque() # new Queue<>()
        self._nodes(self._root, queue, lo_key, hi_key)
        return queue

    def _nodes(self, node_x, queue, lo_key, hi_key):
        if node_x is None: return
        #cmplo_key = lo_key.compareTo(node_x.key)
        #cmphi_key = hi_key.compareTo(node_x.key)
        #if cmplo_key < 0) nodes(node_x.left, queue, lo_key, hi_key)
        ndky = node_x.key
        if lo_key  < ndky: self._nodes(node_x.left, queue, lo_key, hi_key)
        #if cmplo_key <= 0 and cmphi_key >= 0) queue.enqueue(node_x.key)
        if lo_key <= ndky and hi_key >= ndky: queue.append(node_x) # queue.enqueue(node_x)
        #if cmphi_key > 0) nodes(node_x.right, queue, lo_key, hi_key)
        if hi_key  > ndky: self._nodes(node_x.right, queue, lo_key, hi_key)


    def size_lohi(self, lo, hi):
        """Returns the number of keys in the symbol table in the given range."""
        if lo is None: raise Exception("first argument to size() is None")
        if hi is None: raise Exception("second argument to size() is None")
        if lo > hi: return 0
        if self.contains(hi): return self.rank(hi) - self.rank(lo) + 1
        else:                 return self.rank(hi) - self.rank(lo)

    def height(self):
        """return the height of the BST (a 1-node tree has height 0) (for debugging)."""
        return self._height(self._root)

    def _height(self, node_x):
        if node_x is None: return -1
        return 1 + max(self._height(node_x.left), self._height(node_x.right))

    def levelOrder(self):
        """Return the keys in the BST in level order (for debugging)."""
        keys  = cx.deque() # new Queue<>()
        queue = cx.deque() # new Queue<>()
        queue.append(self._root) # queue.enqueue(self._root)
        while queue:
            node_x = queue.popleft() # queue.dequeue()
            if node_x is None: continue
            keys.append(node_x.key)    # keys.enqueue(node_x.key)
            queue.append(node_x.left)  # queue.enqueue(node_x.left)
            queue.append(node_x.right) # queue.enqueue(node_x.right)
        return keys

    # -- Write png --------------------------------------------------------------------
    def wr_png(self, fout_png):
        import AlgsSedgewickWayne.BST_utils as U
        childnames = cx.OrderedDict([('left', 'red'), ('right', 'green')])
        U.wr_png(fout_png, self.nodes(), childnames, self.log)

    # -- BST Checks -------------------------------------------------------------------
    def check(self):
        """Check integrity of BST data structure."""
        if not self.isBST():            self.log.write("Not in symmetric order")
        if not self.isSizeConsistent(): self.log.write("Subtree counts not consistent")
        if not self.isRankConsistent(): self.log.write("Ranks not consistent")
        return self.isBST() and self.isSizeConsistent() and self.isRankConsistent()

    # does self binary tree satisfy symmetric order?
    # Note: self test also ensures that data structure is a binary tree since order is strict
    def isBST(self): return self._isBST(self._root, minval=None, maxval=None)

    # is the tree self._rooted at x a BST with all keys strictly between min and max
    # (if min or max is None, treat as empty constraint)
    # Credit: Bob Dondero's elegant solution
    def _isBST(self, node_x, minval, maxval):
        if node_x is None: return True
        if minval is not None and node_x.key <= minval <= 0: return False
        if maxval is not None and node_x.key >= maxval >= 0: return False
        return self._isBST(node_x.left, minval, node_x.key) and \
               self._isBST(node_x.right, node_x.key, maxval)

    def isSizeConsistent(self): return self._isSizeConsistent(self._root)
    def _isSizeConsistent(self, node_x):
        """are the size fields correct?"""
        if node_x is None: return True
        if node_x.N != self._size(node_x.left) + self._size(node_x.right) + 1: return False
        return self._isSizeConsistent(node_x.left) and self._isSizeConsistent(node_x.right)

    def isRankConsistent(self):
        """check that ranks are consistent."""
        for i in range(self.size()):
            if i != self.rank(self.select(i)): return False
        for key in self.keys():
            if key != self.select(self.rank(key)): return False
        return True

# Algorithms, Part 1 from Princeton University
# by Kevin Wayne, Robert Sedgewick
# https://class.coursera.org/algs4partI-005/lecture/46
# Alg1, Week 4 Lecture Binary Search Trees (19:56)

# --------------------------------------------------------------------------
# 00:08 Binary Search Trees are a classic data structure that will enable us
# to provide an efficient implementations of Symbol Table Algorithms
#
# 00:25 With Heaps we talk about implicit representations with an array.
# With Binary Search Tree actual explicit tree data structures.

# --------------------------------------------------------------------------
# 00:34 BINARY SEARCH TREES
# DEFINITION: A BST is a BINARY TREE in SYMMETRIC ORDER.
#
# A BINARY TREE is either:
#   * Empty
#   * Two disjoint trees (left and right).
#
# SYMMETRIC ORDER: Each node has a key and every node's key is:
#   * Larger  than all keys in its left  subtree
#   * Smaller than all keys in its right subtree

# 01:45 Different from a heap.  HEAPs had every node larger than its children.

# CORRESPONDENCE BETWEEN BSTs and QUICKSORT PARTITIONING 0:17
# REMARK: Correspondence is 1-1 if array has no duplicate keys

# QUESTION: Suppose that N distinct keys are inserted into a binary
# search tree in random order. What is the expected number of 
# compares to search for one of the N keys?
# ANSWER: logorithmic.

# From comments in the Discussion from a student who worked on the exercises for
# level-order traversal of a BST:
#   Each node has a key and every node's key is:
#     * Larger than all keys in its left subtree.
#     * Smaller than all keys in its right subtree.


# https://github.com/kevin-wayne/algs4/commits/master/src/main/java/edu/princeton/cs/algs4/BST.java

# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python implementation.


================================================
FILE: AlgsSedgewickWayne/BST_utils.py
================================================
"""Functions to plot a Binary Search Tree."""

import pydot

__copyright__ = "Copyright (C) 2019, DV Klopfenstein. All rights reserved."
__author__ = "DV Klopfenstein"

# -- Graphing of a Binary Search Tree (BST) ---------------------------------
def wr_png(fout_png, nodes_bst, childnames, log):
    """Save tree figure to png file."""
    # 1. create/initialize graph
    g = pydot.Dot(graph_type='digraph') # directed graph
    # 2. create pydot Nodes
    nodes_dot = _get_dotnodes(nodes_bst, childnames)
    # 3. add nodes to graph
    for dotnode in nodes_dot:
        g.add_node(dotnode)
    # 4. add edges between nodes to graph
    edges_dot = _get_dotedges(nodes_bst, childnames)
    for dotedge in edges_dot:
        g.add_edge(dotedge)
    # 5. write graph to png file
    g.write_png(fout_png)
    log.write("  wrote: {}\n".format(fout_png))

def _get_dotnodes(nodes_bst, childnames):
    """Get a list of pydot Nodes."""
    nodes_dot = []
    for bstnode in nodes_bst:
        # Add nodes in the bst
        nodes_dot.append(pydot.Node(str(bstnode)))
        # Add null child nodes (e.g., key_right, key_left)
        for rl in childnames.keys():
            if getattr(bstnode, rl) is None:
                null_child = _get_name_nullchild(bstnode, rl)
                nodes_dot.append(pydot.Node(null_child, style='invis'))
    return nodes_dot

def _get_dotedges(nodes_bst, childnames):
    """Get a list of pydot Edges."""
    edges_dot = []
    for bstnode in nodes_bst:
        for cname, color in childnames.items():
            child_node = getattr(bstnode, cname)
            if child_node is not None:
                edges_dot.append(pydot.Edge(str(bstnode), str(child_node), color=color))
            else:
                null_child = _get_name_nullchild(bstnode, cname)
                edges_dot.append(pydot.Edge(str(bstnode), null_child, style='invis'))
    return edges_dot

def _get_name_nullchild(src_node, lr):
    """Get a name for a Null child node."""
    return "{SRC}_{LR}".format(SRC=src_node.key, LR=lr)

# -- Utilities --------------------------------------------------------------
def sort_balbst(key_vals):
    """Given a list of (key, value) tuples, return list sorted to build a balanced BST."""
    list_sorted = sorted(key_vals)
    list_balanced = []
    _sort_balbst(list_balanced, list_sorted)
    return list_balanced

def _sort_balbst(balanced_bst, sorted_list):
    """Given a sorted list, return a list in an order to create a balanced BST."""
    if not sorted_list: # sorted list
        return
    middle = len(sorted_list)//2
    balanced_bst.append(sorted_list[middle])
    _sort_balbst(balanced_bst, sorted_list[:middle])   # Process left side
    _sort_balbst(balanced_bst, sorted_list[middle+1:]) # Process right side

# Copyright (C) 2019, DV Klopfenstein. All rights reserved.


================================================
FILE: AlgsSedgewickWayne/BTree.py
================================================
#!/usr/bin/env python#*****************************************************************************
 #  Compilation:  javac BTree.java
 #  Execution:    java BTree
 #  Dependencies: StdOut.java
 #
 #  B-tree.
 #
 #  Limitations
 #  -----------
 #   -  Assumes M is even and M >= 4
 #   -  should b be an array of children or list (it would help with
 #      casting to make it a list)
 #
 #*****************************************************************************/

package edu.princeton.cs.algs4


public class BTree< extends Comparable<>, Value>:
    private static final M = 4;    # max children per B-tree node = M-1

    private  root;             # root of the B-tree
    private HT;                # height of the B-tree
    private N;                 # number of key-value pairs in the B-tree

    # helper B-tree node data type
    private static final class:
        private m;                             # number of children
        private Entry[] children = new Entry[M];   # the array of children

        # create a node with k children
        private (int k):
            m = k

    # internal nodes: only use key and next
    # external nodes: only use key and value
    private static class Entry:
        private key
        private  value
        private  next;     # helper field to iterate over array entries
        public Entry(key,  value,  next):
            this.key   = key
            this.value = value
            this.next  = next

    # constructor
    public BTree():
        root = new (0)
 
    # return number of key-value pairs in the B-tree
    def size(): return N; }

    # return height of B-tree
    def height(): return HT; }


    # search for given key, return associated value; return None if no such key
    def search(root, key, HT); }
    def _search( x,  key, ht):
        Entry[] children = x.children

        # external node
        if ht == 0):
            for (int j = 0; j < x.m; j += 1):
                if eq(key, children[j].key)) return (Value) children[j].value

        # internal node
        else:
            for (int j = 0; j < x.m; j += 1):
                if j+1 == x.m or less(key, children[j+1].key))
                    return search(children[j].next, key, ht-1)
        return None


    # insert key-value pair
    # add code to check for duplicate keys
    def put( key, Value value):
         u = insert(root, key, value, HT)
        N += 1
        if u == None) return

        # need to split root
         t = new (2)
        t.children[0] = new Entry(root.children[0].key, None, root)
        t.children[1] = new Entry(u.children[0].key, None, u)
        root = t
        HT += 1


    private  insert( h,  key, Value value, ht):
        j
        Entry t = new Entry(key, value, None)

        # external node
        if ht == 0):
            for (j = 0; j < h.m; j += 1):
                if less(key, h.children[j].key)) break

        # internal node
        else:
            for (j = 0; j < h.m; j += 1):
                if (j+1 == h.m) or less(key, h.children[j+1].key)):
                     u = insert(h.children[j += 1].next, key, value, ht-1)
                    if u == None) return None
                    t.key = u.children[0].key
                    t.next = u
                    break

        for (int i = h.m; i > j; i -= 1)
            h.children[i] = h.children[i-1]
        h.children[j] = t
        h.m += 1
        if h.m < M) return None
        else:         return split(h)

    # split node in half
    private  split( h):
         t = new (M/2)
        h.m = M/2
        for (int j = 0; j < M/2; j += 1)
            t.children[j] = h.children[M/2+j]
        return t

    # for debugging
    def toString():
        return toString(root, HT, "") + "\n"
    def _toString( h, ht, String indent):
        StringBuilder s = new StringBuilder()
        Entry[] children = h.children

        if ht == 0):
            for (int j = 0; j < h.m; j += 1):
                s.append(indent + children[j].key + " " + children[j].value + "\n")
        else:
            for (int j = 0; j < h.m; j += 1):
                if j > 0) s.append(indent + "(" + children[j].key + ")\n")
                s.append(toString(children[j].next, ht-1, indent + "     "))
        return s.toString()


    # comparison functions - make instead of  to avoid casts
    def _less(k1, k2):
        return k1.compareTo(k2) < 0

    def _eq(k1, k2):
        return k1.compareTo(k2) == 0


   #**************************************************************************
    #  Test client.
    #**************************************************************************/
    def main(String[] args):
        BTree<String, String> st = new BTree<String, String>()

#      st.put("www.cs.princeton.edu", "128.112.136.12")
        st.put("www.cs.princeton.edu", "128.112.136.11")
        st.put("www.princeton.edu",    "128.112.128.15")
        st.put("www.yale.edu",         "130.132.143.21")
        st.put("www.simpsons.com",     "209.052.165.60")
        st.put("www.apple.com",        "17.112.152.32")
        st.put("www.amazon.com",       "207.171.182.16")
        st.put("www.ebay.com",         "66.135.192.87")
        st.put("www.cnn.com",          "64.236.16.20")
        st.put("www.google.com",       "216.239.41.99")
        st.put("www.nytimes.com",      "199.239.136.200")
        st.put("www.microsoft.com",    "207.126.99.140")
        st.put("www.dell.com",         "143.166.224.230")
        st.put("www.slashdot.org",     "66.35.250.151")
        st.put("www.espn.com",         "199.181.135.201")
        st.put("www.weather.com",      "63.111.66.11")
        st.put("www.yahoo.com",        "216.109.118.65")


        prt.write("cs.princeton.edu:  " + st.get("www.cs.princeton.edu"))
        prt.write("hardvardsucks.com: " + st.get("www.harvardsucks.com"))
        prt.write("simpsons.com:      " + st.get("www.simpsons.com"))
        prt.write("apple.com:         " + st.get("www.apple.com"))
        prt.write("ebay.com:          " + st.get("www.ebay.com"))
        prt.write("dell.com:          " + st.get("www.dell.com"))
        prt.write()

        prt.write("size:    " + st.size())
        prt.write("height:  " + st.height())
        prt.write(st)
        prt.write()


#*****************************************************************************
 #  Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
 #
 #  This file is part of algs4.jar, which accompanies the textbook
 #
 #      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 #      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 #      http://algs4.cs.princeton.edu
 #
 #
 #  algs4.jar is free software: you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
 #  the Free Software Foundation, either version 3 of the License, or
 #  (at your option) any later version.
 #
 #  algs4.jar is distributed in the hope that it will be useful,
 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #  GNU General Public License for more details.
 #
 #  You should have received a copy of the GNU General Public License
 #  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 #*****************************************************************************/


================================================
FILE: AlgsSedgewickWayne/Bag.py
================================================
"""Bag class is a container for generic items."""

class Bag(object): # <Item> implements Iterable<Item>:
  """The Bag class represents a bag (or multiset) of generic items."""

  class _Node(object): # private static class <Item>:
    """helper linked list class"""

    def __init__(self, Item, Next):
      self._item = Item
      self._next = Next

  def __init__(self):
    self._first = None # beginning of bag
    self._N = 0        # number of elements in bag

  def isEmpty(self):
    """return true if this bag is empty; false otherwise."""
    return self._first is None

  def size(self):
    """Returns the number of items in this bag."""
    return self._N

  def add(self, item):
    """Adds the arg item to this bag."""
    self._first = self._Node(item, self._first)
    self._N += 1

  # Returns an iterator that iterates over the items in the bag in arbitrary order.
  def __iter__(self):
    return self._ListIterator(self._first)

  class _ListIterator(object): # <Item> implements Iterator<Item>:
    """an iterator, doesn't implement remove() since it's optional."""

    def __init__(self, first):
      self._current = first

    def hasNext(self):
      """If we are not at the end of the Bag."""
      return self._current is not None

    def next(self):
      """Go to the next element."""
      if not self.hasNext():
        raise StopIteration
      item = self._current._item
      self._current = self._current._next
      return item

#************************************************************************
#  Compilation:  javac Bag.java
#  Execution:    java Bag < input.txt
#
#  A generic bag or multiset, implemented using a singly-linked list.
#
#  % more tobe.txt
#  to be or not to - be - - that - - - is
#
#  % java Bag < tobe.txt
#  size of bag = 14
#  is
#  -
#  -
#  -
#  that
#  -
#  -
#  be
#  -
#  to
#  not
#  or
#  be
#  to
#
#************************************************************************/

# The Bag class represents a bag (or multiset) of generic items.
# It supports insertion and iterating over the
# items in arbitrary order.
#
# This implementation uses a singly-linked list with a static nested class Node.
# See {@link LinkedBag} for the version from the
# textbook that uses a non-static nested class.
# The <em>add</em>, <em>isEmpty</em>, and <em>size</em> operations
# take constant time. Iteration takes time proportional to the number of items.
#
# For additional documentation, see
# <a href="http://algs4.cs.princeton.edu/13stacks">Section 1.3</a> of
# <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
#
# @author Robert Sedgewick
# @author Kevin Wayne
# @converted to Python by DV Klopfenstein

# Copyright (C) 2002-2010, Robert Sedgewick and Kevin Wayne.
# Java last updated: Tue Mar 25 04:52:35 EDT 2014.


================================================
FILE: AlgsSedgewickWayne/BaseComp.py
================================================
"""Component Base which holds functions to aid in visulaization and understanding."""

# Copyright (C) 2014-present DV Klopfenstein, PhD. All rights reserved.

from collections import defaultdict
from collections import namedtuple
from collections import Counter
import sys
import pydot
from AlgsSedgewickWayne.testcode.utils import get_png_label

class BaseComp(object):
    """ Holds an index of Nodes which can be combined into components."""

    ### NtRoot = namedtuple("NtRoot", "rootnode depth")

    def __init__(self, name):
        """Derived class will set the actual values."""
        self.name = name
        self.idvals = None

    def _root(self, val):
        """Shows _root interface."""
        raise NotImplementedError(f"TIME TO IMPLEMENT "
            f"A _root({val}) METHOD IN THE DERIVED CLASS")

    def __str__(self):
        """Print the ID vector. Used in    >>> print obj"""
        idxs = " ".join(f"{e:>2}" for e in range(len(self.idvals)))
        vals = " ".join(f"{e:>2}" for e in self.idvals)
        # vals += " ROOTS: " + ' '.join(f"{v}" for v in sorted(set(self.idvals)))
        return '\n'.join(["ROOT: " + vals, "ID:   " + idxs])

    def get_connected_components(self):
        """Return the root and a list of the contents of each component."""
        root2members = defaultdict(set)
        for id_val, parent in enumerate(self.idvals):
            root_parent = self._root(parent)
            ## print(f'ROOT({root_parent}): {id_val}')
            root2members[root_parent].add(id_val)
        ## print(f'ROOTS: {sorted(root2members)}')
        return root2members

    def wr_png(self, fout_png="components.png", prt=sys.stdout, **kwargs):
        """Make a png showing a diagram of the connected components."""
        label = get_png_label(self.idvals, kwargs)
        # 1. Create/initialize Graph
        digraph = pydot.Dot(label=label, graph_type='digraph') # Directed Graph
        # 2. Create Nodes
        nodes = [pydot.Node(str(idx)) for idx in range(len(self.idvals))]
        # 3. Add nodes to Graph
        for node in nodes:
            digraph.add_node(node)
        # 4. Add Edges between Nodes to Graph
        for child, parent in enumerate(self.idvals):
            if child != parent: # Print only edges from one node to another (not to self)
                digraph.add_edge(pydot.Edge(nodes[parent], nodes[child]))
        # 5. Write Graph to png file
        digraph.write_png(fout_png)
        prt.write(f"    WROTE: {fout_png}\n")

    def union_pngs(self, unions, png_base):
        """Do a union, draw a state image. Repeat."""
        for i, (pval, qval) in enumerate(unions):
            fout_png = f"{png_base}{i}.png"
            self.union_png(pval, qval, fout_png)

    def union_png(self, pval, qval, fout_png):
        """Do a union, draw a state image."""
        self.union(pval, qval)
        if fout_png is not None:
            label_pat = f"union({pval}, {qval}) -> {{STATE}}"
            self.wr_png(fout_png, label_pat=label_pat)

    def union(self, pval, qval):
        """Derived class should do union"""
        raise RuntimeError('DERIVED CLASS MUST CALL UNION')

    def get_png(self):
        """Generate a png filename."""
        state = "_".join([str(s) for s in self.idvals])
        return f"state_{self.name}_{state}.png"

    def wr_png_tree_state(self, state=None, fout_png=None):
        """Force state (e.g. [0, 9, 6, 5, 4, 2, 6, 1, 0, 5]), create png showing current state."""
        self.idvals = state
        if fout_png is None:
            fout_png = self.get_png()
        self.wr_png(fout_png)

    def wr_png_tree_statestr(self, statestr=None, fout_png=None):
        """Given state string (e.g. "0 9 6 5 4 2 6 1 0 5"), create png showing current state."""
        usr_state = [int(n) for n in statestr.split()]
        self.wr_png_tree_state(usr_state, fout_png)


================================================
FILE: AlgsSedgewickWayne/BellmanFordSP.py
================================================
"""Bellman-Ford shortest path algorithm in Graphs w/no neg. cycles."""
# TBD: Finish Python port

import collections as cx
from AlgsSedgewickWayne.EdgeWeightedDigraph import EdgeWeightedDigraph
from AlgsSedgewickWayne.EdgeWeightedDirectedCycle import EdgeWeightedDirectedCycle

class BellmanFordSP(object):
  """Gets SP tree in edge-wt'd digraph from src s, or finds a neg. cost cycle reachable from s."""
  Inf = float('Inf')

  def __init__(self, G, s): # G:EdgeWeightedDigraph O(V+E) wc
    self._distTo  = [self.Inf for i in range(G.V())] # distTo[v] = distance  of shortest s->v path
    self._distTo[s] = 0.0
    self._edgeTo  = [None for i in range(G.V())] # edgeTo[v] = last edge on shortest s->v path
    self._onQueue = [False for i in range(G.V())] # onQueue[v] = is v currently on the queue?
    self._cost = 0    # number of calls to relax()
    self._cycle = None # Iterable<DirectedEdge> negative cycle (or null if no such cycle)

    # Bellman-Ford algorithm
    self._queue = cx.deque() # new Queue<Integer>() # queue of vertices to relax
    self._queue.append(s) # enqueue(s)
    self._onQueue[s] = True
    while self._queue and not self.hasNegativeCycle():
      v = self._queue.popleft() # dequeue()
      self._onQueue[v] = False
      self._relax(G, v)
    assert _check(G, s)

  def _relax(self, G, v):
    """relax vertex v and put other endpoints on queue if changed"""
    for e in G.adj(v):
      w = e.get_to()
      if self._distTo[w] > self._distTo[v] + e.weight()):
         self._distTo[w] = self._distTo[v] + e.weight()
         self._edgeTo[w] = e
         if not self._onQueue[w]:
           self_queue.append(w) # enqueue(w)
           self._onQueue[w] = True
      if self._cost%G.V() == 0:
        self.findNegativeCycle()
        if self.hasNegativeCycle(): return  # found a negative cycle
      self._cost += 1

  # Is there a negative cycle reachable from the source vertex <tt>s</tt>?
  def hasNegativeCycle(self): return self._cycle is not None # O(k)

  # Returns a negative cycle reachable from the src s, or None if there is no such cycle.
  def negativeCycle(self): return self._cycle # O(# edges returned)

  def _findNegativeCycle(self):
    """by finding a cycle in predecessor graph"""
    V = len(self._edgeTo)
    spt = EdgeWeightedDigraph(V)
    for v in range(V):
      if self._edgeTo[v] is not None:
         spt.addEdge(self._edgeTo[v])

    finder = EdgeWeightedDirectedCycle(spt)
    self._cycle = finder.cycle()

  def distTo(self, v): # O(k)
    """Returns the length of a shortest path from the source vertex s to vertex v."""
    if self.hasNegativeCycle():
      raise Exception("Negative cost cycle exists")
    return self._distTo[v]

  # Is there a path from the source <tt>s</tt> to vertex <tt>v</tt>?
  def hasPathTo(self, v): return self._distTo[v] < sel.Inf # O(k)

  def pathTo(self, v): # O(# edges returned)
    """Returns a shortest path from the source s to vertex v."""
    if self.hasNegativeCycle():
        raise Exception("Negative cost cycle exists")
    if not self.hasPathTo(v): return None
    path = [] # new Stack<DirectedEdge>()
    e = self._edgeTo[v]
    while e is not None: 
      path.append(e) # push(e)
      e = self._edgeTo[e.get_from()]
    return path

  # check optimality conditions: either 
  # (i) there exists a negative cycle reacheable from s
  #     or 
  # (ii)  for all edges e = v->w:            self._distTo[w] <= self._distTo[v] + e.weight()
  # (ii') for all edges e = v->w on the SPT: self._distTo[w] == self._distTo[v] + e.weight()
  def _check(EdgeWeightedDigraph G, s):

      # has a negative cycle
      if hasNegativeCycle()):
          double weight = 0.0
          for (DirectedEdge e : negativeCycle()):
              weight += e.weight()
          if weight >= 0.0):
              System.err.println("error: weight of negative cycle = " + weight)
              return False

      # no negative cycle reachable from source
      else:

          # check that self._distTo[v] and self._[v] are consistent
          if self._distTo[s] != 0.0 or self._[s] is not None):
              System.err.println("distanceTo[s] and self._[s] inconsistent")
              return False
          for (int v = 0; v < G.V(); v += 1):
              if v == s) continue
              if self._[v] is None and self._distTo[v] != Double.POSITIVE_INFINITY):
                  System.err.println("self._distTo[] and self._[] inconsistent")
                  return False

          # check that all edges e = v->w satisfy self._distTo[w] <= self._distTo[v] + e.weight()
          for (int v = 0; v < G.V(); v += 1):
              for (DirectedEdge e : G.adj(v)):
                  w = e.to()
                  if self._distTo[v] + e.weight() < self._distTo[w]):
                      System.err.println("edge " + e + " not relaxed")
                      return False

          # check that all edges e = v->w on SPT satisfy self._distTo[w] == self._distTo[v] + e.weight()
          for (int w = 0; w < G.V(); w += 1):
              if self._[w] is None) continue
              DirectedEdge e = self._[w]
              v = e.from()
              if w != e.to()) return False
              if self._distTo[v] + e.weight() != self._distTo[w]):
                  System.err.println("edge " + e + " on shortest path not tight")
                  return False

      prt.write("Satisfies optimality conditions")
      prt.write()
      return True

# NEGATIVE WEIGHTS (21:01)

# PROPOSITION: Dynamic programming algorithm computes SPT in any 
# edge-weighted digraph with no negative cycles in time proportional to E*V
#
# PROOF IDEA: After pass, i, found shortest path containing at most i edges. (In book)

# OBSERVATION: If distTo[v] does not change during pass i, no need to relax any 
# edge pointing from v in pass i+1.
#
# FIFO IMPLEMENTATION: Maintain QUEUE of vertices whose distTo[] changed
# ***Be careful to keep at most one copy of each vertex on queue (why?)
#
# OVERALL EFFECT:
#  * The running time is still proportional to E*V in worst case
#  * But much faster than that in practice

# QUESTION: The dynamic programming algorithm computes a shortest-paths tree in
# edge-weighter digraph with no negative cycles in time proportional to ...
# ANSWER: EV
# EXPLANATION: There are V passes; each passes relaxes each of teh E edges.

# BELLMAN-FORD is NOT a greedy algorithm (so can do negative edges)
#
# FUNDAMENTAL IDEA BEHIND BELLMAN-FORD:
#  * THERE CAN BE AT MOST |V|-1 edges in a path starting from the starting node
#    to any other node in the graph.
#  * |V| or more edges in a path -> repeated vertex -> cycle


# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python port


================================================
FILE: AlgsSedgewickWayne/BinarySearch.py
================================================
#!/usr/bin/env python
#************************************************************************
#  Compilation:  javac BinarySearch.java
#  Execution:    java BinarySearch whitelist.txt < input.txt
#  Dependencies: In.java StdIn.java StdOut.java
#  Data files:   http://algs4.cs.princeton.edu/11model/tinyW.txt
#                http://algs4.cs.princeton.edu/11model/tinyT.txt
#                http://algs4.cs.princeton.edu/11model/largeW.txt
#                http://algs4.cs.princeton.edu/11model/largeT.txt
#
#  % java BinarySearch tinyW.txt < tinyT.txt
#  50
#  99
#  13
#
#  % java BinarySearch largeW.txt < largeT.txt | more
#  499569
#  984875
#  295754
#  207807
#  140925
#  161828
#  [367,966 total values]
#
#************************************************************************/


########################################################################
# Lecture Week 1 "Order-of-Growth Classifications" (14:39)
########################################################################
#
# COMMON ORDER-OF-GROWTH CLASSIFICATIONS
#
# 02:44 GOOD NEWS. The small set of functions
#  order    name           code, typical          T(2N)/T(N)
#  -----    --------       -------------          ---------
#   1       constant       a = b + c               1
#   log N   logarithmic    while (N>1)
#                            N = N/2;             ~1
#
#   N       linear    for i in range(N):           2
#   N log N linearithmic   mergesort              ~2 DIVIDE-AND-CONQUER
#
#   N^2     quadratic      for i in range(N):      4
#                            for j in range(N):
#
#   N^3     cubic          ...                     8
#
#   2^N     exponential    combinatorial search    T(N)

# 07:50 BINARY SEARCH: JAVA IMPLEMENTATION
#
# TRIVIAL TO IMPLEMENT?
# * Fist binary search published in 1946; first bug-free one in 1962
# * Bug in Java's Arrays.binarySerch() discovered in 2006.
#
# INVARIANT. If key appears in the array a[], then a[lo] <= key <= a[hi]

# 09:52 BINARY SEARCH: MATHEMATICAL ANALYSIS
#
# PROPOSITION. Binary search uses at most 1 + lg N compares to
# search in a sorted array of size N.
#
# DEFINITION. T(N) = # compares to binary search in a sorted subarray of size <= N.
#
# BINARY SEARCH RECURRENCE. T(N) <= T(N/2) + 1 for N > 1, with T(1) = 1.
#   T(N/2)  left half or right half
#   1       possible to implement w/one 2-way compare instead of 3-way
#
# PROOF SKETCH. (Only holds if power of 2, but can extrapolate)
#
# T(N) <= T(N/2) + 1                          given
#      <= T(N/4) + 1 + 1                      apply recurrence to first term
#      <= T(N/8) + 1 + 1 + 1                  apply recurrence to first term
#      ...
#      <= T(N/N) + 1 + 1 + ... + 1            stop applying. T(1) = 1
#      = 1 + lg N
#

# 02:00 Lecture Week 1 "Theory of Algorithms" (11:35)
#
#   BEST     ~ 1
#   AVERAGE  ~ lg N
#   WORST    ~ lg N

#*
 #  The <tt>BinarySearch</tt> class provides a static method for binary
 #  searching for an integer in a sorted array of integers.
 #  <p>
 #  The <em>rank</em> operations takes logarithmic time in the worst case.
 #  <p>
 #  For additional documentation, see <a href="http://algs4.cs.princeton.edu/11model">Section 1.1</a> of
 #  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 #
 #  @author Robert Sedgewick
 #  @author Kevin Wayne
 #/
import random
import sys
from AlgsSedgewickWayne.testcode.InputArgs import get_ints_from_file
import timeit
import datetime
import os

# @param key the search key
# @param a the array of integers, must be sorted in ascending order
# @return index of key in array a[] if present; -1 if not present
def rank(key, a):
  """Searches for the integer key in the sorted array a[]."""
  lo = 0
  hi = len(a) - 1
  while lo <= hi:
      #  is in a[lo..hi] or not present.
      mid = lo + (hi - lo) / 2
      # One 3-way compare:
      if   key < a[mid]: hi = mid - 1
      elif key > a[mid]: lo = mid + 1
      else: return mid
  return -1

# Reads in a sequence of integers from the whitelist file, specified as
# a command-line argument. Reads in integers from standard input and
# prints to standard output those integers that do *not* appear in the file.
def run(a):
  a   = sorted(a)
  # Randomly pick a key
  key = random.randrange(a[0], a[-1])
  idx = rank(key, a)
  if idx == -1:
    sys.stdout.write('Key({}) not found in array(L={})\n'.format(key, len(a)))
    if len(a)<20: print(a)
  else:
    sys.stdout.write('Key({}) found in array(L={}) at idx({})\n'.format(key, len(a), idx))

# --------------------------------------------------------------------------------------
# Reads in a sequence of integers from a file, specified as a command-line argument;
# counts the number of triples sum to exactly zero; prints out the time to perform
# the computation.
def run_timed(a):
  """Run BinarySearch and report the elapsed time."""
  tic = timeit.default_timer()
  val = run(a)
  sys.stdout.write("Elapsed HMS: {}\n".format(
    str(datetime.timedelta(seconds=(timeit.default_timer()-tic)))))

def run_timed_fin(fin):
  """Run BinarySearch using integers stored in a column in a file."""
  sys.stdout.write('\nRunning BinarySearch on data in: {}\n'.format(fin))
  run_timed(get_ints_from_file(fin))

def run_timed_fins(fins):
  """Run BinarySearch on multiple files containing integers."""
  for fin in fins:
    run_timed_fin(fin)

if __name__ == '__main__':
  """Ways to run this script:

  BinarySearch.py       => Runs data in tinyW.txt
  BinarySearch.py all   => Runs all: tinyW.txt, tinyT.txt, largeW.txt, largeW.txt
  BinarySearch.py tinyW.txt => Runs data in tinyW.txt
  BinarySearch.py 10    => Runs on 10 random numbers from -20 to 20
  """
  # If there are no arguments, run the smallest example on the Sedgewick-Wayne web-site.
  if len(sys.argv) == 1:
    run_timed_fin('../../thirdparty/tinyW.txt')
  # Run all the examples from the Princeton Algorithms book-site
  elif sys.argv[1] == 'all':
    fins = [
      '../../thirdparty/tinyW.txt',
      '../../thirdparty/tinyT.txt',
      '../../thirdparty/largeW.txt',
      '../../thirdparty/largeT.txt']
    run_timed_fins(fins)
  # If the argument is a file, run using the integers from that file
  elif os.path.isfile(sys.argv[1]):
    run_timed_fin(sys.argv[1])
  # If the argument is a digit, run using that many randomly chosen digits.
  elif sys.argv[1].isdigit():
    dig = int(sys.argv[1])
    a = [random.randrange(-2*dig, 2*dig) for i in range(dig)]
    run_timed(a)

# Copyright (C) 2002-2010, Robert Sedgewick and Kevin Wayne.
# Java last updated: Sun Aug 31 21:38:23 EDT 2014.


================================================
FILE: AlgsSedgewickWayne/BoyerMoore.py
================================================

# TBD Finish Python port

 ******************************************************************************/

package edu.princeton.cs.algs4

#
# The <tt>BoyerMoore</tt> class finds the first occurrence of a pattern string
# in a text string.
# <p>
# This implementation uses the Boyer-Moore algorithm (with the bad-character
# rule, but not the strong good suffix rule).
# <p>
# For additional documentation,
# see <a href="http:#algs4.cs.princeton.edu/53substring">Section 5.3</a> of
# <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
#
public class BoyerMoore:
  private final R;     # the radix
  private int[] right;     # the bad-character skip array

  private char[] pattern;  # store the pattern as a character array
  private String pat;      # or as a string

  #
  #Preprocesses the pattern string.
  #
  #@param pat the pattern string
  #
  public BoyerMoore(String pat):
      self.R = 256
      self.pat = pat

      # position of rightmost occurrence of c in the pattern
      right = new int[R]
      for (int c = 0; c < R; c += 1)
          right[c] = -1
      for (int j = 0; j < len(pat)(); j += 1)
          right[pat.charAt(j)] = j

  #
  #Preprocesses the pattern string.
  #
  #@param pattern the pattern string
  #@param R the alphabet size
  #
  public BoyerMoore(char[] pattern, R):
      self.R = R
      self.pattern = new char[len(pattern)]
      for (int j = 0; j < len(pattern); j += 1)
          self.pattern[j] = pattern[j]

      # position of rightmost occurrence of c in the pattern
      right = new int[R]
      for (int c = 0; c < R; c += 1)
          right[c] = -1
      for (int j = 0; j < len(pattern); j += 1)
          right[pattern[j]] = j

  #
  #Returns the index of the first occurrrence of the pattern string
  #in the text string.
  #
  #@param  txt the text string
  #@return the index of the first occurrence of the pattern string
  #        in the text string; N if no such match
  #
  def search(String txt):
      M = len(pat)()
      N = len(txt)()
      skip
      for (int i = 0; i <= N - M; i += skip):
          skip = 0
          for (int j = M-1; j >= 0; j -= 1):
              if pat.charAt(j) != txt.charAt(i+j)):
                  skip = Math.max(1, j - right[txt.charAt(i+j)])
                  break
          if skip == 0) return i;    # found
      return N;                       # not found


  #
  #Returns the index of the first occurrrence of the pattern string
  #in the text string.
  #
  #@param  text the text string
  #@return the index of the first occurrence of the pattern string
  #        in the text string; N if no such match
  #
  def search(char[] text):
      M = len(pattern)
      N = len(text)
      skip
      for (int i = 0; i <= N - M; i += skip):
          skip = 0
          for (int j = M-1; j >= 0; j -= 1):
              if pattern[j] != text[i+j]):
                  skip = Math.max(1, j - right[text[i+j]])
                  break
          if skip == 0) return i;    # found
      return N;                       # not found


  #
  #Takes a pattern string and an input string as command-line arguments
  #searches for the pattern string in the text string; and prints
  #the first occurrence of the pattern string in the text string.
  #


# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python implementation.



================================================
FILE: AlgsSedgewickWayne/BreadthFirstPaths.py
================================================
"""find shortest paths from a source vertex src to every other vertex in an undirected graph."""

import sys
from collections import OrderedDict
from collections import deque

class BreadthFirstPaths:
    """Run breadth first search on an undirected graph."""
    inf = float("inf")

    def __init__(self, graph, src, prt=None):
        # Mark src-vertex path
        self.marked = OrderedDict([(vertex, False)    for vertex in graph.keys])
        # edgeTo[vertex] = last edge on src-vertex path
        self.edge_to = OrderedDict([(vertex, self.inf) for vertex in graph.keys])
        # distTo[vertex] = number of edges shortest src-vertex path
        self.dist_to = OrderedDict([(vertex, self.inf) for vertex in graph.keys])
        self._bfs(graph, src, prt)
        assert self._check(graph, src)

    def _bfs(self, graph, sources, prt):
        """breadth-first search from multiple sources."""
        queue = deque() # Queue
        if isinstance(sources, int):
            sources = [sources]
        for src in sources:
            self.marked[src] = True
            self.dist_to[src] = 0
            queue.append(src) # enqueue
        while queue:
            vertex = self.deque(queue, prt)
            for w in graph.adj(vertex):
                if not self.marked[w]:
                    self.edge_to[w] = vertex
                    self.dist_to[w] = self.dist_to[vertex] + 1
                    self.marked[w] = True
                    queue.append(w) # enqueue(w)

    #### def hasPathTo(self, vertex):
    ####     return self.marked[vertex]

    def has_path_to(self, vertex):
        """True if there is a path to the vertex"""
        return self.marked[vertex]

    #### def distTo(self, vertex):
    ####     return self.dist_to[vertex]

    def get_dist_to(self, vertex):
        """Get distance in 'hops' to vertex"""
        return self.dist_to[vertex]

    def pathTo(self, vertex):
        """Returns a shortest path between the source vertex src (or sources) or None"""
        if not self.has_path_to(vertex):
            return None
        path = [] # Stack
        x = vertex
        while self.dist_to[x] != 0:
            path.append(x) # push
            x = self.edge_to[x]
        path.append(x) # push
        return path

    def deque(self, queue, prt):
        """Deque and print dequed value if user requests."""
        vertex = queue.popleft() # dequeue()
        if prt is not None:
            prt.write(f"{vertex} ")
        return vertex

    def _check(self, graph, src, prt=sys.stdout):
        """check optimality conditions for single source."""

        # check that the distance of src = 0
        if self.dist_to[src] != 0:
            prt.write(f"distance of source {src} to itself = {self.dist_to[src]}\n")
            return False

        # check that for each edge vertex-w dist[w] <= dist[vertex] + 1
        # provided vertex is reachable from src
        for vertex in graph.keys:
            for w in graph.adj(vertex):
                if self.has_path_to(vertex) != self.has_path_to(w):
                    prt.write(f"edge {vertex}-{w}")
                    prt.write(f"has_path_to({vertex}) = {self.has_path_to(vertex)}")
                    prt.write(f"has_path_to({w}) = {self.has_path_to(w)}")
                    return False
                if self.has_path_to(vertex) and (self.dist_to[w] > self.dist_to[vertex] + 1):
                    prt.write(f"edge {vertex}-{w}")
                    prt.write(f"dist_to[{vertex}] = {self.dist_to[vertex]}")
                    prt.write(f"dist_to[{w}] = {self.dist_to[w]}")
                    return False

        # check that vertex = edgeTo[w] satisfies dist_to[w] + dist_to[vertex] + 1
        # provided vertex is reachable from src
        for w in graph.keys:
            if not self.has_path_to(w) or w == src:
                continue
            vertex = self.edge_to[w]
            if self.dist_to[w] != self.dist_to[vertex] + 1:
                prt.write(f"shortest path edge {vertex}-{w}")
                prt.write(f"dist_to[{vertex}] = {self.dist_to[vertex]}")
                prt.write(f"dist_to[{w}] = {self.dist_to[w]}")
                return False

        return True


# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python port


================================================
FILE: AlgsSedgewickWayne/CC.py
================================================
"""Compute connected components using depth first search."""

import collections as cx

class CC(object):
  """Computes the connected components of the undirected graph G in constant time."""

  def __init__(self, G): #  O(E + V)
    self._marked = cx.OrderedDict((v, False) for v in G.keys)
    self._id = cx.OrderedDict((v, None) for v in G.keys)
    self._count = 0        # number of connected components
    self._size = [0]*G.V() # size[id] = number of vertices in given component
    for v in G.keys:
      if not self._marked[v]:
        self._dfs(G, v)
        self._count += 1

  def _dfs(self, G, v):
    """depth-first search"""
    self._marked[v] = True    # marked[v] = has vertex v been marked?
    self._id[v] = self._count # id[v] = id of connected component containing v
    self._size[self._count] += 1
    for w in G.adj(v):
      if not self._marked[w]:
        self._dfs(G, w)

  # Returns the component id of the connected component containing vertex v.
  def id(self, v): return self._id[v] 

  # Returns the number of vertices in the connected component containing vertex v.
  def size(self, v): return self._size[id[v]]

  # Returns the number of connected components in the graph G.
  def count(self): return self._count

  # Returns true if vertices v and w are in the same connected component.
  def connected(self, v, w): return self._id(v) == self._id(w)

  def prt_ids(self, prt):
    """Print Vertex names on line 1 and vertex component ids on line 2."""
    prt.write("id[v] = {}\n".format(' '.join(self._id.keys())))
    prt.write("id[v] = {}\n".format(' '.join(str(i) for i in self._id.values())))

#------------------------------------------------------------------------------
# CONNECTED COMPONENTS (18:56)

# UNION-FIND? No. Could not quite answer question "Is v and w connected" in constant time.

# CONNECTED COMPONENTS: 3:28
# The relation "is connected to" is an equivalence relation:
#  * Reflexive: v is connected to v
#  * Symmetric: if v is connected to w, the w is connected to v
#  * Transitive: if v connected to w and w connected to x, then connected to x.

# CONNECTED COMPONENTS APPLICATION: PARTICLE DETECTION
#
# PARTICLE DETECTION: Given grayscale image of particles, identify "blobs."
#   * Vertex: pixel
#   * Edge: between two adjacent pixels with grayscale value >= 70 (blk=0, wht=255)
#   * Blob: connected component of 20-30 pixels
#
# PARTICLE TRACKING: Trackmoving particles over time.

#------------------------------------------------------------------------------
# GRAPH CHALLENGES (14:29)

# HOW DIFFICULT?
#   * Any programmer could do it
#   * Typical diligent algorithms student could do it.
#   * Hire an expert
#   * Intractable
#   * No one knows
#   * Impossible

# GRAPH-PROCESSING CHALLENGE 1
# 
# PROBLEM: Is a graph bipartite?
# BIPARTITE: You can divide the vertices into two subsets with the property
#   that every edge connects a vertex in one subset to a vertex in another.
# ANSWER: Can use DFS to tell if a graph is bipartite.

# GRAPH-PROCESSING CHALLENGE 2
#
# PROBLEM: Find a cycle in a Graph.
# ANSWER: Simple with DFS (see textbook)

# BRIDGES OF KONIGSBERG
# The Seven Bridges of Konigsberg [Leonhard Euler 1736]
# Exactly cross 7 bridges exactly once
# EULER TOUR: Is there a (general) cycle that uses each edge exactly once?
# ANSWER: A connected graph is Eulerian iff all vertices have even degree.

# GRAPH-PROCESSING CHALLENGE 3
#
# PROBLEM: Find a (general) cycle that uses every edge exactly once. (Eularian Cycle)

# GRAPH-PROCESSING CHALLENGE 4
#
# PROBLEM: Find a (general) cycle that uses every vertex exactly once. 
# AKA: Traveling Sales Person Problem; Hamiltonian Cycle
# INTRACTABLE: NP-complete. Nobody knows an efficient solution for large graphs

# GRAPH-PROCESSING CHALLENGE 5
#
# PROBLEM: Are two graphs identical except for vertex names?
# AKA: Graph isomorphism problem
# NO ONE KNOWS. Don;t even know how to classify the problem

# GRAPH-PROCESSING CHALLENGE 6
#
# PROBLEM: Lay out a grpah in the plane without crossing edges?
# HIRE AN EXPERT: linear time DFS-based planarity algorithm discovered by
#   Tarjan in 1970s (too complicated for most practitioners)

# QUESTION: Which one of the following graph-processing problems is 
# unlikely to have an algorithm whose running time is E + V?
#    * determine whether a graph is bipartite
#    * determine whether a graph has a Euler cycle
# -> * determine whether a graph has a Hamilton cycle
#    * determine whether a graph can be drawn in the plane such that no 2 edges cross
# EXPLANATION: The Hamilton cycle problem is NP-complete -- it is unlikely 
# to have a polynomial-time algorithm. The other 3 problems can be solved in linear time.


# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python implementation


================================================
FILE: AlgsSedgewickWayne/CPM.py
================================================
#*****************************************************************************
 #  Compilation:  javac CPM.java
 #  Execution:    java CPM < input.txt
 #  Dependencies: EdgeWeightedDigraph.java AcyclicDigraphLP.java StdOut.java
 #  Data files:   http://algs4.cs.princeton.edu/44sp/jobsPC.txt
 #
 #  Critical path method.
 #
 #  % java CPM < jobsPC.txt
 #   job   start  finish
 #  --------------------
 #     0     0.0    41.0
 #     1    41.0    92.0
 #     2   123.0   173.0
 #     3    91.0   127.0
 #     4    70.0   108.0
 #     5     0.0    45.0
 #     6    70.0    91.0
 #     7    41.0    73.0
 #     8    91.0   123.0
 #     9    41.0    70.0
 #  Finish time:   173.0
 #
 #*****************************************************************************/

package edu.princeton.cs.algs4

#*
 #  The <tt>CPM</tt> class provides a client that solves the
 #  parallel precedence-constrained job scheduling problem
 #  via the <em>critical path method</em>. It reduces the problem
 #  to the longest-paths problem in edge-weighted DAGs.
 #  It builds an edge-weighted digraph (which must be a DAG)
 #  from the job-scheduling problem specification,
 #  finds the longest-paths tree, and computes the longest-paths
 #  lengths (which are precisely the start times for each job).
 #  <p>
 #  This implementation uses {@link AcyclicLP} to find a longest
 #  path in a DAG.
 #  The running time is proportional to <em>V</em> + <em>E</em>,
 #  where <em>V</em> is the number of jobs and <em>E</em> is the
 #  number of precedence constraints.
 #  <p>
 #  For additional documentation,
 #  see <a href="http://algs4.cs.princeton.edu/44sp">Section 4.4</a> of
 #  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 #
 #  @author Robert Sedgewick
 #  @author Kevin Wayne
 #/
public class CPM:

  # self class cannot be instantiated
  private CPM(): }

    #*
     #  Reads the precedence constraints from standard input
     #  and prints a feasible schedule to standard output.
     #/
  def main(String[] args):

      # number of jobs
      N = StdIn.readInt()

      # source and sink
      source = 2*N
      sink   = 2*N + 1

      # build network
      EdgeWeightedDigraph G = new EdgeWeightedDigraph(2*N + 2)
      for (int i = 0; i < N; i += 1):
          double duration = StdIn.readDouble()
          G.addEdge(new DirectedEdge(source, i, 0.0))
          G.addEdge(new DirectedEdge(i+N, sink, 0.0))
          G.addEdge(new DirectedEdge(i, i+N,    duration))

          # precedence constraints
          M = StdIn.readInt()
          for (int j = 0; j < M; j += 1):
              precedent = StdIn.readInt()
              G.addEdge(new DirectedEdge(N+i, precedent, 0.0))

      # compute longest path
      AcyclicLP lp = new AcyclicLP(G, source)

      # print results
      prt.write(" job   start  finish")
      prt.write(" -= 1 -= 1 -= 1 -= 1 -= 1 -= 1 -= 1 -= 1 -= 1 -= 1")
      for (int i = 0; i < N; i += 1):
          StdOut.printf("%4d %7.1f %7.1f\n", i, lp.distTo(i), lp.distTo(i+N))
      StdOut.printf("Finish time: %7.1f\n", lp.distTo(sink))


#*****************************************************************************
 #  Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
 #
 #  This file is part of algs4.jar, which accompanies the textbook
 #
 #      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 #      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 #      http://algs4.cs.princeton.edu
 #
 #
 #  algs4.jar is free software: you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
 #  the Free Software Foundation, either version 3 of the License, or
 #  (at your option) any later version.
 #
 #  algs4.jar is distributed in the hope that it will be useful,
 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #  GNU General Public License for more details.
 #
 #  You should have received a copy of the GNU General Public License
 #  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 #*****************************************************************************/


================================================
FILE: AlgsSedgewickWayne/CollisionSystem.py
================================================
"""Simulates motion of N rand particles according to the laws of elastic collisions."""
# TBD: DO PYTHON PORT

class CollisionSystem(object):
    private MinPQ<Event> pq;        # the priority queue
    private double t  = 0.0;        # simulation clock time
    private double hz = 0.5;        # number of redraw events per clock tick
    private Particle[] particles;   # the array of particles

    # create a new collision system with the given set of particles
    public CollisionSystem(Particle[] particles):
        this.particles = particles.clone();   # defensive copy

    # updates priority queue with all new events for particle a
    def _predict(Particle a, double limit):
        if a == None) return

        # particle-particle collisions
        for (int i = 0; i < len(particles); i += 1):
            double dt = a.timeToHit(particles[i])
            if t + dt <= limit)
                pq.insert(new Event(t + dt, a, particles[i]))

        # particle-wall collisions
        double dtX = a.timeToHitVerticalWall()
        double dtY = a.timeToHitHorizontalWall()
        if t + dtX <= limit) pq.insert(new Event(t + dtX, a, None))
        if t + dtY <= limit) pq.insert(new Event(t + dtY, None, a))

    # redraw all particles
    def _redraw(double limit):
        StdDraw.clear()
        for (int i = 0; i < len(particles); i += 1):
            particles[i].draw()
        StdDraw.show(20)
        if t < limit):
            pq.insert(new Event(t + 1.0 / hz, None, None))

      
   #**************************************************************************
    #  Event based simulation for limit seconds.
    #**************************************************************************/
    def simulate(double limit):
        
        # initialize PQ with collision events and redraw event
        pq = new MinPQ<Event>()
        for (int i = 0; i < len(particles); i += 1):
            predict(particles[i], limit)
        pq.insert(new Event(0, None, None));        # redraw event


        # the main event-driven simulation loop
        while (!pq.isEmpty()): 

            # get impending event, discard if invalidated
            Event e = pq.delMin()
            if !e.isValid()) continue
            Particle a = e.a
            Particle b = e.b

            # physical collision, so update positions, and then simulation clock
            for (int i = 0; i < len(particles); i += 1)
                particles[i].move(e.time - t)
            t = e.time

            # process event
            if      a != None and b != None) a.bounceOff(b);              # particle-particle collision
            elif (a != None and b == None) a.bounceOffVerticalWall();   # particle-wall collision
            elif (a == None and b != None) b.bounceOffHorizontalWall(); # particle-wall collision
            elif (a == None and b == None) redraw(limit);               # redraw event

            # update the priority queue with new collisions involving a or b
            predict(a, limit)
            predict(b, limit)


   #**************************************************************************
    #  An event during a particle collision simulation. Each event contains
    #  the time at which it will occur (assuming no supervening actions)
    #  and the particles a and b involved.
    #
    #    -  a and b both null:      redraw event
    #    -  a null, b not null:     collision with vertical wall
    #    -  a not null, b null:     collision with horizontal wall
    #    -  a and b both not null:  binary collision between a and b
    #
    #**************************************************************************/
    private static class Event implements Comparable<Event>:
        private final double time;         # time that event is scheduled to occur
        private final Particle a, b;       # particles involved in event, possibly None
        private final countA, countB;  # collision counts at event creation
                
        
        # create a new event to occur at time t involving a and b
        public Event(double t, Particle a, Particle b):
            this.time = t
            this.a    = a
            this.b    = b
            if a != None) countA = a.count()
            else           countA = -1
            if b != None) countB = b.count()
            else           countB = -1

        # compare times when two events will occur
        def compareTo(Event that):
            if      this.time < that.time) return -1
            elif (this.time > that.time) return +1
            else:                            return  0
        
        # has any collision occurred between when event was created and now?
        def isValid():
            if a != None and a.count() != countA) return False
            if b != None and b.count() != countB) return False
            return True
   


   #**************************************************************************
    #  Sample client.
    #**************************************************************************/
    def main(String[] args):

        StdDraw.setCanvasSize(800, 800)

        # remove the border
        # StdDraw.setXscale(1.0/22.0, 21.0/22.0)
        # StdDraw.setYscale(1.0/22.0, 21.0/22.0)

        # turn on animation mode
        StdDraw.show(0)

        # the array of particles
        Particle[] particles

        # create N random particles
        if len(args) == 1):
            N = Integer.parseInt(args[0])
            particles = new Particle[N]
            for (int i = 0; i < N; i += 1)
                particles[i] = new Particle()

        # or read from standard input
        else:
            N = StdIn.readInt()
            particles = new Particle[N]
            for (int i = 0; i < N; i += 1):
                double rx     = StdIn.readDouble()
                double ry     = StdIn.readDouble()
                double vx     = StdIn.readDouble()
                double vy     = StdIn.readDouble()
                double radius = StdIn.readDouble()
                double mass   = StdIn.readDouble()
                r         = StdIn.readInt()
                g         = StdIn.readInt()
                b         = StdIn.readInt()
                Color color   = new Color(r, g, b)
                particles[i] = new Particle(rx, ry, vx, vy, radius, mass, color)

        # create collision system and simulate
        CollisionSystem system = new CollisionSystem(particles)
        system.simulate(10000)
      

#*****************************************************************************
 #  Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
 #
 #  This file is part of algs4.jar, which accompanies the textbook
 #
 #      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 #      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 #      http://algs4.cs.princeton.edu
 #
 #
 #  algs4.jar is free software: you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
 #  the Free Software Foundation, either version 3 of the License, or
 #  (at your option) any later version.
 #
 #  algs4.jar is distributed in the hope that it will be useful,
 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #  GNU General Public License for more details.
 #
 #  You should have received a copy of the GNU General Public License
 #  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 #*****************************************************************************/

# QUESTION: How many priority queue operations are performed for each collision
# in the worst case?
# ANSWER: linear. In the worst case, each of the two colliding particles might
# be predicted to collide with each other of the other particles (and two walls).
# In practice, the number of priority queue operations will be much much smaller.

# Java last updated: Mon Sep 28 11:36:16 EDT 2015.


================================================
FILE: AlgsSedgewickWayne/Date.py
================================================
"""An example of an immutable type which can be used as a key for a Symbol Table."""

from datetime import date, timedelta
import re

class Date:
    """an immutable data type to encapsulate a date (day, month, and year)."""

    def __init__(self, str_month, day=None, year=None):
        """Initializes new date specified as a string in form MM/DD/YYYY."""
        if day is None and year is None:
            self.date = self._init_w_str(str_month)
        else:
            self.date = self._init_w_ints(year, str_month, day)

    def month(self):
        """Return month integer"""
        return self.date.month

    def day(self):
        """Return day integer"""
        return self.date.day

    def year(self):
        """Return year integer"""
        return self.date.year

    @staticmethod
    def is_leap_year(year):
        """is year a leap year?"""
        if year % 400 == 0:
            return True
        if year % 100 == 0:
            return False
        return year % 4 == 0

    def next(self):
        """return a date that represents the next day after this day"""
        nxt = self.date + timedelta(days=1)
        return Date(nxt.month, nxt.day, nxt.year)

    def __gt__(self, that):
        """return True if this date is after that date; False otherwise."""
        return self.date > that.date

    def __ge__(self, that):
        """return True if this date is the same or after that date; False otherwise."""
        return self.date >= that.date

    def __lt__(self, that):
        """return True if this date is before that date; False otherwise."""
        return self.date < that.date

    def __le__(self, that):
        """return True if this date is the same or before that date; False otherwise."""
        return self.date <= that.date

    def __str__(self):
        """Returns a string representation of this date."""
        return "{self.month()}/{self.day()}/{self.year()}"

    def __eq__(self, other):
        """return True if this date equals other; False otherwise."""
        if other is self:
            return True
        if other is None:
            return False
        if type(other).__name__ != type(self).__name__:
            return False
        return self.date == other.date

    #d  ef hashCode():
    #    """Returns an integer hash code for this date."""
    #    hash = 17
    #    hash = 31*hash + month
    #    hash = 31*hash + day
    #    hash = 31*hash + year
    #    return hash

    @staticmethod
    def java_string_hashcode(txt):
        """Returns same result as java'txt String.hashCode()"""
        # From: https://gist.github.com/hanleybrand/5224673#file-java_string_hashcode-py
        hashcode = 0
        for letter in txt:
            hashcode = (31 * hashcode + ord(letter)) & 0xFFFFFFFF
        return ((hashcode + 0x80000000) & 0xFFFFFFFF) - 0x80000000

    def _init_w_str(self, date_str):
        """Get date from the string representation of this date."""
        mtch = re.match(r'(\d{1,2})/(\d{1,2})/(\d{4})', date_str) # MM/DD/YYYY
        if mtch:
            return date(int(mtch.group(3)), int(mtch.group(1)), int(mtch.group(2)))
        raise RuntimeError("Invalid date. Expected MM/DD/YYYY")

    def _init_w_ints(self, year, month, day):
        """Init date object from int values."""
        try:
            return date(year, month, day)
        except Exception as exc:
            # pylint: disable=line-too-long
            raise RuntimeError(f"COULD NOT CREATE date(year={year}, month={month}, day={day})") from exc

# Java last updated: Thu Sep 24 14:16:15 EDT 2015.


================================================
FILE: AlgsSedgewickWayne/DepthFirstDirectedPaths.py
================================================
"""Computes a path between source vertex, s, and every other vertex in undirected graph G."""

class DepthFirstDirectedPaths(object):
  """This implementation uses depth-first search."""

  def __init__(self, G, s):
    self.s = s # source vertex
    self.edgeTo = [None for i in range(G.V())] # edgeTo[v] = last edge on s-v path
    self.marked = [False for i in range(G.V())] # marked[v] = is there an s-v path?
    self._dfs(G, s)

  def _dfs(self, G, v):
    """depth first search from v"""
    self.marked[v] = True
    for w in G.adj(v):
      if not self.marked[w]:
        self.edgeTo[w] = v
        self._dfs(G, w)

  def hasPathTo(self, v):
    """Is there a path between the source vertex s and vertex v?"""
    return self.marked[v]

  def pathTo(self, v):
    """Returns a path between the source vertex s and vertex v, or None"""
    if not self.hasPathTo(v): return None
    path = [] # Stack()
    x = v
    while x != self.s:
      path.append(x) # push(x)
      x = self.edgeTo[x]
    path.append(self.s) # push(self.s)
    return path # seq of vertices on path between vertices, s and v

# DEPTH-FIRST SEARCH PROPERTIES
#
# PROPOSITION: DFS marks all vertices connected to s in time proportional to 
# the sum of their degrees.
# 
# PROPOSITION: After DFS, can find vertices connected to s in constant time
# and can find a path to s (if one exists) in time proportional to its length.

# QUESTION: In a Graph G represented using the adjacency-lists representation,
# depth-first search marks all vertices connected to s in time proportional to
# ANSWER: The sum of the degrees of the vertices in the connected component
# containing s

# QUESTION: The critical data structures used in depth-first search and
# breadth-first search are _____ and ____, respectively.
# ANSWER: DFS->Stack BFS->Queue
# EXPLANATION: With DFS, it is either an explicit stack(w/ nonrecursive version)
# or the function-call stack (w/a recursive version)

# QUESTION: Suppose that during an execution of depth-first search in a digraph G,
# dfs(v) is called after dfs(w) is called but before dfs(w) returns. Which 
# of the following must be true of graph G?
# ANSWER: There exists a directed path from w to v.
# EXPLANATION: The function call stack bwtween when w and v are called contains a 
# directed path from w to v.

# QUESTION from Topological Sort (12:54): 
# Let G be a directed acyclic graph (DAG) containing an edge v->w.
# Suppose that dfs(v) is called during an execution of depth-first search.
# Which one of the following is impossible?
#     dfs(w) has not yet been called.
#     dfs(w) will be the next recursive call after dfs(v)
# --> dfs(w) has already been called but not yet returned
#     dfs(w) has already been called and returned
# EXPLANATION: If dfs(v) is called before dfs(w) returns, then the function
# call-stack contains a directed path from w to v (as in the previous in-video
# quiz). Combining this path with the edge v->w yeilds a directed cycle, which 
# is impossible since G is acylic.

# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python implementation


================================================
FILE: AlgsSedgewickWayne/DepthFirstOrder.py
================================================
# /******************************************************************************
#  *  Compilation:  javac DepthFirstOrder.java
#  *  Execution:    java DepthFirstOrder digraph.txt
#  *  Dependencies: Digraph.java Queue.java Stack.java StdOut.java
#  *                EdgeWeightedDigraph.java DirectedEdge.java
#  *  Data files:   https://algs4.cs.princeton.edu/42digraph/tinyDAG.txt
#  *                https://algs4.cs.princeton.edu/42digraph/tinyDG.txt
#  *
#  *  Compute preorder and postorder for a digraph or edge-weighted digraph.
#  *  Runs in O(E + V) time.
#  *
#  *  % java DepthFirstOrder tinyDAG.txt
#  *     v  pre post
#  *  --------------
#  *     0    0    8
#  *     1    3    2
#  *     2    9   10
#  *     3   10    9
#  *     4    2    0
#  *     5    1    1
#  *     6    4    7
#  *     7   11   11
#  *     8   12   12
#  *     9    5    6
#  *    10    8    5
#  *    11    6    4
#  *    12    7    3
#  *  Preorder:  0 5 4 1 6 9 11 12 10 2 3 7 8 
#  *  Postorder: 4 5 1 12 11 10 9 6 0 3 2 7 8 
#  *  Reverse postorder: 8 7 2 3 0 6 9 10 11 12 1 5 4 
#  *
#  ******************************************************************************/
# 
# package edu.princeton.cs.algs4
# 
# /**
#  *  The {@code DepthFirstOrder} class represents a data type for 
#  *  determining depth-first search ordering of the vertices in a digraph
#  *  or edge-weighted digraph, including preorder, postorder, and reverse postorder.
#  *  <p>
#  *  This implementation uses depth-first search.
#  *  Each constructor takes &Theta;(<em>V</em> + <em>E</em>) time,
#  *  where <em>V</em> is the number of vertices and <em>E</em> is the
#  *  number of edges.
#  *  Each instance method takes &Theta;(1) time.
#  *  It uses &Theta;(<em>V</em>) extra space (not including the digraph).
#  *  <p>
#  *  For additional documentation,
#  *  see <a href="https://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
#  *  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
#  *
#  *  @author Robert Sedgewick
#  *  @author Kevin Wayne
#  */
class DepthFirstOrder:
    """Determines a depth-first order for the digraph"""
    private boolean[] marked;          // marked[v] = has v been marked in dfs?
    private int[] pre;                 // pre[v]    = preorder  number of v
    private int[] post;                // post[v]   = postorder number of v
    private Queue<Integer> preorder;   // vertices in preorder
    private Queue<Integer> postorder;  // vertices in postorder
    private int preCounter;            // counter or preorder numbering
    private int postCounter;           // counter for postorder numbering

    def __init__(self, dag):
        self._pre    = new int[dag.V()]
        self._post   = new int[dag.V()]
        self._postorder = new Queue<Integer>()
        self._preorder  = new Queue<Integer>()
        self._marked    = new boolean[dag.V()]
        for (int v = 0; v < dag.V(); v++)
            if (!marked[v]) dfs(dag, v)

        assert check()

    /**
     * Determines a depth-first order for the edge-weighted digraph {@code dag}.
     * @param dag the edge-weighted digraph
     */
    public DepthFirstOrder(EdgeWeightedDigraph dag) {
        pre    = new int[dag.V()]
        post   = new int[dag.V()]
        postorder = new Queue<Integer>()
        preorder  = new Queue<Integer>()
        marked    = new boolean[dag.V()]
        for (int v = 0; v < dag.V(); v++)
            if (!marked[v]) dfs(dag, v)
    }

    // run DFS in digraph dag from vertex v and compute preorder/postorder
    private void dfs(Digraph dag, int v) {
        marked[v] = true
        pre[v] = preCounter++
        preorder.enqueue(v)
        for (int w : dag.adj(v)) {
            if (!marked[w]) {
                dfs(dag, w)
            }
        }
        postorder.enqueue(v)
        post[v] = postCounter++
    }

    // run DFS in edge-weighted digraph dag from vertex v and compute preorder/postorder
    private void dfs(EdgeWeightedDigraph dag, int v) {
        marked[v] = true
        pre[v] = preCounter++
        preorder.enqueue(v)
        for (DirectedEdge e : dag.adj(v)) {
            int w = e.to()
            if (!marked[w]) {
                dfs(dag, w)
            }
        }
        postorder.enqueue(v)
        post[v] = postCounter++
    }

    /**
     * Returns the preorder number of vertex {@code v}.
     * @param  v the vertex
     * @return the preorder number of vertex {@code v}
     * @throws IllegalArgumentException unless {@code 0 <= v < V}
     */
    public int pre(int v) {
        validateVertex(v)
        return pre[v]
    }

    /**
     * Returns the postorder number of vertex {@code v}.
     * @param  v the vertex
     * @return the postorder number of vertex {@code v}
     * @throws IllegalArgumentException unless {@code 0 <= v < V}
     */
    public int post(int v) {
        validateVertex(v)
        return post[v]
    }

    /**
     * Returns the vertices in postorder.
     * @return the vertices in postorder, as an iterable of vertices
     */
    public Iterable<Integer> post() {
        return postorder
    }

    /**
     * Returns the vertices in preorder.
     * @return the vertices in preorder, as an iterable of vertices
     */
    public Iterable<Integer> pre() {
        return preorder
    }

    /**
     * Returns the vertices in reverse postorder.
     * @return the vertices in reverse postorder, as an iterable of vertices
     */
    public Iterable<Integer> reversePost() {
        Stack<Integer> reverse = new Stack<Integer>()
        for (int v : postorder)
            reverse.push(v)
        return reverse
    }


    // check that pre() and post() are consistent with pre(v) and post(v)
    private boolean check() {

        // check that post(v) is consistent with post()
        int r = 0
        for (int v : post()) {
            if (post(v) != r) {
                StdOut.println("post(v) and post() inconsistent")
                return false
            }
            r++
        }

        // check that pre(v) is consistent with pre()
        r = 0
        for (int v : pre()) {
            if (pre(v) != r) {
                StdOut.println("pre(v) and pre() inconsistent")
                return false
            }
            r++
        }

        return true
    }

    // throw an IllegalArgumentException unless {@code 0 <= v < V}
    private void validateVertex(int v) {
        int V = marked.length
        if (v < 0 || v >= V)
            throw new IllegalArgumentException("vertex " + v + " is not between 0 and " + (V-1))
    }

    /**
     * Unit tests the {@code DepthFirstOrder} data type.
     *
     * @param args the command-line arguments
     */
    public static void main(String[] args) {
        In in = new In(args[0])
        Digraph dag = new Digraph(in)

        DepthFirstOrder dfs = new DepthFirstOrder(dag)
        StdOut.println("   v  pre post")
        StdOut.println("--------------")
        for (int v = 0; v < dag.V(); v++) {
            StdOut.printf("%4d %4d %4d\n", v, dfs.pre(v), dfs.post(v))
        }

        StdOut.print("Preorder:  ")
        for (int v : dfs.pre()) {
            StdOut.print(v + " ")
        }
        StdOut.println()

        StdOut.print("Postorder: ")
        for (int v : dfs.post()) {
            StdOut.print(v + " ")
        }
        StdOut.println()

        StdOut.print("Reverse postorder: ")
        for (int v : dfs.reversePost()) {
            StdOut.print(v + " ")
        }
        StdOut.println()


    }

}

# Copyright 2002-present, Robert Sedgewick and Kevin Wayne.
# Copyright 2002-present, DV Klopfenstein, Python port


================================================
FILE: AlgsSedgewickWayne/DepthFirstPaths.py
================================================
"""Computes a path between source vertex, s, and every other vertex in undirected graph G."""

import collections as cx

class DepthFirstPaths(object):
  """This implementation uses depth-first search."""

  def __init__(self, G, s, prt=None):
    self.s = s # source vertex
    self.edgeTo = cx.OrderedDict([(v, None)  for v in G.keys]) # edgeTo[v] = last edge on s-v path
    self.marked = cx.OrderedDict([(v, False) for v in G.keys]) # marked[v] = is there an s-v path?
    self.prt = prt
    self._dfs(G, s)

  def _dfs(self, G, v):
    """depth first search from v"""
    self._set_mark(v, G)
    for w in G.adj(v):
      if not self.marked[w]:
        self.edgeTo[w] = v
        self._dfs(G, w)

  def hasPathTo(self, v):
    """Is there a path between the source vertex s and vertex v?"""
    return self.marked[v]

  def pathTo(self, v):
    """Returns a path between the source vertex s and vertex v, or None"""
    if not self.hasPathTo(v): return None
    path = [] # Stack()
    x = v
    while x != self.s:
      path.append(x) # push(x)
      x = self.edgeTo[x]
    path.append(self.s) # push(self.s)
    return path # seq of vertices on path between vertices, s and v

  def _set_mark(self, v, G):
    """Set mark and print which mark was set, if desired."""
    self.marked[v] = True 
    if self.prt is not None: 
      self.prt.write("{} ".format(v))

# DEPTH-FIRST SEARCH PROPERTIES
#
# PROPOSITION: DFS marks all vertices connected to s in time proportional to 
# the sum of their degrees.
# 
# PROPOSITION: After DFS, can find vertices connected to s in constant time
# and can find a path to s (if one exists) in time proportional to its length.

# QUESTION: In a Graph G represented using the adjacency-lists representation,
# depth-first search marks all vertices connected to s in time proportional to
# ANSWER: The sum of the degrees of the vertices in the connected component
# containing s

# QUESTION: The critical data structures used in depth-first search and
# breadth-first search are _____ and ____, respectively.
# ANSWER: DFS->Stack BFS->Queue
# EXPLANATION: With DFS, it is either an explicit stack(w/ nonrecursive version)
# or the function-call stack (w/a recursive version)

# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python implementation


================================================
FILE: AlgsSedgewickWayne/DepthFirstSearch.py
================================================
"""Run depth first search on an undirected graph. O(E + V) time."""
# https://algs4.cs.princeton.edu/41graph


class DepthFirstSearch:
    """Gets vertices in graph connected to the source vertex (src_node) O(E + V)"""

    def __init__(self, graph_undirected, src_node):
        """Gets vertices in graph connected to the source vertex (src_node) O(E + V)"""
        # marked[v] = is there an s-v path?
        # THETA(V) extra space (not including the graph)
        self.marked = [False for _ in range(graph_undirected.num_nodes)]
        # number of vertices connected to s
        self.cnt = 0
        self._validate_vertex(src_node)
        self._dfs(graph_undirected, src_node)

    def _dfs(self, graph, node_v):
        """depth first search from node_v"""
        self.cnt += 1
        self.marked[node_v] = True
        for node_w in graph.adj(node_v):
            if not self.marked[node_w]:
                self._dfs(graph, node_w)

    def is_marked(self, node_v):
        """Return True if exists a path between the source vertex {@code s} and vertex {@code v}"""
        self._validate_vertex(node_v)
        return self.marked[node_v]

    def count(self):
        """Get number of vertices connected to the source vertex"""
        return self.cnt

    def _validate_vertex(self, node_v):
        """throw an IllegalArgumentException unless {@code 0 <= node_v < V}"""
        num_nodes = len(self.marked)
        if node_v < 0 or node_v >= num_nodes:
            raise RuntimeError("vertex {V} is not between 0 and {Z}".format(
                V=node_v, Z=num_nodes-1))


# Copyright 2002-present, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-present, DV Klopfenstein, Python implementation


================================================
FILE: AlgsSedgewickWayne/Digraph.py
================================================
"""A directed graph, implemented using an array of lists. Parallel edges & self-loops permitted."""
# pylint: disable=invalid-name
# ../algs4/src/main/java/edu/princeton/cs/algs4/Digraph.java

import sys
from AlgsSedgewickWayne.testcode.utils import adjtxtblk2OrderedDict

class Digraph:
    """A directed graph, implemented w/array of lists. Parallel edges & self-loops permitted."""

    def __init__(self, arr=None, **kwargs):
        if arr is not None:
            if isinstance(arr, int):
                ## print('DIGRAPH ARRAY INPUT:', arr)
                self._init_empty(arr)
            elif len(arr) == 1:
                self._init_empty(arr[0])
            else:
                self._init(arr)
            self.keys = range(self.num_vertices)
        elif 'adjtxt' in kwargs:
            self._adj = adjtxtblk2OrderedDict(kwargs['adjtxt'])
            self.num_vertices = len(self._adj)
            # pylint: disable=line-too-long
            self.num_edges = len(set(tuple(sorted([v, w])) for v, ws in self._adj.items() for w in ws))
            self.keys = self._adj.keys()

    def _init_empty(self, num_vertices):
        ## print(f'DIGRAPH INIT {num_vertices} VERTICES')
        if num_vertices < 0:
            raise RuntimeError("Number of vertices must be nonnegative")
        self.num_vertices = num_vertices # number of vertices
        self.num_edges = 0 # number of edges
        self._adj = [set() for v in range(num_vertices)]
        self._indegree = [0]*num_vertices # indegree[v] = indegree of vertex v

    def _init(self, arr):
        """Initializes arr graph from an input stream."""
        # The format is the number of vertices V, followed by the number of edges E,
        # followed by E pairs of vertices, with each entry separated by whitespace.
        self._init_empty(arr[0]) # init V, and the empty adj list
        num_edges = arr[1]
        if num_edges < 0:
            raise RuntimeError("Number of edges must be nonnegative")
        for src_v, dst_w in arr[2:]:
            self.addEdge(src_v, dst_w)

    def V(self):
        """Returns the number of vertices in self graph"""
        return self.num_vertices

    def E(self):
        """Returns the number of edges in self graph"""
        return self.num_edges

    def addEdge(self, src_v, dst_w):
        """Adds the undirected edge src_v-dst_w to self graph."""
        #self._validateVertex(src_v)
        #self._validateVertex(dst_w)
        self.num_edges += 1
        self._adj[src_v].add(dst_w)
        self._indegree[dst_w] += 1

    def adj(self, src_v):
        """Returns the vertices adjacent to vertex src_v."""
        #self._validateVertex(src_v)
        return self._adj[src_v]

    def outdegree(self, src_v):
        """Returns the number of directed edges incident from vertex src_v."""
        #self._validateVertex(src_v)
        return self._adj[src_v].size()

    def indegree(self, src_v):
        """Returns the number of directed edges incident to vertex src_v."""
        #self._validateVertex(src_v)
        return self._indegree[src_v]

    def reverse(self):
        """Get the reverse of the digraph."""
        rev_digraph = Digraph(self.num_vertices)
        for src_v in range(self.num_vertices):
            for dst_w in self._adj(src_v):
                rev_digraph.addEdge(dst_w, src_v)
        return rev_digraph

    #def _validateVertex(self, src_v):
    #    """raise an IndexOutOfBoundsException unless 0 <= src_v < V."""
    #    if src_v < 0 or src_v >= self.num_vertices or src_v not in self._adj:
    #        raise Exception("vertex {} not between 0 and {} or in {}".format(
    #    src_v, self.num_vertices-1, self._adj))

    def __str__(self):
        txt = [(f"{self.num_vertices} vertices, {self.num_edges} edges\n")]
        for src_v in self.keys:
            txt.append(f"{src_v}: ")
            for dst_w in self._adj[src_v]:
                txt.append(f"{dst_w} ")
            txt.append("\n")
        return ''.join(txt)

    def __iter__(self): # Makes Graph an iterable.
        return iter(self._adj) # returns an iterator.

    def wr_png(self, fout_png="Digraph.png", prt=sys.stdout):
        """Make a png showing a diagram of the connected components."""
        dot_digraph = self.get_pydot_digraph()
        # pylint: disable=no-member
        dot_digraph.write_png(fout_png)
        prt.write(f"  WROTE: {fout_png}\n")

    def get_pydot_digraph(self):
        """Make a pydot graph showing a diagram of the connected components."""
        import pydot
        # 1. Create/initialize Graph
        digraph = pydot.Dot(graph_type='digraph') # Undirected Graph
        # 2. Create Nodes
        nodes = [pydot.Node(src_v) for src_v in self.keys]
        # 3. Add nodes to Graph
        for node in nodes:
            digraph.add_node(node)
        # 4. Add Edges between Nodes to Graph
        for src_v, dst_w in self.get_edges():
            if src_v != dst_w: # Print only edges from one node to another (not to self)
                digraph.add_edge(pydot.Edge(src_v, dst_w))
        return digraph

    def get_edges(self):
        """Get all the edges of this directed graph"""
        edges = set()
        for src_v in self.keys:
            for dst_w in self._adj[src_v]:
                ###edges.add(tuple(sorted([src_v, dst_w])))
                edges.add(tuple([src_v, dst_w]))
        return edges

 #*****************************************************************************/
 #  % Graph.py ../thirdparty/tinyG.txt
 #  13 vertices, 13 edges
 #  0: 6 2 1 5
 #  1: 0
 #  2: 0
 #  3: 5 4
 #  4: 5 6 3
 #  5: 3 4 0
 #  6: 0 4
 #  7: 8
 #  8: 7
 #  9: 11 10 12
 #  10: 9
 #  11: 9 12
 #  12: 11 9
 #
 #*****************************************************************************/

# -----------------------------------------------------------------------------
# INTRODUCTION TO GRAPHS (9:32)


# SOME GRAPH-PROCESSING PROBLEMS 08:14
#
# PATH: Is there a path between s and t?
# SHORTEST PATH: What is the shortest path between s and t?
#
# CYCLE: Is there a cycle in the graph?
# EULER TOUR: Is there a cycle that uses each edge exactly once?
# HAMILTON TOUR: Is there a cycle that uses each vertex exactly once?
#
# CONNECTIVITY: Is there a awy to connect all of the vertices?
# MST: What is the best way to connect all of the vertices?
# BICONNECTIVITY: Is there a vertex whose removeal disconnects the graph?
#
# PLANARITY: Can you draw the graph in the plane with no crossing edges?
# GRAPH ISOMORPHISM: Do two adjacency lists represent the same graph?
#
# CHALLENGE: Whinc of these problems are easy? difficult? intractable?



# QUESTION: A cycle that uses eachedge of a graph exactly once is called
# ANSWER: An Euler tour

#  Copyright 2002-present, Robert Sedgewick and Kevin Wayne.
#  Copyright 2015-present, DV Klopfenstein, PhD, Python implementation


================================================
FILE: AlgsSedgewickWayne/DijkstraSP.py
================================================
"""Dijkstra's algorithm. Computes the shortest path tree. Assumes all weights are nonnegative."""

class DijkstraSP(object):
  """Get shortest-paths tree from src vertex s to every other vertex in the edge-weighted DAG G."""
  private IndexMinPQ<Double> pq;    # priority queue of vertices

  Inf = float('Inf')

  def __init__(self, G, s): # EdgeWeightedDigraph O(E lof V)
    for e in G.edges():
      if e.weight() < 0:
        raise Exception("edge {} has negative weight".format(e))

    self._distTo = [self.Inf for i in range(G.V())] # distTo[v] = distance  of shortest s->v path
    self._edgeTo = [None for i in range(G.V())]     # edgeTo[v] = last edge on shortest s->v path
    self._distTo[s] = 0.0

    # relax vertices in order of distance from s
    pq = new IndexMinPQ<Double>(G.V())
    pq.insert(s, distTo[s])
    while (!pq.isEmpty()):
      v = pq.delMin()
      for e in G.adj(v):
        self._relax(e)

    # check optimality conditions
    assert _check(G, s)

  def _relax(self, e):
    """relax edge e and update pq if changed"""
    v, w = e.get_from_to()
    if self._distTo[w] > (self._distTo[v] + e.weight()):
       self._distTo[w] =  self._distTo[v] + e.weight()
       self._edgeTo[w] = e
       if pq.contains(w): pq.decreaseKey(w, self._distTo[w])
       else               pq.insert(w, self._distTo[w])

  def distTo(self, v): # O(k)
    """Returns the length of a shortest path from the source vertex s to vertex v."""
    return self._distTo[v]

  def hasPathTo(self, v): # O(k)
    """Returns true if there is a path from the source vertex s to vertex v."""
    return self._distTo[v] < self.Inf

  def pathTo(self, v):
    """Returns a shortest path from the source vertex s to vertex v."""
    if not hasPathTo(v): return None
    path = [] # new Stack<DirectedEdge>()
    e = edgeTo[v]
    while e is not None: 
      path.append(e) # push(e)
      e = self.edgeTo[e.from()]
    return path


  # check optimality conditions:
  # (i) for all edges e:            distTo[e.to()] <= distTo[e.from()] + e.weight()
  # (ii) for all edge e on the SPT: distTo[e.to()] == distTo[e.from()] + e.weight()
  def _check(EdgeWeightedDigraph G, s):

      # check that edge weights are nonnegative
      for (DirectedEdge e : G.edges()):
          if e.weight() < 0):
              System.err.println("negative edge weight detected")
              return False

      # check that distTo[v] and edgeTo[v] are consistent
      if distTo[s] != 0.0 or edgeTo[s] is not None):
          System.err.println("distTo[s] and edgeTo[s] inconsistent")
          return False
      for (int v = 0; v < G.V(); v += 1):
          if v == s) continue
          if edgeTo[v] is None and distTo[v] != Double.POSITIVE_INFINITY):
              System.err.println("distTo[] and edgeTo[] inconsistent")
              return False

      # check that all edges e = v->w satisfy distTo[w] <= distTo[v] + e.weight()
      for (int v = 0; v < G.V(); v += 1):
          for (DirectedEdge e : G.adj(v)):
              w = e.to()
              if distTo[v] + e.weight() < distTo[w]):
                  System.err.println("edge " + e + " not relaxed")
                  return False

      # check that all edges e = v->w on SPT satisfy distTo[w] == distTo[v] + e.weight()
      for (int w = 0; w < G.V(); w += 1):
          if edgeTo[w] is None) continue
          DirectedEdge e = edgeTo[w]
          v = e.from()
          if w != e.to()) return False
          if distTo[v] + e.weight() != distTo[w]):
              System.err.println("edge " + e + " on shortest path not tight")
              return False
      return True

# Dijkstra's Algorithm (18:58)
#
# PQ implementation insert    delete-min decrease-key total
# ----------------- ------    ---------- ------------ -----
# unordered array      1           V          1         V^2
# binary heap        log V       log V      log V     E log V
# d-way heap       d log_d V   d log_d V   log_d V   E log_E/V V
# Fibonacci heap       1         log V        1      E + V log V
#
# BOTTOM LINE:
#   * Array implementation optiomal for dense graphs
#   * Binary heap faster for sparse graphs.
#   * 4-way heap wort the trouble in preformance-critical situations
#   * Fibonacci heap best in theory, but not worht implementing.

# QUESTION: What is the order of growth of the running time of Dijkstra's 
# algorithm using a binary heap: Assume that all vertices are reachable 
# from the source.
# ANSWER: E log V
# EXPLANATION: The bottleneck is the hap operations. There are at most
# V insert, V delete-min, and E decrease-key operations. Each operation
# is logarithmic in the size of the binary heap, which is at most V.

# DIJKSTRA'S Algorithm is GREEDY (so cannot do negative edges)





# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python port


================================================
FILE: AlgsSedgewickWayne/DirectedDFS.py
================================================
"""Data type for determining the vertices reachable from a given src vertex(s)."""
# pylint: disable=invalid-name


class DirectedDFS:
    """Data type for determining the vertices reachable from a given src vertex(s)."""

    def __init__(self, graph, sources): # O ~ V + E (wc)
        if isinstance(sources, int):
            self._init(graph, [sources])
        else:
            self._init(graph, sources)

    def _init(self, graph, sources):
        """Computes vertices in digraph graph that are connected to any src vertices, sources"""
        ## print(f'DirectedDFS ON GRAPH({graph})')
        self._marked = [False for _ in range(graph.num_vertices)] # True if v is reachable from src (or srcs)
        self._count = 0 # number of vertexertices reachable from s
        for vertex in sources:
            if not self._marked[vertex]:
                self._dfs(graph, vertex)

    def _dfs(self, graph, v_src):
        """Depth First Search; Recursively called"""
        self._count += 1
        self._marked[v_src] = True
        for w_dst in graph.adj(v_src):
            if not self._marked[w_dst]:
                self._dfs(graph, w_dst)

    def marked(self, vertex):
        """Directed path from source vertex (or any of the source vertices) and vertex ?"""
        return self._marked[vertex]

    def count(self):
        """Returns the number of vertices reachable from the source vertex"""
        return self._count


# Copyright 2002-present, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-present, DV Klopfenstein, Python implementation.


================================================
FILE: AlgsSedgewickWayne/DirectedEdge.py
================================================
"""Immutable weighted directed edge."""

class DirectedEdge(object): 
  """a directed edge from vertex v to vertex w with the given weight"""

  def __init__(self, v, w, weight):
    if v < 0: raise Exception("Vertex names must be nonnegative integers")
    if w < 0: raise Exception("Vertex names must be nonnegative integers")
    if not isinstance(weight, float): raise Exception("Weight is NaN")
    self._v = v # the tail vertex
    self._w = w # the head vertex
    self._weight = weight # the weight of the directed edge

  def get_from(self): return self._v # Returns the tail vertex of the directed edge.
  def get_to(self): return self._w # Returns the head vertex of the directed edge.
  def get_from_to(self): return [self._v, self._w]
  def get_weight(self): return self._weight # Returns the weight of the directed edge.
  def __str__(self):
    return "{v} -> {w} {wt:5.2f}".format(v=self._v, w=self._w, wt=self._weight)

# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python port


================================================
FILE: AlgsSedgewickWayne/Edge.py
================================================
"""Immutable weighted edge."""
# pylint: disable=invalid-name


class Edge:
    """Edge between two vertices"""

    def __init__(self, v, w, weight):
        if v < 0:
            raise Exception("Vertex name must be a nonnegative integer")
        if w < 0:
            raise Exception("Vertex name must be a nonnegative integer")
        if not isinstance(weight, float):
            raise Exception("Weight is NaN")
        self.v_src = v
        self.w_dst = w
        self.weight = weight

    def either(self):
        """Returns either endpoint of self edge"""
        return self.v_src

    def get_vw(self):
        """Get both vertices attached to this edge"""
        return [self.v_src, self.w_dst]

    def other(self, vertex):
        """Returns the endpoint of self edge that is different from the given vertex."""
        if vertex == self.v_src:
            return self.w_dst
        if vertex == self.w_dst:
            return self.v_src
        raise Exception("Illegal endpoint")

    def compare_to(self, that):
        """Compares two edges by weight."""
        if self.weight < that.weight:
            return -1
        if self.weight > that.weight:
            return +1
        return  0

    def __str__(self):
        return "{}-{} {:.5f}".format(
            self.v_src, self.w_dst, self.weight)


# Copyright 2002-present Robert Sedgewick and Kevin Wayne.
# Copyright 2002-present DV Klopfenstein, Pythom port


================================================
FILE: AlgsSedgewickWayne/EdgeWeightedDigraph.py
================================================
"""An edge-weighted digraph, implemented using adjacency lists."""
# TBD: Finish Python port

from AlgsSedgewickWayne.DirectedEdge import DirectedEdge
import random

class EdgeWeightedDigraph(object):
  
  def __init__(self, V, E=None):
    if isinstance(V, int):
      self._init_VE(V, E)
    else:
      self._init_arr(V)

  def _init_V(self, V):
    if V < 0: raise Exception("Number of vertices in a Digraph must be nonnegative")
    self._V = V # number of vertices in self digraph
    self._E = 0 # number of edges in self digraph
    self._indegree = new int[V] # adj[v] = adjacency list for vertex v
    self._adj = [set() for for v in range(V)] # indegree[v] = indegree of vertex v

  def _init_VE(self, V, E):
    """Initializes a random edge-weighted digraph with V vertices and E edges."""
    self._init_V(V)
    if E is not None:
      if E < 0: raise Exception("Number of edges in a Digraph must be nonnegative")
      for i in E:
        v = random.randint(0, V) # get random int in [0, V)
        w = random.randint(0, V)
        weight = .01 * random.uniform(100)
        e = DirectedEdge(v, w, weight)
        self.addEdge(e)

  def _init_arr(arr):
    """Initializes a random edge-weighted digraph with V vertices and E edges."""
    self._init_V(arr[0])
    self._E = arr[1]
    if E < 0: raise Exception("Number of edges must be nonnegative")
    for v, w, weight in a[2:]:
      if v < 0 or v >= self._V: raise Exception("vertex {} is not between 0 and {}".format(v, (V-1)))
      if w < 0 or w >= self._V: raise Exception("vertex {} is not between 0 and {}".format(w, (V-1)))
      self.addEdge(DirectedEdge(v, w, weight))

  def __copy__(self, G):
    """Initializes a new edge-weighted digraph that is a deep copy of G."""
    self._init_V(G.V())
    self._E = G.E()
    for v in range(G.V()):
      self._indegree[v] = G.indegree(v)
    for v in range(G.V()):
      # reverse so that adjacency list is in same order as original
      reverse = [] # new Stack<DirectedEdge>()
      for e in G._adj[v]:
        reverse.push(e)
      for e in reverse:
        self._adj[v].add(e)

  # number of vertices in this edge-weighted digraph.
  def V(self): return self._V

  # number of edges in this edge-weighted digraph.
  def E(self): return self._E

  # raise an IndexOutOfBoundsException unless 0 <= v < V
  def _validateVertex(self, v):
    if v < 0 or v >= self._V:
      raise Exception("vertex {} is not between 0 and {}".format(v, V-1))

  def addEdge(self, e):
    """Adds the directed edge <tt>e</tt> to this edge-weighted digraph."""
    v = e.get_from()
    w = e.get_to()
    self._validateVertex(v)
    self._validateVertex(w)
    self._adj[v].add(e)
    self._E += 1

  def adj(self, v):
    """Returns the directed edges incident from vertex v."""
    self._validateVertex(v)
    return self._adj[v]

  def outdegree(self, v):
    """Returns the number of directed edges incident from vertex v."""
    self._validateVertex(v)
    return self._adj[v].size()

  def indegree(self, v):
    """Returns the number of directed edges incident to vertex v."""
    self._validateVertex(v)
    return self._indegree[v]

  def edges(self):
    """Returns all directed edges in this edge-weighted digraph."""
    lst = set()
    for v in range(V):
      for e in self._adj(v):
        lst.add(e)
    return lst

  def __str__(self):
    s = ["{V} {E}\n".format(V=self._V, E=self._E)]
    for v in range(V):
      s.append("{v}: ".format(v=v))
      for e in self._adj[v]:
        s.append("{e} ".format(e=e))
      s.append("\n")
    return "".join(s)

# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python port


================================================
FILE: AlgsSedgewickWayne/EdgeWeightedDirectedCycle.py
================================================
"""Finds a directed cycle in an edge-weighted digraph."""
# TBD: Finish python port

#*****************************************************************************
 #  Compilation:  javac EdgeWeightedDirectedCycle.java
 #  Execution:    java EdgeWeightedDirectedCycle V E F
 #  Dependencies: EdgeWeightedDigraph.java DirectedEdge.java Stack.java
 #
 #  Runs in O(E + V) time.
 #
 #
 #*****************************************************************************/

#*
 #  The <tt>EdgeWeightedDirectedCycle</tt> class represents a data type for 
 #  determining whether an edge-weighted digraph has a directed cycle.
 #  The <em>hasCycle</em> operation determines whether the edge-weighted
 #  digraph has a directed cycle and, if so, the <em>cycle</em> operation
 #  returns one.
 #  <p>
 #  This implementation uses depth-first search.
 #  The constructor takes time proportional to <em>V</em> + <em>E</em>
 #  (in the worst case),
 #  where <em>V</em> is the number of vertices and <em>E</em> is the number of edges.
 #  Afterwards, the <em>hasCycle</em> operation takes constant time;
 #  the <em>cycle</em> operation takes time proportional
 #  to the length of the cycle.
 #  <p>
 #  See {@link Topological} to compute a topological order if the edge-weighted
 #  digraph is acyclic.
 #  <p>
 #  For additional documentation,   
 #  see <a href="http://algs4.cs.princeton.edu/44sp">Section 4.4</a> of   
 #  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne. 
 #
 #  @author Robert Sedgewick
 #  @author Kevin Wayne
 #/
public class EdgeWeightedDirectedCycle:
  private boolean[] marked;             # marked[v] = has vertex v been marked?
  private DirectedEdge[] edgeTo;        # edgeTo[v] = previous edge on path to v
  private boolean[] onStack;            # onStack[v] = is vertex on the stack?
  def _cycle(or None if no such cycle)

    #*
     # Determines whether the edge-weighted digraph <tt>G</tt> has a directed cycle and,
     # if so, finds such a cycle.
     # @param G the edge-weighted digraph
     #/
  public EdgeWeightedDirectedCycle(EdgeWeightedDigraph G):
      marked  = new boolean[G.V()]
      onStack = new boolean[G.V()]
      edgeTo  = new DirectedEdge[G.V()]
      for (int v = 0; v < G.V(); v += 1)
          if !marked[v]) dfs(G, v)

      # check that digraph has a cycle
      assert check(G)

  # check that algorithm computes either the topological order or finds a directed cycle
  def _dfs(EdgeWeightedDigraph G, v):
      onStack[v] = True
      marked[v] = True
      for (DirectedEdge e : G.adj(v)):
          w = e.to()

          # short circuit if directed cycle found
          if cycle is not None) return

          #found new vertex, so recur
          elif (!marked[w]):
              edgeTo[w] = e
              dfs(G, w)

          # trace back directed cycle
          elif (onStack[w]):
              cycle = new Stack<DirectedEdge>()
              while (e.from() != w):
                  cycle.push(e)
                  e = edgeTo[e.from()]
              cycle.push(e)
              return

      onStack[v] = False

    #*
     # Does the edge-weighted digraph have a directed cycle?
     # @return <tt>true</tt> if the edge-weighted digraph has a directed cycle,
     # <tt>false</tt> otherwise
     #/
  def hasCycle():
      return cycle is not None

    #*
     # Returns a directed cycle if the edge-weighted digraph has a directed cycle,
     # and <tt>null</tt> otherwise.
     # @return a directed cycle (as an iterable) if the edge-weighted digraph
     #    has a directed cycle, and <tt>null</tt> otherwise
     #/
  def cycle():
      return cycle


  # certify that digraph is either acyclic or has a directed cycle
  def _check(EdgeWeightedDigraph G):

      # edge-weighted digraph is cyclic
      if hasCycle()):
          # verify cycle
          DirectedEdge first = None, last = None
          for (DirectedEdge e : cycle()):
              if first is None) first = e
              if last is not None):
                  if last.to() != e.from()):
                      System.err.printf("cycle edges %s and %s not incident\n", last, e)
                      return False
              last = e

          if last.to() != first.from()):
              System.err.printf("cycle edges %s and %s not incident\n", last, first)
              return False


      return True

# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python port


================================================
FILE: AlgsSedgewickWayne/EdgeWeightedGraph.py
================================================
"""An edge-weighted undirected graph, implemented using adjacency lists."""
# pylint: disable=invalid-name

import random
from AlgsSedgewickWayne.Edge import Edge


class EdgeWeightedGraph:
    """Undirected weighter graph. Parallel edges and self-loops are permitted."""

    def __init__(self, V, E=None):
        if isinstance(V, int):
            self._init_int(V, E)
        else:
            self._init_arr(V)

    def _init_num_vertices(self, num_vertices):
        """Graph with num_vertices vertices and no Edges."""
        if num_vertices < 0:
            raise Exception("Number of vertices must be nonnegative")
        self.num_vertices = num_vertices  # Use instead of Java's V()
        self.num_edges = 0                # Use instead of Java's E()
        self._adj = [set() for v_src in range(num_vertices)]

    def _init_int(self, num_vertices, num_edges):
        """Graph with num_vertices vertices, randomly connected w_dst/random weights."""
        self._init_num_vertices(num_vertices)
        if num_edges < 0:
            raise Exception("Number of edges must be nonnegative")
        for _ in range(num_edges):
            v_src = random.randint(0, num_vertices) # get random int in [0, num_vertices)
            w_dst = random.randint(0, num_vertices)
            weight = random.uniform()
            edge = Edge(v_src, w_dst, weight)
            self.add_edge(edge)

    def _init_arr(self, arr):
        self._init_num_vertices(arr[0])
        self.num_edges = arr[1]
        if self.num_edges < 0:
            raise Exception("Number of edges must be nonnegative")
        for num_edges in arr[2:]:
            v_src = num_edges[0]
            w_dst = num_edges[1]
            weight = num_edges[2]
            edge = Edge(v_src, w_dst, weight)
            self.add_edge(edge)

    def __copy__(self):
        self._init_num_vertices(self.num_vertices)
        self.num_edges in self.num_edges
        for v_src in range(self.num_vertices):
            # reverse so that adjacency list is in same order as original
            reverse = [] # Stack<Edge>()
            for edge in self._adj[v_src]:
                reverse.append(edge) # push(edge)
            for edge in reverse:
                self._adj[v_src].add(edge)

    def _validate_vertex(self, v_src):
        """raise an IndexOutOfBoundsException unless 0 <= v_src < num_vertices"""
        if v_src < 0 or v_src >= self.num_vertices:
            raise Exception("vertex {} is not between 0 and {}".format(
                v_src, (self.num_vertices-1)))

    def add_edge(self, edge):
        """Adds the undirected edge <tt>edge</tt> to this edge-weighted graph."""
        v_src = edge.either()
        w_dst = edge.other(v_src)
        self._validate_vertex(v_src)
        self._validate_vertex(w_dst)
        self._adj[v_src].add(edge)
        self._adj[w_dst].add(edge)
        self.num_edges += 1

    def adj(self, v_src):
        """Returns the edges incident on vertex v_src."""
        self._validate_vertex(v_src)
        return self._adj[v_src]

    def degree(self, v_src):
        """Returns the degree of vertex v_src."""
        self._validate_vertex(v_src)
        return self._adj[v_src].size()

    def edges(self):
        """Returns all edges in this edge-weighted graph."""
        bag = set()
        for v_src in range(self.num_vertices):
            self_loops = 0
            for edge in self._adj[v_src]:
                if edge.other(v_src) > v_src:
                    bag.add(edge)
                # only add one copy of each self loop (self loops will be consecutive)
                elif edge.other(v_src) == v_src:
                    if self_loops % 2 == 0:
                        bag.add(edge)
                    self_loops += 1
        return bag

    def __str__(self):
        txt = ["{} {}\n".format(self.num_vertices, self.num_edges)]
        for v_src in range(self.num_vertices):
            txt.append("{}: ".format(v_src))
            for edge in self._adj[v_src]:
                txt.append("{}  ".format(edge))
            txt.append("\n")
        return ''.join(txt)


# Copyright 2002-present, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-present, DV Klopfenstein, Python port


================================================
FILE: AlgsSedgewickWayne/FileIndex.py
================================================
#!/usr/bin/env python#*****************************************************************************
 #  Compilation:  javac FileIndex.java
 #  Execution:    java FileIndex file1.txt file2.txt file3.txt ...
 #  Dependencies: ST.java SET.java In.java StdIn.java StdOut.java
 #  Data files:   http://algs4.cs.princeton.edu/35applications/ex1.txt
 #                http://algs4.cs.princeton.edu/35applications/ex2.txt
 #                http://algs4.cs.princeton.edu/35applications/ex3.txt
 #                http://algs4.cs.princeton.edu/35applications/ex4.txt
 #
 #  % java FileIndex ex*.txt
 #  age
 #   ex3.txt
 #   ex4.txt 
 # best
 #   ex1.txt 
 # was
 #   ex1.txt
 #   ex2.txt
 #   ex3.txt
 #   ex4.txt 
 #
 #  % java FileIndex *.txt
 #
 #  % java FileIndex *.java
 #
 #*****************************************************************************/

package edu.princeton.cs.algs4

import java.io.File

#*
 #  The <tt>FileIndex</tt> class provides a client for indexing a set of files,
 #  specified as command-line arguments. It takes queries from standard input
 #  and prints each file that contains the given query.
 #  <p>
 #  For additional documentation, see <a href="http://algs4.cs.princeton.edu/35applications">Section 3.5</a> of
 #  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 #  
 #  @author Robert Sedgewick
 #  @author Kevin Wayne
 #/
public class FileIndex: 

    # Do not instantiate.
    private FileIndex(): }

    def main(String[] args):

        # key = word, value = set of files containing that word
        ST<String, SET<File>> st = new ST<String, SET<File>>()

        # create inverted index of all files
        prt.write("Indexing files")
        for (String filename : args):
            prt.write("  " + filename)
            File file = new File(filename)
            In in = new In(file)
            while (!in.isEmpty()):
                String word = in.readString()
                if !st.contains(word)) st.put(word, new SET<File>())
                SET<File> set = st.get(word)
                set.add(file)


        # read queries from standard input, one per line
        while (!StdIn.isEmpty()):
            String query = StdIn.readString()
            if st.contains(query)):
                SET<File> set = st.get(query)
                for (File file : set):
                    prt.write("  " + file.getName())



#*****************************************************************************
 #  Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
 #
 #  This file is part of algs4.jar, which accompanies the textbook
 #
 #      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 #      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 #      http://algs4.cs.princeton.edu
 #
 #
 #  algs4.jar is free software: you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
 #  the Free Software Foundation, either version 3 of the License, or
 #  (at your option) any later version.
 #
 #  algs4.jar is distributed in the hope that it will be useful,
 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #  GNU General Public License for more details.
 #
 #  You should have received a copy of the GNU General Public License
 #  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 #*****************************************************************************/


================================================
FILE: AlgsSedgewickWayne/FlowEdge.py
================================================
"""Capacitated edge with a flow in a flow network."""

class FlowEdge(object):

  def __init__(self, v, w, capacity, flow=0.0):
    if v < 0: raise Exception("Vertex name must be a nonnegative integer")
    if w < 0: raise Exception("Vertex name must be a nonnegative integer")
    if not (capacity >= 0.0):  raise Exception("Edge capacity must be nonnegaitve")
    if not (flow <= capacity): raise Exception("Flow exceeds capacity")
    if not (flow >= 0.0):      raise Exception("Flow must be nonnnegative")
    self._v         = v  # v the tail vertex (int)
    self._w         = w  # w the head vertex (int)
    self._capacity  = capacity #  capacity of the edge (float)
    self._flow      = flow # flow on the edge (float)

  def __copy__(self, e):
    self._v         = e.v
    self._w         = e.w
    self._capacity  = e.capacity
    self._flow      = e.flow

  def get_from(self): return self._v # Returns the tail vertex of the edge.
  def get_to(self): return self._w # Returns the head vertex of the edge.
  def get_capacity(self): return self._capacity # Returns the capacity of the edge.
  def get_flow(self): return self._flow # Returns the flow on the edge.

  def get_other(self, vertex):
    """Returns the endpoint of the edge that is different from the given vertex"""
    if   vertex == self._v: return self._w
    elif vertex == selv._w: return self._v
    else: raise Exception("Illegal endpoint")

  def residualCapacityTo(self, vertex):
    """Returns the max capacity thru the edge in the direction to the given vertex"""
    if   vertex == self._v: return self._flow;                  # backward edge
    elif vertex == self._w: return self._capacity - self._flow; # forward edge
    else: raise Exception("Illegal endpoint")

  #   If <tt>vertex</tt> is the tail vertex, this increases the flow on the edge by <tt>delta</tt>;
  #   if <tt>vertex</tt> is the head vertex, this decreases the flow on the edge by <tt>delta</tt>.
  # @param vertex one endpoint of the edge
  # @throws java.lang.IllegalArgumentException if <tt>vertex</tt> is not one of the endpoints
  #   of the edge
  # @throws java.lang.IllegalArgumentException if <tt>delta</tt> makes the flow on
  #   on the edge either negative or larger than its capacity
  # @throws java.lang.IllegalArgumentException if <tt>delta</tt> is <tt>NaN</tt>
  def addResidualFlowTo(self, vertex, delta):
    """Increases the flow on the edge in the direction to the given vertex."""
    if   vertex == self._v: self._flow -= delta # backward edge
    elif vertex == self._w: self._flow += delta # forward edge
    else: raise Exception("Illegal endpoint")
    if Double.isNaN(delta): raise Exception("Change in flow = NaN")
    if not (self._flow >= 0.0):      raise Exception("Flow is negative")
    if not (self._flow <= self._capacity): raise Exception("Flow exceeds capacity")

  def __str__(self): return "{} {} -> {} / {}".format(self._v, self._w, self._flow, self._capacity)

# ------------------------------------------------------------------------
# JAVA IMPLEMENTATION (14:29)

#	KEY POINT: Augmenting path in original network is equivalent to 
# directed path in residual network.

# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python port


================================================
FILE: AlgsSedgewickWayne/FlowNetwork.py
================================================
"""A capacitated flow network, implemented using adjacency lists."""
# TBD Finish Python port

 #  The <tt>FlowNetwork</tt> class represents a capacitated network
 #  with vertices named 0 through <em>V</em> - 1, where each directed
 #  edge is of type {@link FlowEdge} and has a real-valued capacity
 #  and flow.
 #  It supports the following two primary operations: add an edge to the network,
 #  iterate over all of the edges incident to or from a vertex. It also provides
 #  methods for returning the number of vertices <em>V</em> and the number
 #  of edges <em>E</em>. Parallel edges and self-loops are permitted.
 #  <p>

from AlgsSedgewickWayne.FlowEdge import FlowEdge
import random

class FlowNetwork(object):

  def _init_V(self, V):
    """Initializes an empty flow network with V vertices and 0 edges."""
    if V < 0: raise Exception("Number of vertices in a Graph must be nonnegative")
    self._V = V
    self._E = 0
    self._adj = [set() for v in range(V)] # adj-list representation of FlowNetwork

  def _init_VE(self, V, E):
    """Initializes a random flow network with V vertices and E edges."""
    self._init_V(V)
    if E < 0: raise Exception("Number of edges must be nonnegative")
    for i in range(E):
      v = random.randint(V)
      w = random.randint(V)
      # The capacities are integers between 0 and 99 and the flow values are zero.
      capacity = random.randint(100)
      self.addEdge(FlowEdge(v, w, capacity))

  def _init_arr(self, arr):
    """Inits from an array structure representing a FlowNetwork."""
    self._init_V(arr[0])
    self._E = arr[1]
    if self._E < 0: raise Exception("Number of edges must be nonnegative")
    for v, w, capacity in arr[2:]:
      if v < 0 or v >= self._V: raise Exception("vertex {} is not between 0 and {}".format(v, (self._V-1)))
      if w < 0 or w >= self._V: raise Exception("vertex {} is not between 0 and {}".format(w, (self._V-1)))
      self.addEdge(FlowEdge(v, w, capacity))

  def V(self): return self._V # Returns the number of vertices in the edge-weighted graph.
  def E(self): return self._E # Returns the number of edges in the edge-weighted graph.

  def _validateVertex(self, v):
    """raise an IndexOutOfBoundsException unless 0 <= v < V"""
    if v < 0 or v >= self._V:
      raise Exception("vertex {} is not between 0 and {}".format(v, (self._V-1)))

  def addEdge(self, e): # O(1)
    """Adds the edge e to the network."""
    v = e.get_from()
    w = e.get_to()
    self._validateVertex(v)
    self._validateVertex(w)
    self._adj[v].add(e)
    self._adj[w].add(e)
    self._E += 1

  def adj(self, v): # O(1)
    """Returns the edges incident on vertex v (includes both edges pointing to and from v."""
    self._validateVertex(v)
    return self._adj[v]

  def edges(self): # iter edges incident to a given vertex takes time ~ to the number of such edges
    """return list of all edges - excludes self loops"""
    bag = set()
    for v in range(self._V):
      for e in self._adj(v):
        if e.get_to() != v:
          bag.add(e)
    return bag

  def __str__(self):
    s = ["{} {}\n".format(self._V, self_E)]
    for v in range(self._V):
      s.append("{}:  ".format(v))
      for e in self._adj[v]:
        if e.get_to() != v: s.append("{}  ".format(e))
      s.append("\n")
    return ''.join(s)

# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python port


================================================
FILE: AlgsSedgewickWayne/FordFulkerson.py
================================================
"""Ford-Fulkerson: compute a max flow and a min cut using shortest augmenting path rule."""
# TBD Finish Python port

 #  This implementation uses the <em>Ford-Fulkerson</em> algorithm with
 #  the <em>shortest augmenting path</em> heuristic.
 #  The constructor takes time proportional to <em>E V</em> (<em>E</em> + <em>V</em>)
 #  in the worst case and extra space (not including the network)
 #  proportional to <em>V</em>, where <em>V</em> is the number of vertices
 #  and <em>E</em> is the number of edges. In practice, the algorithm will
 #  run much faster.
 #  Afterwards, the <tt>inCut()</tt> and <tt>value()</tt> methods take
 #  constant time.
 #  <p>
 #  If the capacities and initial flow values are all integers, then this
 #  implementation guarantees to compute an integer-valued maximum flow.
 #  If the capacities and floating-point numbers, then floating-point
 #  roundoff error can accumulate.
 #
 #  @author Robert Sedgewick
 #  @author Kevin Wayne
 #/

from AlgsSedgewickWayne.FlowNetwork import FlowNetwork

class FordFulkerson(object):
  """Data type for computing maxflow and mincut in a flow network."""

  Inf = float('Inf')
  FLOATING_POINT_EPSILON = 1E-11

  def __init__(self, G, s, t): # G is FlowNetwork
    self._validate(s, G.V())
    self._validate(t, G.V())
    self._marked # marked[v] = True iff s->v path in residual graph
    self._edgeTo # edgeTo[v] = last FlowEdge on shortest residual s->v path
    self._value  # current value(float) of max flow
    if s == t:                        raise Exception("Source equals sink")
    if not self._isFeasible(G, s, t): raise Exception("Initial flow is infeasible")

    # while there exists an augmenting path, use it
    self._value = self._excess(G, t) # current value of max flow
    while self._hasAugmentingPath(G, s, t):

        # compute bottleneck capacity
        bottle = self.Inf
        v = t
        while v != s:
          bottle = min(bottle, self._edgeTo[v].residualCapacityTo(v))
          v = self._edgeTo[v].other(v)):

        # augment flow
        v = t
        while v != s:
          self._edgeTo[v].addResidualFlowTo(v, bottle)
          v = self._edgeTo[v].other(v)):

        self._value += bottle

    # check optimality conditions
    assert self._check(G, s, t)

  # Returns the value of the maximum flow.
  def value(self): return self._value

  def inCut(self, v):
    """Returns true if the specified vertex is on the s side of the mincut."""
    self._validate(v, len(self._marked))
    return self._marked[v]

  def _validate(self, v, V):
    """raise an exception if v is outside prescibed range"""
    if v < 0 or v >= V:
      raise Exception("vertex {} is not between 0 and {}\n".format(v, V-1))

  # is there an augmenting path? 
  # if so, upon termination edgeTo[] will contain a parent-link representation of such a path
  # self implementation finds a shortest augmenting path (fewest number of edges),
  # which performs well both in theory and in practice
  def _hasAugmentingPath(self, G, s, t): # G id FlowNetwork
    self._edgeTo = [None  for i in range(G.V())] # Will contain FlowEdges
    self._marked = [False for i in range(G.V())]

    # breadth-first search (note: Can also use other search algorithms can also be adapted)
    queue = cx.deque() # Queue
    queue.append(s) # enqueue(s)
    self._marked[s] = True
    while queue and not self._marked[t]:
      v = queue.popleft() # dequeue()

      for e in G.adj(v): # Loop thru FLowEdges
        w = e.other(v)

        # if residual capacity from v to w
        if e.residualCapacityTo(w) > 0: # Have a way to get to w
          if not self._marked[w]: # Have not been there yet
            self._edgeTo[w] = e
            self._marked[w] = True
            queue.append(w) # enqueue(w)

    # is there an augmenting path?
    return self._marked[t] # Is t reachable from s in residual network?



  def _excess(self, G, v):
    """return excess flow at vertex v"""
    excess = 0.0
    for e in G.adj(v): # Loop thru FlowEdges of FlowNetwork
      if v == e.get_from(): excess -= e.flow()
      else:                 excess += e.flow()
    return excess

  # return excess flow at vertex v
  def _isFeasible(FlowNetwork G, s, t):

      # check that capacity constraints are satisfied
      for (int v = 0; v < G.V(); v += 1):
          for (FlowEdge e : G.adj(v)):
              if e.flow() < -self.FLOATING_POINT_EPSILON or e.flow() > e.capacity() + self.FLOATING_POINT_EPSILON):
                  sys.stderr.write("Edge does not satisfy capacity constraints: " + e)
                  return False

      # check that net flow into a vertex equals zero, except at source and sink
      if abs(value + self._excess(G, s)) > self.FLOATING_POINT_EPSILON):
        sys.stderr.write("Excess at source = {}".format(self._excess(G, s)))
        sys.stderr.write("Max flow         = {}".format(value))
        return False
      if abs(value - self._excess(G, t)) > self.FLOATING_POINT_EPSILON):
        sys.stderr.write("Excess at sink   = {}".format(self._excess(G, t)))
        sys.stderr.write("Max flow         = {}".format(value))
        return False
      for v in G.V():
        if v == s or v == t: continue
        elif abs(self._excess(G, v)) > self.FLOATING_POINT_EPSILON):
          sys.stderr.write("Net flow out of " + v + " doesn't equal zero")
          return False
      return True



  # check optimality conditions
  def _check(FlowNetwork G, s, t):

      # check that flow is feasible
      if not self._isFeasible(G, s, t):
          sys.stderr.write("Flow is infeasible")
          return False

      # check that s is on the source side of min cut and that t is not on source side
      if not self.inCut(s):
          sys.stderr.write("source {} is not on source side of min cut".format(s))
          return False
      if self.inCut(t):
          sys.stderr.write("sink {} is on source side of min cut".format(t))
          return False

      # check that value of min cut = value of max flow
      mincutValue = 0.0
      for (int v = 0; v < G.V(); v += 1):
          for e in G.adj(v): # iterate thru FlowEdges
              if (v == e.from()) and self.inCut(e.from()) and not self.inCut(e.to()))
                  mincutValue += e.capacity()

      if Math.abs(mincutValue - value) > self.FLOATING_POINT_EPSILON):
          sys.stderr.write("Max flow value = " + value + ", min cut value = " + mincutValue)
          return False

      return True


# -----------------------------------------------------------------
# INTRODUCTION TO MAXFLOW (10:33)

# MINCUT PROBLEM 2:49
#
# DEF: A **st-cut (cut)** is a partition of the vertices into two disjoint sets,
# with s in onset A and t in the other set B.
#
# DEF: Its **capacity** is the sum of the capacities of the edges from A to B.

# 1) QUESTION: In the flow network below, what is the capacity of the cut with 
# A = {s, 2, 4} and B = {1, 3, t}?
#
#           (1)--4-->(3)
#          ^ | \      ^ \
#         /  |  \     |  \
#        /   |   \    |   \
#      10    2    8   6    10
#      /     |     \  |     \
#     /      v      v |      v
#   (s)-10->(2)--9-->(4)-10->(t)
#
# ANSWER #1 (Pick one):
#   19
#   20
#   26 
#   36

# MAXFLOW PROBLEM 6:11
#
# DEF: An **st-flow (flow)** is an assignment of values to the edges such that:
#   * Capacity constraint: 0 <= edge's flow <= edge's capacity.
#   * Local equilibrium: inflow = outflow at every vertex (except s and t)
#
# DEF: The **value** of a flow is "the inflow at t" or the "outflow at s".
#      (we assume no edge points to s or from t)
#
# MAXIMUM ST-FLOW (MAXFLOW) PROBLEM. Find a flow of maximum value.

# 2) QUESTION: In the flow network below, what is the value of the flow f?
#
#           (1)-0/4->(3)
#          ^ | \      ^ \
#         /  |  \     |  \
#        /   |   \    |   \
#   10/10   2/2  8/8 6/6  6/10
#      /     |     \  |     \
#     /      v      v |      v
#   (s)6/10>(2)-8/9->(4)10/10>(t)
#
# ANSWER #2 (Pick one):
#   10
#   16
#   18 
#   19
#
# EXPLANATION: By definition, it is the inflow at t, which is 10 + 6

# SUMMARY:
# 
# INPUT: A weighted digraph, source vertex s, and target vertex t.
# MINCUT PROBLEM: Find a cut of minimum capacity.
# MAXFLOW PROBLEM: Find a flow of maximum value.
#
# REMARKABLE FACT: These two problems are dual!
# If you solve one problem, you solve the other.

#-----------------------------------------------------------------------
# FORD-FULKERSON ALGORITHM (6:32)
# (Dates back to the 1950s)

# FORD-FULKERSON ALGORITHM 
#
# INITIALIZATION: Start with 0 flow. (But has capacity)

# IDEA: INCREASE FLOW ALONG AUGMENTING PATHS 00:34
#
# AUGMENTING PATH: Find an undirected path from s to t such that:
#   * Can increase flow on forward edges (not full).
#   * Can decrease flow on backward edge (not empty).

# IDEA: INCREASE FLOW ALONG AUGMENTING PATHS 4:29
#
# TERMINATION: All paths from s to t are blocked by either a
#   * Full forward edge.  (ie Can't add    more flow to forward edge)
#   * Empty backward edge.(ie Can't remove more flow from a backward edge)

# FORD-FULKERSON ALGORITHM  5:06
#
# 1. Start with 0 flow.
# 2. While there exists an augmenting path:
#    * find an augmenting path
#    * compute bottleneck capacity
#    * increase flow on that path by bottleneck capcity
#
# QUESTIONS:
#   * How to compute a mincut? EASY.
#   * How to find an augmenting path? BFS WORKS WELL. (Many ways, though)
#   * If FF terminates, does it always compute a maxflow? YES
#   * Does DD always terminate?
#     => yes, provided edge capacities are integers (or augmenting paths are chosen carefully)
#     * If so, after how many augmentations?
#       -> requires clever analysis

# 3) QUESTION: In the flow network below, how many distinct augmenting paths are there 
# with respect to the given flow f?
#
#           (1)-0/4->(3)
#          ^ | \      ^ \
#         /  |  \     |  \
#        /   |   \    |   \
#   10/10   2/2  8/8 6/6  6/10
#      /     |     \  |     \
#     /      v      v |      v
#   (s)6/10>(2)-8/9->(4)10/10>(t)
#
# ANSWER #3 (pick one):
#   0
#   1
#   2 
#   3
#

#-----------------------------------------------------------------------
# MAXFLOW-MINCUT THEOREM (9:38)

# 4) QUESTION: Given a flow network, let f be any flow and let (A, B) be any cut.
# Then, the net flow across (A, B) is ____ the value of f.
#
#  * less than
#  * greater than
#  * not related to

# 5) QUESTION: Given a maxflow f in a flow network, what is the order of growth 
# of the running time to compute a mincut?
#
#  * V + E
#  * V^2
#  * V(E + V)
#  * E^2

#-----------------------------------------------------------------------
# RUNNING TIME ANALYSIS (8:49)

# FORD-FULKERSON ALGORITHM
# 1. Start with 0 flow.
# 2. While there exists an augmenting path:
#    * find an augmenting path
#    * compute bottleneck capacity
#    * increase flow on that path by bottleneck capcity
#
# QUESTIONS:
#   * How to compute a mincut? EASY.
#   * How to find an augmenting path? BFS WORKS WELL. (Many ways, though)
#   * If FF terminates, does it always compute a maxflow? YES
#   * Does DD always terminate?
#     => yes, provided edge capacities are integers (or augmenting paths are chosen carefully)
#     * If so, after how many augmentations?
#       -> requires clever analysis

# FF W/INTEGER CAPACITIES 02:05
# IMPORTANT SPECIAL CASE: Edge capacities are integers betwen 1 and U.
# INVARIANT: The flow is **integer-values** throughout FF.
# ...
# INTEGRALITY THEOREM: There exists an integer-valued maxflow (and FF finds one!).
#   * important for some applications (stay tuned)
# ...

# 6) QUESTION: If all the edge capacities are integers, the value of the maxflow is:
#    * integer 
#    * rational number 
#    * real number
#    * imaginary number

#-----------------------------------------------------------------------
# JAVA IMPLEMENTATION (14:29)

# 7) QUESTION: Suppose that Edge e is an edge returned by G.adj(v), with w = e.other(v) and
# e.residualCapacityTo(w) > 0. Which of the following myst be true?
#   * e = v -> w is a forward edge that is not full
#   * e = v -> w is a backward edge that is not empty
#   * e = v -> w is either a forward edge that is not full or a backward edge that is not empty.
#   * None of the above

#-----------------------------------------------------------------------
# MAXFLOW AND MINCUT APPLICATIONS (22:20)
#  * Data mining
#  * Open-pit mining
#  * Bipartite matching
#  * Network reliability
#  * Baseball elimination
#  * Image segmentation
#  * Betwork connectivity
#  * Distributed computing
#  * Egaltarian stable matching
#  * Security of statistical data.
#  * Mutli-camera scene reconstruction
#  * Sensor placment for homeland security
#  ...

# 8) QUESTION: Suppose that you run the Ford-Fulkerson algorithm(using the 
#    shortest augmenting path heuristic) to solve a bipartite matching problem
#    with N students and N companies. How many augmenting paths are needed in the 
#    worst case?
#      *       N
#      *       N^2
#      * (1/2)*N^3
#      *       N^3

# 9) QUESTION: How many vertices and edges, respectively, are there in the flow
#    network that is constructed to determine whether one team is mathematically
#    eliminated from a baseball league containing N teams? Give the order of growth
#    in the worst case (when there is a game remaining between every pair of teams
#    in the league).
#      * N   and N^2
#      * N^2 and N^2
#      * N^2 and N^3
#      * N^2 and N^4

#-----------------------------------------------------------------------
# ANSWERS: WEEK 3 MAXIMUM FLOW (72:21)
#
# 1) ANSWER: 26 
#
# 2) ANSWER: 16 
#
# 3) ANSWER: 2
#   EXPLANATION: The two augmenting paths are:
#     s -> 2 -> 1 -> 3 -> t         (with bottleneck capacity 2) and
#     s -> 2 -> 4 -> 1 -> -> 3 -> t (with bottleneck capacity 1)
#
# 4) ANSWER: equal to
#
# 5) ANSWER: V + E
#   EXPLANATION: The algorithm is to find all of the vertices reachable from s
#     using only forward edges that aren't full or backwards edges that aren't
#     empty. This can be done in linear time using either breadth-first search
#     or depth-first search.
#
# 6) ANSWER: integer (not rational number, real number, imaginary number)
#   EXPLANATION: The integrality theorem asserts that there exists a maxflow in which 
#   the flow on each edge is an integer. This impolies that the value of the
#   maxflow is an integer.
#
# 7) ANSWER:e = v -> w is either a forward edge that is not full or a backward edge that is not empty.
#   EXPLANATION: e = v -> w is an edge in the residual graph, which means that either it is
#   a forward edge that is not full or a backward edge that is not empty.
#
# 8) ANSWER: N
#   EXPLANATION: For general networks, the shortest augmenting path heuristic 
#   requires (1/2)*EV augmenting paths to find a maxflow in a network with V
#   vertices and E edges. However, in the bipartite matching reduction, all edge
#   capacities are 1 and the value of the maximum flow is at most N. Thus, at
#   most N augmenting paths are needed (since each augmenting path delivers 1 unit of flow to t).
#
#   We note that a more refined version of the shortest augmenting path heuristic 
#   leads to an overall running time of E*sqrt(V) for the bipartite matching problem.
#
# 9) ANSWER: N^2 and N^2                      (N-1)
#   EXPLANATION: There are N-1 team vertices, ( 2 ) (N-1 CHOOSE 2) game vertices, 1 source, and 1 sink.
#   In the worst case, there are 2*(N-1 CHOOSE 2) edges from game vertices to team vertices
#   (2 for each game vertex), (N-1 CHOOSE 2) edges pointing from the source, and N-1
#   edges pointing to the sink.

# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python port



================================================
FILE: AlgsSedgewickWayne/FrequencyCounter.py
================================================
#!/usr/bin/env python
# TBD: DO PYTHON PORT

# Reads in a command-line integer and sequence of words from
# standard input and prints out a word (whose length exceeds
# the threshold) that occurs most frequently to standard output.
# It also prints out the number of words whose length exceeds
# the threshold and the number of distinct such words.
def main():
  distinct = 0, words = 0
  minlen = Integer.parseInt(args[0])
  st = ST()

  # compute frequency counts
  while (!StdIn.isEmpty()):
    String key = StdIn.readString()
    if len(key)() < minlen) continue
    words += 1
    if st.contains(key)):
      st.put(key, st.get(key) + 1)
    else:
      st.put(key, 1)
      distinct += 1

  # find a key with the highest frequency count
  String max_key = ""
  st.put(max_key, 0)
  for word in st.keys():
    if st.get(word) > st.get(max_key):
      max_key = word

  prt.write("{} {}\n".format(max_key, st.get(max_key)))
  prt.write("distinct = {}\n".format(distinct))
  prt.write("words    = {}\n".format(words))



================================================
FILE: AlgsSedgewickWayne/GREP.py
================================================

# TBD Finish Python port

 ******************************************************************************/

package edu.princeton.cs.algs4

#
# The <tt>GREP</tt> class provides a client for reading in a sequence of
# lines from standard input and printing to standard output those lines
# that contain a substring matching a specified regular expression.
# <p>
# For additional documentation, see <a href="http:#algs4.cs.princeton.edu/31elementary">Section 3.1</a> of
# <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
#
# @author Robert Sedgewick
# @author Kevin Wayne
#
public class GREP:

  # do not instantiate
  private GREP(): }

  #
  #Interprets the command-line argument as a regular expression
  #(supporting closure, binary or, parentheses, and wildcard)
  #reads in lines from standard input; writes to standard output
  #those lines that contain a substring matching the regular
  #expression.
  #


# Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright 2015-2019, DV Klopfenstein, Python implementation.



================================================
FILE: AlgsSedgewickWayne/GabowSCC.py
================================================
#*****************************************************************************
 #  Compilation:  javac GabowSCC.java
 #  Execution:    java GabowSCC V E
 #  Dependencies: Digraph.java Stack.java TransitiveClosure.java StdOut.java
 #
 #  Compute the strongly-connected components of a digraph using 
 #  Gabow's algorithm (aka Cheriyan-Mehlhorn algorithm).
 #
 #  Runs in O(E + V) time.
 #
 #  % java GabowSCC tinyDG.txt
 #  5 components
 #  1 
 #  0 2 3 4 5
 #  9 10 11 12
 #  6 8
 #  7 
 #
 #*****************************************************************************/

package edu.princeton.cs.algs4
#*
 #  The <tt>GabowSCC</tt> class represents a data type for 
 #  determining the strong components in a digraph.
 #  The <em>id</em> operation determines in which strong component
 #  a given vertex lies; the <em>areStronglyConnected</em> operation
 #  determines whether two vertices are in the same strong component;
 #  and the <em>count</em> operation determines the number of strong
 #  components.

 #  The <em>component identifier</em> of a component is one of the
 #  vertices in the strong component: two vertices have the same component
 #  identifier if and only if they are in the same strong component.

 #  <p>
 #  This implementation uses the Gabow's algorithm.
 #  The constructor takes time proportional to <em>V</em> + <em>E</em>
 #  (in the worst case),
 #  where <em>V</em> is the number of vertices and <em>E</em> is the number of edges.
 #  Afterwards, the <em>id</em>, <em>count</em>, and <em>areStronglyConnected</em>
 #  operations take constant time.
 #  For alternate implementations of the same API, see
 #  {@link KosarajuSharirSCC} and {@link TarjanSCC}.
 #  <p>
 #  For additional documentation,
 #  see <a href="http://algs4.cs.princeton.edu/42digraph">Section 4.2</a> of
 #  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
 #
 #  @author Robert Sedgewick
 #  @author Kevin Wayne
 #/
public class GabowSCC:

  private boolean[] marked;        # marked[v] = has v been visited?
  private int[] id;                # id[v] = id of strong component containing v
  private int[] preorder;          # preorder[v] = preorder of v
  private pre;                 # preorder number counter
  private count;               # number of strongly-connected components
  private Stack<Integer> stack1
  private Stack<Integer> stack2


    #*
     # Computes the strong components of the digraph <tt>G</tt>.
     # @param G the digraph
     #/
  public GabowSCC(Digraph G):
      marked = new boolean[G.V()]
      stack1 = new Stack<Integer>()
      stack2 = new Stack<Integer>()
      id = new int[G.V()]
      preorder = new int[G.V()]
      for (int v = 0; v < G.V(); v += 1)
          id[v] = -1

      for (int v = 0; v < G.V(); v += 1):
          if !marked[v]) dfs(G, v)

      # check that id[] gives strong components
      assert check(G)

  def _dfs(Digraph G, v): 
      marked[v] = True
      preorder[v] = pre += 1
      stack1.push(v)
      stack2.push(v)
      for (int w : G.adj(v)):
          if !marked[w]) dfs(G, w)
          elif (id[w] == -1):
              while (preorder[stack2.peek()] > preorder[w])
                  stack2.pop()

      # found strong component containing v
      if stack2.peek() == v):
          stack2.pop()
          w
          do:
              w = stack1.pop()
              id[w] = count
          } while (w != v)
          count += 1

    #*
     # Returns the number of strong components.
     # @return the number of strong components
     #/
  def count():
      return count

    #*
     # Are vertices <tt>v</tt> and <tt>w</tt> in the same strong component?
     # @param v one vertex
     # @param w the other vertex
     # @return <tt>true</tt> if vertices <tt>v</tt> and <tt>w</tt> are in the same
     #     strong component, and <tt>false</tt> otherwise
     #/
  def stronglyConnected(int v, w):
      return id[v] == id[w]

    #*
     # Returns the component id of the strong component containing vertex <tt>v</tt>.
     # @param v the vertex
     # @return the component id of the strong component containing vertex <tt>v</tt>
     #/
  def id(int v):
      return id[v]

  # does the id[] array contain the strongly connected components?
  def _check(Digraph G):
      TransitiveClosure tc = new TransitiveClosure(G)
      for (int v = 0; v < G.V(); v += 1):
          for (int w = 0; w < G.V(); w += 1):
              if stronglyConnected(v, w) != (tc.reachable(v, w) and tc.reachable(w, v)))
                  return False
      return True

    #*
     # Unit tests the <tt>GabowSCC</tt> data type.
     #/
  def main(String[] args):
      In in = new In(args[0])
      Digraph G = new Digraph(in)
      GabowSCC scc = new GabowSCC(G)

      # number of connected components
      M = scc.count()
      prt.write(M + " components")

      # compute list of vertices in each strong component
      Queue<Integer>[] components = (Queue<Integer>[]) new Queue[M]
      for (int i = 0; i < M; i += 1):
          components[i] = new Queue<Integer>()
      for (int v = 0; v < G.V(); v += 1):
          components[scc.id(v)].enqueue(v)

      # print results
      for (int i = 0; i < M; i += 1):
          for (int v : components[i]):
              StdOut.print(v + " ")
          prt.write()

# Strong Components

# 19902: more easy linear-time algorithms
#   Gabow: fixed old OR (Operations Research) algorithm
#   Cheriyan-Mehlhorn: needed one-pass algorithm for LEDA.

#*****************************************************************************
 #  Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
 #
 #  This file is part of algs4.jar, which accompanies the textbook
 #
 #      Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
 #      Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
 #      http://algs4.cs.princeton.edu
 #
 #
 #  algs4.jar is free software: you can redistribute it and/or modify
 #  it under the terms of the GNU General Public License as published by
 #  the Free Software Foundation, either version 3 of the License, or
 #  (at your option) any later version.
 #
 #  algs4.jar is distributed in the hope that it will be useful,
 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 #  GNU General Public License for more details.
 #
 #  You should have received a copy of the GNU General Public License
 #  along with algs4.jar.  If not, see http://www.gnu.org/licenses.
 #*****************************************************************************/


================================================
FILE: AlgsSedgewickWayne/GrahamScan.py
================================================
#!/usr/bin/env python3
"""GrahamScan class"""

from copy import deepcopy
from AlgsSedgewickWayne.Stack import Stack
from AlgsSedgewickWayne.Point2D import Point2D

class GrahamScan:
    #### private Stack<Point2D> hull = new Stack<Point2D>();

    def __init__(self, pts): # Point2D[] pts) {
        self.hull = self._init_convex_hull(pts) if pts else None

    def _init_convex_hull(pts):

        hull = Stack()
        # defensive copy
        points = [Point2D(*t) for t in pts]
        print(f'1. COPY:   {points}')

        # preprocess so that points[0] has lowest y-coordinate; break ties by x-coordinate
        # points[0] is an extreme point of the convex hull
        # (alternatively, could do easily in linear time)
        points.sort(key=lambda p: [p.get_y(), p.get_x()])
        pt0 = points[0]
        print(f'2. Y-SORT: {points}')

        # sort by polar angle with respect to base point points[0],
        # breaking ties by distance to points[0]
        points[1:].sort(pt0.POLAR_ORDER)

        self.hull.push(points[0])       # p[0] is first extreme point

        # find index k1 of first point not equal to points[0]
        k1 = None
        for k1 in range(1, N):
            if not points[0].equals(points[k1]): break
        if k1 == N: return        # all points equal

        # find index k2 of first point not collinear with points[0] and points[k1]
        k2 = None
        for k2 in range(k1 + 1, N):
            if Point2D.ccw(points[0], points[k1], points[k2]) != 0:
                break
        self.hull.push(points[k2-1])    # points[k2-1] is second extreme point

        # Graham scan; note that points[N-1] is extreme point different from points[0]
        for k2 in range(k2, N):
            top = self.hull.pop()
            while Point2D.ccw(self.hull.peek(), top, points[i]) <= 0:
                top = self.hull.pop()
            self.hull.push(top)
            self.hull.push(points[i])

        ## assert self._is_convex()

    ## # return extreme points on convex hull in counterclockwise order as an Iterable
    ## #### public Iterable<Point2D> hull() {
    ## def __iter__(self):
    ##     ## Stack<Point2D> stck = new Stack<Point2D>();
    ##     ## stck = Stack()
    ##     for pt2d in self.hull:
    ##         yield pt2d
    ##         ## stck.push(pt2d)
    ##     ## return stck

    ## def _is_convex(self):  # _isConvex():
    ##     """Check that boundary of hull is strictly convex"""
    ##     hull_size = hull.size()
    ##     if hull_size <= 2:
    ##         return True

    ##     points = [pt2d for pt2d in hull()]
    ##     #### points = new Point2D[hull_size];
    ##     #### int n = 0
    ##     #### for pt2d in hull()):
    ##     ####     points[n++] = pt2d;

    ##     for i in range(hull_size):
    ##         if Point2D.ccw(points[i], points[(i+1) % hull_size], points[(i+2) % hull_size]) <= 0:
    ##             return False;
    ##     return True;


##########################################
# Alg1, Week 2 Lecture "Convex Hull
#   https://class.coursera.org/algs4partI-005/lecture/29
##########################################

# CONVEX HULL: Application of sorting for the field of computational geometry
#
# DEFINITION: CONVEX HULL is the smallest polygon which encloses all the points for
# a set of points on a plane
#
# 00:38 EQUIVALENT DEFINITIONS:
#   * Smallest convex set contining all the points.
#   * Smallest area convex polygon enclosing the points.
#   * Convex polygon enclosing the points, whose vertices are points in set.
#
# 01:40 CONVEX HULL OUTPUT: Sequence of vertics in counterclockwise order.
# (Do not include point on the boundry which are not vertices)
#
# 02:11 CONVEX HULL: MECHANICAL ALGORITHM
# Hammer nails perpendicular to the plane; stretch elastic rubber band around points.

##########################################
# CONVEX HULL APPLICATION EXAMPLES
##########################################

# 02:30 CONVEX HULL APPLICATION: MOTION PLANNING
# ROBOT MOTION PLANNING: Find shorest path in the plane from s to t
# that avoids polygon obstacle between s and t.
# 02:48 FACT: Shortest path is either straight line from s to t or
#             is is part of one of the two polygonal chains of convex hull.

# 03:08 CONVEX HULL APPLICATION: FARTHEST PAIR PROBLEM
# Given N points in the plane, find a pair of points with the largest
# Euclidean distance between them. (They will be on the convex hull)


#-----------------------------------------
# 03:43 CONVEX HULL: GEOMETRIC PROPERTIES
# FACT: Can travers the convex hull by making only clockwise turns.
# FACT: The vertices of convex hull appear in increasing order of
#       polar angle with respect to point p with lowest y-coordinate.
# The Graham Scan algorithm uses these two facts.

# GRAHAM SCAN DEMO 05:03-07:52
# * Choose point p with smallest y-coordinate.
# * Sort points by polar angle with p.
# * Consider point in order; discard unless it creates a ccw turn.

#-----------------------------------------
# 8:00 GRAHAM SCAN: IMPLMENTATION CHALLENGES
# Q: How to find point p with SMALLEST Y-COORDINATE?
# A: Define a total order, comparing by y-coordinate. [next lecture]
#
# Q: How to SORT POINTS BY POLAR ANGLE with respect to p? 08:48
# A: Define a total order *for each* point p. [next lecture]
#    Example of wanting to be able to sort the same thing in different ways
#
# Q: How to determine whether p1->p2->p3 is a COUNTERCLOCKWISE TURN? 09:15
# A: Computational geometery. [briefly on the next two slides]
#
# Q: How to SORT EFFICIENTLY? 09:35 (Convex sorting:  Where the most work is)
# A: Mergesort sorts in N*log(N) time. [next lecture]
#
# Q: How to handle DEGENERACIES (3+ points on a line)? 10:19
# A: Requires some care, but not hard [see booksite]

#-----------------------------------------
# 10:37 IMPLEMENTING CCW
# CCW: Given 3 points a, b, and c, is a->b->c a counterclockwise turn?
#   i.e. is c to the left of the ray a->b?
#       1        2       3    4    5    6
#       c               c     c    c    b
#        \               \    |    |    |
#         b     b-c       b   b    A    c
#        /       \        |   |    |    |
#       A         A       A   A    b    A
#
#      yes       no     yes   no   no   no
#                      m=Inf  <-collinear->
# TRICKY BECAUSE:
# * Infinite slope:   3 4 5 6
# * collinear points:   4 5 6
#
# LESSON: Geometric primitives are tricky to implement.
#   * Dealing with degenerate cases.
#   * Coping with floating-point precision.
#
# 12:04 THE IDEA FOR CALCULATING IF 3 POINTS ARE CCW:
# Computing slopes between a-b and a-c and comparing the slopes to see if you
# are turning counter-clockwise or clockwise

# 12:05 IMPLEMENTING CCW
# CCW. Given three points a, b, and c, is a->b->c a counterclockwise turn?
#  * Determinant (or cross product) gives 2x signed area of planar triangle.
#
#                        | ax ay 1 |
#    2 x Area(a, b, c) = | bx by 1 | = (bx - ax)(cy - ay)(cx - ax)
#                        | cx cy 1 |
#                                          (b - a) x (c - a)
#
# * If signed area > 0, then a->b->c is counterclockwise
# * If signed area < 0, then a->b->c is clockwise
# * If signed area = 0, then a->b->c are collinear
#
#         (bx, by)               (bx, by)           (bx, by)
#            o                      o                  o
#           / \                    / \                 |
#          /<--\                  /-->\            = 0 o (cx, cy)
#         /  >0 \                /  <0 \               |
#        o-------o              o-------o              o
#   (cx, cy)   (ax, ay)    (ax, ay)   (cx, cy)      (ax, ay)
#    counterclockwise          clockwise            collinear
#
#-----------------------------------------
# 12:50 GRAHAM SCAN: IMPLEMENTATION
# SIMPLIFYING ASSUMPTIONS: No 3 points on a line; at least 3 points.
#
# Stack<Point2D> hull = new Stack<Point>();
#
# # Two different ways to sort the stack:
# Arrays.sort(p, Point2D.Y_ORDER); # p[0] is not point w/lowest y-coord
# Arrays.sort(p, p[0].BY_POLAR_ORDER); # sort by polar angle w/respect to p[0]
#
# hull.push(p[0]); # <- definitely on hull
# hull.push(p[1]);
#
# for (int i = 2; i < N; i++) {
#   Point2D top = hull.pop();
#   # Do two top points plus new point make a ccw?
#   while (Point2D.ccw(hull.peek(), top, p[i] <= 0)
#     top.hull.pop();
#   hull.push(top);
#   hull.push(p[i]); # <- add p[i] to putative hull
# }
#
# RUNNING TIME: N*log(N) for sorting and linear for rest.
# PROOF: N*log(N) for sorting; each point pushed and popped at most once.

#-----------------------------------------
# 13:44 QUESTION: What is the maximum number of vertices that can be on the convex hull
# of a set of N points:
# ANSWER: linear
# EXPLANATION: If the input points are points on the circumference of a
# circle (or a regular N-gon), then all N pointw will be on the convex hull.


 #************************************************************************
 #  Compilation:  javac GrahamaScan.java
 #  Execution:    java GrahamScan < input.txt
 #  Dependencies: Point2D.java
 #
 #  Create points from standard input and compute the convex hull using
 #  Graham scan algorithm.
 #
 #  May be floating-point issues if x- and y-coordinates are not integers.
 #
 #************************************************************************/



# Copyright © 2002–2010, Robert Sedgewick and Kevin Wayne.


================================================
FILE: AlgsSedgewickWayne/Graph.py
================================================
"""A undirected graph, implemented using an array of sets. Parallel edges and self-loops allowed."""

import sys
from AlgsSedgewickWayne.testcode.utils import adjtxtblk2OrderedDict

class Graph:
    """Undirected graph"""

    def __init__(self, arg=None, **kwargs):
        if arg is not None:
            if isinstance(arg, int):
                self._init_empty(arg)
            elif len(arg) == 1:
                self._init_empty(arg[0])
            else:
                self._init(arg)
            self.keys = range(self.num_nodes)
        elif 'adjtxt' in kwargs:
            self._adj = adjtxtblk2OrderedDict(kwargs['adjtxt'])
            self.num_nodes = len(self._adj)
            self.num_edges = self._init_num_edges()
            self.keys = self._adj.keys()

    def V(self):
        """Returns the number of vertices in self graph."""
        return self.num_nodes

    def E(self):
        """Returns the number of edges in self graph."""
        return self.num_edges

    def addEdge(self, node_v, node_w):
        """Adds the undirected edge node_v-node_w to self graph."""
        self.add_edge(node_v, node_w)

    def add_edge(self, node_v, node_w):
        """Adds the undirected edge node_v-node_w to self graph."""
        #self._validateVertex(node_v)
        #self._validateVertex(node_w)
        self.num_edges += 1
        self._adj[node_v].add(node_w)
        self._adj[node_w].add(node_v)

    def adj(self, node_v):
        """Returns the vertices adjacent to vertex node_v."""
        #self._validateVertex(node_v)
        return self._adj[node_v]

    def degree(self, node_v):
        """Returns the degree of vertex node_v."""
        #self._validateVertex(node_v)
        return self._adj[node_v].size()

    #def _validateVertex(self, node_v):
    #  """raise an IndexOutOfBoundsException unless 0 <= node_v < V."""
    #  if node_v < 0 or node_v >= self.num_nodes or node_v not in self._adj:
    #    raise Exception("vertex {} is not between 0 and {} or in {}".format(
    #        node_v, self.num_nodes-1, self._adj))

    def __str__(self):
        txt = [(("{V} vertices, {E} edges\n").format(V=self.num_nodes, E=self.num_edges))]
        for node_v in self.keys:
            txt.append("{node_v}: ".format(node_v=node_v))
            for node_w in self._adj[node_v]:
                txt.append("{node_w} ".format(node_w=node_w))
            txt.append("\n")
        return ''.join(txt)

    def __iter__(self): # Makes Graph an iterable.
        return iter(self._adj) # returns an iterator.

    def wr_png(self, fout_png="Graph.png", prt=sys.stdout, **kwargs):
        """Make a png showing a diagram of the connected components."""
        import pydot
        # 1. create/initialize graph
        graph = pydot.Dot(graph_type='graph') # undirected graph
        # 2. create nodes
        nodes = [pydot.Node(node_v) for node_v in self.keys]
        # 3. add nodes to graph
        for node in nodes:
            graph.add_node(node)
        # 4. add edges between nodes to graph
        for node_v, node_w in self.get_edges():
            if node_v != node_w: # print only edges from one node to another (not to self)
                graph.add_edge(pydot.Edge(node_v, node_w))
        # 5. write graph to png file
        graph.write_png(fout_png)
        prt.write("  wrote: {}\n".format(fout_png))

    def get_edges(self):
        """Get edges"""
        edges = set()
        for node_v in self.keys:
            for node_w in self._adj[node_v]:
                edges.add(tuple(sorted([node_v, node_w])))
        return edges

    def _init_empty(self, num_nodes):
        """Initialize an empty graph containing N nodes"""
        if num_nodes < 0:
            raise Exception("Number of vertices must be nonnegative")
        self.num_nodes = num_nodes
        self.num_edges = 0
        self._adj = [set() for node_v in range(num_nodes)]

    def _init(self, arg):
        """Initializes arg graph from an input stream."""
        # The format is the number of vertices V, followed by the number of edges E,
        # followed by E pairs of vertices, with each entry separated by whitespace.
        self._init_empty(arg[0]) # init V, and the empty adj list
        edge = arg[1]
        if edge < 0:
            raise Exception("Number of edges must be nonnegative")
        for node_v, node_w in arg[2:]:
            self.add_edge(node_v, node_w)

    def _init_num_edges(self):
        """Get the number of edges"""
        edges = set()
        for node_v, nodes in self._adj.items():
            for node_w in nodes:
                edges.add(frozenset([node_v, node_w]))
        return len(edges)

 #*****************************************************************************/
 #  % Graph.py ../thirdparty/tinyG.txt
 #  13 vertices, 13 edges
 #  0: 6 2 1 5
 #  1: 0
 #  2: 0
 #  3: 5 4
 #  4: 5 6 3
 #  5: 3 4 0
 #  6: 0 4
 #  7: 8
 #  8: 7
 #  9: 11 10 12
 #  10: 9
 #  11: 9 12
 #  12: 11 9
 #
 #*****************************************************************************/

# -----------------------------------------------------------------------------
# INTRODUCTION TO GRAPHS (9:32)


# SOME GRAPH-PROCESSING PROBLEMS 08:14
#
# PATH: Is there a path between s and t?
# SHORTEST PATH: What is the shortest path between s and t?
#
# CYCLE: Is there a cycle in the graph?
# EULER TOUR: Is there a cycle that uses each edge exactly once?
# HAMILTON TOUR: Is there a cycle that uses each vertex exactly once?
#
# CONNECTIVITY: Is there a awy to connect all of the vertices?
# MST: What is the best way to connect all of the vertices?
# BICONNECTIVITY: Is there a vertex whose removeal disconnects the graph?
#
# PLANARITY: Can you draw the graph in the plane with no crossing edges?
# GRAPH ISOMORPHISM: Do two adjacency lists represent the same graph?
#
# CHALLENGE: Whinc of these problems are easy? difficult? intractable?



# QUESTION: A cycle that uses eachedge of a graph exactly once is called
# ANSWER: An Euler tour

#  Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
#  Copyright 2015-2019, DV Klopfenstein, Python implementation


================================================
FILE: AlgsSedgewickWayne/HTree.py
================================================
#!/usr/bin/env python3
#*****************************************************************************
 #  H-tree.
 #    * O(1)  --  Used in Python's os.path.exists with an ext4 filesystem
 #    * https://stackoverflow.com/questions/6176547/python-complexity-of-os-path-exists-with-a-ext4-filesystem
 #    * Unlike standard B-tree, HTree has:
 #      * Constant depth
 #      * Uses hash-map per node, thus its lookup complexity is O(1{
 #    * http://ext2.sourceforge.net/2005-ols/paper-html/node3.html
 #    * https://en.wikipedia.org/wiki/HTree
 #    * improved the scalability of Linux ext2 based filesystems from a practical limit of a few thousand files,
 #      into the range of tens of millions of files per directory
 #    * 2000: Developed by Daniel Phillips
 #    * 2001: Implemented for the ext2 filesystem
 #    * 2002: Ported to ext3 by Christopher Li and Andrew Morton
 #
 #  Limitations
 #  -----------
 #
 #*****************************************************************************/



================================================
FILE: AlgsSedgewickWayne/Heap.py
================================================
"""Heapsort."""

from AlgsSedgewickWayne.utils import _isSorted

def Sort(pq):
  N = len(pq)
  for k in range(N/2, 0, -1):
    _sink(pq, k, N)
  while (N > 1):
    _exch(pq, 1, N)
    N -= 1
    _sink(pq, 1, N)
  assert _isSorted(pq)

def _sink(pq, k, N):
  while 2*k <= N:
    j = 2*k
    if j < N and _less(pq, j, j+1): 
      j += 1
    if not _less(pq, k, j): 
      break
    _exch(pq, k, j)
    k = j

def _less(pq, i, j):
  return pq[i-1] < (pq[j-1])

def _exch(pq, i, j):
  pq[i-1], pq[j-1] = pq[j-1], pq[i-1]


# Copyright (C) 2002-2016, Robert Sedgewick and Kevin Wayne.
# Copyright (C) 2019, DV Klopfenstein, Python Implementation

## Algorithms, Part 1 from Princeton University
## by Kevin Wayne, Robert Sedgewick
## https://class.coursera.org/algs4partI-005 retreived July 2014
## Lecture 8 - 3 Heapsort (14-29)
#
#
## BASIC PLAN FOR AN IN-PLACE SORT:
## * Create max-heap with all N keys.
## * Repeatedly remove the maximum key
#
#1. START WITH ARRAY OF KEYS IN ARBITRARY ORDER
#
#            ______S______
#           /             \
#        __O__           __R__
#       /     \         /     \
#      T       E       X       A
#     / \     / \                
#    M   P   L   E                
#
#2. BUILD A MAX-HEAP (IN PLACE) USING BOTTOM-UP (right-to-left) METHOD. 03:57
#
#            ______X______
#           /             \
#        __T__           __S__
#       /     \         /     \
#      P       L       R       A
#     / \     / \                
#    M   O   E   E                
#
#3. SORTED RESULT (IN PLACE) 04:43
#A E E L M O P R S T X
#1 2 3 4 5 6 7 8 9 0 1
#
#                  A      
#                          
#          E               E  
#                              
#      L       M       O       P
#                                
#    R   S   T   X                
   
# Fine sort algorithm that is very little code
# Sort gets done while touching relatively few objects

    # HEAPSORT: HEAP CONSTRUCTION
    # First pass. Build using bottom-up method
    # Go backwards through the heap starting at N/2 because right-most 
    # half of array is little heaps of size 1
    # 
    #             ______1______  for(int k=5; k>=1; k--)...
    #            /             \
    #         __2__           __3__
    #        /     \         /     \
    #       4       5       -       -
    #      / \     / \                
    #     -   -   -   -                
    # 

    #   
    # HEAPSORT: SORTDOWN
    # Second pass.
    # * Remove the maximum, one at a time.
    # * Leave in array, instead of nulling out.

  # array helper functions (Lecture 8 - 2)
  # TBD: CONVERT FROM 1-BASED INDEXING TO 0-BASE INDEXING

# HEAPSORT: MATHEMATICAL ANALYSIS 10:47
# PROPOSITION. Heap construction uses <= 2 N (linear number) compares and exchanges.
# PROPOSITION. Heapsort uses <= 2 N lg N compares and exchanges.
#   Size of the heap is at most lg(N)
#
# SIGNIFICANCE. In-place sorting algorithm with N log N worst-case. 11:14
# First sorting algorithm that is both:
#   1. In-place
#   2. Manages to get sorting job done with guaranteed N lg N compares
# * Mergesort: no, linear extra space
#              in-place merge possible, not practical
# * Quicksort: no, quadratic time in worst case 
#              (even though unlikely with random shuffling).
#              N log N worst-case quicksort possible. not practical
# * Heapsort:  yes!

# Job interview Question:
# What is a sorting algorithm that is both in-place and guaranteed N lg N time? HEAPSORT 12:00

# In practice, heapsort is not used that much...
# BOTTOM LINE. Heapsort is optimal for both time and space, but:
# * Inner loop longer than quicksorts:
#   Two compares that get done N lg N times
#   And then there is the array arithmetic.
# * Makes poor use of cache memory:
#   References to memory are all over the place when it is a huge array 12:41
#   Quicksort has a local memory reference, but heapsort looks far away
# * Not stable. (Mergesort is stable)
#   Because it does long distance exchanges... 
#   brings items that have equal keys back out of order

# FULL SUMMARY OF SORTING ALGORITHMS
#           inplace?
#             stable?
#               Worst     Avg       Best      Remarks
# --------- - - --------  --------  --------  --------------------
# selection x   N^2/2     N^2/2     N^2/2     N exchanges
# insertion x x N^2/2     N^2/4       N       use for small N or partially ordered
# shell     x    ???       ???        N       tight code, subquadratic
# quick     x   N^2/2     2 N ln N  N lg N    N log N probabilistic guarantee
#                                             fastest in practice
# 3-way qu  x   N^2/2     2 N ln N    N       improves quicksort in presence
#                                             of duplicate keys
# merge       x N lg N    N lg N    N lg N    N log N guarantee, stable
# heap      x   2 N lg N  2 N lg N  N lg N    N log N guarantee, in-place
# ???       x x N lg N    N lg N    N lg N    Holy sorting grail

# QUESTION: How many compares does bottom-up heap construction perform 
# in the worst case when sorting an array of N keys?
# ANSWER: Linear. The bottom-up version of heapsort makes ~2N compares in the worst case.


# Java last updated: Sat Sep 26 08:34:31 EDT 2015.


================================================
FILE: AlgsSedgewickWayne/Insertion.py
================================================
"""Alg1 Week2 Lecture Insertion Sort.

AVG:  ~1/4 N**2 compares and 1/4 N**2 exchanges on avg: Randomly-ordered array w/distinct keys
BEST:       N-1 compares and        0 exchanges: Ascending  order array (linear)
WORST: 1/2 N**2 compares and 1/2 N**2 exchanges: Descending order array
"""

from AlgsSedgewickWayne.utils import _isSorted, __lt__, _exch
from AlgsSedgewickWayne.utils import add_array_history


def Sort(arr, array_history=None):
    """Insertion Sort: Rearranges the array in ascending order"""
    # 00:57 Everything to the left is in acending order
    #       Everything to the right, we have not seen at all
    for i in range(len(arr)):
        j = i
        # Exchange the curr Elem with every element to the left that is > 01:21
        while j > 0 and arr[j-1] > arr[j]: # Iterate from i back towards 0
            add_array_history(array_history, arr, {j:'*', j-1:'*'})
            _exch(arr, j, j-1)
            j -= 1
        assert _isSorted(arr, 0, i)
    assert _isSorted(arr)
    add_array_history(array_history, arr, None)


#************************************************************************
#  Compilation:  javac Insertion.java
#
#  % more tiny.txt
#  S O R T E X A M P L E
#
#  % java Insertion < tiny.txt
#  A E E L M O P R S T X                 [ one string per line ]
#
#  % more words3.txt
#  bed bug dad yes zoo ... all bad yet
#
#  % java Insertion < words3.txt
#  all bad bed bug dad ... yes yet zoo   [ one string per line ]
#
#************************************************************************/

#*
#  The <tt>Insertion</tt> class provides static methods for sorting an
#  array using insertion sort.
#  <p>
#  For additional documentation, see :
#      <a href="http:#algs4.cs.princeton.edu/21elementary">Section 2.1</a> of
#  <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
#
#  @author Robert Sedgewick
#  @author Kevin Wayne
#/

# SIMULATION: 00:32 to 02:40
#
# ALGORITHM: Ptr scans from Left to Right
# INVARIANTS: 02:50
#   * Entries to the left or Ptr (inc Ptr) are in ascending order
#   * Entries to the right of Ptr have not yet been seen
# PROPOSITION: 04:27 To sort a randomly-ordered array with distinct keys:
#   ~ 1/4*N^2 compares  on average
#   ~ 1/4*N^2 exchanges on average
# PROOF: 05:16 Expect each entry to move halfway back below the diagonal on the average
#
# INSERTION SORT: BEST CASE AND WORST CASE: 06:10
# BEST CASE 06:12: If the array is in ascending order,
#   insertion sort makes N-1 compares and 0 exchanges
#   A E E L , O P R S T X
# WORST CASE 06:37: If the array is in descending order (and no duplicates),
#   insertion sort makes:
#       ~ 1/2*N^2 compares and
#       ~ 1/2*N^2 exchanges (Slower that Selection sort)
#   X T S R P O M L E E A
#   For every step, it is not just comparing, it is also exchanging
#
# MEMORY: Insertion sort uses only a constant amount of memory (other than the input array).
# This is a key property of insertion sort.
#
# INSERTION SORT: PARTIALLY-SORTED ARRAYS 07:47 - 08:20
#   Appear often in practice:
#     1. All elems sorted except a few unsorted elements appended at the end
#     2. Just a few elems out of place.
# DEFINITION: An INVERSION is a pair of keys that are out of order:
#   A E E L M O T R X P S (6 inversions: T-R T-P T-S R-P X-P X-S)
# DEFINITION: An array is PARTIALLY-SORTED if the number of inversions is <= c*N
#  * Ex 1. A subarray of size 10 appended to a sorted subarray of size N
#  * Ex 2. An array of size N with only 10 entries out of place
#
# PROPOSITION: For partially-sorted arrays, insertion sort runs in linear time. 08:57
# PROOF: Number of exchanges equals the numbers of inversions
#   number of compares = exchanges + (N - 1)
#
# INSERTION SORT IS INEFFICIENT because elements only move one place at a time
# even if we know that they have to move far away.
#
# QUESTION: How many compares does insertion sort make on an imput array that is already sorted?
# ANSWER: linear
#
# QUESTION: True or False? The expected # of compares to insertion sort an array
# containing N/2 0s and N/2 1s in uniformly random order is ~1/4 N^2.
# ANSWER: False.
# Consider element i>0. How many of the items a[0], a[1], ..., a[i-1] is a[i] inverted with?
# If a[i] == 1 (which happens with probability 1/2), then the number is 0.
# If a[i] == 0 (which happens with probability 1/2), then we expect half of the i previous
# elements to be 1s, so the expected number is i/2.
# So the expected number of inversions is:
#     1/2(0/2 + 1/2 + 2/2 + 3/2 + ... + (N-1)/2) ~N^2/8.
# Thus, the expected number of compares is ~ 1/8 N^2

# TRUE: Any pair of items is compared no more than once during insertion sort.
# EXPLANATION: Let a[i] and a[j] be two entries in the unsorted array with i<j.
# The entries a[i] and a[j] are compred no more than once during iteration j and they are not
# compared during any other iteration.

# When I actually run these and get a count of compares, I get a different
# number of compares than what the answer says, but here is 'the answer':
#
# Seed: 962938
# QUESTION: The number of compares to insertion sort an array of the form

# ANSWER: False. The number of inversions is 0 + 1 + ... + N/2 - 1 ~ 1/8 N^2.
# Thus, the number of compares is ~ 1/8 N^2.
# MY ANSWER: 19 compares on an actual run. 1/8 N^2=100/8=12.5 Anyone know why?
#
# QUESTION: The number of compares to insertion sort an array of N/2 1s
# interleaved with N/2 0s (e.g., 1 0 1 0 1 0 1 0 1 0) is ~ 1/8 N^2.
# ANSWER: True. The number of inversions is 1 + 2 + 3 + ... + N/2 ~ 1/8 N^2.
# Thus, the number of compares is ~ 1/8 N^2.
# MY ANSWER: 23 compares on an actual run. 1/8 N^2=100/8=12.5 Anyone know why?

# QUESTION: The number of compares to insertion sort an array of N/2 1s
# followed by N/2 0s (e.g., 1 1 1 1 1 0 0 0 0 0) is ~ 1/2 N^2.
# ANSWER: False. The number of inversions is (N/2)*(N/2) = 1/4 N^2.
# Thus, the number of compares is ~ 1/4 N^2.
# MY ANSWER: 33 compares on an actual run.

# QUESTION: The number of compares to insertion sort an array of N/2 keys
# in strictly increasing order followed by the same N/2 keys in strictly
# decreasing order (e.g., 0 1 2 3 4 4 3 2 1 0) is ~1/4 N^2.
# ANSWER: The number of inversions is 0 + 2 + 4 + 6 + ... + (N-2) ~ 1/4 N^2.
# Thus, the number of compares is ~ 1/4 N^2.
# MY ANSWER: 29 compares on an actual run.



########################################################
### Stability (Week 3 Lecture "Stability")
########################################################
#
# #----------------------------------------------
# 03:29 PROPOSITION: INSERTION SORT IS STABLE
#
# PROOF: Equal items never move past each other (in the "Sort" code)
#
# NOTE: Items depicted as A1 and A2 in the example below have the same
# key, "A".  The 1 and 2 following the "A" are denote that A1 was 1st
# and A2 was 2nd.
#
# NOTE: if "__lt__" in the "Sort" routine were "less than or equal to",
# it would not work.
#
# i j   0   1   2   3   4
# -----------------------
# 0 0 >B1  A1  A2  A3  B2
# 1 0 >A1 *B1  A2  A3  B2
# 2 1 *A1 >A2 *B1  A3  B2
# 3 2 *A1 *A2 >A3 *B1  B2
# 4 4 *A1 *A2 *A3 *B1 >B2
#     *A1 *A2 *A3 *B1 *B2
#
#



#  #*
#  # Rearranges the array in ascending order, using a compa
Download .txt
gitextract__qej4jrm/

├── .gitignore
├── AlgsSedgewickWayne/
│   ├── .gitignore
│   ├── AcyclicLP.py
│   ├── AcyclicSP.py
│   ├── BST.py
│   ├── BST_utils.py
│   ├── BTree.py
│   ├── Bag.py
│   ├── BaseComp.py
│   ├── BellmanFordSP.py
│   ├── BinarySearch.py
│   ├── BoyerMoore.py
│   ├── BreadthFirstPaths.py
│   ├── CC.py
│   ├── CPM.py
│   ├── CollisionSystem.py
│   ├── Date.py
│   ├── DepthFirstDirectedPaths.py
│   ├── DepthFirstOrder.py
│   ├── DepthFirstPaths.py
│   ├── DepthFirstSearch.py
│   ├── Digraph.py
│   ├── DijkstraSP.py
│   ├── DirectedDFS.py
│   ├── DirectedEdge.py
│   ├── Edge.py
│   ├── EdgeWeightedDigraph.py
│   ├── EdgeWeightedDirectedCycle.py
│   ├── EdgeWeightedGraph.py
│   ├── FileIndex.py
│   ├── FlowEdge.py
│   ├── FlowNetwork.py
│   ├── FordFulkerson.py
│   ├── FrequencyCounter.py
│   ├── GREP.py
│   ├── GabowSCC.py
│   ├── GrahamScan.py
│   ├── Graph.py
│   ├── HTree.py
│   ├── Heap.py
│   ├── Insertion.py
│   ├── Interval1D.py
│   ├── KMP.py
│   ├── KosarajuSharirSCC.py
│   ├── KruskalMST.py
│   ├── LSD.py
│   ├── LazyPrimMST.py
│   ├── LinearProbingHashST.py
│   ├── LinearProgramming.py
│   ├── LinkedBag.py
│   ├── LinkedQueue.py
│   ├── LinkedStack.py
│   ├── LookupCSV.py
│   ├── MSD.py
│   ├── MST_check.py
│   ├── MaxPQ.py
│   ├── Merge.py
│   ├── MergeBU.py
│   ├── MergeX.py
│   ├── MinPQ.py
│   ├── NFA.py
│   ├── Particle.py
│   ├── Point2D.py
│   ├── PowerLaw.py
│   ├── PrimMST.py
│   ├── Queue.py
│   ├── Quick.py
│   ├── Quick3way.py
│   ├── QuickFindUF.py
│   ├── QuickUnionUF.py
│   ├── QuickX.py
│   ├── RabinKarp.py
│   ├── RedBlackBST.py
│   ├── ResizingArrayBag.py
│   ├── ResizingArrayQueue.py
│   ├── ResizingArrayStack.py
│   ├── SET.py
│   ├── ST.py
│   ├── Selection.py
│   ├── SeparateChainingHashST.py
│   ├── SequentialSearchST.py
│   ├── Shell.py
│   ├── SparseVector.py
│   ├── Stack.py
│   ├── StdIn.py
│   ├── TST.py
│   ├── TarjanSCC.py
│   ├── ThreeSum.py
│   ├── ThreeSumFast.py
│   ├── TopM.py
│   ├── Topological.py
│   ├── TopologicalX.py
│   ├── Transaction.py
│   ├── TrieST.py
│   ├── UnorderedArrayMaxPQ.py
│   ├── WeightedQuickUnionPlusUF.py
│   ├── WeightedQuickUnionUF.py
│   ├── Whitelist.py
│   ├── __init__.py
│   ├── digraph_dvk.py
│   ├── directed_dfs.py
│   ├── knuth_shuffle.py
│   ├── makefile
│   ├── nfa_dvk.py
│   ├── notes_Search_Problems.txt
│   ├── plt_regex_graph.py
│   ├── pylintrc
│   ├── substrsrc_bruteforce.py
│   ├── substrsrc_bruteforce_alt.py
│   ├── testcode/
│   │   ├── ArrayHistory.py
│   │   ├── InputArgs.py
│   │   ├── __init__.py
│   │   ├── binary_heaps.py
│   │   ├── chaining_table.py
│   │   ├── order.py
│   │   └── utils.py
│   └── utils.py
├── LICENSE
├── README.md
├── doc/
│   ├── README.md
│   ├── README_Analysis_of_Algorithms.md
│   ├── README_BST.md
│   ├── README_BST_geom.md
│   ├── README_Data_Compression.md
│   ├── README_Directed_Graphs.md
│   ├── README_ElemSymbolTbls.md
│   ├── README_Elementary_Sorts.md
│   ├── README_HashTables.md
│   ├── README_Intractability.md
│   ├── README_Intractability_details.md
│   ├── README_Linear_Programming.md
│   ├── README_Maximum_Flow_and_Minimum_Cut.md
│   ├── README_Mergesort.md
│   ├── README_Minimum_Spanning_Trees.md
│   ├── README_PriorityQueues.md
│   ├── README_Quicksort.md
│   ├── README_Radix_Sorts.md
│   ├── README_Reductions.md
│   ├── README_Regular_Expressions.md
│   ├── README_Shortest_Paths.md
│   ├── README_StacksQueues.md
│   ├── README_Substring_Search.md
│   ├── README_Tries.md
│   ├── README_Undirected_Graphs.md
│   ├── README_Union_Find.md
│   ├── README_analysis_summary.md
│   ├── discussions.txt
│   ├── scratchpad/
│   │   ├── Interview_Questions.txt
│   │   ├── PQ_doc.txt
│   │   ├── lec10.txt
│   │   ├── lecture_week3_Sorting_Complexity.txt
│   │   ├── notes
│   │   ├── notes.txt
│   │   ├── oog1.py
│   │   ├── wk1_ex_AnalysisOfAlgorithms_Q2.py
│   │   ├── wk1_ex_q2.py
│   │   └── wk2.txt
│   ├── video_toc.md
│   ├── wk1_ex_mem.txt
│   └── wk1_memory
├── makefile
├── notebooks/
│   ├── .gitignore
│   ├── ElemSymbolTbls.ipynb
│   └── makefile
├── py/
│   └── UnorderedMaxPQ.py
├── setup.py
├── tests/
│   ├── 1Kints.txt
│   ├── 2Kints.txt
│   ├── 4Kints.txt
│   ├── 8Kints.txt
│   ├── __init__.py
│   ├── brownian.txt
│   ├── diffusion.txt
│   ├── images/
│   │   └── README_figs.md
│   ├── largeW.txt
│   ├── makefile
│   ├── mediumG.txt
│   ├── plot_graphs.py
│   ├── shellsST.txt
│   ├── test_AcyclicSP.py
│   ├── test_BST.py
│   ├── test_BST_sortinput.py
│   ├── test_Bag.py
│   ├── test_BellmanFordSP.py
│   ├── test_BoyerMoore.py
│   ├── test_BreadthFirstPaths.py
│   ├── test_CC.py
│   ├── test_Date.py
│   ├── test_DepthFirstDirectedPaths.py
│   ├── test_DepthFirstPaths.py
│   ├── test_DepthFirstSearch.py
│   ├── test_Deque.py
│   ├── test_Digraph.py
│   ├── test_DijkstraSP.py
│   ├── test_DirectedDFS.py
│   ├── test_DirectedEdge.py
│   ├── test_Edge.py
│   ├── test_EdgeWeightedDigraph.py
│   ├── test_EdgeWeightedDirectedCycle.py
│   ├── test_EdgeWeightedGraph.py
│   ├── test_FlowEdge.py
│   ├── test_FlowNetwork.py
│   ├── test_FordFulkerson.py
│   ├── test_GREP.py
│   ├── test_Graph.py
│   ├── test_Heap.py
│   ├── test_Insertion.py
│   ├── test_Interval1D.py
│   ├── test_KMP.py
│   ├── test_KruskalMST.py
│   ├── test_LSD.py
│   ├── test_LazyPrimMST.py
│   ├── test_LinearProbingHashST.py
│   ├── test_LinearProgramming.py
│   ├── test_MSD.py
│   ├── test_MaxPQ.py
│   ├── test_Merge.py
│   ├── test_MergeBU.py
│   ├── test_MergeX.py
│   ├── test_MinPQ.py
│   ├── test_NFA.py
│   ├── test_Point2D.py
│   ├── test_PowerLaw.py
│   ├── test_PrimMST.py
│   ├── test_Queue.py
│   ├── test_Quick.py
│   ├── test_Quick3way.py
│   ├── test_QuickFindUF.py
│   ├── test_QuickUnionUF.py
│   ├── test_QuickX.py
│   ├── test_Quick_partition.py
│   ├── test_RabinKarp.py
│   ├── test_RandomizedQueue.py
│   ├── test_RandomizedQueueOrdered.py
│   ├── test_RedBlackBST.py
│   ├── test_ResizingArrayQueue.py
│   ├── test_ResizingArrayStack.py
│   ├── test_ST.py
│   ├── test_Selection.py
│   ├── test_SeparateChainingHashST.py
│   ├── test_SequentialSearchST.py
│   ├── test_Shell.py
│   ├── test_Sorting.py
│   ├── test_Stack.py
│   ├── test_TST.py
│   ├── test_Transaction.py
│   ├── test_TrieST.py
│   ├── test_UnorderedArrayMaxPQ.py
│   ├── test_WeightedQUF_state_pics.py
│   ├── test_WeightedQuickUnionPlusUF.py
│   ├── test_WeightedQuickUnionUF.py
│   ├── test_adjtxtblk2arr.py
│   ├── test_knuth_shuffle.py
│   ├── test_nfa_dvk.py
│   ├── test_quickfinduf_01a_03_11.py
│   ├── test_regex_is_exponential.py
│   ├── test_substr_search.py
│   ├── tinyBatch.txt
│   ├── tinyCG.txt
│   ├── tinyDAG.txt
│   ├── tinyDG.txt
│   ├── tinyDG2.txt
│   ├── tinyEWG.txt
│   ├── tinyG.txt
│   ├── tinyST.txt
│   ├── tinyT.txt
│   ├── tinyTale.txt
│   ├── tinyW.txt
│   ├── utils.py
│   ├── visualize_blktxt.py
│   └── words3.txt
└── thirdparty/
    ├── .gitignore
    ├── BouncingBalls.java
    ├── EvaluatePostfix.java
    ├── FileSorter.java
    ├── HelloWorld.java
    ├── README.md
    ├── UnorderedArrayMaxPQ.java
    ├── a2_hw1/
    │   ├── COS_226_Programming_Assignment_1_WordNet.html
    │   ├── Programming_Assignment_1_Checklist_WordNet.html
    │   └── wordnet/
    │       ├── digraph-ambiguous-ancestor.txt
    │       ├── digraph-wordnet.txt
    │       ├── digraph1.txt
    │       ├── digraph2.txt
    │       ├── digraph3.txt
    │       ├── digraph4.txt
    │       ├── digraph5.txt
    │       ├── digraph6.txt
    │       ├── digraph9.txt
    │       ├── hypernyms.txt
    │       ├── hypernyms100-subgraph.txt
    │       ├── hypernyms1000-subgraph.txt
    │       ├── hypernyms10000-subgraph.txt
    │       ├── hypernyms100K.txt
    │       ├── hypernyms11AmbiguousAncestor.txt
    │       ├── hypernyms11ManyPathsOneAncestor.txt
    │       ├── hypernyms15Path.txt
    │       ├── hypernyms15Tree.txt
    │       ├── hypernyms200K.txt
    │       ├── hypernyms300K.txt
    │       ├── hypernyms3InvalidCycle.txt
    │       ├── hypernyms3InvalidTwoRoots.txt
    │       ├── hypernyms500-subgraph.txt
    │       ├── hypernyms5000-subgraph.txt
    │       ├── hypernyms50000-subgraph.txt
    │       ├── hypernyms6InvalidCycle+Path.txt
    │       ├── hypernyms6InvalidCycle.txt
    │       ├── hypernyms6InvalidTwoRoots.txt
    │       ├── hypernyms6TwoAncestors.txt
    │       ├── hypernyms8ManyAncestors.txt
    │       ├── hypernyms8WrongBFS.txt
    │       ├── hypernymsManyPathsOneAncestor.txt
    │       ├── outcast10.txt
    │       ├── outcast10a.txt
    │       ├── outcast11.txt
    │       ├── outcast12.txt
    │       ├── outcast12a.txt
    │       ├── outcast17.txt
    │       ├── outcast2.txt
    │       ├── outcast20.txt
    │       ├── outcast29.txt
    │       ├── outcast3.txt
    │       ├── outcast4.txt
    │       ├── outcast5.txt
    │       ├── outcast5a.txt
    │       ├── outcast7.txt
    │       ├── outcast8.txt
    │       ├── outcast8a.txt
    │       ├── outcast8b.txt
    │       ├── outcast8c.txt
    │       ├── outcast9.txt
    │       ├── outcast9a.txt
    │       ├── synsets.txt
    │       ├── synsets100-subgraph.txt
    │       ├── synsets1000-subgraph.txt
    │       ├── synsets10000-subgraph.txt
    │       ├── synsets11.txt
    │       ├── synsets15.txt
    │       ├── synsets3.txt
    │       ├── synsets500-subgraph.txt
    │       ├── synsets5000-subgraph.txt
    │       ├── synsets50000-subgraph.txt
    │       ├── synsets6.txt
    │       └── synsets8.txt
    ├── a2_hw2/
    │   ├── Programming_Assignment_2_Checklist_Seam_Carving.html
    │   ├── Programming_Assignment_2_Seam_Carving.html
    │   └── seamCarving/
    │       ├── 10x10.printseams.txt
    │       ├── 10x12.printseams.txt
    │       ├── 12x10.printseams.txt
    │       ├── 3x4.printseams.txt
    │       ├── 3x7.printseams.txt
    │       ├── 4x6.printseams.txt
    │       ├── 5x6.printseams.txt
    │       ├── 6x5.printseams.txt
    │       ├── 7x10.printseams.txt
    │       ├── 7x3.printseams.txt
    │       ├── PrintEnergy.java
    │       ├── PrintSeams.java
    │       ├── ResizeDemo.java
    │       ├── SCUtility.java
    │       ├── ShowEnergy.java
    │       ├── ShowSeams.java
    │       ├── diagonals.printseams.txt
    │       └── stripes.printseams.txt
    ├── a2_hw3/
    │   ├── Programming_Assignment_3_Baseball_Elimination.html
    │   ├── Programming_Assignment_Checklist_Baseball_Elimination.html
    │   └── baseball/
    │       ├── readme.txt
    │       ├── teams1.txt
    │       ├── teams10.txt
    │       ├── teams12-allgames.txt
    │       ├── teams12.txt
    │       ├── teams24.txt
    │       ├── teams29.txt
    │       ├── teams30.txt
    │       ├── teams32.txt
    │       ├── teams36.txt
    │       ├── teams4.txt
    │       ├── teams42.txt
    │       ├── teams48.txt
    │       ├── teams4a.txt
    │       ├── teams4b.txt
    │       ├── teams5.txt
    │       ├── teams50.txt
    │       ├── teams54.txt
    │       ├── teams5a.txt
    │       ├── teams5b.txt
    │       ├── teams5c.txt
    │       ├── teams60.txt
    │       ├── teams7.txt
    │       └── teams8.txt
    ├── a2_hw4/
    │   ├── Programming_Assignment_4_Boggle.html
    │   ├── Programming_Assignment_Checklist_Boggle.html
    │   └── boggle/
    │       ├── BoggleBoard.java
    │       ├── BoggleGame.java
    │       ├── board-16q.txt
    │       ├── board-antidisestablishmentarianisms.txt
    │       ├── board-aqua.txt
    │       ├── board-couscous.txt
    │       ├── board-diagonal.txt
    │       ├── board-dichlorodiphenyltrichloroethanes.txt
    │       ├── board-dodo.txt
    │       ├── board-estrangers.txt
    │       ├── board-horizontal.txt
    │       ├── board-inconsequentially.txt
    │       ├── board-noon.txt
    │       ├── board-pneumonoultramicroscopicsilicovolcanoconiosis.txt
    │       ├── board-points0.txt
    │       ├── board-points1.txt
    │       ├── board-points100.txt
    │       ├── board-points1000.txt
    │       ├── board-points1111.txt
    │       ├── board-points1250.txt
    │       ├── board-points13464.txt
    │       ├── board-points1500.txt
    │       ├── board-points2.txt
    │       ├── board-points200.txt
    │       ├── board-points2000.txt
    │       ├── board-points26539.txt
    │       ├── board-points3.txt
    │       ├── board-points300.txt
    │       ├── board-points4.txt
    │       ├── board-points400.txt
    │       ├── board-points4410.txt
    │       ├── board-points4527.txt
    │       ├── board-points4540.txt
    │       ├── board-points5.txt
    │       ├── board-points500.txt
    │       ├── board-points750.txt
    │       ├── board-points777.txt
    │       ├── board-q.txt
    │       ├── board-quinquevalencies.txt
    │       ├── board-qwerty.txt
    │       ├── board-rotavator.txt
    │       ├── board-vertical.txt
    │       ├── board4x4.txt
    │       ├── dictionary-16q.txt
    │       ├── dictionary-2letters.txt
    │       ├── dictionary-algs4.txt
    │       ├── dictionary-common.txt
    │       ├── dictionary-enable2k.txt
    │       ├── dictionary-nursery.txt
    │       ├── dictionary-shakespeare.txt
    │       ├── dictionary-sowpods.txt
    │       ├── dictionary-twl06.txt
    │       ├── dictionary-yawl.txt
    │       └── dictionary-zingarelli2005.txt
    ├── a2_hw5/
    │   ├── Programming_Assignment_5_Burrows_Wheeler_Data_Compression_Algorithm.html
    │   ├── Programming_Assignment_Checklist_Burrows_Wheeler_Data_Compression.html
    │   └── burrows/
    │       ├── a.txt
    │       ├── abra.txt
    │       ├── abra.txt.bwt
    │       ├── abra.txt.bwt.mtf.huf
    │       ├── abra.txt.huf
    │       ├── abra.txt.mtf
    │       ├── aesop.txt
    │       ├── aesop.txt.bwt
    │       ├── aesop.txt.bwt.mtf.huf
    │       ├── aesop.txt.huf
    │       ├── aesop.txt.mtf
    │       ├── alphanum.txt
    │       ├── amendments.txt
    │       ├── cadabra.txt
    │       ├── couscous.txt
    │       ├── encodedSecretMessage.txt
    │       ├── stars.txt
    │       ├── us.gif.bwt
    │       ├── us.gif.bwt.mtf.huf
    │       ├── us.gif.huf
    │       ├── us.gif.mtf
    │       └── zebra.txt
    ├── algs4.jar
    ├── hw1/
    │   ├── Programming_Assignment_1_Checklist_Percolation.html
    │   ├── Programming_Assignment_1_Percolation.html
    │   └── percolation/
    │       ├── CREDITS
    │       ├── InteractivePercolationVisualizer.java
    │       ├── PercolationVisualizer.java
    │       ├── greeting57.txt
    │       ├── heart25.txt
    │       ├── input1-no.txt
    │       ├── input1.txt
    │       ├── input10-no.txt
    │       ├── input10.txt
    │       ├── input2-no.txt
    │       ├── input2.txt
    │       ├── input20.txt
    │       ├── input3.txt
    │       ├── input4.txt
    │       ├── input5.txt
    │       ├── input50.txt
    │       ├── input6.txt
    │       ├── input7.txt
    │       ├── input8-no.txt
    │       ├── input8.txt
    │       ├── jerry47.txt
    │       ├── sedgewick60.txt
    │       └── wayne98.txt
    ├── hw2/
    │   ├── Programming_Assignment_2_Checklist_Randomized_Queues_and_Dequeues.html
    │   └── Programming_Assignment_2_Randomized_Queues_and_Deques.html
    ├── hw3/
    │   ├── Programming_Assignment_3_Checklist_Pattern_Recognition.html
    │   ├── Programming_Assignment_3_Pattern_Recognition_Assignment.html
    │   └── collinear/
    │       ├── LineSegment.java
    │       ├── equidistant.txt
    │       ├── grid4x4.txt
    │       ├── grid5x5.txt
    │       ├── grid6x6.txt
    │       ├── horizontal100.txt
    │       ├── horizontal25.txt
    │       ├── horizontal5.txt
    │       ├── horizontal50.txt
    │       ├── horizontal75.txt
    │       ├── inarow.txt
    │       ├── input1.txt
    │       ├── input10.txt
    │       ├── input100.txt
    │       ├── input1000.txt
    │       ├── input10000.txt
    │       ├── input150.txt
    │       ├── input2.txt
    │       ├── input20.txt
    │       ├── input200.txt
    │       ├── input2000.txt
    │       ├── input250.txt
    │       ├── input299.txt
    │       ├── input3.txt
    │       ├── input300.txt
    │       ├── input3000.txt
    │       ├── input350.txt
    │       ├── input40.txt
    │       ├── input400.txt
    │       ├── input4000.txt
    │       ├── input48.txt
    │       ├── input50.txt
    │       ├── input5000.txt
    │       ├── input56.txt
    │       ├── input6.txt
    │       ├── input6000.txt
    │       ├── input8.txt
    │       ├── input80.txt
    │       ├── input8000.txt
    │       ├── input9.txt
    │       ├── kw1260.txt
    │       ├── mystery10089.txt
    │       ├── random152.txt
    │       ├── random23.txt
    │       ├── random38.txt
    │       ├── random91.txt
    │       ├── rs1423.txt
    │       ├── vertical100.txt
    │       ├── vertical25.txt
    │       ├── vertical5.txt
    │       ├── vertical50.txt
    │       └── vertical75.txt
    ├── hw4/
    │   ├── 8-Puzzle_Programming_Assignment.html
    │   ├── 8puzzle/
    │   │   ├── PuzzleChecker.java
    │   │   ├── puzzle00.txt
    │   │   ├── puzzle01.txt
    │   │   ├── puzzle02.txt
    │   │   ├── puzzle03.txt
    │   │   ├── puzzle04.txt
    │   │   ├── puzzle04_goal.txt
    │   │   ├── puzzle05.txt
    │   │   ├── puzzle06.txt
    │   │   ├── puzzle07.txt
    │   │   ├── puzzle08.txt
    │   │   ├── puzzle09.txt
    │   │   ├── puzzle10.txt
    │   │   ├── puzzle11.txt
    │   │   ├── puzzle12.txt
    │   │   ├── puzzle13.txt
    │   │   ├── puzzle14.txt
    │   │   ├── puzzle15.txt
    │   │   ├── puzzle16.txt
    │   │   ├── puzzle17.txt
    │   │   ├── puzzle18.txt
    │   │   ├── puzzle19.txt
    │   │   ├── puzzle20.txt
    │   │   ├── puzzle21.txt
    │   │   ├── puzzle22.txt
    │   │   ├── puzzle23.txt
    │   │   ├── puzzle24.txt
    │   │   ├── puzzle25.txt
    │   │   ├── puzzle26.txt
    │   │   ├── puzzle27.txt
    │   │   ├── puzzle28.txt
    │   │   ├── puzzle29.txt
    │   │   ├── puzzle2x2-00.txt
    │   │   ├── puzzle2x2-01.txt
    │   │   ├── puzzle2x2-02.txt
    │   │   ├── puzzle2x2-03.txt
    │   │   ├── puzzle2x2-04.txt
    │   │   ├── puzzle2x2-05.txt
    │   │   ├── puzzle2x2-06.txt
    │   │   ├── puzzle2x2-unsolvable1.txt
    │   │   ├── puzzle2x2-unsolvable2.txt
    │   │   ├── puzzle2x2-unsolvable3.txt
    │   │   ├── puzzle30.txt
    │   │   ├── puzzle31.txt
    │   │   ├── puzzle32.txt
    │   │   ├── puzzle33.txt
    │   │   ├── puzzle34.txt
    │   │   ├── puzzle35.txt
    │   │   ├── puzzle36.txt
    │   │   ├── puzzle37.txt
    │   │   ├── puzzle38.txt
    │   │   ├── puzzle39.txt
    │   │   ├── puzzle3x3-00.txt
    │   │   ├── puzzle3x3-01.txt
    │   │   ├── puzzle3x3-02.txt
    │   │   ├── puzzle3x3-03.txt
    │   │   ├── puzzle3x3-04.txt
    │   │   ├── puzzle3x3-05.txt
    │   │   ├── puzzle3x3-06.txt
    │   │   ├── puzzle3x3-07.txt
    │   │   ├── puzzle3x3-08.txt
    │   │   ├── puzzle3x3-09.txt
    │   │   ├── puzzle3x3-10.txt
    │   │   ├── puzzle3x3-11.txt
    │   │   ├── puzzle3x3-12.txt
    │   │   ├── puzzle3x3-13.txt
    │   │   ├── puzzle3x3-14.txt
    │   │   ├── puzzle3x3-15.txt
    │   │   ├── puzzle3x3-16.txt
    │   │   ├── puzzle3x3-17.txt
    │   │   ├── puzzle3x3-18.txt
    │   │   ├── puzzle3x3-19.txt
    │   │   ├── puzzle3x3-20.txt
    │   │   ├── puzzle3x3-21.txt
    │   │   ├── puzzle3x3-22.txt
    │   │   ├── puzzle3x3-23.txt
    │   │   ├── puzzle3x3-24.txt
    │   │   ├── puzzle3x3-25.txt
    │   │   ├── puzzle3x3-26.txt
    │   │   ├── puzzle3x3-27.txt
    │   │   ├── puzzle3x3-28.txt
    │   │   ├── puzzle3x3-29.txt
    │   │   ├── puzzle3x3-30.txt
    │   │   ├── puzzle3x3-31.txt
    │   │   ├── puzzle3x3-unsolvable.txt
    │   │   ├── puzzle3x3-unsolvable1.txt
    │   │   ├── puzzle3x3-unsolvable2.txt
    │   │   ├── puzzle40.txt
    │   │   ├── puzzle41.txt
    │   │   ├── puzzle42.txt
    │   │   ├── puzzle43.txt
    │   │   ├── puzzle44.txt
    │   │   ├── puzzle45.txt
    │   │   ├── puzzle46.txt
    │   │   ├── puzzle47.txt
    │   │   ├── puzzle48.txt
    │   │   ├── puzzle49.txt
    │   │   ├── puzzle4x4-00.txt
    │   │   ├── puzzle4x4-01.txt
    │   │   ├── puzzle4x4-02.txt
    │   │   ├── puzzle4x4-03.txt
    │   │   ├── puzzle4x4-04.txt
    │   │   ├── puzzle4x4-05.txt
    │   │   ├── puzzle4x4-06.txt
    │   │   ├── puzzle4x4-07.txt
    │   │   ├── puzzle4x4-08.txt
    │   │   ├── puzzle4x4-09.txt
    │   │   ├── puzzle4x4-10.txt
    │   │   ├── puzzle4x4-11.txt
    │   │   ├── puzzle4x4-12.txt
    │   │   ├── puzzle4x4-13.txt
    │   │   ├── puzzle4x4-14.txt
    │   │   ├── puzzle4x4-15.txt
    │   │   ├── puzzle4x4-16.txt
    │   │   ├── puzzle4x4-17.txt
    │   │   ├── puzzle4x4-18.txt
    │   │   ├── puzzle4x4-19.txt
    │   │   ├── puzzle4x4-20.txt
    │   │   ├── puzzle4x4-21.txt
    │   │   ├── puzzle4x4-22.txt
    │   │   ├── puzzle4x4-23.txt
    │   │   ├── puzzle4x4-24.txt
    │   │   ├── puzzle4x4-25.txt
    │   │   ├── puzzle4x4-26.txt
    │   │   ├── puzzle4x4-27.txt
    │   │   ├── puzzle4x4-28.txt
    │   │   ├── puzzle4x4-29.txt
    │   │   ├── puzzle4x4-30.txt
    │   │   ├── puzzle4x4-31.txt
    │   │   ├── puzzle4x4-32.txt
    │   │   ├── puzzle4x4-33.txt
    │   │   ├── puzzle4x4-34.txt
    │   │   ├── puzzle4x4-35.txt
    │   │   ├── puzzle4x4-36.txt
    │   │   ├── puzzle4x4-37.txt
    │   │   ├── puzzle4x4-38.txt
    │   │   ├── puzzle4x4-39.txt
    │   │   ├── puzzle4x4-40.txt
    │   │   ├── puzzle4x4-41.txt
    │   │   ├── puzzle4x4-42.txt
    │   │   ├── puzzle4x4-43.txt
    │   │   ├── puzzle4x4-44.txt
    │   │   ├── puzzle4x4-45.txt
    │   │   ├── puzzle4x4-46.txt
    │   │   ├── puzzle4x4-47.txt
    │   │   ├── puzzle4x4-48.txt
    │   │   ├── puzzle4x4-49.txt
    │   │   ├── puzzle4x4-50.txt
    │   │   ├── puzzle4x4-78.txt
    │   │   ├── puzzle4x4-80.txt
    │   │   ├── puzzle4x4-unsolvable.txt
    │   │   └── puzzle50.txt
    │   └── Programming_Assignment_4_Checklist_8_Puzzle.html
    ├── hw5/
    │   ├── NearestNeighborVisualizer.java
    │   ├── Programming_Assignment_5_Checklist_Kd-Trees.html
    │   ├── Programming_Assignment_5_Kd-Trees.html
    │   ├── RangeSearchVisualizer.java
    │   └── kdtree/
    │       ├── KdTreeGenerator.java
    │       ├── KdTreeVisualizer.java
    │       ├── NearestNeighborVisualizer.java
    │       ├── RangeSearchVisualizer.java
    │       ├── circle10.txt
    │       ├── circle100.txt
    │       ├── circle1000.txt
    │       ├── circle10000.txt
    │       ├── circle10k.txt
    │       ├── circle4.txt
    │       ├── horizontal8.txt
    │       ├── input100K.txt
    │       ├── input10K.txt
    │       ├── input1M.txt
    │       ├── input200K.txt
    │       ├── input20K.txt
    │       ├── input400K.txt
    │       ├── input40K.txt
    │       ├── input800K.txt
    │       ├── input80K.txt
    │       └── vertical7.txt
    ├── java2tmp.py
    ├── makefile
    ├── test/
    │   └── percolation/
    │       ├── CREDITS
    │       ├── greeting57.txt
    │       ├── heart25.txt
    │       ├── input1-no.txt
    │       ├── input1.txt
    │       ├── input10-no.txt
    │       ├── input10.txt
    │       ├── input2-no.txt
    │       ├── input2.txt
    │       ├── input20.txt
    │       ├── input3.txt
    │       ├── input4.txt
    │       ├── input5.txt
    │       ├── input50.txt
    │       ├── input6.txt
    │       ├── input7.txt
    │       ├── input8-no.txt
    │       ├── input8.txt
    │       ├── jerry47.txt
    │       ├── sedgewick60.txt
    │       └── wayne98.txt
    └── test_RandomizedQueue.java
Download .txt
SYMBOL INDEX (1132 symbols across 203 files)

FILE: AlgsSedgewickWayne/AcyclicLP.py
  class AcyclicLP (line 44) | class AcyclicLP:
  function _relax (line 72) | def _relax(DirectedEdge e):
  function distTo (line 84) | def distTo(int v):
  function hasPathTo (line 93) | def hasPathTo(int v):
  function pathTo (line 102) | def pathTo(int v):
  function main (line 114) | def main(String[] args):

FILE: AlgsSedgewickWayne/AcyclicSP.py
  class AcyclicSP (line 7) | class AcyclicSP(object):
    method __init__ (line 11) | def __init__(self, G, s): # G=DAG, v=source vertex O(V+E)
    method _relax (line 24) | def _relax(self, e):
    method distTo (line 31) | def distTo(self, v): # O(K)
    method hasPathTo (line 35) | def hasPathTo(self, v): # O(K)
    method pathTo (line 39) | def pathTo(self, v): # O(E in shortest path)

FILE: AlgsSedgewickWayne/BST.py
  class BST (line 30) | class BST(object):
    class _Node (line 37) | class _Node(object):
      method __init__ (line 39) | def __init__(self, key, val, N):
      method __str__ (line 46) | def __str__(self):
    method __init__ (line 50) | def __init__(self, keyvals=None):
    method isEmpty (line 59) | def isEmpty(self): return self.size() == 0
    method size (line 62) | def size(self): return self._size(self._root)
    method _size (line 65) | def _size(self, node_x): return node_x.N if node_x is not None else 0
    method contains (line 67) | def contains(self, key):
    method get (line 72) | def get(self, key): # $ = 1 + depth
    method _get (line 76) | def _get(self, node_x, key):
    method put (line 87) | def put(self, key, val):
    method _put (line 96) | def _put(self, node_x, key, val):
    method deleteMin (line 105) | def deleteMin(self):
    method _deleteMin (line 111) | def _deleteMin(self, node_x):
    method deleteMax (line 117) | def deleteMax(self):
    method _deleteMax (line 123) | def _deleteMax(self, node_x):
    method delete (line 129) | def delete(self, key):
    method _delete (line 135) | def _delete(self, node_x, key):
    method get_min (line 151) | def get_min(self): return self.get_min_node().key
    method _get_min_node (line 153) | def _get_min_node(self, node_x):
    method get_max (line 157) | def get_max(self): return self.get_max_node().key
    method _get_max_node (line 159) | def _get_max_node(self, node_x):
    method get_min_node (line 162) | def get_min_node(self):
    method get_max_node (line 167) | def get_max_node(self):
    method floor (line 173) | def floor(self, key):
    method _floor (line 180) | def _floor(self, node_x, key):
    method ceiling (line 187) | def ceiling(self, key):
    method _ceiling (line 194) | def _ceiling(self, node_x, key):
    method select (line 202) | def select(self, rank_k):
    method _select (line 208) | def _select(self, node_x, rank_k):
    method rank (line 216) | def rank(self, key):
    method _rank (line 221) | def _rank(self, key, node_x):
    method keys (line 229) | def keys(self):
    method nodes (line 233) | def nodes(self): return self._nodes_lohi(self.get_min(), self.get_max())
    method _nodes_lohi (line 235) | def _nodes_lohi(self, lo_key, hi_key):
    method _nodes (line 243) | def _nodes(self, node_x, queue, lo_key, hi_key):
    method size_lohi (line 256) | def size_lohi(self, lo, hi):
    method height (line 264) | def height(self):
    method _height (line 268) | def _height(self, node_x):
    method levelOrder (line 272) | def levelOrder(self):
    method wr_png (line 286) | def wr_png(self, fout_png):
    method check (line 292) | def check(self):
    method isBST (line 301) | def isBST(self): return self._isBST(self._root, minval=None, maxval=None)
    method _isBST (line 306) | def _isBST(self, node_x, minval, maxval):
    method isSizeConsistent (line 313) | def isSizeConsistent(self): return self._isSizeConsistent(self._root)
    method _isSizeConsistent (line 314) | def _isSizeConsistent(self, node_x):
    method isRankConsistent (line 320) | def isRankConsistent(self):

FILE: AlgsSedgewickWayne/BST_utils.py
  function wr_png (line 9) | def wr_png(fout_png, nodes_bst, childnames, log):
  function _get_dotnodes (line 26) | def _get_dotnodes(nodes_bst, childnames):
  function _get_dotedges (line 39) | def _get_dotedges(nodes_bst, childnames):
  function _get_name_nullchild (line 52) | def _get_name_nullchild(src_node, lr):
  function sort_balbst (line 57) | def sort_balbst(key_vals):
  function _sort_balbst (line 64) | def _sort_balbst(balanced_bst, sorted_list):

FILE: AlgsSedgewickWayne/BTree.py
  class Entry (line 37) | class Entry:
  function size (line 51) | def size(): return N; }
  function put (line 77) | def put( key, Value value):
  function toString (line 125) | def toString():
  function _toString (line 127) | def _toString( h, ht, String indent):
  function _less (line 142) | def _less(k1, k2):
  function _eq (line 145) | def _eq(k1, k2):
  function main (line 152) | def main(String[] args):

FILE: AlgsSedgewickWayne/Bag.py
  class Bag (line 3) | class Bag(object): # <Item> implements Iterable<Item>:
    class _Node (line 6) | class _Node(object): # private static class <Item>:
      method __init__ (line 9) | def __init__(self, Item, Next):
    method __init__ (line 13) | def __init__(self):
    method isEmpty (line 17) | def isEmpty(self):
    method size (line 21) | def size(self):
    method add (line 25) | def add(self, item):
    method __iter__ (line 31) | def __iter__(self):
    class _ListIterator (line 34) | class _ListIterator(object): # <Item> implements Iterator<Item>:
      method __init__ (line 37) | def __init__(self, first):
      method hasNext (line 40) | def hasNext(self):
      method next (line 44) | def next(self):

FILE: AlgsSedgewickWayne/BaseComp.py
  class BaseComp (line 12) | class BaseComp(object):
    method __init__ (line 17) | def __init__(self, name):
    method _root (line 22) | def _root(self, val):
    method __str__ (line 27) | def __str__(self):
    method get_connected_components (line 34) | def get_connected_components(self):
    method wr_png (line 44) | def wr_png(self, fout_png="components.png", prt=sys.stdout, **kwargs):
    method union_pngs (line 62) | def union_pngs(self, unions, png_base):
    method union_png (line 68) | def union_png(self, pval, qval, fout_png):
    method union (line 75) | def union(self, pval, qval):
    method get_png (line 79) | def get_png(self):
    method wr_png_tree_state (line 84) | def wr_png_tree_state(self, state=None, fout_png=None):
    method wr_png_tree_statestr (line 91) | def wr_png_tree_statestr(self, statestr=None, fout_png=None):

FILE: AlgsSedgewickWayne/BellmanFordSP.py
  class BellmanFordSP (line 8) | class BellmanFordSP(object):
    method __init__ (line 12) | def __init__(self, G, s): # G:EdgeWeightedDigraph O(V+E) wc
    method _relax (line 30) | def _relax(self, G, v):
    method hasNegativeCycle (line 46) | def hasNegativeCycle(self): return self._cycle is not None # O(k)
    method negativeCycle (line 49) | def negativeCycle(self): return self._cycle # O(# edges returned)
    method _findNegativeCycle (line 51) | def _findNegativeCycle(self):
    method distTo (line 62) | def distTo(self, v): # O(k)
    method hasPathTo (line 69) | def hasPathTo(self, v): return self._distTo[v] < sel.Inf # O(k)
    method pathTo (line 71) | def pathTo(self, v): # O(# edges returned)
    method _check (line 88) | def _check(EdgeWeightedDigraph G, s):

FILE: AlgsSedgewickWayne/BinarySearch.py
  function rank (line 108) | def rank(key, a):
  function run (line 124) | def run(a):
  function run_timed (line 139) | def run_timed(a):
  function run_timed_fin (line 146) | def run_timed_fin(fin):
  function run_timed_fins (line 151) | def run_timed_fins(fins):

FILE: AlgsSedgewickWayne/BreadthFirstPaths.py
  class BreadthFirstPaths (line 7) | class BreadthFirstPaths:
    method __init__ (line 11) | def __init__(self, graph, src, prt=None):
    method _bfs (line 21) | def _bfs(self, graph, sources, prt):
    method has_path_to (line 42) | def has_path_to(self, vertex):
    method get_dist_to (line 49) | def get_dist_to(self, vertex):
    method pathTo (line 53) | def pathTo(self, vertex):
    method deque (line 65) | def deque(self, queue, prt):
    method _check (line 72) | def _check(self, graph, src, prt=sys.stdout):

FILE: AlgsSedgewickWayne/CC.py
  class CC (line 5) | class CC(object):
    method __init__ (line 8) | def __init__(self, G): #  O(E + V)
    method _dfs (line 18) | def _dfs(self, G, v):
    method id (line 28) | def id(self, v): return self._id[v]
    method size (line 31) | def size(self, v): return self._size[id[v]]
    method count (line 34) | def count(self): return self._count
    method connected (line 37) | def connected(self, v, w): return self._id(v) == self._id(w)
    method prt_ids (line 39) | def prt_ids(self, prt):

FILE: AlgsSedgewickWayne/CPM.py
  class CPM (line 51) | class CPM:
    method main (line 60) | def main(String[] args):

FILE: AlgsSedgewickWayne/CollisionSystem.py
  class CollisionSystem (line 4) | class CollisionSystem(object):
  function _redraw (line 31) | def _redraw(double limit):
  function simulate (line 43) | def simulate(double limit):
  class Event (line 88) | class Event implements Comparable<Event>:
  function compareTo (line 105) | def compareTo(Event that):
  function isValid (line 111) | def isValid():
  function main (line 121) | def main(String[] args):

FILE: AlgsSedgewickWayne/Date.py
  class Date (line 6) | class Date:
    method __init__ (line 9) | def __init__(self, str_month, day=None, year=None):
    method month (line 16) | def month(self):
    method day (line 20) | def day(self):
    method year (line 24) | def year(self):
    method is_leap_year (line 29) | def is_leap_year(year):
    method next (line 37) | def next(self):
    method __gt__ (line 42) | def __gt__(self, that):
    method __ge__ (line 46) | def __ge__(self, that):
    method __lt__ (line 50) | def __lt__(self, that):
    method __le__ (line 54) | def __le__(self, that):
    method __str__ (line 58) | def __str__(self):
    method __eq__ (line 62) | def __eq__(self, other):
    method java_string_hashcode (line 81) | def java_string_hashcode(txt):
    method _init_w_str (line 89) | def _init_w_str(self, date_str):
    method _init_w_ints (line 96) | def _init_w_ints(self, year, month, day):

FILE: AlgsSedgewickWayne/DepthFirstDirectedPaths.py
  class DepthFirstDirectedPaths (line 3) | class DepthFirstDirectedPaths(object):
    method __init__ (line 6) | def __init__(self, G, s):
    method _dfs (line 12) | def _dfs(self, G, v):
    method hasPathTo (line 20) | def hasPathTo(self, v):
    method pathTo (line 24) | def pathTo(self, v):

FILE: AlgsSedgewickWayne/DepthFirstPaths.py
  class DepthFirstPaths (line 5) | class DepthFirstPaths(object):
    method __init__ (line 8) | def __init__(self, G, s, prt=None):
    method _dfs (line 15) | def _dfs(self, G, v):
    method hasPathTo (line 23) | def hasPathTo(self, v):
    method pathTo (line 27) | def pathTo(self, v):
    method _set_mark (line 38) | def _set_mark(self, v, G):

FILE: AlgsSedgewickWayne/DepthFirstSearch.py
  class DepthFirstSearch (line 5) | class DepthFirstSearch:
    method __init__ (line 8) | def __init__(self, graph_undirected, src_node):
    method _dfs (line 18) | def _dfs(self, graph, node_v):
    method is_marked (line 26) | def is_marked(self, node_v):
    method count (line 31) | def count(self):
    method _validate_vertex (line 35) | def _validate_vertex(self, node_v):

FILE: AlgsSedgewickWayne/Digraph.py
  class Digraph (line 8) | class Digraph:
    method __init__ (line 11) | def __init__(self, arr=None, **kwargs):
    method _init_empty (line 28) | def _init_empty(self, num_vertices):
    method _init (line 37) | def _init(self, arr):
    method V (line 48) | def V(self):
    method E (line 52) | def E(self):
    method addEdge (line 56) | def addEdge(self, src_v, dst_w):
    method adj (line 64) | def adj(self, src_v):
    method outdegree (line 69) | def outdegree(self, src_v):
    method indegree (line 74) | def indegree(self, src_v):
    method reverse (line 79) | def reverse(self):
    method __str__ (line 93) | def __str__(self):
    method __iter__ (line 102) | def __iter__(self): # Makes Graph an iterable.
    method wr_png (line 105) | def wr_png(self, fout_png="Digraph.png", prt=sys.stdout):
    method get_pydot_digraph (line 112) | def get_pydot_digraph(self):
    method get_edges (line 128) | def get_edges(self):

FILE: AlgsSedgewickWayne/DijkstraSP.py
  class DijkstraSP (line 3) | class DijkstraSP(object):
    method __init__ (line 9) | def __init__(self, G, s): # EdgeWeightedDigraph O(E lof V)
    method _relax (line 29) | def _relax(self, e):
    method distTo (line 38) | def distTo(self, v): # O(k)
    method hasPathTo (line 42) | def hasPathTo(self, v): # O(k)
    method pathTo (line 46) | def pathTo(self, v):
    method _check (line 60) | def _check(EdgeWeightedDigraph G, s):

FILE: AlgsSedgewickWayne/DirectedDFS.py
  class DirectedDFS (line 5) | class DirectedDFS:
    method __init__ (line 8) | def __init__(self, graph, sources): # O ~ V + E (wc)
    method _init (line 14) | def _init(self, graph, sources):
    method _dfs (line 23) | def _dfs(self, graph, v_src):
    method marked (line 31) | def marked(self, vertex):
    method count (line 35) | def count(self):

FILE: AlgsSedgewickWayne/DirectedEdge.py
  class DirectedEdge (line 3) | class DirectedEdge(object):
    method __init__ (line 6) | def __init__(self, v, w, weight):
    method get_from (line 14) | def get_from(self): return self._v # Returns the tail vertex of the di...
    method get_to (line 15) | def get_to(self): return self._w # Returns the head vertex of the dire...
    method get_from_to (line 16) | def get_from_to(self): return [self._v, self._w]
    method get_weight (line 17) | def get_weight(self): return self._weight # Returns the weight of the ...
    method __str__ (line 18) | def __str__(self):

FILE: AlgsSedgewickWayne/Edge.py
  class Edge (line 5) | class Edge:
    method __init__ (line 8) | def __init__(self, v, w, weight):
    method either (line 19) | def either(self):
    method get_vw (line 23) | def get_vw(self):
    method other (line 27) | def other(self, vertex):
    method compare_to (line 35) | def compare_to(self, that):
    method __str__ (line 43) | def __str__(self):

FILE: AlgsSedgewickWayne/EdgeWeightedDigraph.py
  class EdgeWeightedDigraph (line 7) | class EdgeWeightedDigraph(object):
    method __init__ (line 9) | def __init__(self, V, E=None):
    method _init_V (line 15) | def _init_V(self, V):
    method _init_VE (line 22) | def _init_VE(self, V, E):
    method _init_arr (line 34) | def _init_arr(arr):
    method __copy__ (line 44) | def __copy__(self, G):
    method V (line 59) | def V(self): return self._V
    method E (line 62) | def E(self): return self._E
    method _validateVertex (line 65) | def _validateVertex(self, v):
    method addEdge (line 69) | def addEdge(self, e):
    method adj (line 78) | def adj(self, v):
    method outdegree (line 83) | def outdegree(self, v):
    method indegree (line 88) | def indegree(self, v):
    method edges (line 93) | def edges(self):
    method __str__ (line 101) | def __str__(self):

FILE: AlgsSedgewickWayne/EdgeWeightedDirectedCycle.py
  class EdgeWeightedDirectedCycle (line 39) | class EdgeWeightedDirectedCycle:
  function hasCycle (line 91) | def hasCycle():
  function cycle (line 100) | def cycle():
  function _check (line 105) | def _check(EdgeWeightedDigraph G):

FILE: AlgsSedgewickWayne/EdgeWeightedGraph.py
  class EdgeWeightedGraph (line 8) | class EdgeWeightedGraph:
    method __init__ (line 11) | def __init__(self, V, E=None):
    method _init_num_vertices (line 17) | def _init_num_vertices(self, num_vertices):
    method _init_int (line 25) | def _init_int(self, num_vertices, num_edges):
    method _init_arr (line 37) | def _init_arr(self, arr):
    method __copy__ (line 49) | def __copy__(self):
    method _validate_vertex (line 60) | def _validate_vertex(self, v_src):
    method add_edge (line 66) | def add_edge(self, edge):
    method adj (line 76) | def adj(self, v_src):
    method degree (line 81) | def degree(self, v_src):
    method edges (line 86) | def edges(self):
    method __str__ (line 101) | def __str__(self):

FILE: AlgsSedgewickWayne/FileIndex.py
  class FileIndex (line 43) | class FileIndex:
    method main (line 48) | def main(String[] args):

FILE: AlgsSedgewickWayne/FlowEdge.py
  class FlowEdge (line 3) | class FlowEdge(object):
    method __init__ (line 5) | def __init__(self, v, w, capacity, flow=0.0):
    method __copy__ (line 16) | def __copy__(self, e):
    method get_from (line 22) | def get_from(self): return self._v # Returns the tail vertex of the edge.
    method get_to (line 23) | def get_to(self): return self._w # Returns the head vertex of the edge.
    method get_capacity (line 24) | def get_capacity(self): return self._capacity # Returns the capacity o...
    method get_flow (line 25) | def get_flow(self): return self._flow # Returns the flow on the edge.
    method get_other (line 27) | def get_other(self, vertex):
    method residualCapacityTo (line 33) | def residualCapacityTo(self, vertex):
    method addResidualFlowTo (line 47) | def addResidualFlowTo(self, vertex, delta):
    method __str__ (line 56) | def __str__(self): return "{} {} -> {} / {}".format(self._v, self._w, ...

FILE: AlgsSedgewickWayne/FlowNetwork.py
  class FlowNetwork (line 17) | class FlowNetwork(object):
    method _init_V (line 19) | def _init_V(self, V):
    method _init_VE (line 26) | def _init_VE(self, V, E):
    method _init_arr (line 37) | def _init_arr(self, arr):
    method V (line 47) | def V(self): return self._V # Returns the number of vertices in the ed...
    method E (line 48) | def E(self): return self._E # Returns the number of edges in the edge-...
    method _validateVertex (line 50) | def _validateVertex(self, v):
    method addEdge (line 55) | def addEdge(self, e): # O(1)
    method adj (line 65) | def adj(self, v): # O(1)
    method edges (line 70) | def edges(self): # iter edges incident to a given vertex takes time ~ ...
    method __str__ (line 79) | def __str__(self):

FILE: AlgsSedgewickWayne/FordFulkerson.py
  class FordFulkerson (line 25) | class FordFulkerson(object):
    method __init__ (line 31) | def __init__(self, G, s, t): # G is FlowNetwork
    method value (line 63) | def value(self): return self._value
    method inCut (line 65) | def inCut(self, v):
    method _validate (line 70) | def _validate(self, v, V):
    method _hasAugmentingPath (line 79) | def _hasAugmentingPath(self, G, s, t): # G id FlowNetwork
    method _excess (line 105) | def _excess(self, G, v):
    method _isFeasible (line 114) | def _isFeasible(FlowNetwork G, s, t):
  function _check (line 142) | def _check(FlowNetwork G, s, t):

FILE: AlgsSedgewickWayne/FrequencyCounter.py
  function main (line 9) | def main():

FILE: AlgsSedgewickWayne/GabowSCC.py
  class GabowSCC (line 52) | class GabowSCC:
  function count (line 107) | def count():
  function stronglyConnected (line 117) | def stronglyConnected(int v, w):
  function id (line 125) | def id(int v):
  function _check (line 129) | def _check(Digraph G):
  function main (line 140) | def main(String[] args):

FILE: AlgsSedgewickWayne/GrahamScan.py
  class GrahamScan (line 8) | class GrahamScan:
    method __init__ (line 11) | def __init__(self, pts): # Point2D[] pts) {
    method _init_convex_hull (line 14) | def _init_convex_hull(pts):

FILE: AlgsSedgewickWayne/Graph.py
  class Graph (line 6) | class Graph:
    method __init__ (line 9) | def __init__(self, arg=None, **kwargs):
    method V (line 24) | def V(self):
    method E (line 28) | def E(self):
    method addEdge (line 32) | def addEdge(self, node_v, node_w):
    method add_edge (line 36) | def add_edge(self, node_v, node_w):
    method adj (line 44) | def adj(self, node_v):
    method degree (line 49) | def degree(self, node_v):
    method __str__ (line 60) | def __str__(self):
    method __iter__ (line 69) | def __iter__(self): # Makes Graph an iterable.
    method wr_png (line 72) | def wr_png(self, fout_png="Graph.png", prt=sys.stdout, **kwargs):
    method get_edges (line 90) | def get_edges(self):
    method _init_empty (line 98) | def _init_empty(self, num_nodes):
    method _init (line 106) | def _init(self, arg):
    method _init_num_edges (line 117) | def _init_num_edges(self):

FILE: AlgsSedgewickWayne/Heap.py
  function Sort (line 5) | def Sort(pq):
  function _sink (line 15) | def _sink(pq, k, N):
  function _less (line 25) | def _less(pq, i, j):
  function _exch (line 28) | def _exch(pq, i, j):

FILE: AlgsSedgewickWayne/Insertion.py
  function Sort (line 12) | def Sort(arr, array_history=None):
  function indexSort (line 201) | def indexSort(arr, array_history=None):

FILE: AlgsSedgewickWayne/Interval1D.py
  class Interval1D (line 18) | class Interval1D(object):
    method __init__ (line 21) | def __init__(self, min_val, max_val):
    method intersects (line 29) | def intersects(self, that):
    method contains (line 36) | def contains(self, x): return self.min_val <= x and x <= self.max_val
    method length (line 39) | def length(self): return self.max_val - self.min_val
    method __str__ (line 42) | def __str__(self): return "[{MIN}, {MAX}]".format(MIN=self.min_val, MA...
    method equals (line 44) | def equals(self, other):
    method sortby_minendpoint (line 52) | def sortby_minendpoint(intervals):
    method sortby_maxendpoint (line 56) | def sortby_maxendpoint(intervals):
    method sortby_length (line 60) | def sortby_length(intervals):

FILE: AlgsSedgewickWayne/KMP.py
  function search (line 7) | def search(pat, txt):
  class KMP (line 13) | class KMP: # O ~ txtlen + patlen * alphabet-size (wc)
    method __init__ (line 16) | def __init__(self, pat):
    method _init_dfa (line 22) | def _init_dfa(self):
    method search (line 34) | def search(self, txt):
    method prt_dfa (line 52) | def prt_dfa(self, prt):

FILE: AlgsSedgewickWayne/KosarajuSharirSCC.py
  class KosarajuSharirSCC (line 95) | class KosarajuSharirSCC:
  function _dfs (line 121) | def _dfs(Digraph G, v):
  function count (line 131) | def count():
  function stronglyConnected (line 141) | def stronglyConnected(int v, w):
  function id (line 149) | def id(int v):
  function _check (line 153) | def _check(Digraph G):
  function main (line 164) | def main(String[] args):
  function _dfs (line 204) | def _dfs(self, G, v):
  function id (line 214) | def id(self, v): return self._id[v]
  function size (line 217) | def size(self, v): return self._size[id[v]]
  function count (line 220) | def count(self): return self._count
  function connected (line 223) | def connected(self, v, w): return self._id(v) == self._id(w)
  function areConnected (line 226) | def areConnected(self, v, w): return self._id(v) == self._id(w)

FILE: AlgsSedgewickWayne/KruskalMST.py
  class KruskalMST (line 9) | class KruskalMST(object):
    method __init__ (line 14) | def __init__(self, G): # t ~ O(E log E), s ~ V
    method edges (line 33) | def edges(self):
    method weight (line 37) | def weight(self):

FILE: AlgsSedgewickWayne/LSD.py
  function key_idx_cnt (line 7) | def key_idx_cnt(a):

FILE: AlgsSedgewickWayne/LazyPrimMST.py
  class LazyPrimMST (line 6) | class LazyPrimMST(object):
    method __init__ (line 10) | def __init__(self, G):  # G the edge-weighted graph t ~ O(E log E). s ~ E
    method _prim (line 19) | def _prim(self, G, s):
    method _scan (line 32) | def _scan(self, G, v):
    method edges (line 40) | def edges(self): return self._mst
    method weight (line 43) | def weight(self): return self._weight

FILE: AlgsSedgewickWayne/LinearProbingHashST.py
  class LinearProbingHashST (line 6) | class LinearProbingHashST(object):
    method __init__ (line 9) | def __init__(self, capacity=None):
    method size (line 17) | def size(self): return self._N
    method isEmpty (line 18) | def isEmpty(self): return self.size() == 0
    method contains (line 19) | def contains(self, key): return self.get(key) is not None
    method _hash (line 21) | def _hash(self, key):
    method _resize (line 25) | def _resize(self, capacity):
    method put (line 35) | def put(self, key, val):
    method get (line 54) | def get(self, key):
    method delete (line 63) | def delete(self, key):
    method keys (line 95) | def keys(self):
    method _check (line 102) | def _check(self, prt=sys.stdout):

FILE: AlgsSedgewickWayne/LinkedBag.py
  function isEmpty (line 68) | def isEmpty():
  function size (line 75) | def size():
  function add (line 82) | def add(Item item):
  function iterator (line 93) | def iterator():
  class ListIterator (line 97) | class ListIterator implements Iterator<Item>:
    method hasNext (line 100) | def hasNext(): return current != None;                     }
  function main (line 112) | def main(String[] args):

FILE: AlgsSedgewickWayne/LinkedQueue.py
  function isEmpty (line 60) | def isEmpty():
  function size (line 67) | def size():
  function peek (line 75) | def peek():
  function enqueue (line 83) | def enqueue(Item item):
  function dequeue (line 98) | def dequeue():
  function toString (line 111) | def toString():
  function _check (line 118) | def _check():
  function iterator (line 150) | def iterator():
  class ListIterator (line 154) | class ListIterator implements Iterator<Item>:
    method hasNext (line 157) | def hasNext(): return current != None;                     }
  function main (line 170) | def main(String[] args):

FILE: AlgsSedgewickWayne/LinkedStack.py
  class LinkedStack (line 37) | class LinkedStack: # <Item> implements Iterable<Item>:
    class _Node (line 39) | class _Node: # helper linked list class
    method __init__ (line 43) | def __init__(self):    # Initializes an empty stack.
    method isEmpty (line 50) | def isEmpty(self): return (self._first is None)
    method size (line 54) | def size(self): return self._N
    method push (line 58) | def push(item):
    method pop (line 69) | def pop(self):
    method __str__ (line 87) | def __str__():
    method _check (line 111) | def _check():
  function main (line 129) | def main(String[] args):

FILE: AlgsSedgewickWayne/LookupCSV.py
  function main (line 7) | def main():

FILE: AlgsSedgewickWayne/MSD.py
  function sort (line 10) | def sort(String[] a):
  function _charAt (line 17) | def _charAt(String s, d):
  function _sort (line 23) | def _sort(String[] a, lo, hi, d, String[] aux):

FILE: AlgsSedgewickWayne/MST_check.py
  function _check (line 4) | def _check(MST, G):

FILE: AlgsSedgewickWayne/MaxPQ.py
  class MaxPQ (line 5) | class MaxPQ: # <Key extends Comparable<Key>> # 15:01
    method __init__ (line 8) | def __init__(self, capacity):
    method isEmpty (line 12) | def isEmpty(self):
    method insert (line 16) | def insert(self, val): # 06:27
    method delMax (line 22) | def delMax(self): # 10:03
    method _swim (line 34) | def _swim(self, k): # 05:15
    method _sink (line 40) | def _sink(self, k): # 8:52
    method insert_array (line 224) | def insert_array(self, arr):
    method less (line 273) | def less(self, i, j):
    method exch (line 276) | def exch(self, i, j):
    method __str__ (line 282) | def __str__(self):
    method __repr__ (line 285) | def __repr__(self):
    method __len__ (line 288) | def __len__(self):
    method draw (line 291) | def draw(self): # TBD: Finish this

FILE: AlgsSedgewickWayne/Merge.py
  function Sort (line 9) | def Sort(arr, array_history=None): # 09:30
  function _sort (line 17) | def _sort(arr, aux, low, high, array_history):
  function merge (line 35) | def merge(arr, aux, low, mid, high): # 05:00-06:00
  function _add_history (line 64) | def _add_history(array_history, arr, aux, anno=None):
  function _vis_merge (line 74) | def _vis_merge(arr, aux, low, mid, high, prt=sys.stdout):
  function _merge_index (line 429) | def _merge_index(arr, index, aux, low, mid, high):
  function _sort_index (line 460) | def _sort_index(arr, index, aux, low, high):
  function indexSort (line 472) | def indexSort(arr):

FILE: AlgsSedgewickWayne/MergeBU.py
  function Sort (line 6) | def Sort(a, array_history=None): # N lg N

FILE: AlgsSedgewickWayne/MergeX.py
  function _merge (line 44) | def _merge(src, dst, lo, mid, hi):
  function _sort (line 61) | def _sort(src, dst, lo, hi):
  function Sort (line 85) | def Sort(a, array_history=None):
  function _insertionSort (line 92) | def _insertionSort(a, lo, hi):
  function _exch (line 103) | def _exch(a, i, j):
  function _less (line 109) | def _less(a, b): return a < b
  function _isSorted (line 114) | def _isSorted(a, lo=None, hi=None):

FILE: AlgsSedgewickWayne/MinPQ.py
  class MinPQ (line 5) | class MinPQ(object):
    method __init__ (line 8) | def __init__(self, *args, **kwargs):
    method _init_capacity (line 18) | def _init_capacity(self, initCapacity):
    method _init_w_keys (line 22) | def _init_w_keys(self, keys):
    method isEmpty (line 29) | def isEmpty(self): return self.N == 0
    method size (line 30) | def size(self): return self.N
    method min (line 32) | def min(self):
    method _resize (line 38) | def _resize(self, capacity):
    method insert (line 43) | def insert(self, x):
    method delMin (line 54) | def delMin(self):
    method _swim (line 67) | def _swim(self, k):
    method _sink (line 73) | def _sink(self, k):
    method __str__ (line 84) | def __str__(self): return "MinPQ({N}): {PQ}".format(N=self.N, PQ=self.pq)
    method _greater (line 89) | def _greater(self, i, j):
    method _exch (line 95) | def _exch(self, i, j):
    method _isMinHeap (line 98) | def _isMinHeap(self, k=1):
    method __iter__ (line 108) | def __iter__(self):

FILE: AlgsSedgewickWayne/NFA.py
  class NFA (line 41) | class NFA:
    method __init__ (line 44) | def __init__(self, regexp):
    method _init_digraph (line 51) | def _init_digraph(self, regexp):
    method recognizes (line 85) | def recognizes(self, txt):

FILE: AlgsSedgewickWayne/Particle.py
  class Particle (line 18) | class Particle:
  function move (line 69) | def move(double dt):
  function draw (line 76) | def draw():
  function count (line 89) | def count():
  function timeToHit (line 101) | def timeToHit(Particle that):
  function timeToHitVerticalWall (line 126) | def timeToHitVerticalWall():
  function timeToHitHorizontalWall (line 140) | def timeToHitHorizontalWall():
  function bounceOff (line 152) | def bounceOff(Particle that):
  function bounceOffVerticalWall (line 180) | def bounceOffVerticalWall():
  function bounceOffHorizontalWall (line 189) | def bounceOffHorizontalWall():
  function kineticEnergy (line 200) | def kineticEnergy():

FILE: AlgsSedgewickWayne/Point2D.py
  class Point2D (line 28) | class Point2D: # implements Comparable<Point2D> {
    method __init__ (line 55) | def __init__(self, xval, yval):
    method __repr__ (line 71) | def __repr__(self):
    method get_x (line 74) | def get_x(self):
    method get_y (line 78) | def get_y(self):
    method get_polar_radius (line 82) | def get_polar_radius(self):  # def r
    method theta (line 88) | def theta(self):
    method _angleTo (line 93) | def _angleTo(self, that):
    method ccw (line 102) | def ccw(apt, bpt, cpt):
    method area2 (line 121) | def area2(a, b, c):
    method distanceTo (line 127) | def distanceTo(self, that):
    method distanceSquaredTo (line 135) | def distanceSquaredTo(self, that):
    method compareTo (line 144) | def compareTo(self, that):
    class _XOrder (line 152) | class _XOrder: # implements Comparator<Point2D> {
      method compare (line 153) | def compare(pval, qval):
    class _YOrder (line 159) | class _YOrder: # implements Comparator<Point2D> {
      method compare (line 160) | def compare(pval, qval):
    class _ROrder (line 166) | class _ROrder: # implements Comparator<Point2D> {
      method compare (line 167) | def compare(pval, qval):
    class _Atan2Order (line 174) | class _Atan2Order: # implements Comparator<Point2D> {
      method compare (line 175) | def compare(q1, q2):
    class _PolarOrder (line 183) | class _PolarOrder: # implements Comparator<Point2D> {
      method compare (line 184) | def compare(q1, q2):
    class _DistanceToOrder (line 210) | class _DistanceToOrder: # implements Comparator<Point2D> {
      method compare (line 211) | def compare(self, pval, qval):
    method equals (line 222) | def equals(self, other):
    method __str__ (line 234) | def __str__(self):

FILE: AlgsSedgewickWayne/PowerLaw.py
  function getData (line 9) | def getData(blktxt):
  function est_b (line 24) | def est_b(data, prt=sys.stdout):
  function solve_a (line 45) | def solve_a(data, b, prt=sys.stdout):
  function do_plot (line 58) | def do_plot(data, a, b):

FILE: AlgsSedgewickWayne/PrimMST.py
  class PrimMST (line 33) | class PrimMST(object):
    method __init__ (line 37) | def __init__(self, G): # G is an edge-weighted graph
    method _prim (line 51) | def _prim(self, G, s):
    method _scan (line 59) | def _scan(self, G, v):
    method edges (line 71) | def edges(self):
    method weight (line 80) | def weight(self):
    method _check (line 89) | def _check(EdgeWeightedGraph G):

FILE: AlgsSedgewickWayne/Queue.py
  class Queue (line 3) | class Queue(object):
    class _Node (line 6) | class _Node(object):
      method __init__ (line 8) | def __init__(self, item, last):
    method __init__ (line 12) | def __init__(self):
    method isEmpty (line 17) | def isEmpty(self):
    method enqueue (line 21) | def enqueue(self, item):  # Week 2, "Queues" 02:32
    method dequeue (line 32) | def dequeue(self):
    method size (line 43) | def size(self):
    method peek (line 47) | def peek(self):
    method __str__ (line 53) | def __str__(self):
    method __iter__ (line 57) | def __iter__(self):

FILE: AlgsSedgewickWayne/Quick.py
  function Sort (line 6) | def Sort(arr, array_history=None):
  function _sort (line 14) | def _sort(arr, lo_idx, hi_idx, array_history):
  function _partition (line 24) | def _partition(arr, lo_idx, hi_idx, array_history=None):
  function Select (line 75) | def Select(arr, k):
  function _exch (line 92) | def _exch(arr, i_idx, j_idx):
  function _is_sorted (line 98) | def _is_sorted(arr, lo_idx=None, hi_idx=None):
  function _add_history (line 108) | def _add_history(array_history, arr, anno=None):

FILE: AlgsSedgewickWayne/Quick3way.py
  function Sort (line 6) | def Sort(a, array_history=None, shuffle=True):
  function _sort (line 14) | def _sort(a, lo, hi, array_history):
  function _less (line 45) | def _less(v, w): return v < w
  function _eq (line 46) | def _eq(v, w): return v == w
  function _exch (line 47) | def _exch(a, i, j): a[i], a[j] = a[j], a[i]
  function _isSorted (line 52) | def _isSorted(a, lo=None, hi=None):
  function _add_history (line 61) | def _add_history(array_history, a, anno=None):

FILE: AlgsSedgewickWayne/QuickFindUF.py
  class QuickFindUF (line 5) | class QuickFindUF(BaseComp): # Eager Approach
    method __init__ (line 8) | def __init__(self, N): #     $ = N                 i        0 1 2 3 4 ...
    method connected (line 13) | def connected(self, pval, qval): # $ = 1
    method union (line 17) | def union(self, pval, qval): #         $ = N
    method _root (line 28) | def _root(self, val):

FILE: AlgsSedgewickWayne/QuickUnionUF.py
  class QuickUnionUF (line 5) | class QuickUnionUF(BaseComp):
    method __init__ (line 8) | def __init__(self, N):           # $ = N
    method connected (line 13) | def connected(self, p_id, q_id): # $ = N
    method union (line 17) | def union(self, p_id, q_id):     # $ = N
    method _root (line 23) | def _root(self, val):

FILE: AlgsSedgewickWayne/QuickX.py
  function Sort (line 31) | def Sort(arr_unsorted, array_history=None):
  function _sort (line 36) | def _sort(arr, low, high):
  function _insertion_sort (line 108) | def _insertion_sort(arr, low, high):
  function _median3 (line 117) | def _median3(arr, i, j, k):
  function _less (line 128) | def _less(v, w):
  function _eq (line 132) | def _eq(v, w):
  function _exch (line 136) | def _exch(arr, i, j):
  function _is_sorted (line 146) | def _is_sorted(arr):

FILE: AlgsSedgewickWayne/ResizingArrayBag.py
  function isEmpty (line 43) | def isEmpty():
  function size (line 50) | def size():
  function _resize (line 54) | def _resize(int capacity):
  function add (line 65) | def add(Item item):
  function iterator (line 74) | def iterator():
  class ArrayIterator (line 78) | class ArrayIterator implements Iterator<Item>:
    method hasNext (line 80) | def hasNext(): return i < N;                               }
  function main (line 90) | def main(String[] args):

FILE: AlgsSedgewickWayne/ResizingArrayQueue.py
  class ResizingArrayQueue (line 3) | class ResizingArrayQueue: # <Item> implements Iterable<Item>:
    method __init__ (line 6) | def __init__(self):
    method isEmpty (line 12) | def isEmpty(self):
    method size (line 16) | def size(self):
    method _resize (line 20) | def _resize(self, maxval):
    method enqueue (line 31) | def enqueue(self, item):
    method dequeue (line 42) | def dequeue(self):
    method __str__ (line 57) | def __str__(self):
    method peek (line 60) | def peek(self):
    method __iter__ (line 66) | def __iter__(self):
    class _ArrayIterator (line 70) | class _ArrayIterator: # implements Iterator<Item>:
      method __init__ (line 72) | def __init__(self, Q):
      method hasNext (line 75) | def hasNext(self):
      method next (line 77) | def next(self):

FILE: AlgsSedgewickWayne/ResizingArrayStack.py
  class ResizingArrayStack (line 3) | class ResizingArrayStack: #<Item> implements Iterable<Item>:
    method __init__ (line 6) | def __init__(self): # Initializes an empty stack.
    method isEmpty (line 11) | def isEmpty(self):
    method push (line 15) | def push(self, item):
    method pop (line 23) | def pop(self):
    method size (line 35) | def size(self):
    method _resize (line 39) | def _resize(self, capacity):
    method __str__ (line 47) | def __str__(self):
    method peek (line 50) | def peek():
    method __iter__ (line 55) | def __iter__(self):
    class _ReverseArrayIterator (line 59) | class _ReverseArrayIterator: # implements Iterator<Item>:
      method __init__ (line 60) | def __init__(self, stk):
      method hasNext (line 63) | def hasNext(self):
      method next (line 65) | def next(self):

FILE: AlgsSedgewickWayne/SET.py
  class SET (line 7) | class SET(object):
    method __init__ (line 9) | def __init__(self):
    method add (line 12) | def add(self, key):
    method contains (line 17) | def contains(self, key):
    method delete (line 22) | def delete(self, key):
    method size (line 27) | def size(self): return self._treeset.size()
    method isEmpty (line 28) | def isEmpty(self): return size() == 0
    method iterator (line 30) | def iterator(self):
    method max (line 34) | def max(self):
    method min (line 39) | def min(self):
  function union (line 79) | def union(SET<> that):
  function intersects (line 95) | def intersects(SET<> that):
  function equals (line 119) | def equals(self, other):
  function hashCode (line 139) | def hashCode(self):
  function toString (line 149) | def toString(self):
  function main (line 158) | def main(String[] args):

FILE: AlgsSedgewickWayne/ST.py
  class ST (line 5) | class ST:
    method __init__ (line 8) | def __init__(self):
    method get (line 11) | def get(self, key):
    method put (line 17) | def put(self, key, val):
    method delete (line 26) | def delete(self, key):
    method contains (line 32) | def contains(self, key):
    method size (line 38) | def size(self):
    method is_empty (line 42) | def is_empty(self):
    method get_keys (line 46) | def get_keys(self):
    method iterator (line 50) | def iterator(self):
    method min (line 54) | def min(self):
    method max (line 60) | def max(self):
    method ceiling (line 66) | def ceiling(self, key):
    method floor (line 75) | def floor(self, key):

FILE: AlgsSedgewickWayne/Selection.py
  function Sort (line 11) | def Sort(arr, array_history=None):

FILE: AlgsSedgewickWayne/SeparateChainingHashST.py
  class SeparateChainingHashST (line 6) | class SeparateChainingHashST(object):
    method __init__ (line 17) | def __init__(self, M=None):
    method _resize (line 23) | def _resize(self, chains):
    method _hash (line 33) | def _hash(self, key):
    method size (line 37) | def size(self): return self.N
    method isEmpty (line 38) | def isEmpty(self): return self.size() == 0
    method contains (line 39) | def contains(self, key): return self.get(key) is not None
    method get (line 41) | def get(self, key):
    method put (line 46) | def put(self, key, val):
    method delete (line 59) | def delete(self, key):
    method keys (line 68) | def keys(self):
    method prt_chaining_symtbl (line 76) | def prt_chaining_symtbl(self, prt=sys.stdout):

FILE: AlgsSedgewickWayne/SequentialSearchST.py
  class SequentialSearchST (line 4) | class SequentialSearchST(object):
    class _Node (line 6) | class _Node:
      method __init__ (line 9) | def __init__(self, key, val, nxt):
    method __init__ (line 14) | def __init__(self):
    method size (line 18) | def size(self): return self._N
    method isEmpty (line 19) | def isEmpty(self): return self.size() == 0
    method contains (line 20) | def contains(self, key): return self.get(key) is not None
    method get (line 22) | def get(self, key):
    method put (line 31) | def put(self, key, val):
    method delete (line 46) | def delete(self, key):
    method _delete (line 50) | def _delete(self, x, key):
    method keys (line 60) | def keys(self):
    method __iter__ (line 69) | def __iter__(self):

FILE: AlgsSedgewickWayne/Shell.py
  function Sort (line 8) | def Sort(arr, array_history=None, sort_seq=None):
  function _is_h_sorted (line 35) | def _is_h_sorted(arr, hval):
  function _get_sort_seq (line 42) | def _get_sort_seq(len_array, sort_seq=None):

FILE: AlgsSedgewickWayne/SparseVector.py
  class SparseVector (line 3) | class SparseVector(object):
    method __init__ (line 5) | def __init__(self, d):
    method put (line 9) | def put(self, i, value):
    method get (line 15) | def get(self, i):
    method magnitude (line 21) | def magnitude(self):
    method norm (line 24) | def norm(self):
    method scale (line 28) | def scale(self, alpha):
    method __str__ (line 42) | def __str__(self):

FILE: AlgsSedgewickWayne/Stack.py
  class Stack (line 5) | class Stack:
    class _Node (line 9) | class _Node: # helper linked list class
      method __init__ (line 12) | def __init__(self, item, nxt):
    method __init__ (line 16) | def __init__(self):
    method isEmpty (line 20) | def isEmpty(self):
    method push (line 24) | def push(self, item): # 05:27 Lecture Week 2 "Stacks" (16:24)
    method pop (line 30) | def pop(self): # 06:30 Lecture Week 2 "Stacks" (16:24)
    method size (line 39) | def size(self):
    method peek (line 43) | def peek(self):
    method __str__ (line 49) | def __str__(self):
    method __iter__ (line 56) | def __iter__(self):
    class ListIterator (line 60) | class ListIterator:
      method __init__ (line 63) | def __init__(self, first):
      method next (line 66) | def next(self):

FILE: AlgsSedgewickWayne/TST.py
  class TST (line 22) | class TST(object):
    class _Node (line 24) | class _Node(object):
      method __init__ (line 26) | def __init__(self, c):
      method __str__ (line 33) | def __str__(self):
    method __init__ (line 38) | def __init__(self):
    method size (line 42) | def size(self): return self._N # number of key-value pairs in symbol t...
    method contains (line 43) | def contains(self, key): return self.get(key) is not None # symbol tab...
    method get (line 49) | def get(self, key):
    method _get (line 56) | def _get(self, x, key, d):
    method put (line 70) | def put(self, key, val):
    method _put (line 75) | def _put(self, x, key, val, d):
    method longestPrefixOf (line 91) | def longestPrefixOf(self, query):
    method keys (line 106) | def keys(self):
    method collect (line 113) | def collect(self, name, x, prefix, queue):
    method _collect (line 125) | def _collect(self, x, prefix, i, pattern, queue):
    method keysThatMatch (line 136) | def keysThatMatch(self, pattern):
    method keysWithPrefix (line 142) | def keysWithPrefix(self, prefix):

FILE: AlgsSedgewickWayne/TarjanSCC.py
  class TarjanSCC (line 53) | class TarjanSCC:
  function count (line 102) | def count():
  function stronglyConnected (line 113) | def stronglyConnected(int v, w):
  function id (line 121) | def id(int v):
  function _check (line 125) | def _check(Digraph G):
  function main (line 136) | def main(String[] args):

FILE: AlgsSedgewickWayne/ThreeSum.py
  function count_slow (line 436) | def count_slow(a, prt=False): # initial translate of Java (super slow)
  function count_itertools (line 451) | def count_itertools(a): # written by Ashwini Chaudhary
  function count_itertools_faster (line 457) | def count_itertools_faster(a): # written by Veedrak/modified (fastest)
  function count_fixed (line 462) | def count_fixed(a): # written by roippi
  function count_enumerate (line 474) | def count_enumerate(a): # written by roippi
  function run_timed (line 488) | def run_timed(a, cnt_fnc=count_enumerate):
  function run_timed_fin (line 496) | def run_timed_fin(fin, cnt_fnc=count_enumerate):
  function run_timed_fins (line 501) | def run_timed_fins(fins):

FILE: AlgsSedgewickWayne/TopM.py
  function main (line 10) | def main(prt=sys.stdout):

FILE: AlgsSedgewickWayne/Topological.py
  class Topological (line 10) | class Topological(object):
    method __init__ (line 13) | def __init__(self, G): # G is Digraph O(V+E) wc
    method Topological (line 24) | def Topological(EdgeWeightedDigraph G): # EdgeWeightedDigraph
    method order (line 32) | def order(self): return self._order # O(V)
    method hasOrder (line 35) | def hasOrder(self): return self._order is not None # O(k)
    method rank (line 37) | def rank(self, v): # O(k)
    method _validateVertex (line 43) | def _validateVertex(self, v):

FILE: AlgsSedgewickWayne/TopologicalX.py
  class TopologicalX (line 40) | class TopologicalX:
  function order (line 87) | def order():
  function hasOrder (line 95) | def hasOrder():
  function rank (line 106) | def rank(int v):
  function _check (line 112) | def _check(Digraph G):
  function _validateVertex (line 145) | def _validateVertex(int v):
  function main (line 153) | def main(String[] args):

FILE: AlgsSedgewickWayne/Transaction.py
  class Transaction (line 6) | class Transaction(object):
    method __init__ (line 9) | def __init__(self, tr_who, when=None, amount=None):
    method __str__ (line 20) | def __str__(self):
    method __lt__ (line 23) | def __lt__(self, that):
    method __gt__ (line 26) | def __gt__(self, that):
    method compareTo (line 32) | def compareTo(self, that):
    method __eq__ (line 36) | def __eq__(self, other):
    method hashCode (line 44) | def hashCode(self):

FILE: AlgsSedgewickWayne/TrieST.py
  class TrieSt (line 21) | class TrieSt(object):

FILE: AlgsSedgewickWayne/UnorderedArrayMaxPQ.py
  class UnorderedArrayMaxPQ (line 1) | class UnorderedArrayMaxPQ:
    method __init__ (line 3) | def __init__(self, capacity):
    method isEmpty (line 8) | def isEmpty(self): return self.N == 0
    method size (line 9) | def size(self): return self.N
    method insert (line 11) | def insert(self, x):
    method delMax (line 15) | def delMax(self):
    method _less (line 25) | def _less(self, i, j): return self.pq[i] < self.pq[j]
    method _exch (line 26) | def _exch(self, i, j): self.pq[i], self.pq[j] = self.pq[j], self.pq[i]

FILE: AlgsSedgewickWayne/WeightedQuickUnionPlusUF.py
  class WeightedQuickUnionPlusUF (line 5) | class WeightedQuickUnionPlusUF(BaseComp):
    method __init__ (line 8) | def __init__(self, N):     # $ = N
    method _root (line 17) | def _root(self, val):
    method connected (line 37) | def connected(self, p_id, q_id): # $ = lg N
    method union (line 43) | def union(self, p_id, q_id):     # $ = lg N
    method __str__ (line 65) | def __str__(self):

FILE: AlgsSedgewickWayne/WeightedQuickUnionUF.py
  class WeightedQuickUnionUF (line 5) | class WeightedQuickUnionUF(BaseComp):
    method __init__ (line 8) | def __init__(self, N):     # $ = N
    method connected (line 15) | def connected(self, p_id, q_id): # $ = lg N
    method union (line 21) | def union(self, p_id, q_id):     # $ = lg N
    method _root (line 45) | def _root(self, val):
    method __str__ (line 54) | def __str__(self):

FILE: AlgsSedgewickWayne/Whitelist.py
  class Whitelist (line 44) | class Whitelist:
    method main (line 54) | def main(String[] args):

FILE: AlgsSedgewickWayne/digraph_dvk.py
  class Digraph (line 7) | class Digraph:
    method __init__ (line 10) | def __init__(self, num_vertices):
    method add_edge (line 17) | def add_edge(self, src_v, dst_w):
    method get_edges (line 24) | def get_edges(self):
    method adj (line 29) | def adj(self, src_v):
    method __str__ (line 33) | def __str__(self):
    method __iter__ (line 42) | def __iter__(self): # Makes Graph an iterable.

FILE: AlgsSedgewickWayne/directed_dfs.py
  class DirectedDFS (line 4) | class DirectedDFS:
    method __init__ (line 7) | def __init__(self, digraph): # O ~ V + E (wc)
    method get_reachable_states (line 12) | def get_reachable_states(self):
    method dfs (line 16) | def dfs(self, digraph, v_src):
    method from_state0 (line 24) | def from_state0(cls, digraph):
    method from_sources (line 31) | def from_sources(cls, digraph, sources):

FILE: AlgsSedgewickWayne/knuth_shuffle.py
  function shuffle (line 5) | def shuffle(arr):

FILE: AlgsSedgewickWayne/nfa_dvk.py
  class ReferenceItNFA (line 9) | class ReferenceItNFA:
    method __init__ (line 12) | def __init__(self, regexp):
    method _init_digraph (line 19) | def _init_digraph(self, regexp):
    method _prt_color_regex (line 59) | def _prt_color_regex(self, reg_i, reg_chr, idx_lparen_or_chr):
    method recognizes (line 67) | def recognizes(self, txt):
    method _prt_regex (line 113) | def _prt_regex(regexp):
    method _prt_state_names (line 120) | def _prt_state_names(idx, txt_chr, reachable_states, regexp):
    method _prt_state_names0 (line 126) | def _prt_state_names0(reachable_states, regexp):

FILE: AlgsSedgewickWayne/plt_regex_graph.py
  function plt_nfa (line 5) | def plt_nfa(fout_png, nfa):

FILE: AlgsSedgewickWayne/substrsrc_bruteforce.py
  function search (line 17) | def search(pat, txt):

FILE: AlgsSedgewickWayne/substrsrc_bruteforce_alt.py
  function search (line 14) | def search(pat, txt):

FILE: AlgsSedgewickWayne/testcode/ArrayHistory.py
  function run (line 25) | def run(container, seqstr, expected=None, prt=sys.stdout, prt_details=sy...
  function run_list (line 39) | def run_list(container, item_list, prt=sys.stdout):
  function run_Queue (line 58) | def run_Queue(container, seqstr, prt=sys.stdout):
  function run_Queue_list (line 62) | def run_Queue_list(container, item_list, prt=sys.stdout):
  function ex_stdin (line 77) | def ex_stdin(container, prt=sys.stdout):
  function chk (line 90) | def chk(arr0, txt):
  function arrays_equal (line 95) | def arrays_equal(arr0, arr1):
  function history_contains (line 100) | def history_contains(array_history, potential_midpoint):
  function get_keystr (line 107) | def get_keystr(elem):
  function get_elem2num (line 117) | def get_elem2num(array_history):
  function get_anno (line 128) | def get_anno(idx, idx2sym):
  function xor_txt (line 134) | def xor_txt(txt_prev, txt_curr):
  class ArrayHistory (line 149) | class ArrayHistory:
    method __init__ (line 152) | def __init__(self):
    method add_history (line 158) | def add_history(self, array, anno, name='a'):
    method __iter__ (line 168) | def __iter__(self):
    method prt (line 173) | def prt(self, prt=sys.stdout):
    method prt_intlvd (line 189) | def prt_intlvd(self, prt=sys.stdout):
    method show (line 214) | def show(self, desc, prt=sys.stdout):
    method _show_array_history (line 226) | def _show_array_history(array_history, name, desc, prt):
    method _set_elem_width (line 240) | def _set_elem_width(self):
    method get_array_str (line 252) | def get_array_str(self, array_st):
    method get_anno_str (line 258) | def get_anno_str(self, ntarr):
    method get_anno_val_str (line 265) | def get_anno_val_str(ntarr):

FILE: AlgsSedgewickWayne/testcode/InputArgs.py
  function cli_get_array (line 9) | def cli_get_array(seqstr=None):
  function cli_get_fin (line 34) | def cli_get_fin(fin):
  function arr_int_str (line 50) | def arr_int_str(arg):
  function conv_num (line 64) | def conv_num(arr):
  function _conv (line 78) | def _conv(txt):
  function _prt_usage_msg (line 88) | def _prt_usage_msg(default_seq="a f b d g e c"):

FILE: AlgsSedgewickWayne/testcode/binary_heaps.py
  function wr_png (line 7) | def wr_png(bh_arrstr, **kwargs):
  function wr_png_array (line 10) | def wr_png_array(bh_st, kwargs):
  function get_edges (line 36) | def get_edges(arr):

FILE: AlgsSedgewickWayne/testcode/chaining_table.py
  function prt_chaining_symtbl (line 4) | def prt_chaining_symtbl(st):

FILE: AlgsSedgewickWayne/testcode/order.py
  function run_277853s (line 5) | def run_277853s():
  function run_277853 (line 11) | def run_277853(N):
  function run_605062s (line 21) | def run_605062s():
  function run_605062 (line 27) | def run_605062(N):

FILE: AlgsSedgewickWayne/testcode/utils.py
  function run_unions (line 10) | def run_unions(alg, union_txt, msg, pngbase=None, prt=sys.stdout):
  function _str_ccomps (line 22) | def _str_ccomps(alg):
  function get_unions (line 34) | def get_unions(union_txt):
  function chk_roots (line 41) | def chk_roots(alg, expected):
  function chk_arrays (line 50) | def chk_arrays(actual, expected):
  function blk_visualizer (line 58) | def blk_visualizer(blkstr, prt=sys.stdout):
  function arr_vis (line 68) | def arr_vis(arr, array_id=0, i0=0, prt=sys.stdout):
  function str_vis (line 77) | def str_vis(str_arr, array_id=0, prt=sys.stdout):
  function get_png_label (line 80) | def get_png_label(arr, kwargs):
  function adjtxtblk2arr_ud (line 93) | def adjtxtblk2arr_ud(txtblk):
  function adjtxtblk2OrderedDict (line 97) | def adjtxtblk2OrderedDict(txtblk):
  function adjOrderedDict2VEpairs_ud (line 106) | def adjOrderedDict2VEpairs_ud(od):
  function _adjstr2arr (line 116) | def _adjstr2arr(adjstr):
  function hl_idnum (line 124) | def hl_idnum(idnum, array, bgcolor=0, fgcolor=15):
  function hl_idroot (line 137) | def hl_idroot(idnum, rootvals, bgcolor=0, fgcolor=15):

FILE: AlgsSedgewickWayne/utils.py
  function __lt__ (line 5) | def __lt__(v, w, prt=None):
  function _exch (line 11) | def _exch(a, i, j):
  function _isSorted (line 15) | def _isSorted(a, lo=None, hi=None):
  function add_array_history (line 24) | def add_array_history(ahistobj, arr, info):

FILE: doc/scratchpad/oog1.py
  function run (line 9) | def run(N):

FILE: doc/scratchpad/wk1_ex_AnalysisOfAlgorithms_Q2.py
  function Q2_238926 (line 135) | def Q2_238926(N):
  class Q2_Tests (line 160) | class Q2_Tests(unittest.TestCase):
    method test_B (line 162) | def test_B(self):

FILE: doc/scratchpad/wk1_ex_q2.py
  function runit (line 6) | def runit(N):
  function time_runit (line 19) | def time_runit():
  function getN (line 25) | def getN():

FILE: py/UnorderedMaxPQ.py
  class UnorderedMaxPQ (line 3) | class UnorderedMaxPQ(object): # <Key extends Comparable<Key>> # 10:38
    method __init__ (line 5) | def __init__(self, capacity):
    method isEmpty (line 9) | def isEmpty(self): return self._N == 0
    method insert (line 11) | def insert(self, key):
    method delMax (line 15) | def delMax(self):

FILE: setup.py
  function get_long_description (line 29) | def get_long_description():

FILE: tests/plot_graphs.py
  function main (line 16) | def main(prt=sys.stdout):

FILE: tests/test_BST.py
  function test_0 (line 31) | def test_0(prt=sys.stdout):

FILE: tests/test_BST_sortinput.py
  function _get_kv (line 15) | def _get_kv(keys):
  function test_0 (line 19) | def test_0(log=stdout):
  function test_1 (line 30) | def test_1(log=stdout):
  function run_all (line 41) | def run_all(log=stdout):

FILE: tests/test_Bag.py
  function run (line 8) | def run(item_list):

FILE: tests/test_BreadthFirstPaths.py
  function test_0 (line 15) | def test_0(prt=stdout):
  function test_1 (line 40) | def test_1(prt=stdout):
  function run_all (line 57) | def run_all(prt=stdout):

FILE: tests/test_CC.py
  function test_0 (line 17) | def test_0(prt=sys.stdout):
  function test_1 (line 38) | def test_1(prt=sys.stdout):
  function cli (line 56) | def cli():

FILE: tests/test_Date.py
  function test_date (line 7) | def test_date(prt=sys.stdout):

FILE: tests/test_DepthFirstDirectedPaths.py
  function main (line 8) | def main(prt=sys.stdout):

FILE: tests/test_DepthFirstPaths.py
  function test_0 (line 8) | def test_0(prt=sys.stdout):

FILE: tests/test_DepthFirstSearch.py
  function test_depthfirstsearch (line 15) | def test_depthfirstsearch():
  function _run (line 45) | def _run(graph, src_node):

FILE: tests/test_Digraph.py
  function test_main (line 13) | def test_main(prt=sys.stdout):
  function test_lecture (line 18) | def test_lecture(prt=sys.stdout):
  function run_all (line 25) | def run_all(prt=sys.stdout):

FILE: tests/test_DirectedDFS.py
  function test_main (line 13) | def test_main(digraph, *sources):
  function cli (line 35) | def cli(prt=sys.stdout):

FILE: tests/test_DirectedEdge.py
  function main (line 6) | def main(prt=sys.stdout):

FILE: tests/test_Edge.py
  function main (line 9) | def main():

FILE: tests/test_EdgeWeightedDigraph.py
  function main (line 6) | def main(prt=sys.stdout):

FILE: tests/test_EdgeWeightedDirectedCycle.py
  function main (line 17) | def main(prt=sys.stdout):

FILE: tests/test_EdgeWeightedGraph.py
  function main (line 21) | def main(prt=sys.stdout):

FILE: tests/test_FlowEdge.py
  function main (line 6) | def main(prt=sys.stdout):

FILE: tests/test_FlowNetwork.py
  function main (line 7) | def main(prt=sys.stdout):

FILE: tests/test_FordFulkerson.py
  function main (line 19) | def main(prt=sys.stdout):

FILE: tests/test_GREP.py
  function test_0 (line 32) | def test_0(prt=sys.stdout):

FILE: tests/test_Graph.py
  function test_0 (line 14) | def test_0():
  function test_1 (line 20) | def test_1(prt=sys.stdout):
  function _run (line 38) | def _run(data, prt=sys.stdout):

FILE: tests/test_Heap.py
  function main (line 7) | def main(prt=sys.stdout):

FILE: tests/test_Insertion.py
  function _run (line 10) | def _run(arr, desc=None, prt=sys.stdout):
  function test_wk2_lec (line 21) | def test_wk2_lec():
  function test_wk2_lec_best (line 26) | def test_wk2_lec_best():
  function test_wk2_lec_worst (line 31) | def test_wk2_lec_worst():
  function test_wk2_lec_partial (line 36) | def test_wk2_lec_partial():
  function test_1 (line 42) | def test_1():
  function test_2 (line 47) | def test_2():
  function test_3 (line 53) | def test_3():
  function test_4 (line 58) | def test_4():
  function test_5 (line 63) | def test_5():
  function test_half01a (line 68) | def test_half01a():
  function test_half01b (line 73) | def test_half01b():
  function test_half01c (line 78) | def test_half01c():
  function run_all (line 83) | def run_all():
  function _cli (line 98) | def _cli():

FILE: tests/test_Interval1D.py
  function test_0 (line 6) | def test_0(prt=sys.stdout):

FILE: tests/test_KMP.py
  function test_0 (line 9) | def test_0(pat, txt, prt=stdout):
  function cli (line 51) | def cli():

FILE: tests/test_KruskalMST.py
  function main (line 42) | def main(prt=sys.stdout):

FILE: tests/test_LSD.py
  function main (line 36) | def main(seqinfo, prt=sys.stdout):

FILE: tests/test_LazyPrimMST.py
  function main (line 50) | def main(fin_G, prt=sys.stdout):

FILE: tests/test_LinearProbingHashST.py
  function test_stdin (line 7) | def test_stdin(prt=sys.stdout):
  function cli (line 23) | def cli():

FILE: tests/test_LinearProgramming.py
  function test_0 (line 20) | def test_0(prt=sys.stdout):

FILE: tests/test_MSD.py
  function main (line 32) | def main(seqinfo, prt=sys.stdout):

FILE: tests/test_MaxPQ.py
  function test_week4_lec_8_2_m11_29 (line 7) | def test_week4_lec_8_2_m11_29(): # Lecture 8 - 2 12:18
  function test_week4_quiz_Q1 (line 18) | def test_week4_quiz_Q1():
  function test_week4_quiz_Q2 (line 26) | def test_week4_quiz_Q2():
  function test_week4_quiz_Q1b (line 34) | def test_week4_quiz_Q1b(): # seed 201303
  function test_week4_quiz_Q2b (line 43) | def test_week4_quiz_Q2b():

FILE: tests/test_Merge.py
  function run (line 10) | def run(arr, desc, prt=sys.stdout):
  function test_14238 (line 17) | def test_14238():
  function test_3 (line 21) | def test_3():
  function test_2 (line 28) | def test_2():
  function test_1 (line 35) | def test_1():
  function run_all (line 40) | def run_all():
  function run_seq (line 45) | def run_seq():

FILE: tests/test_MergeBU.py
  function run (line 8) | def run(a, desc, prt=sys.stdout):
  function test_193860 (line 15) | def test_193860(prt=sys.stdout):
  function test_1 (line 23) | def test_1(prt=sys.stdout):
  function run_all (line 30) | def run_all(prt=sys.stdout):
  function run_seq (line 34) | def run_seq(prt=sys.stdout):

FILE: tests/test_MergeX.py
  function test_1 (line 10) | def test_1():

FILE: tests/test_MinPQ.py
  function main (line 8) | def main(prt=sys.stdout):

FILE: tests/test_NFA.py
  function test_nfa (line 31) | def test_nfa():
  function _run (line 44) | def _run(num, regexp, txt):

FILE: tests/test_Point2D.py
  function main (line 7) | def main(prt=sys.stdout):

FILE: tests/test_PowerLaw.py
  function test_Lecture_Observations_Question (line 10) | def test_Lecture_Observations_Question():
  function test_week1_ex_Q1_398112 (line 35) | def test_week1_ex_Q1_398112(): # Lecture: Quick-Union Improvements 1:22
  function test_week1_ex_Q1_990354 (line 56) | def test_week1_ex_Q1_990354(): # Lecture: Quick-Union Improvements 1:22
  function test_week1_ex_Q1_130450 (line 78) | def test_week1_ex_Q1_130450(): # Lecture: Quick-Union Improvements 1:22
  function test_week1_exercise_Q1 (line 100) | def test_week1_exercise_Q1(): # Lecture: Quick-Union Improvements 1:22
  function test_week1_exercise_Q1b (line 128) | def test_week1_exercise_Q1b(): # Lecture: Quick-Union Improvements 1:22
  function test_week1_exercise_Q1c (line 146) | def test_week1_exercise_Q1c(): # Lecture: Quick-Union Improvements 1:22
  function test_week1_exercise_Q1d (line 171) | def test_week1_exercise_Q1d(): # Lecture: Quick-Union Improvements 1:22
  function test_week1_exerciseA_Q1 (line 193) | def test_week1_exerciseA_Q1():
  function test_week1_exerciseA_Q2 (line 211) | def test_week1_exerciseA_Q2():

FILE: tests/test_Queue.py
  function test_wk2_ex_Queues_608030 (line 9) | def test_wk2_ex_Queues_608030():
  function test_wk2_ex_Queues_511394 (line 33) | def test_wk2_ex_Queues_511394():
  function run_all (line 47) | def run_all():

FILE: tests/test_Quick.py
  function test_quicksort (line 9) | def test_quicksort():
  function _run (line 13) | def _run(arr):

FILE: tests/test_Quick3way.py
  function run (line 8) | def run(a, prt=sys.stdout):

FILE: tests/test_QuickFindUF.py
  function test_1 (line 10) | def test_1():
  function test_week1_quiz_q1 (line 16) | def test_week1_quiz_q1():
  function test_week1_quiz_q1b (line 22) | def test_week1_quiz_q1b():
  function test_week1_quiz_q1_567561 (line 28) | def test_week1_quiz_q1_567561():
  function test_week1_quiz_q1_838874 (line 33) | def test_week1_quiz_q1_838874():
  function test_week1_quiz_q1_533243 (line 38) | def test_week1_quiz_q1_533243():
  function test_week1_quiz_q1_489602 (line 43) | def test_week1_quiz_q1_489602():
  function test_week1_quiz_q1_126228 (line 48) | def test_week1_quiz_q1_126228():
  function test_all (line 53) | def test_all():

FILE: tests/test_QuickUnionUF.py
  function test_week1_lecture_print (line 8) | def test_week1_lecture_print():
  function test_week1_lecture (line 26) | def test_week1_lecture():
  function test_week1_exercise_q2 (line 32) | def test_week1_exercise_q2():
  function test_all (line 38) | def test_all():

FILE: tests/test_QuickX.py
  function test_quickx (line 9) | def test_quickx():

FILE: tests/test_Quick_partition.py
  function run (line 8) | def run(a, prt=sys.stdout):

FILE: tests/test_RabinKarp.py
  function test_0 (line 38) | def test_0(prt=sys.stdout):

FILE: tests/test_ResizingArrayQueue.py
  function run (line 9) | def run(item_list):
  function default_example (line 19) | def default_example():

FILE: tests/test_ResizingArrayStack.py
  function main (line 8) | def main(prt=sys.stdout):

FILE: tests/test_ST.py
  function test_symbol_table (line 6) | def test_symbol_table():
  function test_symbol_table_01_08_01a (line 15) | def test_symbol_table_01_08_01a():
  function _run (line 33) | def _run(seq_in, exp_out):

FILE: tests/test_Selection.py
  function test_wk2_lec (line 11) | def test_wk2_lec(prt=sys.stdout):
  function test_wk2_ex_selections_489125 (line 18) | def test_wk2_ex_selections_489125(prt=sys.stdout):
  function test_wk2_q3a (line 26) | def test_wk2_q3a(prt=sys.stdout):
  function test_wk2_q3b (line 32) | def test_wk2_q3b(prt=sys.stdout):
  function test_wk2_q2a (line 40) | def test_wk2_q2a(prt=sys.stdout):
  function run (line 53) | def run(arr, desc=None, prt=sys.stdout):
  function run_all (line 63) | def run_all():
  function cli (line 70) | def cli():

FILE: tests/test_SeparateChainingHashST.py
  function test_stdin (line 8) | def test_stdin(prt=sys.stdout):
  function cli (line 24) | def cli():

FILE: tests/test_SequentialSearchST.py
  function main (line 7) | def main(prt=sys.stdout):

FILE: tests/test_Shell.py
  function test_wk2_lec_a (line 12) | def test_wk2_lec_a():
  function test_wk2_lec_b (line 17) | def test_wk2_lec_b():
  function test_1 (line 22) | def test_1():
  function test_2 (line 40) | def test_2():
  function test_3 (line 48) | def test_3():
  function test_q3a (line 53) | def test_q3a():
  function test_q3b (line 61) | def test_q3b():
  function run (line 69) | def run(arr, desc=None, sort_seq=None, prt=sys.stdout):
  function run_all (line 80) | def run_all():
  function cli (line 88) | def cli():

FILE: tests/test_Sorting.py
  function getData (line 42) | def getData(blktxt):
  function prtData (line 56) | def prtData(D):
  function get_sort_history (line 62) | def get_sort_history(lst ):
  function determine_sort (line 74) | def determine_sort( list_orig, data ):
  class Sorting_Tests (line 102) | class Sorting_Tests(unittest.TestCase):
    method test_week2_exercise_Q2 (line 104) | def test_week2_exercise_Q2(self): # Lecture: Quick-Union Improvements ...
    method test_week2_exercise_Q2a (line 152) | def test_week2_exercise_Q2a(self): # Lecture: Quick-Union Improvements...
  function curr (line 192) | def curr(): # Exercise
  function prt_easy_viz (line 237) | def prt_easy_viz(str_data):

FILE: tests/test_Stack.py
  function test_stack_lec_quiz (line 9) | def test_stack_lec_quiz(prt=sys.stdout):
  function test_wk2_ex_stacks_489125 (line 19) | def test_wk2_ex_stacks_489125(prt=sys.stdout):
  function test_wk2_ex_stacks_634506 (line 43) | def test_wk2_ex_stacks_634506(prt=sys.stdout):
  function test_wk2_ex_stacks_634506b (line 63) | def test_wk2_ex_stacks_634506b(prt=sys.stdout):
  function test_wk2_ex_stacks_489125b (line 77) | def test_wk2_ex_stacks_489125b(prt=sys.stdout):
  function simple_test (line 92) | def simple_test():
  function default_examples (line 98) | def default_examples():
  function run_all (line 104) | def run_all():

FILE: tests/test_TST.py
  function main (line 45) | def main(fin, prt=sys.stdout):

FILE: tests/test_Transaction.py
  function test_sortbys (line 8) | def test_sortbys(prt=sys.stdout):
  function test_hash (line 32) | def test_hash(prt=sys.stdout):
  function run_all (line 41) | def run_all():

FILE: tests/test_TrieST.py
  function main (line 27) | def main(prt=sys.stdout):

FILE: tests/test_UnorderedArrayMaxPQ.py
  function main (line 6) | def main(prt=sys.stdout):

FILE: tests/test_WeightedQUF_state_pics.py
  function test_wk1_ex_166199 (line 9) | def test_wk1_ex_166199():
  function test_wk1_ex_166199b (line 18) | def test_wk1_ex_166199b():
  function test_wk1_ex_686557x (line 24) | def test_wk1_ex_686557x():
  function test_wk1_ex_x1 (line 30) | def test_wk1_ex_x1():
  function try_unions (line 37) | def try_unions(alg, seed, unions):
  function run_all (line 42) | def run_all():

FILE: tests/test_WeightedQuickUnionPlusUF.py
  function test_week1_lecture (line 9) | def test_week1_lecture():
  function test_wk1_ex_455127 (line 16) | def test_wk1_ex_455127():
  function run_all (line 21) | def run_all():

FILE: tests/test_WeightedQuickUnionUF.py
  function test_week1_lecture (line 9) | def test_week1_lecture():
  function test_wk1_ex_455127 (line 16) | def test_wk1_ex_455127():
  function run_all (line 21) | def run_all():

FILE: tests/test_adjtxtblk2arr.py
  function test_0 (line 8) | def test_0():
  function run_all (line 38) | def run_all():

FILE: tests/test_knuth_shuffle.py
  function test_knuth_shuffle (line 10) | def test_knuth_shuffle():

FILE: tests/test_nfa_dvk.py
  function test_reference_it_nfa (line 10) | def test_reference_it_nfa():
  function test_reference_it_nfa2 (line 24) | def test_reference_it_nfa2():

FILE: tests/test_quickfinduf_01a_03_11.py
  function test_union_find (line 10) | def test_union_find():
  function _union (line 15) | def _union(alg, pid, qid):
  function _prt_before (line 21) | def _prt_before(idstr, alg, idnum, bgcolor=0, fgcolor=15):

FILE: tests/test_regex_is_exponential.py
  function test_regex_is_exponential (line 11) | def test_regex_is_exponential():
  function _run_nfa (line 47) | def _run_nfa(regexp, txt):
  function _run_re (line 55) | def _run_re(regexp, txt):
  function _prt_hdr (line 63) | def _prt_hdr():

FILE: tests/test_substr_search.py
  function test_substrsrc_bruteforce (line 11) | def test_substrsrc_bruteforce():
  function _timeit_all (line 60) | def _timeit_all(txt, pat, num_runs):
  function _timekmp (line 67) | def _timekmp(txt, pat, num_runs):
  function _timeit (line 77) | def _timeit(txt, pat, num_runs, fncname):
  function _chk_all (line 85) | def _chk_all(txt, pat, exp):
  function _chk (line 91) | def _chk(txt, pat, exp, fncname):

FILE: tests/utils.py
  function prt_hms (line 18) | def prt_hms(tic, msg, prt=sys.stdout):
  function repo_fn (line 24) | def repo_fn(fin):

FILE: tests/visualize_blktxt.py
  function test_849965 (line 6) | def test_849965():
  function test_976184 (line 37) | def test_976184():
  function test_131507 (line 58) | def test_131507():
  function run_all (line 75) | def run_all():

FILE: thirdparty/BouncingBalls.java
  class BouncingBalls (line 19) | public class BouncingBalls
    method main (line 24) | public static void main(String[] args)

FILE: thirdparty/EvaluatePostfix.java
  class EvaluatePostfix (line 41) | public class EvaluatePostfix {
    method main (line 42) | public static void main(String[] args) {

FILE: thirdparty/FileSorter.java
  class FileSorter (line 18) | public class FileSorter {
    method main (line 20) | public static void main(String[] args) {

FILE: thirdparty/HelloWorld.java
  class HelloWorld (line 1) | public class HelloWorld {
    method main (line 2) | public static void main(String[] args) {

FILE: thirdparty/UnorderedArrayMaxPQ.java
  class UnorderedArrayMaxPQ (line 15) | public class UnorderedArrayMaxPQ<Key extends Comparable<Key>> {
    method UnorderedArrayMaxPQ (line 20) | public UnorderedArrayMaxPQ(int capacity) {
    method isEmpty (line 25) | public boolean isEmpty()   { return N == 0; }
    method size (line 26) | public int size()          { return N;      }
    method insert (line 27) | public void insert(Key x)  { pq[N++] = x;   }
    method delMax (line 29) | public Key delMax() {
    method less (line 42) | private boolean less(int i, int j) {
    method exch (line 46) | private void exch(int i, int j) {
    method main (line 56) | public static void main(String[] args) {

FILE: thirdparty/a2_hw2/seamCarving/PrintEnergy.java
  class PrintEnergy (line 15) | public class PrintEnergy {
    method main (line 17) | public static void main(String[] args) {

FILE: thirdparty/a2_hw2/seamCarving/PrintSeams.java
  class PrintSeams (line 37) | public class PrintSeams {
    method printSeam (line 41) | private static void printSeam(SeamCarver carver, int[] seam, boolean d...
    method main (line 63) | public static void main(String[] args) {

FILE: thirdparty/a2_hw2/seamCarving/ResizeDemo.java
  class ResizeDemo (line 17) | public class ResizeDemo {
    method main (line 18) | public static void main(String[] args) {

FILE: thirdparty/a2_hw2/seamCarving/SCUtility.java
  class SCUtility (line 15) | public class SCUtility {
    method randomPicture (line 19) | public static Picture randomPicture(int W, int H) {
    method toEnergyMatrix (line 33) | public static double[][] toEnergyMatrix(SeamCarver sc) {
    method showEnergy (line 43) | public static void showEnergy(SeamCarver sc) {
    method toEnergyPicture (line 47) | public static Picture toEnergyPicture(SeamCarver sc) {
    method doubleToPicture (line 54) | public static Picture doubleToPicture(double[][] grayValues) {
    method seamOverlay (line 88) | public static Picture seamOverlay(Picture p, boolean horizontal, int[]...

FILE: thirdparty/a2_hw2/seamCarving/ShowEnergy.java
  class ShowEnergy (line 15) | public class ShowEnergy {
    method main (line 17) | public static void main(String[] args) {

FILE: thirdparty/a2_hw2/seamCarving/ShowSeams.java
  class ShowSeams (line 15) | public class ShowSeams {
    method showHorizontalSeam (line 17) | private static void showHorizontalSeam(SeamCarver sc) {
    method showVerticalSeam (line 25) | private static void showVerticalSeam(SeamCarver sc) {
    method main (line 32) | public static void main(String[] args) {

FILE: thirdparty/a2_hw4/boggle/BoggleBoard.java
  class BoggleBoard (line 14) | public class BoggleBoard {
    method BoggleBoard (line 67) | public BoggleBoard() {
    method BoggleBoard (line 85) | public BoggleBoard(String filename) {
    method BoggleBoard (line 113) | public BoggleBoard(int M, int N) {
    method BoggleBoard (line 132) | public BoggleBoard(char[][] a) {
    method rows (line 153) | public int rows() { return M; }
    method cols (line 159) | public int cols() { return N; }
    method getLetter (line 169) | public char getLetter(int i, int j) {
    method toString (line 177) | public String toString() {
    method main (line 193) | public static void main(String[] args) {

FILE: thirdparty/a2_hw4/boggle/BoggleGame.java
  class BoggleGame (line 51) | public class BoggleGame extends JFrame {
    method BoggleGame (line 138) | public BoggleGame(int rows, int cols) {
    method newGame (line 424) | private void newGame() {
    method endGame (line 506) | private void endGame() {
    class Countdown (line 571) | private class Countdown extends TimerTask {
      method run (line 572) | @Override
    method checkWord (line 591) | private void checkWord() {
    method scoreWord (line 640) | private int scoreWord(String s) {
    class BoardPanel (line 655) | private class BoardPanel extends JPanel {
      method BoardPanel (line 665) | public BoardPanel() {
      method clearSelection (line 756) | public void clearSelection() {
      method getCurrentPath (line 767) | public String getCurrentPath() {
      method setBoard (line 781) | public void setBoard() {
      method highlightCubes (line 797) | public void highlightCubes() {
      method unhighlightCubes (line 807) | public void unhighlightCubes() {
      method matchWord (line 819) | public void matchWord(String s) {
      method dfs (line 846) | private void dfs(String s, int curChar, int pathIndex, int i, int j) {
    method makeMenuBar (line 889) | private void makeMenuBar() {
    method main (line 957) | public static void main(final String[] args) {

FILE: thirdparty/hw1/percolation/InteractivePercolationVisualizer.java
  class InteractivePercolationVisualizer (line 17) | public class InteractivePercolationVisualizer {
    method main (line 19) | public static void main(String[] args) {

FILE: thirdparty/hw1/percolation/PercolationVisualizer.java
  class PercolationVisualizer (line 24) | public class PercolationVisualizer {
    method draw (line 30) | public static void draw(Percolation perc, int N) {
    method main (line 64) | public static void main(String[] args) {

FILE: thirdparty/hw3/collinear/LineSegment.java
  class LineSegment (line 13) | public class LineSegment {
    method LineSegment (line 25) | public LineSegment(Point p, Point q) {
    method draw (line 37) | public void draw() {
    method toString (line 48) | public String toString() {
    method hashCode (line 60) | public int hashCode() {

FILE: thirdparty/hw4/8puzzle/PuzzleChecker.java
  class PuzzleChecker (line 31) | public class PuzzleChecker {
    method main (line 33) | public static void main(String[] args) {

FILE: thirdparty/hw5/NearestNeighborVisualizer.java
  class NearestNeighborVisualizer (line 14) | public class NearestNeighborVisualizer {
    method main (line 16) | public static void main(String[] args) {

FILE: thirdparty/hw5/RangeSearchVisualizer.java
  class RangeSearchVisualizer (line 16) | public class RangeSearchVisualizer {
    method main (line 18) | public static void main(String[] args) {

FILE: thirdparty/hw5/kdtree/KdTreeGenerator.java
  class KdTreeGenerator (line 20) | public class KdTreeGenerator {
    method main (line 22) | public static void main(String[] args) {

FILE: thirdparty/hw5/kdtree/KdTreeVisualizer.java
  class KdTreeVisualizer (line 16) | public class KdTreeVisualizer {
    method main (line 18) | public static void main(String[] args) {

FILE: thirdparty/hw5/kdtree/NearestNeighborVisualizer.java
  class NearestNeighborVisualizer (line 18) | public class NearestNeighborVisualizer {
    method main (line 20) | public static void main(String[] args) {

FILE: thirdparty/hw5/kdtree/RangeSearchVisualizer.java
  class RangeSearchVisualizer (line 20) | public class RangeSearchVisualizer {
    method main (line 22) | public static void main(String[] args) {

FILE: thirdparty/java2tmp.py
  function main (line 7) | def main(prt=sys.stdout):
  function chk_def (line 101) | def chk_def(line):
  function chk_else (line 106) | def chk_else(line):
  function chk_public (line 112) | def chk_public(line):
  function chk_private (line 118) | def chk_private(line):
  function chk_if (line 124) | def chk_if(line):
  function chk_start (line 130) | def chk_start(line):
  function chk_semi (line 136) | def chk_semi(line):
  function chk_end (line 142) | def chk_end(line):
  function get_foutnames (line 149) | def get_foutnames(fin):
  function get_fouts (line 157) | def get_fouts(fin):
  function get_odir (line 164) | def get_odir():
  function get_fin (line 172) | def get_fin():

FILE: thirdparty/test_RandomizedQueue.java
  class test_RandomizedQueue (line 5) | public class test_RandomizedQueue {
    method main (line 7) | public static void main(String[] argv) {
Copy disabled (too large) Download .json
Condensed preview — 755 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (69,515K chars).
[
  {
    "path": ".gitignore",
    "chars": 2455,
    "preview": "/*.png\n\nthirdparty/percolation.zip\nthirdparty/PercolationStats.java\nthirdparty/Percolation.java\npy/AlgsSedgewickWayne/Pe"
  },
  {
    "path": "AlgsSedgewickWayne/.gitignore",
    "chars": 259,
    "preview": "tmp*\n\n# Algs 1, wk1\nPercolation.py\nPercolationStats.py\n\n# Algs 1, wk2\nDeque.py \nRandomizedQueue.py \nSubset.py\n\n# Algs 1,"
  },
  {
    "path": "AlgsSedgewickWayne/AcyclicLP.py",
    "chars": 6286,
    "preview": "#*****************************************************************************\n #  Compilation:  javac AcyclicLP.java\n #"
  },
  {
    "path": "AlgsSedgewickWayne/AcyclicSP.py",
    "chars": 3449,
    "preview": "\"\"\"Solve single-source shortest paths problem in edge-weighted DAG\"\"\"\n# TBD: Finish Python port\n\nfrom AlgsSedgewickWayne"
  },
  {
    "path": "AlgsSedgewickWayne/BST.py",
    "chars": 16625,
    "preview": "\"\"\"A symbol table implemented with a binary search tree (BST).\"\"\"\n\n# It also provides a **keys** method for iterating ov"
  },
  {
    "path": "AlgsSedgewickWayne/BST_utils.py",
    "chars": 2842,
    "preview": "\"\"\"Functions to plot a Binary Search Tree.\"\"\"\n\nimport pydot\n\n__copyright__ = \"Copyright (C) 2019, DV Klopfenstein. All r"
  },
  {
    "path": "AlgsSedgewickWayne/BTree.py",
    "chars": 7389,
    "preview": "#!/usr/bin/env python#*****************************************************************************\n #  Compilation:  ja"
  },
  {
    "path": "AlgsSedgewickWayne/Bag.py",
    "chars": 2806,
    "preview": "\"\"\"Bag class is a container for generic items.\"\"\"\n\nclass Bag(object): # <Item> implements Iterable<Item>:\n  \"\"\"The Bag c"
  },
  {
    "path": "AlgsSedgewickWayne/BaseComp.py",
    "chars": 3882,
    "preview": "\"\"\"Component Base which holds functions to aid in visulaization and understanding.\"\"\"\n\n# Copyright (C) 2014-present DV K"
  },
  {
    "path": "AlgsSedgewickWayne/BellmanFordSP.py",
    "chars": 6748,
    "preview": "\"\"\"Bellman-Ford shortest path algorithm in Graphs w/no neg. cycles.\"\"\"\n# TBD: Finish Python port\n\nimport collections as "
  },
  {
    "path": "AlgsSedgewickWayne/BinarySearch.py",
    "chars": 6596,
    "preview": "#!/usr/bin/env python\n#************************************************************************\n#  Compilation:  javac B"
  },
  {
    "path": "AlgsSedgewickWayne/BoyerMoore.py",
    "chars": 3384,
    "preview": "\n# TBD Finish Python port\n\n ******************************************************************************/\n\npackage edu"
  },
  {
    "path": "AlgsSedgewickWayne/BreadthFirstPaths.py",
    "chars": 4320,
    "preview": "\"\"\"find shortest paths from a source vertex src to every other vertex in an undirected graph.\"\"\"\n\nimport sys\nfrom collec"
  },
  {
    "path": "AlgsSedgewickWayne/CC.py",
    "chars": 4836,
    "preview": "\"\"\"Compute connected components using depth first search.\"\"\"\n\nimport collections as cx\n\nclass CC(object):\n  \"\"\"Computes "
  },
  {
    "path": "AlgsSedgewickWayne/CPM.py",
    "chars": 4193,
    "preview": "#*****************************************************************************\n #  Compilation:  javac CPM.java\n #  Exec"
  },
  {
    "path": "AlgsSedgewickWayne/CollisionSystem.py",
    "chars": 8007,
    "preview": "\"\"\"Simulates motion of N rand particles according to the laws of elastic collisions.\"\"\"\n# TBD: DO PYTHON PORT\n\nclass Col"
  },
  {
    "path": "AlgsSedgewickWayne/Date.py",
    "chars": 3586,
    "preview": "\"\"\"An example of an immutable type which can be used as a key for a Symbol Table.\"\"\"\n\nfrom datetime import date, timedel"
  },
  {
    "path": "AlgsSedgewickWayne/DepthFirstDirectedPaths.py",
    "chars": 3143,
    "preview": "\"\"\"Computes a path between source vertex, s, and every other vertex in undirected graph G.\"\"\"\n\nclass DepthFirstDirectedP"
  },
  {
    "path": "AlgsSedgewickWayne/DepthFirstOrder.py",
    "chars": 7650,
    "preview": "# /******************************************************************************\n#  *  Compilation:  javac DepthFirstOr"
  },
  {
    "path": "AlgsSedgewickWayne/DepthFirstPaths.py",
    "chars": 2334,
    "preview": "\"\"\"Computes a path between source vertex, s, and every other vertex in undirected graph G.\"\"\"\n\nimport collections as cx\n"
  },
  {
    "path": "AlgsSedgewickWayne/DepthFirstSearch.py",
    "chars": 1715,
    "preview": "\"\"\"Run depth first search on an undirected graph. O(E + V) time.\"\"\"\n# https://algs4.cs.princeton.edu/41graph\n\n\nclass Dep"
  },
  {
    "path": "AlgsSedgewickWayne/Digraph.py",
    "chars": 6855,
    "preview": "\"\"\"A directed graph, implemented using an array of lists. Parallel edges & self-loops permitted.\"\"\"\n# pylint: disable=in"
  },
  {
    "path": "AlgsSedgewickWayne/DijkstraSP.py",
    "chars": 4858,
    "preview": "\"\"\"Dijkstra's algorithm. Computes the shortest path tree. Assumes all weights are nonnegative.\"\"\"\n\nclass DijkstraSP(obje"
  },
  {
    "path": "AlgsSedgewickWayne/DirectedDFS.py",
    "chars": 1568,
    "preview": "\"\"\"Data type for determining the vertices reachable from a given src vertex(s).\"\"\"\n# pylint: disable=invalid-name\n\n\nclas"
  },
  {
    "path": "AlgsSedgewickWayne/DirectedEdge.py",
    "chars": 1046,
    "preview": "\"\"\"Immutable weighted directed edge.\"\"\"\n\nclass DirectedEdge(object): \n  \"\"\"a directed edge from vertex v to vertex w wit"
  },
  {
    "path": "AlgsSedgewickWayne/Edge.py",
    "chars": 1442,
    "preview": "\"\"\"Immutable weighted edge.\"\"\"\n# pylint: disable=invalid-name\n\n\nclass Edge:\n    \"\"\"Edge between two vertices\"\"\"\n\n    def"
  },
  {
    "path": "AlgsSedgewickWayne/EdgeWeightedDigraph.py",
    "chars": 3686,
    "preview": "\"\"\"An edge-weighted digraph, implemented using adjacency lists.\"\"\"\n# TBD: Finish Python port\n\nfrom AlgsSedgewickWayne.Di"
  },
  {
    "path": "AlgsSedgewickWayne/EdgeWeightedDirectedCycle.py",
    "chars": 4476,
    "preview": "\"\"\"Finds a directed cycle in an edge-weighted digraph.\"\"\"\n# TBD: Finish python port\n\n#**********************************"
  },
  {
    "path": "AlgsSedgewickWayne/EdgeWeightedGraph.py",
    "chars": 4230,
    "preview": "\"\"\"An edge-weighted undirected graph, implemented using adjacency lists.\"\"\"\n# pylint: disable=invalid-name\n\nimport rando"
  },
  {
    "path": "AlgsSedgewickWayne/FileIndex.py",
    "chars": 3500,
    "preview": "#!/usr/bin/env python#*****************************************************************************\n #  Compilation:  ja"
  },
  {
    "path": "AlgsSedgewickWayne/FlowEdge.py",
    "chars": 3282,
    "preview": "\"\"\"Capacitated edge with a flow in a flow network.\"\"\"\n\nclass FlowEdge(object):\n\n  def __init__(self, v, w, capacity, flo"
  },
  {
    "path": "AlgsSedgewickWayne/FlowNetwork.py",
    "chars": 3427,
    "preview": "\"\"\"A capacitated flow network, implemented using adjacency lists.\"\"\"\n# TBD Finish Python port\n\n #  The <tt>FlowNetwork</"
  },
  {
    "path": "AlgsSedgewickWayne/FordFulkerson.py",
    "chars": 15780,
    "preview": "\"\"\"Ford-Fulkerson: compute a max flow and a min cut using shortest augmenting path rule.\"\"\"\n# TBD Finish Python port\n\n #"
  },
  {
    "path": "AlgsSedgewickWayne/FrequencyCounter.py",
    "chars": 1022,
    "preview": "#!/usr/bin/env python\n# TBD: DO PYTHON PORT\n\n# Reads in a command-line integer and sequence of words from\n# standard inp"
  },
  {
    "path": "AlgsSedgewickWayne/GREP.py",
    "chars": 1054,
    "preview": "\n# TBD Finish Python port\n\n ******************************************************************************/\n\npackage edu"
  },
  {
    "path": "AlgsSedgewickWayne/GabowSCC.py",
    "chars": 6592,
    "preview": "#*****************************************************************************\n #  Compilation:  javac GabowSCC.java\n # "
  },
  {
    "path": "AlgsSedgewickWayne/GrahamScan.py",
    "chars": 9397,
    "preview": "#!/usr/bin/env python3\n\"\"\"GrahamScan class\"\"\"\n\nfrom copy import deepcopy\nfrom AlgsSedgewickWayne.Stack import Stack\nfrom"
  },
  {
    "path": "AlgsSedgewickWayne/Graph.py",
    "chars": 6115,
    "preview": "\"\"\"A undirected graph, implemented using an array of sets. Parallel edges and self-loops allowed.\"\"\"\n\nimport sys\nfrom Al"
  },
  {
    "path": "AlgsSedgewickWayne/HTree.py",
    "chars": 1004,
    "preview": "#!/usr/bin/env python3\n#*****************************************************************************\n #  H-tree.\n #    "
  },
  {
    "path": "AlgsSedgewickWayne/Heap.py",
    "chars": 5265,
    "preview": "\"\"\"Heapsort.\"\"\"\n\nfrom AlgsSedgewickWayne.utils import _isSorted\n\ndef Sort(pq):\n  N = len(pq)\n  for k in range(N/2, 0, -1"
  },
  {
    "path": "AlgsSedgewickWayne/Insertion.py",
    "chars": 8414,
    "preview": "\"\"\"Alg1 Week2 Lecture Insertion Sort.\n\nAVG:  ~1/4 N**2 compares and 1/4 N**2 exchanges on avg: Randomly-ordered array w/"
  },
  {
    "path": "AlgsSedgewickWayne/Interval1D.py",
    "chars": 2559,
    "preview": "\"\"\"The Interval1D class represents a one-dimensional interval.\n\n       The interval is closed - it contains both endpoin"
  },
  {
    "path": "AlgsSedgewickWayne/KMP.py",
    "chars": 2507,
    "preview": "\"\"\"Knuth-Morris-Pratt finds the 1st occurrence of a pattern in a text string wo/backing-up.\"\"\"\n# pylint: disable=invalid"
  },
  {
    "path": "AlgsSedgewickWayne/KosarajuSharirSCC.py",
    "chars": 8764,
    "preview": "\"\"\"Compute the strong components of a digraph in O(E + V)\"\"\"\n\n #  Execution:    java KosarajuSharirSCC filename.txt\n #  "
  },
  {
    "path": "AlgsSedgewickWayne/KruskalMST.py",
    "chars": 2456,
    "preview": "\"\"\"Compute a min. spanning forest(for each connected comp) or tree(if 1 CC) w/Kruskal's algorithm.\"\"\"\n\nfrom AlgsSedgewic"
  },
  {
    "path": "AlgsSedgewickWayne/LSD.py",
    "chars": 2166,
    "preview": "\"\"\"sorting an array of W-character strings or 32-bit integers using LSD radix sort.\"\"\"\n# TBD Finish Python port\n\nimport "
  },
  {
    "path": "AlgsSedgewickWayne/LazyPrimMST.py",
    "chars": 2886,
    "preview": "\"\"\"Compute a minimum spanning forest using a lazy version of Prim's algorithm.\"\"\"\n\nfrom heapq import heappush, heappop\nf"
  },
  {
    "path": "AlgsSedgewickWayne/LinearProbingHashST.py",
    "chars": 8894,
    "preview": "\"\"\"Avoiding collision through linear probing.\"\"\"\n\nimport sys\nfrom AlgsSedgewickWayne.Queue import Queue\n\nclass LinearPro"
  },
  {
    "path": "AlgsSedgewickWayne/LinearProgramming.py",
    "chars": 9363,
    "preview": "\n# TBD Finish Python port\n\n ******************************************************************************/\n\npackage edu"
  },
  {
    "path": "AlgsSedgewickWayne/LinkedBag.py",
    "chars": 3303,
    "preview": "#!/usr/bin/env python#************************************************************************\n #  Compilation:  javac L"
  },
  {
    "path": "AlgsSedgewickWayne/LinkedQueue.py",
    "chars": 5847,
    "preview": "#!/usr/bin/env python\n#************************************************************************\n #  Compilation:  javac "
  },
  {
    "path": "AlgsSedgewickWayne/LinkedStack.py",
    "chars": 5127,
    "preview": "#!/usr/bin/env python\n\n#************************************************************************\n #  Compilation:  javac"
  },
  {
    "path": "AlgsSedgewickWayne/LookupCSV.py",
    "chars": 883,
    "preview": "# TBD: Do Python Implementation\n\nfrom AlgsSedgewickWayne.ST import ST\nimport sys\nimport fileinput\n\ndef main():\n  keyFiel"
  },
  {
    "path": "AlgsSedgewickWayne/MSD.py",
    "chars": 5335,
    "preview": "\"\"\"Sort an array of extended ASCII strings or integers using MSD radix sort.\"\"\"\n# TBD Finish Python port\n\n  private stat"
  },
  {
    "path": "AlgsSedgewickWayne/MST_check.py",
    "chars": 1367,
    "preview": "from AlgsSedgewickWayne.QuickUnionUF import QuickUnionUF\nimport sys\n\ndef _check(MST, G):\n  \"\"\"check optimality condition"
  },
  {
    "path": "AlgsSedgewickWayne/MaxPQ.py",
    "chars": 18815,
    "preview": "\"\"\"Priority Queue (unordered array implementation), return maximum value.\"\"\"\n# TBD: FINISH PYTHON PORT\nimport math\n\nclas"
  },
  {
    "path": "AlgsSedgewickWayne/Merge.py",
    "chars": 20224,
    "preview": "\"\"\"Merge Sort (Top Down) from Week 3 lecture.\"\"\"\n\nimport sys\nimport collections as cx\nfrom AlgsSedgewickWayne.utils impo"
  },
  {
    "path": "AlgsSedgewickWayne/MergeBU.py",
    "chars": 2876,
    "preview": "\"Bottom-up Mergesort\"\"\"\n\nfrom AlgsSedgewickWayne.utils import __lt__, _exch, _isSorted\nfrom AlgsSedgewickWayne.Merge imp"
  },
  {
    "path": "AlgsSedgewickWayne/MergeX.py",
    "chars": 3961,
    "preview": "\"\"\"MERGESORT WITH PRACTICAL IMPROVEMENTS.\n\n  * Mergesort is too complicated for tiny arrays)\n  * Recursive nature of sor"
  },
  {
    "path": "AlgsSedgewickWayne/MinPQ.py",
    "chars": 3561,
    "preview": "\"\"\"Minimum Priority Queue data type\"\"\"\n\nimport copy\n\nclass MinPQ(object):\n  \"\"\"Priority Queue supporting insert and dele"
  },
  {
    "path": "AlgsSedgewickWayne/NFA.py",
    "chars": 4647,
    "preview": "\"\"\"Initializes the NFA from the specified regular expression\"\"\"\n# pylint: disable=invalid-name\n\nfrom AlgsSedgewickWayne."
  },
  {
    "path": "AlgsSedgewickWayne/Particle.py",
    "chars": 8635,
    "preview": "\"\"\"A particle moving in the unit box with a given position, velocity, radius, and mass.\"\"\"\n# TBD: DO PYTHON PORT\n\n#*\n # "
  },
  {
    "path": "AlgsSedgewickWayne/Point2D.py",
    "chars": 9954,
    "preview": "\n#************************************************************************\n#  Compilation:  javac Point2D.java\n#  Execut"
  },
  {
    "path": "AlgsSedgewickWayne/PowerLaw.py",
    "chars": 3234,
    "preview": "\"\"\"For determining a formula for the runtime of a program.\"\"\"\n\nimport re\nimport sys\nimport math\nimport pylab as plt\nimpo"
  },
  {
    "path": "AlgsSedgewickWayne/PrimMST.py",
    "chars": 6012,
    "preview": "\"\"\"Compute a minimum spanning forest using Prim's algorithm.\"\"\"\n\n #  Dependencies: EdgeWeightedGraph.java Edge.java Queu"
  },
  {
    "path": "AlgsSedgewickWayne/Queue.py",
    "chars": 3735,
    "preview": "\"\"\"Class Queue.\"\"\"\n\nclass Queue(object):\n  \"\"\"Queue container class.\"\"\"\n\n  class _Node(object):\n    \"\"\"Queue will contai"
  },
  {
    "path": "AlgsSedgewickWayne/Quick.py",
    "chars": 17622,
    "preview": "\"\"\"Quicksort\"\"\"\n\nimport random\nimport collections as cx\n\ndef Sort(arr, array_history=None):\n    \"\"\"QuickSort.\n    Avg nu"
  },
  {
    "path": "AlgsSedgewickWayne/Quick3way.py",
    "chars": 8672,
    "preview": "\"\"\"Speed up quicksort in the presence of duplicate keys.\"\"\"\n\nimport random\nimport collections as cx\n\ndef Sort(a, array_h"
  },
  {
    "path": "AlgsSedgewickWayne/QuickFindUF.py",
    "chars": 4746,
    "preview": "\"\"\"Python implentation of QuickFind.\"\"\"\n\nfrom AlgsSedgewickWayne.BaseComp import BaseComp # Base class is for visualizat"
  },
  {
    "path": "AlgsSedgewickWayne/QuickUnionUF.py",
    "chars": 6497,
    "preview": "\"\"\"QuickUnion (union-find) Algorithm.\"\"\"\n\nfrom AlgsSedgewickWayne.BaseComp import BaseComp\n\nclass QuickUnionUF(BaseComp)"
  },
  {
    "path": "AlgsSedgewickWayne/QuickX.py",
    "chars": 4515,
    "preview": "\"\"\"Rearranges the array in ascending order, using the natural order\"\"\"\n# TODO: pylint\n#*********************************"
  },
  {
    "path": "AlgsSedgewickWayne/RabinKarp.py",
    "chars": 3418,
    "preview": "\n# TBD Finish Python port\n\n ******************************************************************************/\n\npackage edu"
  },
  {
    "path": "AlgsSedgewickWayne/RedBlackBST.py",
    "chars": 20920,
    "preview": "\"\"\"2-3 version of left-leaning red-black BST implemented with a symbol table.\"\"\"\n# TBD: finish Python implementation\n\n #"
  },
  {
    "path": "AlgsSedgewickWayne/ResizingArrayBag.py",
    "chars": 3249,
    "preview": "#************************************************************************\n #  Compilation:  javac ResizingArrayBag.java\n"
  },
  {
    "path": "AlgsSedgewickWayne/ResizingArrayQueue.py",
    "chars": 7882,
    "preview": "\"\"\"ResizingArrayQueue class.\"\"\"\n\nclass ResizingArrayQueue: # <Item> implements Iterable<Item>:\n  \"\"\"Queue stores its dat"
  },
  {
    "path": "AlgsSedgewickWayne/ResizingArrayStack.py",
    "chars": 8560,
    "preview": "\"\"\"Class ResizingArrayStack.\"\"\"\n\nclass ResizingArrayStack: #<Item> implements Iterable<Item>:\n  \"\"\"Stack implemented wit"
  },
  {
    "path": "AlgsSedgewickWayne/SET.py",
    "chars": 8391,
    "preview": "\"\"\"Ordered self._treeset of keys implmented with a Balanced Binary Search Tree.\"\"\"\n\n# import java.util.Iterator\n# import"
  },
  {
    "path": "AlgsSedgewickWayne/ST.py",
    "chars": 2919,
    "preview": "\"\"\"Basic symbol table.\"\"\"\n# TBD: DO PYTHON PORT\n\n\nclass ST:\n    \"\"\"Associate one value with each key.\"\"\"\n\n    def __init"
  },
  {
    "path": "AlgsSedgewickWayne/Selection.py",
    "chars": 8129,
    "preview": "\"\"\"Selection Sort.\n\nSelection Sort uses ~ N^2/2 (Quadratic) compares and N (linear) exchanges\n\n\"\"\"\n\nfrom AlgsSedgewickWa"
  },
  {
    "path": "AlgsSedgewickWayne/SeparateChainingHashST.py",
    "chars": 3761,
    "preview": "\nfrom AlgsSedgewickWayne.Queue import Queue\nfrom AlgsSedgewickWayne.SequentialSearchST import SequentialSearchST\nimport "
  },
  {
    "path": "AlgsSedgewickWayne/SequentialSearchST.py",
    "chars": 2155,
    "preview": "\nfrom AlgsSedgewickWayne.Queue import Queue\n\nclass SequentialSearchST(object):\n\n  class _Node:\n    \"\"\"a helper linked li"
  },
  {
    "path": "AlgsSedgewickWayne/Shell.py",
    "chars": 8045,
    "preview": "\"\"\"Shell Sort.\n\n\"\"\"\n\nfrom AlgsSedgewickWayne.utils import _isSorted, _exch\nfrom AlgsSedgewickWayne.utils import add_arra"
  },
  {
    "path": "AlgsSedgewickWayne/SparseVector.py",
    "chars": 2112,
    "preview": "from AlgsSedgewickWayne.ST import ST\n\nclass SparseVector(object):\n\n  def __init__(self, d):\n    self._d = d # dimension\n"
  },
  {
    "path": "AlgsSedgewickWayne/Stack.py",
    "chars": 9701,
    "preview": "\"\"\"Stack Class\"\"\"\n\n\n# pylint: disable=too-few-public-methods\nclass Stack:\n    \"\"\"Stack class: Linked list of Nodes.\"\"\"\n "
  },
  {
    "path": "AlgsSedgewickWayne/StdIn.py",
    "chars": 13704,
    "preview": "#!/ust/bin/env python\n\n#************************************************************************\n#  Compilation:  javac "
  },
  {
    "path": "AlgsSedgewickWayne/TST.py",
    "chars": 6984,
    "preview": "# TBD Finish Python port\n\"\"\"Ternary search trie (TST).\"\"\"\n\n #  The <tt>TST</tt> class represents an symbol table of key-"
  },
  {
    "path": "AlgsSedgewickWayne/TarjanSCC.py",
    "chars": 6304,
    "preview": "#*****************************************************************************\n #  Compilation:  javac TarjanSCC.java\n #"
  },
  {
    "path": "AlgsSedgewickWayne/ThreeSum.py",
    "chars": 18990,
    "preview": "#!/usr/bin/env python\n#************************************************************************\n #  Compilation:  javac "
  },
  {
    "path": "AlgsSedgewickWayne/ThreeSumFast.py",
    "chars": 5460,
    "preview": "#!/usr/bin/env python\n#************************************************************************\n #  Compilation:  javac "
  },
  {
    "path": "AlgsSedgewickWayne/TopM.py",
    "chars": 1061,
    "preview": "#!/usr/bin/env python\n\"\"\"Find the largest M items in a stream of N items.\"\"\"\n\nimport sys\nimport fileinput\nfrom AlgsSedge"
  },
  {
    "path": "AlgsSedgewickWayne/Topological.py",
    "chars": 2002,
    "preview": "\"\"\"Compute topological ordering(w DFS) of a DAG or edge-weighted DAG. Runs in O(E + V) time.\"\"\"\n# TBD Finish Python port"
  },
  {
    "path": "AlgsSedgewickWayne/TopologicalX.py",
    "chars": 7385,
    "preview": "#*****************************************************************************\n #  Compilation:  javac TopologicalX.java"
  },
  {
    "path": "AlgsSedgewickWayne/Transaction.py",
    "chars": 4228,
    "preview": "# TBD: amount: -0.0 check\n\nfrom AlgsSedgewickWayne.Date import Date\n\n\nclass Transaction(object):\n  \"\"\"encapsulate a comm"
  },
  {
    "path": "AlgsSedgewickWayne/TrieST.py",
    "chars": 7451,
    "preview": "\"\"\"A string symbol table for extended ASCII strings, implemented using a 256-way trie.\"\"\"\n# TBD Finish Python port\n\n #  "
  },
  {
    "path": "AlgsSedgewickWayne/UnorderedArrayMaxPQ.py",
    "chars": 4406,
    "preview": "class UnorderedArrayMaxPQ:\n\n  def __init__(self, capacity):\n    # set inititial size of heap to hold size elements\n    s"
  },
  {
    "path": "AlgsSedgewickWayne/WeightedQuickUnionPlusUF.py",
    "chars": 17877,
    "preview": "\"\"\"WeightedQuickUnionUF, weighted to avoid tall trees with path compression.\"\"\"\n\nfrom AlgsSedgewickWayne.BaseComp import"
  },
  {
    "path": "AlgsSedgewickWayne/WeightedQuickUnionUF.py",
    "chars": 16528,
    "preview": "\"\"\"Weighted Quick Union Algorithm takes steps to avoid tall trees.\"\"\"\n\nfrom AlgsSedgewickWayne.BaseComp import BaseComp\n"
  },
  {
    "path": "AlgsSedgewickWayne/Whitelist.py",
    "chars": 3136,
    "preview": "#!/usr/bin/env python#*****************************************************************************\n #  Compilation:  ja"
  },
  {
    "path": "AlgsSedgewickWayne/__init__.py",
    "chars": 59,
    "preview": "\"\"\"Initialize the AlgsSedgewickWayne Top-level package.\"\"\"\n"
  },
  {
    "path": "AlgsSedgewickWayne/digraph_dvk.py",
    "chars": 1742,
    "preview": "\"\"\"A directed graph, implemented using an array of lists. Parallel edges & self-loops permitted.\"\"\"\n\n__copyright__ = 'Co"
  },
  {
    "path": "AlgsSedgewickWayne/directed_dfs.py",
    "chars": 1371,
    "preview": "\"\"\"Depth-First-Search to determine vertices reachable given a source vertix(s)\"\"\"\n\n\nclass DirectedDFS:\n    \"\"\"Depth-Firs"
  },
  {
    "path": "AlgsSedgewickWayne/knuth_shuffle.py",
    "chars": 4936,
    "preview": "\"\"\"Shuffling using Knuth shuffle\"\"\"\n\nfrom random import randint\n\ndef shuffle(arr):\n    \"\"\"Rearranges an array, a, of obj"
  },
  {
    "path": "AlgsSedgewickWayne/makefile",
    "chars": 234,
    "preview": "\n# Example from Algs1, Programming Assignment #2\nwk2_subset:\n\techo A B C D E F G H I | Subset.py 3\n\techo AA BB BB BB BB "
  },
  {
    "path": "AlgsSedgewickWayne/nfa_dvk.py",
    "chars": 5786,
    "preview": "\"\"\"Initializes the NFA from the specified regular expression\"\"\"\n# pylint: disable=invalid-name\n\nfrom AlgsSedgewickWayne."
  },
  {
    "path": "AlgsSedgewickWayne/notes_Search_Problems.txt",
    "chars": 15919,
    "preview": "#---------------------------------------------------------------------------------\n# Search Problems (10:56)\n\n# Satisfia"
  },
  {
    "path": "AlgsSedgewickWayne/plt_regex_graph.py",
    "chars": 1854,
    "preview": "\"\"\"Create plot of regex NFA state machine and write into a png file\"\"\"\n\nimport pydot\n\ndef plt_nfa(fout_png, nfa):\n    \"\""
  },
  {
    "path": "AlgsSedgewickWayne/pylintrc",
    "chars": 12474,
    "preview": "[MASTER]\n\n# Specify a configuration file.\n#rcfile=\n\n# Python code to execute, usually for sys.path manipulation such as\n"
  },
  {
    "path": "AlgsSedgewickWayne/substrsrc_bruteforce.py",
    "chars": 1053,
    "preview": "\"\"\"Brute-force substring search using brute-force.\n\n\"Fine in many contexts and actually is the one Java's indexOf uses\n "
  },
  {
    "path": "AlgsSedgewickWayne/substrsrc_bruteforce_alt.py",
    "chars": 1157,
    "preview": "\"\"\"Brute-force substring search using the alternate brute-force implementation.\n\ni points to end of sequence of already-"
  },
  {
    "path": "AlgsSedgewickWayne/testcode/ArrayHistory.py",
    "chars": 11076,
    "preview": "\"\"\"A module for helping to visualize array sorting.\"\"\"\n\n# Copyright (C) 2014-2019, DV Klopfenstein\n#\n# This program is f"
  },
  {
    "path": "AlgsSedgewickWayne/testcode/InputArgs.py",
    "chars": 3286,
    "preview": "\"\"\"Get input from STDIN or from text\"\"\"\n\nimport sys\nimport os\nimport fileinput\nimport re\n\n\ndef cli_get_array(seqstr=None"
  },
  {
    "path": "AlgsSedgewickWayne/testcode/__init__.py",
    "chars": 40,
    "preview": "\"\"\"Initialize the subpackage, tests.\"\"\"\n"
  },
  {
    "path": "AlgsSedgewickWayne/testcode/binary_heaps.py",
    "chars": 1510,
    "preview": "\"\"\"Utilities for Binary Heaps.\"\"\"\n\nimport sys\nfrom AlgsSedgewickWayne.testcode.InputArgs import cli_get_array\nfrom AlgsS"
  },
  {
    "path": "AlgsSedgewickWayne/testcode/chaining_table.py",
    "chars": 359,
    "preview": "\nimport sys\n\ndef prt_chaining_symtbl(st):\n  prt = sys.stdout\n  prt.write(\"INNARDS OF SEPARATE CHAINING SYMBOL TABLE:\\n\")"
  },
  {
    "path": "AlgsSedgewickWayne/testcode/order.py",
    "chars": 768,
    "preview": "#!/usr/bin/env python\n\nimport sys\n\ndef run_277853s():\n  N = 1\n  while N<16384:\n    run_277853(N)\n    N = N*2\n\ndef run_27"
  },
  {
    "path": "AlgsSedgewickWayne/testcode/utils.py",
    "chars": 5660,
    "preview": "\"\"\"Visualizations\"\"\"\n\n__copyright__ = 'Copyright (C) 2016-present, DV Klopfenstein, PhD. All rights reserved'\n__author__"
  },
  {
    "path": "AlgsSedgewickWayne/utils.py",
    "chars": 775,
    "preview": "\"\"\"Utilities for running/checking algorithms.\"\"\"\n\n# ------------------------------------------------------------\n# Used "
  },
  {
    "path": "LICENSE",
    "chars": 18025,
    "preview": "GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundati"
  },
  {
    "path": "README.md",
    "chars": 16674,
    "preview": "# [Princeton University's \"Algorithms and Clients\"](doc/README.md)\n## by Robert Sedgewick, Kevin Wayne\n  \nImplemented in"
  },
  {
    "path": "doc/README.md",
    "chars": 9378,
    "preview": "# Schedule\nNote: There are no Programming Assignment Solutions on this site.\n\n  * [Algorithms I on Coursera](#algorithms"
  },
  {
    "path": "doc/README_Analysis_of_Algorithms.md",
    "chars": 7081,
    "preview": "# Analysis of Algorithms\n  * [Order of Growth Examples](#order-of-growth-examples)\n  * [Memory Examples](#memory-example"
  },
  {
    "path": "doc/README_BST.md",
    "chars": 356,
    "preview": "# [Binary Search Trees](http://algs4.cs.princeton.edu/32bst/)\n\n## Code\n  * **[2-3 Search Trees](http://algs4.cs.princeto"
  },
  {
    "path": "doc/README_BST_geom.md",
    "chars": 507,
    "preview": "# Geometric Applications of BSTs\n\n## Code\n  * **1d Range Search**    \n    Get *1d range count* using **size** function: "
  },
  {
    "path": "doc/README_Data_Compression.md",
    "chars": 2086,
    "preview": "# Data Compression\n\n## Code\n  * **Introduction to Data Compression**\n  * **Run-Length Coding**: RunLength.py\n  * **Huffm"
  },
  {
    "path": "doc/README_Directed_Graphs.md",
    "chars": 6225,
    "preview": "# [Directed Graphs](http://algs4.cs.princeton.edu/42digraph)\n\n## Code\n  * [Digraph.py](../py/AlgsSedgewickWayne/Digraph."
  },
  {
    "path": "doc/README_ElemSymbolTbls.md",
    "chars": 1064,
    "preview": "# [Elementary Symbol Tables](http://algs4.cs.princeton.edu/31elementary/)\n\n## Code\n  1. **Symbol Table API**     \n    * "
  },
  {
    "path": "doc/README_Elementary_Sorts.md",
    "chars": 62861,
    "preview": "# Stacks and Queues\n\n## Code\n  * [Selection Sort](../py/AlgsSedgewickWayne/Selection.py)\n  * [Insertion Sort](../py/Algs"
  },
  {
    "path": "doc/README_HashTables.md",
    "chars": 770,
    "preview": "# [Hash Tables](http://algs4.cs.princeton.edu/34hash/)\n\n## Code\n  * **hash functions**\n    Example hash implementation i"
  },
  {
    "path": "doc/README_Intractability.md",
    "chars": 3177,
    "preview": "# Intractability\n\n## Code\n  * **Introduction to Intractability**\n  * **Search Problems**\n  * **P vs. NP**\n  * **Classify"
  },
  {
    "path": "doc/README_Intractability_details.md",
    "chars": 137,
    "preview": "# Intractability\n\n## Definitions:\n  * A computational problem is **intractable** if and only if it cannot be solved in p"
  },
  {
    "path": "doc/README_Linear_Programming.md",
    "chars": 6360,
    "preview": "# Linear Programming\n\n## Code\n  * **Brewer's Problem**\n  * **Simplex Algorithm**\n  * **Simplex Implementations**: Linear"
  },
  {
    "path": "doc/README_Maximum_Flow_and_Minimum_Cut.md",
    "chars": 12095,
    "preview": "# [Maximum Flow and Minimum Cut](http://algs4.cs.princeton.edu/64maxflow)\n\n## Code\n  * **Introduction to Mincut and Maxf"
  },
  {
    "path": "doc/README_Mergesort.md",
    "chars": 6094,
    "preview": "# Mergesort\n\n## Code\n  * [Merge](../py/AlgsSedgewickWayne/Merge.py) => Top-down Mergesort\n  * MergeX => Top-down Mergeso"
  },
  {
    "path": "doc/README_Minimum_Spanning_Trees.md",
    "chars": 9288,
    "preview": "# [Minimum Spanning Trees](http://algs4.cs.princeton.edu/43mst)\n\n## Code\n  * **Introduction to MSTs** \n    [Applications"
  },
  {
    "path": "doc/README_PriorityQueues.md",
    "chars": 2046,
    "preview": "# Priority Queues\nRemove the **largest** (or **smallest**) item.\n\n## Code\n  * **API and elementary implementations**    "
  },
  {
    "path": "doc/README_Quicksort.md",
    "chars": 2704,
    "preview": "# Quicksort\n\n## Code\n  * [Quick](../py/AlgsSedgewickWayne/Quick.py)\n  * [Quick3way](../py/AlgsSedgewickWayne/Quick3way.p"
  },
  {
    "path": "doc/README_Radix_Sorts.md",
    "chars": 2168,
    "preview": "# [Radix Sorts](http://algs4.cs.princeton.edu/51radix)\n\n## Code\n  * **Strings in Java**\n  * **Key-Indexed Counting**\n  *"
  },
  {
    "path": "doc/README_Reductions.md",
    "chars": 4323,
    "preview": "# [Reductions](http://algs4.cs.princeton.edu/65reductions)\n\n## Code\n  * **Introduction to Reductions**\n  * **Designing A"
  },
  {
    "path": "doc/README_Regular_Expressions.md",
    "chars": 2118,
    "preview": "# Regular Expressions\n\n## Code\n  * **Regular Expressions**\n  * **REs (Regular Expression) and NFAs (Nondeterministic Fin"
  },
  {
    "path": "doc/README_Shortest_Paths.md",
    "chars": 8068,
    "preview": "# [Shortest Paths](http://algs4.cs.princeton.edu/44sp)\n\n## Code     \n[summary](README_analysis_summary.md#single-source-"
  },
  {
    "path": "doc/README_StacksQueues.md",
    "chars": 1938,
    "preview": "# Stacks and Queues\n\n## Code\n  * [Stack](../py/AlgsSedgewickWayne/Stack.py)\n  * [ResizingArrayStack.py](../py/AlgsSedgew"
  },
  {
    "path": "doc/README_Substring_Search.md",
    "chars": 2919,
    "preview": "# [Substring Search](http://algs4.cs.princeton.edu/53substring)\n\n## Code\n  * **Introduction to Substring Search**\n  * **"
  },
  {
    "path": "doc/README_Tries.md",
    "chars": 1696,
    "preview": "# [Tries](http://algs4.cs.princeton.edu/52trie) from re**trie**val, but pronounced \"try\"    \n\n## Code\n  * **R-way Tries*"
  },
  {
    "path": "doc/README_Undirected_Graphs.md",
    "chars": 9928,
    "preview": "# [Undirected Graphs](http://algs4.cs.princeton.edu/41graph/)\n\n## Code\n  * [Graph.py](../py/AlgsSedgewickWayne/Graph.py)"
  },
  {
    "path": "doc/README_Union_Find.md",
    "chars": 5820,
    "preview": "# QuickUnion\n\n## Code\n  * [QuickFindUF.py](../py/AlgsSedgewickWayne/QuickFindUF.py)\n  * [QuickUnionUF.py](../py/AlgsSedg"
  },
  {
    "path": "doc/README_analysis_summary.md",
    "chars": 3774,
    "preview": "# Implementations Summary\n\n  * [**Sorting Summary**](#sorting-summary)\n  * [**ST(Search Tree) implementations**](#stsear"
  },
  {
    "path": "doc/discussions.txt",
    "chars": 1600,
    "preview": "# --------------------------------------------------------------\nKevin WayneINSTRUCTOR· 2015\nFrom the Q+A.\n\nQ. Does Dijk"
  },
  {
    "path": "doc/scratchpad/Interview_Questions.txt",
    "chars": 2300,
    "preview": "----------------------------------------------------------------\nQuestion 1\nSocial network connectivity. Given a social "
  },
  {
    "path": "doc/scratchpad/PQ_doc.txt",
    "chars": 3655,
    "preview": "#!/usr/bin/env python\n\n# 8 - 1 - APIs and Elementary Implementations (12-52)\n# \n# * API and elementary implementations ("
  },
  {
    "path": "doc/scratchpad/lec10.txt",
    "chars": 1266,
    "preview": "# Lecture 10 - 1 - 2-3 Search Trees (16:55) at 1:05\n#\n# SYMBOL TABLE REVIEW\n# -------------+---------------------------+"
  },
  {
    "path": "doc/scratchpad/lecture_week3_Sorting_Complexity.txt",
    "chars": 6266,
    "preview": "#-----------------------------------------------------------------------\nSORTING COMPLEXITY\n\n00:18 COMPLEXITY OF SORTING"
  },
  {
    "path": "doc/scratchpad/notes",
    "chars": 1058,
    "preview": "#############################################################################333333\n# Lecture Week 1 \"Theory of Algorith"
  },
  {
    "path": "doc/scratchpad/notes.txt",
    "chars": 751,
    "preview": "# Which is more important if one wants to become a good programmer, algorithms or programming language principles?\n\n## J"
  },
  {
    "path": "doc/scratchpad/oog1.py",
    "chars": 754,
    "preview": "#!/usr/bin/python\n\n# (seed = 435338)\n# What is the order of growth of the worst case running time of the following code "
  },
  {
    "path": "doc/scratchpad/wk1_ex_AnalysisOfAlgorithms_Q2.py",
    "chars": 5560,
    "preview": "#!/usr/bin/env python\n\n# https://class.coursera.org/algs4partI-005/quiz/attempt?quiz_id=141\n# Algorithms, Part 1 \n# by K"
  },
  {
    "path": "doc/scratchpad/wk1_ex_q2.py",
    "chars": 694,
    "preview": "#!/usr/bin/env python\n\nimport sys\nimport time\n\ndef runit(N):\n  # What is the order of growth of the worst case running t"
  },
  {
    "path": "doc/scratchpad/wk2.txt",
    "chars": 1136,
    "preview": "###############################################################\nAlg1 Week 2 Lecture Sorting Introduction\n3 Different Cli"
  },
  {
    "path": "doc/video_toc.md",
    "chars": 5475,
    "preview": "# Algorithms Video Lectures): 24-part Lecture Series\nTable of Contents\n\n# PART 1\n## INTRODUCTION\n### 01_00_00 Algorithms"
  },
  {
    "path": "doc/wk1_ex_mem.txt",
    "chars": 9407,
    "preview": "###########################################################################\n# WEEK 1\n# primative types\n#   1 boolean\n#  "
  },
  {
    "path": "doc/wk1_memory",
    "chars": 604,
    "preview": "(seed = 584559)\nGiven the following definition of a MysteryBox object: \n\npublic class MysteryBox {             16       "
  },
  {
    "path": "makefile",
    "chars": 317,
    "preview": ".PHONY: py\npy:\n\tfind tests AlgsSedgewickWayne -name \\*.py\n\np:\n\tfind AlgsSedgewickWayne -name \\*.py\n\nt:\n\tfind tests -name"
  },
  {
    "path": "notebooks/.gitignore",
    "chars": 40,
    "preview": "Jupyter*Notebook.lnk\n.ipynb_checkpoints\n"
  },
  {
    "path": "notebooks/ElemSymbolTbls.ipynb",
    "chars": 4927,
    "preview": "{\n \"cells\": [\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"# [Elementary Symbol Tables](http:/"
  },
  {
    "path": "notebooks/makefile",
    "chars": 21,
    "preview": "\nclean:\n\trm -f *.png\n"
  },
  {
    "path": "py/UnorderedMaxPQ.py",
    "chars": 3721,
    "preview": "#!/usr/bin/env python\n\nclass UnorderedMaxPQ(object): # <Key extends Comparable<Key>> # 10:38\n\n  def __init__(self, capac"
  },
  {
    "path": "setup.py",
    "chars": 2228,
    "preview": "#!/usr/bin/env python\n# -*- coding: UTF-8 -*-\n\"\"\"For installing AlgsSedgewickWayne package and accompanying scripts.\"\"\"\n"
  },
  {
    "path": "tests/1Kints.txt",
    "chars": 8000,
    "preview": " 324110\n-442472\n 626686\n-157678\n 508681\n 123414\n -77867\n 155091\n 129801\n 287381\n 604242\n 686904\n-247109\n  77867\n 982455\n"
  },
  {
    "path": "tests/2Kints.txt",
    "chars": 16000,
    "preview": " 324110\n-442472\n 626686\n-157678\n 508681\n 123414\n -77867\n 155091\n 129801\n 287381\n 604242\n 686904\n-247109\n  77867\n 982455\n"
  },
  {
    "path": "tests/4Kints.txt",
    "chars": 32000,
    "preview": " 324110\n-442472\n 626686\n-157678\n 508681\n 123414\n -77867\n 155091\n 129801\n 287381\n 604242\n 686904\n-247109\n  77867\n 982455\n"
  },
  {
    "path": "tests/8Kints.txt",
    "chars": 64000,
    "preview": " 324110\n-442472\n 626686\n-157678\n 508681\n 123414\n -77867\n 155091\n 129801\n 287381\n 604242\n 686904\n-247109\n  77867\n 982455\n"
  },
  {
    "path": "tests/__init__.py",
    "chars": 19,
    "preview": "\"\"\"Test package\"\"\"\n"
  },
  {
    "path": "tests/brownian.txt",
    "chars": 103826,
    "preview": "1000\r\n 0.4391413288848957 0.569232769825693 1.933140129359508E-4 1.8570231336254684E-4 0.1 1.0 100 0 0\r\n 0.7623656598836"
  },
  {
    "path": "tests/diffusion.txt",
    "chars": 21145,
    "preview": "200\r\n 0.5000000026621 0.020000000893816157 2.0182035127897148E-10 6.776241843803062E-11 0.02 100000.0 0 0 0\r\n 0.50000000"
  },
  {
    "path": "tests/images/README_figs.md",
    "chars": 907,
    "preview": "# Plots\n* [Graphs](#graphs)\n  * [tinyG.txt](#tinygtxt)\n* [Digraphs](#digraphs)\n  * [tinyDG.txt](#tinydgtxt)\n  * [tinyDG2"
  },
  {
    "path": "tests/largeW.txt",
    "chars": 7000000,
    "preview": "489910\n 18940\n774392\n490636\n125544\n407391\n115771\n992663\n923282\n176914\n217904\n571222\n519039\n395667\n489931\n910419\n929671\n "
  },
  {
    "path": "tests/makefile",
    "chars": 366,
    "preview": "\nPKG := test_WeightedQUF_state_pics\nFNC := test_wk1_ex_166199\n\nrun:\n\tpython -c 'import $(PKG); $(PKG).$(FNC)()'\n\nssst:\n\t"
  },
  {
    "path": "tests/mediumG.txt",
    "chars": 9107,
    "preview": "250\n1273\n244 246\n239 240\n238 245\n235 238\n233 240\n232 248\n231 248\n229 249\n228 241\n226 231\n223 242\n223 249\n222 225\n220 247"
  },
  {
    "path": "tests/plot_graphs.py",
    "chars": 1068,
    "preview": "#!/usr/bin/env python3\n\"\"\"Plot tiny graph\"\"\"\n\nimport sys\nfrom os.path import join\nfrom os.path import dirname\nfrom os.pa"
  },
  {
    "path": "tests/shellsST.txt",
    "chars": 38,
    "preview": "she sells sea shells by the sea shore\n"
  },
  {
    "path": "tests/test_AcyclicSP.py",
    "chars": 1564,
    "preview": "#!/usr/bin/env python\n\"\"\"Test AcyclicSP\"\"\"\n\n#***************************************************************************"
  },
  {
    "path": "tests/test_BST.py",
    "chars": 1432,
    "preview": "#!/usr/bin/env python\n\"\"\"Test Binary Search Tree (BST).\"\"\"\n\nimport sys\nfrom AlgsSedgewickWayne.BST import BST\nfrom AlgsS"
  },
  {
    "path": "tests/test_BST_sortinput.py",
    "chars": 1546,
    "preview": "#!/usr/bin/env python\n\"\"\"Test sorting of a list such that the sorted list will build a balanced BST.\"\"\"\n\nfrom sys import"
  },
  {
    "path": "tests/test_Bag.py",
    "chars": 495,
    "preview": "#!/usr/bin/env python\n\"\"\"Tests the Bag class.\"\"\"\n\nimport sys\nfrom AlgsSedgewickWayne.Bag import Bag\nfrom AlgsSedgewickWa"
  },
  {
    "path": "tests/test_BellmanFordSP.py",
    "chars": 2317,
    "preview": "#!/usr/bin/env python\n# TBD: Finish Python port\n\n#**********************************************************************"
  },
  {
    "path": "tests/test_BoyerMoore.py",
    "chars": 2225,
    "preview": "#!/usr/bin/env python\n# TBD Finish Python port\n\nimport sys\n#from AlgsSedgewickWayne.BoyerMoore import BoyerMoore\n#\n##***"
  },
  {
    "path": "tests/test_BreadthFirstPaths.py",
    "chars": 1691,
    "preview": "#!/usr/bin/env python\n\nfrom sys import stdout\nfrom sys import argv\nfrom os.path import join\nfrom os.path import dirname\n"
  },
  {
    "path": "tests/test_CC.py",
    "chars": 1617,
    "preview": "#!/usr/bin/env python\n\nimport sys\nfrom os.path import join\nfrom os.path import dirname\nfrom os.path import abspath\nfrom "
  },
  {
    "path": "tests/test_Date.py",
    "chars": 750,
    "preview": "#!/usr/bin/env python3\n\"\"\"Test Date class implementation\"\"\"\n\nimport sys\nfrom AlgsSedgewickWayne.Date import Date\n\ndef te"
  },
  {
    "path": "tests/test_DepthFirstDirectedPaths.py",
    "chars": 727,
    "preview": "#!/usr/bin/env python\n\nimport sys\nfrom AlgsSedgewickWayne.Digraph import Digraph\nfrom AlgsSedgewickWayne.DepthFirstDirec"
  },
  {
    "path": "tests/test_DepthFirstPaths.py",
    "chars": 510,
    "preview": "#!/usr/bin/env python\n\nfrom AlgsSedgewickWayne.testcode.utils  import adjtxtblk2arr_ud\nfrom AlgsSedgewickWayne.Graph    "
  },
  {
    "path": "tests/test_DepthFirstSearch.py",
    "chars": 2042,
    "preview": "#!/usr/bin/env python3\n\"\"\"Unit tests DepthFirstSearch data type\"\"\"\n\nimport sys\nfrom os.path import join\nfrom os.path imp"
  },
  {
    "path": "tests/test_Deque.py",
    "chars": 1257,
    "preview": "#!/usr/bin/env python\n\n#import sys\n#from AlgsSedgewickWayne.Deque import Deque\n#\n#def test_2a(prt=sys.stdout):\n#  deque "
  },
  {
    "path": "tests/test_Digraph.py",
    "chars": 798,
    "preview": "#!/usr/bin/env python\n\nimport sys\nfrom os.path import join\nfrom os.path import dirname\nfrom os.path import abspath\nfrom "
  },
  {
    "path": "tests/test_DijkstraSP.py",
    "chars": 2029,
    "preview": "#!/usr/bin/env python\n\n#*****************************************************************************\n #  Compilation:  "
  },
  {
    "path": "tests/test_DirectedDFS.py",
    "chars": 1827,
    "preview": "#!/usr/bin/env python\n\"\"\"Determine single-source or multiple-source reachability in a digraph\"\"\"\n#pylint: disable=invali"
  },
  {
    "path": "tests/test_DirectedEdge.py",
    "chars": 223,
    "preview": "#!/usr/bin/env python\n\nfrom AlgsSedgewickWayne.DirectedEdge import DirectedEdge\nimport sys\n\ndef main(prt=sys.stdout):\n  "
  },
  {
    "path": "tests/test_Edge.py",
    "chars": 756,
    "preview": "#!/usr/bin/env python\n\"\"\"Unit tests the Edge data type\"\"\"\n# pylint: disable=invalid-name\n\nfrom sys import stdout\nfrom Al"
  },
  {
    "path": "tests/test_EdgeWeightedDigraph.py",
    "chars": 285,
    "preview": "#!/usr/bin/env python\n\n#from AlgsSedgewickWayne.EdgeWeightedDigraph as EdgeWeightedDigraph\nimport sys\n\ndef main(prt=sys."
  },
  {
    "path": "tests/test_EdgeWeightedDirectedCycle.py",
    "chars": 1770,
    "preview": "#/usr/bin/env python\n# TBD: Finish Python port\n\n#***********************************************************************"
  },
  {
    "path": "tests/test_EdgeWeightedGraph.py",
    "chars": 892,
    "preview": "#!/usr/bin/env python\n\nimport sys\nfrom AlgsSedgewickWayne.EdgeWeightedGraph import EdgeWeightedGraph\nfrom AlgsSedgewickW"
  }
]

// ... and 555 more files (download for full content)

About this extraction

This page contains the full source code of the dvklopfenstein/PrincetonAlgorithms GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 755 files (93.1 MB), approximately 16.4M tokens, and a symbol index with 1132 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!