# worstCase.py
# Compare computational complexity for 
# Binary and Exhaustive Search
from Processing import *
from names import names

window(500, 500)

def runExperiment():
    h, w = height(), width()

    # Draw axes for chart
    drawAxes()

    # Repeat for list sizes from 10 to 3830
    noStroke()
    max = 10
    while max <= 3830:

        # Choose 10 random names and search for each
        for j in range(10):
            rand = int(random(max))
            rname = names[rand]

            # Peform Exhaustive search and plot
            scale = 0.1
            count1 = eSearch(rname, names, max)
            fill(0,0,255)
            ellipse(50.0+max*0.1, h - count1*scale-50.0, 3, 3)

            # Perform Binary search and plot
            #scale = 0.1
            scale = 20
            count2 = bSearch(rname, names, max)
            fill(255,0,0)
            ellipse(50.0+max*0.1, h - count2*scale-50.0, 3, 3)

        max += 10

# Draw axes for plot
def drawAxes():
    h, w = height(), width()
    background(0)
    stroke(200)
    line(50,h-50,w-50,h-50)
    line(50,h-50,50,50)
    fill(255)
    textAlign(CENTER, CENTER)
    textSize(20)
    text("List Size vs. Search Iterations", 0, 10, w, 30)
    text("Binary vs. Exhaustive Search", 0, 40, w, 30)

# Search for a matching String val in the array vals.
# If found, return index. If not found, return None.
def eSearch(val, items, max):
    count = 0

    # Loop over all items in the list
    i = 0
    while i < max:
        count += 1

        # Compare items
        if val == items[i]:
            return count
        i += 1

    # If we get this far, val was not found.
    return None

# Search for a matching val in items
# If found, return index. If not found, return None
# Use binary search.
def bSearch(val, items, max):
    mid, min, count = 0, 0, 0
    #max = len(items)-1

    while min <= max:
        count += 1                              # Track iterations
        mid = int((max + min) / 2.0)            # Compute next index
        #print("[" + str(min) + ", " + str(max) + "] --> " + str(mid))

        if val == items[mid]:                   # Found it
            #print(str(val) + " found at index " + str(mid) + " (" + str(count) + " iterations)")
            #return mid
            return count                        # Return number of iterations
        elif val < items[mid]:                  # val is before items[mid]
            max = mid - 1                       # Reset max to item before mid
        else:                                   # val is after items[mid]
            min = mid + 1                       # Reset min to item after mid

    # If we get this far, val was not found.
    #print(str(val) + " not found in " + str(count) + " iterations")
    return None

# Perform the experiment and plot the results
runExperiment()
