Date

Lecture Date: Friday, November 18

Okay, computer scientists! I've got two new algorithms for you! Let's see if we can code them up and figure out what the complexity is!

I call them yolo_search and yolo_sort.

Here's the pseudocode for yolo_search:

while(I haven't picked the number I'm looking for yet) {
    pick a number at random from the list
}

We can even do advanced_yolo_search!

make a copy of my list
while(I haven't picked the number I'm looking for yet) {
    pick a number at random from the list
    if it's not the number {
        delete it from the list
    }
}

There's a slight problem with this algorithm. Every time we delete something from the list, all the indices change... so if we are looking for a particular index, this doesn't work. If we are looking for a particular item from the list, it works fine.

What's the complexity of these two searching algorithms? How do we know? Can we code them up?

Let's take a look at yolo_sort now:

while(the list isn't in order) {
    shuffle the list
}

How about this one? What's the complexity? How can we code it up? How long will it take to run?

import random

def check_list_order(list_to_verify):
    index = 0
    while index < len(list_to_verify) - 1:
        if list_to_verify[index] > list_to_verify[index + 1]:
            return False
        index += 1
    return True


def yolo_search(list_to_search, item_to_find):
    steps = 1
    random_index = random.randint(0,len(list_to_search)-1)
    while list_to_search[random_index] != item_to_find:
        random_index = random.randint(0, len(list_to_search) - 1)
        steps += 1

    return random_index, steps


def advanced_yolo_search(list_to_search, item_to_find):
    temp_list = list_to_search.copy()
    steps = 1
    random_index = random.randint(0, len(temp_list) - 1)
    while len(temp_list) > 1:
        steps += 1
        if temp_list[random_index] != item_to_find:
            del temp_list[random_index]
            random_index = random.randint(0, len(temp_list) - 1)
        else:
            return temp_list[random_index], steps

    return "Not here!", steps



def yolo_sort(list_to_sort):
    temp_list = list_to_sort.copy()
    steps = 1
    while not check_list_order(temp_list):
        random.shuffle(temp_list)
        steps += 1
    return temp_list, steps



def bubble_sort(list_to_sort):
    steps = 1
    temp_list = list_to_sort.copy()
    for i in range(len(temp_list)):
        for j in range(i+1, len(temp_list)):
            steps += 1
            if temp_list[j] < temp_list[i]:
                temp_list[j], temp_list[i] = temp_list[i], temp_list[j]

    return temp_list, steps


# Using the min function is slightly cheating as 
# it optimizes a bit more than what we did in class
def selection_sort(list_to_sort):
    steps = 1
    temp_list = list_to_sort.copy()
    for i in range(len(temp_list)):
        steps += 1
        mini = min(temp_list[i:])
        min_index = temp_list[i:].index(mini)
        temp_list[i + min_index] = temp_list[i]
        temp_list[i] = mini

    return temp_list, steps


my_list = [4,5,2,3,7,9,6,1,8]
short_list = [3,2,1]

print("yolo_search", yolo_search(my_list, 8))
print("advanced_yolo_search",advanced_yolo_search(my_list,8))
print("advanced_yolo_search",advanced_yolo_search(my_list,10))
print("yolo_sort",yolo_sort(my_list))
print("bubble_sort", bubble_sort(my_list))
print("selection_sort", selection_sort(my_list))