mirror of
https://github.com/autistic-symposium/master-algorithms-py.git
synced 2025-05-23 08:51:31 -04:00
reorganize dir
Signed-off-by: Mia Steinkirch <mia.steinkirch@gmail.com>
This commit is contained in:
parent
1b6f705e7c
commit
a8e71c50db
276 changed files with 23954 additions and 0 deletions
35
other_resources/interview_cake/bitwise_stuff/clean_bit.py
Normal file
35
other_resources/interview_cake/bitwise_stuff/clean_bit.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
''' Clear a bit in a binary number.
|
||||
Like the reverse of set bit:
|
||||
1) first create a number filled of 1s,
|
||||
with 0 at i (can create 0001000 and ~)
|
||||
2) AND the number so it clears the ith bit
|
||||
'''
|
||||
|
||||
|
||||
|
||||
def clear_bit(num, i):
|
||||
mask = ~ (1 << i) # -0b10001
|
||||
return bin(num & mask)
|
||||
|
||||
|
||||
def clear_all_bits_from_i_to_0(num, i):
|
||||
mask = ~ ( (1 << (i+1)) - 1)
|
||||
return bin(num & mask)
|
||||
|
||||
|
||||
def clear_all_bits_from_most_sig_to_1(num, i):
|
||||
mask = ( 1 << i) -1
|
||||
return bin(num & mask)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
num = int('10010000', 2)
|
||||
print clear_bit(num, 4) # '0b10000000'
|
||||
|
||||
num = int('10010011', 2)
|
||||
print clear_all_bits_from_i_to_0(num, 2) # '0b10010000'
|
||||
|
||||
num = int('1110011', 2)
|
||||
print clear_all_bits_from_most_sig_to_1(num, 2) #'0b11'
|
37
other_resources/interview_cake/bitwise_stuff/count_bits.py
Normal file
37
other_resources/interview_cake/bitwise_stuff/count_bits.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
''' This method returns the number of bits that are necessary to change to convert two
|
||||
numbers A and B:
|
||||
1) XOR
|
||||
2) count 1s
|
||||
'''
|
||||
|
||||
def count_bits_swap2(a, b):
|
||||
count = 0
|
||||
m = a^b
|
||||
while m:
|
||||
count +=1
|
||||
m = m & (m-1)
|
||||
return count
|
||||
|
||||
|
||||
|
||||
def count_bits_swap(a, b):
|
||||
m = a^b
|
||||
return count_1s(m)
|
||||
|
||||
|
||||
def count_1s(m):
|
||||
count = 0
|
||||
while m:
|
||||
if m& 1 :
|
||||
count +=1
|
||||
m >>= 1
|
||||
return count
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
a = int('10010000', 2)
|
||||
b = int('01011010', 2)
|
||||
print count_bits_swap(a, b) #4
|
||||
print count_bits_swap2(a, b) #4
|
20
other_resources/interview_cake/bitwise_stuff/get_bit.py
Normal file
20
other_resources/interview_cake/bitwise_stuff/get_bit.py
Normal file
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/python
|
||||
''' Set a bit in a binary number:
|
||||
1) Shifts 1 over by i bits
|
||||
2) make an OR with the number, only the value at bit i will change and all the others bit
|
||||
of the mask are zero so will not affect the num
|
||||
|
||||
'''
|
||||
def set_bit(num, i):
|
||||
mask = 1 << i
|
||||
return bin( num | mask )
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
num = int('0100100', 2)
|
||||
print set_bit(num, 0) #'0b100101'
|
||||
print set_bit(num, 1) #'0b100110'
|
||||
print set_bit(num, 2) # nothing change '0b100100'
|
||||
print set_bit(num, 3) #'0b101100'
|
||||
print set_bit(num, 4) #'0b110100'
|
||||
print set_bit(num, 5) # nothing change '0b100100'
|
19
other_resources/interview_cake/bitwise_stuff/update_bit.py
Normal file
19
other_resources/interview_cake/bitwise_stuff/update_bit.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
''' This method merges set bit and clean bit:
|
||||
1) first clear the bit at i using a mask such as 1110111
|
||||
2) then shift the intended value v by i bits
|
||||
3) this will create a number with bit i to v and all other to 0
|
||||
4) finally update the ith bit with or
|
||||
'''
|
||||
|
||||
|
||||
|
||||
def update_bit(num, i, v):
|
||||
mask = ~ (1 << i)
|
||||
return bin( (num & mask) | (v << i) )
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
num = int('10010000', 2)
|
||||
print update_bit(num, 2, 1) # '0b10010100'
|
37
other_resources/interview_cake/data_structures/angry_bird.py
Normal file
37
other_resources/interview_cake/data_structures/angry_bird.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
#!/bin/python
|
||||
|
||||
"""
|
||||
Each round, players receive a score between 0 and 100, which you use to rank them from highest to lowest. So far you're using an algorithm that sorts in O(n\lg{n})O(nlgn) time, but players are complaining that their rankings aren't updated fast enough. You need a faster sorting algorithm.
|
||||
|
||||
Write a function that takes:
|
||||
|
||||
a list of unsorted_scores
|
||||
the highest_possible_score in the game
|
||||
and returns a sorted list of scores in less than O(n\lg{n})O(nlgn) time.
|
||||
"""
|
||||
|
||||
def sort_scores(unsorted_scores, highest_score):
|
||||
|
||||
score_counts = [0] * (highest_score+1)
|
||||
|
||||
for score in unsorted_scores:
|
||||
score_counts[score] += 1
|
||||
|
||||
sorted_scores = []
|
||||
|
||||
for score in range(len(score_counts)-1, -1, -1):
|
||||
count = score_counts[score]
|
||||
|
||||
for i in range(count):
|
||||
sorted_scores.append(score)
|
||||
|
||||
return sorted_scores
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
unsorted_scores = [37, 89, 41, 65, 91, 53]
|
||||
HIGHEST_POSSIBLE_SCORE = 100
|
||||
|
||||
print sort_scores(unsorted_scores, HIGHEST_POSSIBLE_SCORE)
|
|
@ -0,0 +1,76 @@
|
|||
#!/bin/python
|
||||
|
||||
"""
|
||||
Write a function that returns a list of all the duplicate files.
|
||||
|
||||
the first item is the duplicate file
|
||||
the second item is the original file
|
||||
For example:
|
||||
|
||||
[('/tmp/parker_is_dumb.mpg', '/home/parker/secret_puppy_dance.mpg'),
|
||||
('/home/trololol.mov', '/etc/apache2/httpd.conf')]
|
||||
You can assume each file was only duplicated once.
|
||||
"""
|
||||
|
||||
import os
|
||||
import hashlib
|
||||
|
||||
def find_duplicate_files(starting_directory):
|
||||
files_seen_already = {}
|
||||
stack = [starting_directory]
|
||||
|
||||
duplicates = []
|
||||
|
||||
while len(stack):
|
||||
current_path = stack.pop()
|
||||
|
||||
if os.path.isdir(current_path):
|
||||
for path in os.listdir(current_path):
|
||||
full_path = os.path.join(current_path, path)
|
||||
stack.append(full_path)
|
||||
|
||||
else:
|
||||
file_hash = sample_hash_file(current_path)
|
||||
|
||||
current_last_edited_time = os.path.getmtime(current_path)
|
||||
|
||||
if file_hash in files_seen_already:
|
||||
existing_last_edited_time, existing_path = files_seen_already[file_hash]
|
||||
if current_last_edited_time > existing_last_edited_time:
|
||||
|
||||
duplicates.append((current_path, existing_path))
|
||||
else:
|
||||
|
||||
duplicates.append((existing_path, current_path))
|
||||
files_seen_already[file_hash] = (current_last_edited_time, current_path)
|
||||
|
||||
else:
|
||||
files_seen_already[file_hash] = (current_last_edited_time, current_path)
|
||||
|
||||
return duplicates
|
||||
|
||||
|
||||
def sample_hash_file(path):
|
||||
num_bytes_to_read_per_sample = 4000
|
||||
total_bytes = os.path.getsize(path)
|
||||
hasher = hashlib.sha512()
|
||||
|
||||
with open(path, 'rb') as file:
|
||||
|
||||
if total_bytes < num_bytes_to_read_per_sample * 3:
|
||||
hasher.update(file.read())
|
||||
else:
|
||||
num_bytes_between_samples = (
|
||||
(total_bytes - num_bytes_to_read_per_sample * 3) / 2
|
||||
)
|
||||
|
||||
for offset_multiplier in range(3):
|
||||
start_of_sample = (
|
||||
offset_multiplier
|
||||
* (num_bytes_to_read_per_sample + num_bytes_between_samples)
|
||||
)
|
||||
file.seek(start_of_sample)
|
||||
sample = file.read(num_bytes_to_read_per_sample)
|
||||
hasher.update(sample)
|
||||
|
||||
return hasher.hexdigest()
|
|
@ -0,0 +1,42 @@
|
|||
#!/bin/python
|
||||
|
||||
"""
|
||||
Users on longer flights like to start a second movie right when their first one ends,
|
||||
but they complain that the plane usually lands before they can see the ending.
|
||||
So you're building a feature for choosing two movies whose total runtimes will equal the exact flight length.
|
||||
|
||||
Write a function that takes an integer flight_length (in minutes) and a
|
||||
list of integers movie_lengths (in minutes) and returns a boolean indicating
|
||||
whether there are two numbers in movie_lengths whose sum equals flight_length.
|
||||
|
||||
When building your function:
|
||||
|
||||
Assume your users will watch exactly two movies
|
||||
Don't make your users watch the same movie twice
|
||||
Optimize for runtime over memory
|
||||
"""
|
||||
|
||||
def is_there_two_movies(flight_length, movie_lengths):
|
||||
movie_lengths_seen = set()
|
||||
|
||||
for first_movie_length in movie_lengths:
|
||||
matching_second_movie_length = flight_length - first_movie_length
|
||||
if matching_second_movie_length in movie_lengths_seen:
|
||||
return True
|
||||
movie_lengths_seen.add(first_movie_length)
|
||||
|
||||
return False
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
flight_length = 10
|
||||
|
||||
movie_lengths = [2, 4, 7]
|
||||
print(is_there_two_movies(flight_length, movie_lengths))
|
||||
print("Should be True")
|
||||
|
||||
movie_lengths = [5, 6, 7, 8]
|
||||
print(is_there_two_movies(flight_length, movie_lengths))
|
||||
print("Should be False")
|
27
other_resources/interview_cake/math/apple_stocks.py
Normal file
27
other_resources/interview_cake/math/apple_stocks.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
#!/bin/python
|
||||
|
||||
"""
|
||||
Grab Apple's stock prices and put them in a list called stock_prices, where:
|
||||
|
||||
The indices are the time (in minutes) past trade opening time, which was 9:30am local time.
|
||||
The values are the price (in US dollars) of one share of Apple stock at that time.
|
||||
So if the stock cost $500 at 10:30am, that means stock_prices[60] = 500.
|
||||
|
||||
Write an efficient function that takes stock_prices and returns the best profit I could have made from one purchase and one sale of one share.
|
||||
"""
|
||||
|
||||
def apple_stock_profit(stock_prices):
|
||||
|
||||
min_s, max_s = max(stock_prices), 0
|
||||
|
||||
while stock_prices:
|
||||
stock = stock_prices.pop()
|
||||
min_s = min(min_s, stock)
|
||||
max_s = max(max_s, stock)
|
||||
|
||||
return max_s - min_s
|
||||
|
||||
|
||||
stock_prices = [10, 7, 5, 8, 11, 9]
|
||||
print apple_stock_profit(stock_prices)
|
||||
print("Should return 6 (buying for $5 and selling for $11)")
|
36
other_resources/interview_cake/math/fib.py
Normal file
36
other_resources/interview_cake/math/fib.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
#!/bin/python
|
||||
|
||||
"""
|
||||
Write a function fib() that takes an integer nn and returns the nnth Fibonacci number.
|
||||
"""
|
||||
|
||||
# this is O(2^n)
|
||||
def fib(n):
|
||||
if n in [1, 0]:
|
||||
return n
|
||||
return fib(n - 1) + fib(n - 2)
|
||||
|
||||
|
||||
print fib(10)
|
||||
|
||||
|
||||
# this is O(n)
|
||||
def fib(n):
|
||||
if n < 0:
|
||||
raise ValueError('Index was negative. No such thing as a '
|
||||
'negative index in a series.')
|
||||
elif n in [0, 1]:
|
||||
return n
|
||||
|
||||
prev_prev = 0 # 0th fibonacci
|
||||
prev = 1 # 1st fibonacci
|
||||
|
||||
for _ in range(n - 1):
|
||||
current = prev + prev_prev
|
||||
prev_prev = prev
|
||||
prev = current
|
||||
|
||||
return current
|
||||
|
||||
|
||||
print fib(10)
|
38
other_resources/interview_cake/math/find_dup.py
Normal file
38
other_resources/interview_cake/math/find_dup.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
#!/bin/python
|
||||
|
||||
"""
|
||||
Find a duplicate
|
||||
We have a list of integers, where:
|
||||
The integers are in the range 1..n1..n
|
||||
The list has a length of n+1n+1
|
||||
It follows that our list has at least one integer which appears at least twice. But it may have several duplicates, and each duplicate may appear more than twice.
|
||||
|
||||
Write a function which finds an integer that appears more than once in our list. (If there are multiple duplicates, you only need to find one of them.)
|
||||
"""
|
||||
|
||||
def find_dups(num_list):
|
||||
num_dict = {}
|
||||
for n in num_list:
|
||||
if n in num_dict.keys():
|
||||
num_dict[n] += 1
|
||||
else:
|
||||
num_dict[n] = 1
|
||||
|
||||
for k,v in num_dict.items():
|
||||
if v > 1:
|
||||
print "dup is {}".format(k)
|
||||
|
||||
def find_dups_set(num_list):
|
||||
|
||||
num_set = set()
|
||||
|
||||
for n in num_list:
|
||||
if n in num_set:
|
||||
print n
|
||||
else:
|
||||
num_set.add(n)
|
||||
|
||||
|
||||
num_list = [6,1,3,7,6,4,5,2,8,5,6,6,7]
|
||||
find_dups(num_list)
|
||||
find_dups_set(num_list)
|
26
other_resources/interview_cake/math/float_bin_num.py
Normal file
26
other_resources/interview_cake/math/float_bin_num.py
Normal file
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
''' Given a real number between 0 and 1 (eg: 0.72), this method print the binary
|
||||
representation. If the Number cannot be represented accurately in binary, with at
|
||||
most 32 chars, print error:
|
||||
'''
|
||||
|
||||
def get_float_rep(num):
|
||||
if num >= 1 or num <= 0: return 'Error 1'
|
||||
result = '.'
|
||||
while num:
|
||||
if len(result) >= 32: return 'Error 2', result
|
||||
r = num*2
|
||||
if r >= 1:
|
||||
result += '1'
|
||||
num = r - 1
|
||||
else:
|
||||
result += '0'
|
||||
num = r
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print get_float_rep(0.72) #('Error 2', '.1011100001010001111010111000010')
|
||||
print get_float_rep(0.1) # ('Error 2', '.0001100110011001100110011001100')
|
||||
print get_float_rep(0.5) #'.1'
|
54
other_resources/interview_cake/math/highest_product_3_int.py
Normal file
54
other_resources/interview_cake/math/highest_product_3_int.py
Normal file
|
@ -0,0 +1,54 @@
|
|||
#!/bin/python
|
||||
|
||||
"""
|
||||
Given a list of integers, find the highest product you can get from three of the integers.
|
||||
|
||||
The input list_of_ints will always have at least three integers.
|
||||
"""
|
||||
|
||||
def highest_num(list_of_ints):
|
||||
|
||||
if len(list_of_ints) == 3:
|
||||
return list_of_ints[0]*list_of_ints[1]*list_of_ints[2]
|
||||
|
||||
sorted_list = sorted(list_of_ints)
|
||||
|
||||
return sorted_list[-3]*sorted_list[-2]*sorted_list[-1]
|
||||
|
||||
|
||||
def highest_product_of_3_On(list_of_ints):
|
||||
|
||||
highest = max(list_of_ints[0], list_of_ints[1])
|
||||
lowest = min(list_of_ints[0], list_of_ints[1])
|
||||
highest_product_of_2 = list_of_ints[0] * list_of_ints[1]
|
||||
lowest_product_of_2 = list_of_ints[0] * list_of_ints[1]
|
||||
|
||||
highest_product_of_3 = list_of_ints[0] * list_of_ints[1] * list_of_ints[2]
|
||||
|
||||
for i in range(2, len(list_of_ints)):
|
||||
current = list_of_ints[i]
|
||||
|
||||
highest_product_of_3 = max(highest_product_of_3,
|
||||
current * highest_product_of_2,
|
||||
current * lowest_product_of_2)
|
||||
|
||||
highest_product_of_2 = max(highest_product_of_2,
|
||||
current * highest,
|
||||
current * lowest)
|
||||
|
||||
lowest_product_of_2 = min(lowest_product_of_2,
|
||||
current * highest,
|
||||
current * lowest)
|
||||
|
||||
highest = max(highest, current)
|
||||
|
||||
lowest = min(lowest, current)
|
||||
|
||||
return highest_product_of_3
|
||||
|
||||
list_of_ints = [4, 2, 5, 6]
|
||||
print highest_num(list_of_ints)
|
||||
print "Should be 120"
|
||||
|
||||
print highest_product_of_3_On(list_of_ints)
|
||||
print "Should be 120"
|
33
other_resources/interview_cake/math/in_place_shuffle.py
Normal file
33
other_resources/interview_cake/math/in_place_shuffle.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
#!/bin/python
|
||||
|
||||
"""
|
||||
Write a function for doing an in-place shuffle of a list.
|
||||
|
||||
The shuffle must be "uniform," meaning each item in the original list must have the same probability of ending up in each spot in the final list.
|
||||
|
||||
Assume that you have a function get_random(floor, ceiling) for getting a random integer that is >= floor and <= ceiling.
|
||||
"""
|
||||
|
||||
import random
|
||||
|
||||
def get_random(floor, ceiling):
|
||||
return random.randrange(floor, ceiling + 1)
|
||||
|
||||
def shuffle(the_list):
|
||||
|
||||
if len(the_list) <= 1:
|
||||
return the_list
|
||||
|
||||
last_index_in_the_list = len(the_list) - 1
|
||||
|
||||
for i in range(len(the_list) - 1):
|
||||
random_choice_index = get_random(i,
|
||||
last_index_in_the_list)
|
||||
if random_choice_index != i:
|
||||
the_list[i], the_list[random_choice_index] = \
|
||||
the_list[random_choice_index], the_list[i]
|
||||
|
||||
|
||||
seed_list = [5, 2, 6, 2, 6]
|
||||
shuffle(seed_list)
|
||||
print seed_list
|
38
other_resources/interview_cake/math/product_every_int.py
Normal file
38
other_resources/interview_cake/math/product_every_int.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
#!/bin/python
|
||||
|
||||
"""
|
||||
You have a list of integers, and for each index you want to find the product of every integer except the integer at that index.
|
||||
|
||||
Write a function get_products_of_all_ints_except_at_index() that takes a list of integers and returns a list of the products.
|
||||
|
||||
For example, given:
|
||||
|
||||
[1, 7, 3, 4]
|
||||
|
||||
your function would return:
|
||||
|
||||
[84, 12, 28, 21]
|
||||
|
||||
by calculating:
|
||||
|
||||
[7 * 3 * 4, 1 * 3 * 4, 1 * 7 * 4, 1 * 7 * 3]
|
||||
|
||||
Here's the catch: You can't use division in your solution!
|
||||
"""
|
||||
|
||||
def get_products_of_all_ints_except_at_index(array):
|
||||
prod_array = []
|
||||
|
||||
for i, num in enumerate(array):
|
||||
prod = 1
|
||||
for other_num in array[:i] + array[i+1:]:
|
||||
prod *= other_num
|
||||
|
||||
prod_array.append(prod)
|
||||
|
||||
return prod_array
|
||||
|
||||
|
||||
array = [1, 7, 3, 4]
|
||||
print get_products_of_all_ints_except_at_index(array)
|
||||
print "Should be [84, 12, 28, 21]"
|
32
other_resources/interview_cake/math/recursive_per.py
Normal file
32
other_resources/interview_cake/math/recursive_per.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
#!/bin/python
|
||||
|
||||
"""
|
||||
Write a recursive function for generating all permutations of an input string. Return them as a set.
|
||||
"""
|
||||
|
||||
def get_permutations(string):
|
||||
|
||||
if len(string) < 2:
|
||||
return set([string])
|
||||
|
||||
all_chars_except_last = string[:-1]
|
||||
last_char = string[-1]
|
||||
|
||||
permutations_of_all_chars_except_last = get_permutations(all_chars_except_last)
|
||||
|
||||
permutations = set()
|
||||
for permutation_of_all_chars_except_last in permutations_of_all_chars_except_last:
|
||||
for position in range(len(all_chars_except_last) + 1):
|
||||
permutation = (
|
||||
permutation_of_all_chars_except_last[:position]
|
||||
+ last_char
|
||||
+ permutation_of_all_chars_except_last[position:]
|
||||
)
|
||||
permutations.add(permutation)
|
||||
|
||||
|
||||
return permutations
|
||||
|
||||
|
||||
str = "abcd"
|
||||
print get_permutations(str)
|
70
other_resources/interview_cake/sort_and_search/big_words.py
Normal file
70
other_resources/interview_cake/sort_and_search/big_words.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
#!/bin/python
|
||||
|
||||
"""
|
||||
I want to learn some big words so people think I'm smart.
|
||||
|
||||
I opened up a dictionary to a page in the middle and started flipping through, looking for words I didn't know. I put each word I didn't know at increasing indices in a huge list I created in memory. When I reached the end of the dictionary, I started from the beginning and did the same thing until I reached the page I started at.
|
||||
|
||||
Now I have a list of words that are mostly alphabetical, except they start somewhere in the middle of the alphabet, reach the end, and then start from the beginning of the alphabet. In other words, this is an alphabetically ordered list that has been "rotated." For example:
|
||||
|
||||
words = [
|
||||
'ptolemaic',
|
||||
'retrograde',
|
||||
'supplant',
|
||||
'undulate',
|
||||
'xenoepist',
|
||||
'asymptote', # <-- rotates here!
|
||||
'babka',
|
||||
'banoffee',
|
||||
'engender',
|
||||
'karpatka',
|
||||
'othellolagkage',
|
||||
]
|
||||
|
||||
Write a function for finding the index of the "rotation point," which is where I started working from the beginning of the dictionary. This list is huge (there are lots of words I don't know) so we want to be efficient here.
|
||||
"""
|
||||
|
||||
def find_index(words):
|
||||
|
||||
for i, word in enumerate(words):
|
||||
if word[0] > words[i+1][0]:
|
||||
return i+1, words[i+1]
|
||||
|
||||
return "Not found"
|
||||
|
||||
|
||||
|
||||
def find_index_bs(words):
|
||||
first_word = words[0]
|
||||
floor_index = 0
|
||||
ceiling_index = len(words) - 1
|
||||
|
||||
while floor_index < ceiling_index:
|
||||
guess_index = floor_index + ((ceiling_index - floor_index) / 2)
|
||||
|
||||
if words[guess_index] >= first_word:
|
||||
floor_index = guess_index
|
||||
else:
|
||||
ceiling_index = guess_index
|
||||
|
||||
if floor_index + 1 == ceiling_index:
|
||||
return ceiling_index
|
||||
|
||||
|
||||
words = [
|
||||
'ptolemaic',
|
||||
'retrograde',
|
||||
'supplant',
|
||||
'undulate',
|
||||
'xenoepist',
|
||||
'asymptote',
|
||||
'babka',
|
||||
'banoffee',
|
||||
'engender',
|
||||
'karpatka',
|
||||
'othellolagkage',
|
||||
]
|
||||
|
||||
print find_index(words)
|
||||
print
|
||||
print find_index_bs(words)
|
|
@ -0,0 +1,48 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
|
||||
def binary_search(array, value):
|
||||
last, first = len(array), 0
|
||||
|
||||
while first < last:
|
||||
mid = (last - first)//2
|
||||
item = array[mid]
|
||||
|
||||
if item == value:
|
||||
return True
|
||||
|
||||
elif item < value:
|
||||
last = mid
|
||||
|
||||
else:
|
||||
first = mid
|
||||
|
||||
return False
|
||||
|
||||
def binary_search_rec(array, value, first=0, last=None):
|
||||
last = last or len(array)
|
||||
if len(array[first:last]) < 1:
|
||||
return False
|
||||
|
||||
mid = (last - first)//2
|
||||
if array[mid] == value:
|
||||
return True
|
||||
elif array[mid] < value:
|
||||
return binary_search_rec(array, value, first=first, last=mid)
|
||||
else:
|
||||
return binary_search_rec(array, value, first=mid, last=last)
|
||||
|
||||
|
||||
array = [3, 4, 6, 7, 10, 11, 34, 67, 84]
|
||||
value = 6
|
||||
assert(binary_search(array, value) == True)
|
||||
assert(binary_search_rec(array, value) == True)
|
||||
value = 8
|
||||
assert(binary_search(array, value) == False)
|
||||
assert(binary_search_rec(array, value) == False)
|
||||
array = [8]
|
||||
assert(binary_search(array, value) == True)
|
||||
assert(binary_search_rec(array, value) == True)
|
||||
array = []
|
||||
assert(binary_search(array, value) == False)
|
||||
assert(binary_search_rec(array, value) == False)
|
37
other_resources/interview_cake/sort_and_search/merge_sort.py
Normal file
37
other_resources/interview_cake/sort_and_search/merge_sort.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
def merge_sort(list_to_sort):
|
||||
# Base case: lists with fewer than 2 elements are sorted
|
||||
if len(list_to_sort) < 2:
|
||||
return list_to_sort
|
||||
|
||||
# Step 1: divide the list in half
|
||||
mid_index = len(list_to_sort) / 2
|
||||
left = list_to_sort[:mid_index]
|
||||
right = list_to_sort[mid_index:]
|
||||
|
||||
# Step 2: sort each half
|
||||
sorted_left = merge_sort(left)
|
||||
sorted_right = merge_sort(right)
|
||||
|
||||
# Step 3: merge the sorted halves
|
||||
sorted_list = []
|
||||
current_index_left = 0
|
||||
current_index_right = 0
|
||||
|
||||
while len(sorted_list) < len(left) + len(right):
|
||||
if ((current_index_left < len(left)) and
|
||||
(current_index_right == len(right) or
|
||||
sorted_left[current_index_left] < sorted_right[current_index_right])):
|
||||
sorted_list.append(sorted_left[current_index_left])
|
||||
current_index_left += 1
|
||||
else:
|
||||
sorted_list.append(sorted_right[current_index_right])
|
||||
current_index_right += 1
|
||||
return sorted_list
|
||||
|
||||
|
||||
|
||||
list_to_sort = [5, 3, 7, 12, 1, 0, 10]
|
||||
|
||||
print merge_sort(list_to_sort)
|
|
@ -0,0 +1,52 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
In order to win the prize for most cookies sold, my friend Alice and
|
||||
# I are going to merge our Girl Scout Cookies orders and enter as one unit.
|
||||
# Each order is represented by an "order id" (an integer).
|
||||
We have our lists of orders sorted numerically already, in lists.
|
||||
Write a function to merge our lists of orders into one sorted list.
|
||||
"""
|
||||
|
||||
def merge_lists(my_list, alices_list):
|
||||
|
||||
result = []
|
||||
index_alice_list = 0
|
||||
index_my_list = 0
|
||||
|
||||
while index_alice_list < len(alices_list) and index_my_list < len(my_list):
|
||||
if alices_list[index_alice_list] < my_list[index_my_list]:
|
||||
result.append(alices_list[index_alice_list])
|
||||
index_alice_list += 1
|
||||
elif alices_list[index_alice_list] > my_list[index_my_list]:
|
||||
result.append(my_list[index_my_list])
|
||||
index_my_list += 1
|
||||
else:
|
||||
result.append(my_list[index_my_list])
|
||||
result.append(alices_list[index_alice_list])
|
||||
index_my_list += 1
|
||||
index_alice_list += 1
|
||||
|
||||
if index_alice_list < len(alices_list):
|
||||
result.extend(alices_list[index_alice_list:])
|
||||
|
||||
if index_my_list < len(my_list):
|
||||
result.extend(my_list[index_my_list:])
|
||||
|
||||
return result
|
||||
|
||||
|
||||
my_list = [3, 4, 6, 10, 11, 15]
|
||||
alices_list = [1, 5, 8, 12, 14, 19]
|
||||
|
||||
|
||||
print merge_lists(my_list, alices_list)
|
||||
print "Must be [1, 3, 4, 5, 6, 8, 10, 11, 12, 14, 15, 19]"
|
||||
|
||||
|
||||
# Or just using Timsort
|
||||
def merge_sorted_lists(arr1, arr2):
|
||||
return sorted(arr1 + arr2)
|
||||
|
||||
print merge_sorted_lists(my_list, alices_list)
|
||||
print "Must be [1, 3, 4, 5, 6, 8, 10, 11, 12, 14, 15, 19]"
|
|
@ -0,0 +1,51 @@
|
|||
#!/bin/python
|
||||
|
||||
"""
|
||||
Build a calendar.
|
||||
|
||||
A meeting is stored as a tuple of integers (start_time, end_time).
|
||||
These integers represent the number of 30-minute blocks past 9:00am.
|
||||
|
||||
For example:
|
||||
|
||||
(2, 3)# Meeting from 10:00-10:30 am
|
||||
(6, 9)# Meeting from 12:00-1:30 pm
|
||||
|
||||
Write a function merge_ranges() that takes a list of multiple meeting time ranges and returns a list of condensed ranges.
|
||||
|
||||
For example, given:
|
||||
|
||||
[(0, 1), (3, 5), (4, 8), (10, 12), (9, 10)]
|
||||
|
||||
your function would return:
|
||||
|
||||
[(0, 1), (3, 8), (9, 12)]
|
||||
|
||||
Do not assume the meetings are in order. The meeting times are coming from multiple teams.
|
||||
|
||||
Write a solution that's efficient even when we can't put a nice upper bound on the numbers representing our time ranges.
|
||||
Here we've simplified our times down to the number of 30-minute slots past 9:00 am.
|
||||
But we want the function to work even for very large numbers, like Unix timestamps.
|
||||
In any case, the spirit of the challenge is to merge meetings where start_time and end_time don't have an upper bound.
|
||||
"""
|
||||
|
||||
def merge_ranges(meetings):
|
||||
|
||||
sorted_meetings = sorted(meetings)
|
||||
merged_meetings = [sorted_meetings[0]]
|
||||
|
||||
for current_meeting_start, current_meeting_ending in sorted_meetings[1:]:
|
||||
last_merged_meeting_start, last_merged_meeting_end = merged_meetings[-1]
|
||||
|
||||
if (current_meeting_start <= last_merged_meeting_end):
|
||||
merged_meetings[-1] = (last_merged_meeting_start, max(last_merged_meeting_end, current_meeting_ending))
|
||||
else:
|
||||
merged_meetings.append((current_meeting_start, current_meeting_ending))
|
||||
|
||||
return merged_meetings
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
meetings = [(0, 1), (3, 5), (4, 8), (10, 12), (9, 10)]
|
||||
print(merge_ranges(meetings))
|
||||
print("Should return {}".format([(0, 1), (3, 8), (9, 12)]))
|
28
other_resources/interview_cake/strings/online_poker.py
Normal file
28
other_resources/interview_cake/strings/online_poker.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
#!/bin/python
|
||||
|
||||
"""
|
||||
Write a function to tell us if a full deck of cards shuffled_deck is a single riffle of two other halves half1 and half2.
|
||||
|
||||
We'll represent a stack of cards as a list of integers in the range 1..521..52 (since there are 5252 distinct cards in a deck).
|
||||
Why do I care? A single riffle is not a completely random shuffle. If I'm right, I can make more informed bets and get rich and finally prove to my ex that I am not a "loser with an unhealthy cake obsession" (even though it's too late now because she let me go and she's never getting me back).
|
||||
"""
|
||||
|
||||
def is_single_riffle(half1, half2, shuffled_deck,
|
||||
shuffled_deck_index=0, half1_index=0, half2_index=0):
|
||||
if shuffled_deck_index == len(shuffled_deck):
|
||||
return True
|
||||
|
||||
if ((half1_index < len(half1)) and
|
||||
half1[half1_index] == shuffled_deck[shuffled_deck_index]):
|
||||
half1_index += 1
|
||||
|
||||
elif ((half2_index < len(half2)) and
|
||||
half2[half2_index] == shuffled_deck[shuffled_deck_index]):
|
||||
half2_index += 1
|
||||
else:
|
||||
return False
|
||||
|
||||
shuffled_deck_index += 1
|
||||
return is_single_riffle(
|
||||
half1, half2, shuffled_deck, shuffled_deck_index,
|
||||
half1_index, half2_index)
|
25
other_resources/interview_cake/strings/palindrome.py
Normal file
25
other_resources/interview_cake/strings/palindrome.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Write an efficient function that checks whether
|
||||
any permutation of an input string is a palindrome.
|
||||
"""
|
||||
|
||||
def has_palindrome_permutation(the_string):
|
||||
unpaired_characters = set()
|
||||
|
||||
for char in the_string:
|
||||
if char in unpaired_characters:
|
||||
unpaired_characters.remove(char)
|
||||
else:
|
||||
unpaired_characters.add(char)
|
||||
|
||||
return len(unpaired_characters) <= 1
|
||||
|
||||
str1 = "civic"
|
||||
print has_palindrome_permutation(str1)
|
||||
print "Should be True"
|
||||
|
||||
str2 = "ivilc"
|
||||
print has_palindrome_permutation(str2)
|
||||
print "Should be False"
|
17
other_resources/interview_cake/strings/reverse_in_place.py
Normal file
17
other_resources/interview_cake/strings/reverse_in_place.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Write a function that takes a list of characters and reverses the letters in place.
|
||||
O(n) time and O(1)O(1) space.
|
||||
"""
|
||||
|
||||
def reverse_in_place(char_list):
|
||||
return char_list[::-1]
|
||||
|
||||
|
||||
char_list = ['a', 'b', 'c', 'd', 'e', 'f']
|
||||
|
||||
|
||||
|
||||
print(char_list)
|
||||
print(reverse_in_place(char_list))
|
Loading…
Add table
Add a link
Reference in a new issue