mirror of
https://github.com/autistic-symposium/master-algorithms-py.git
synced 2025-04-29 20:26:07 -04:00
reorganize
This commit is contained in:
parent
2fdaad121c
commit
2e96a35a0d
BIN
HALEIWA.jpg
BIN
HALEIWA.jpg
Binary file not shown.
Before Width: | Height: | Size: 2.9 MiB |
Binary file not shown.
@ -1,35 +0,0 @@
|
|||||||
#!/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'
|
|
@ -1,37 +0,0 @@
|
|||||||
#!/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
|
|
@ -1,20 +0,0 @@
|
|||||||
#!/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'
|
|
@ -1,19 +0,0 @@
|
|||||||
#!/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'
|
|
@ -1,37 +0,0 @@
|
|||||||
#!/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)
|
|
@ -1,76 +0,0 @@
|
|||||||
#!/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()
|
|
@ -1,42 +0,0 @@
|
|||||||
#!/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")
|
|
@ -1,27 +0,0 @@
|
|||||||
#!/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)")
|
|
@ -1,36 +0,0 @@
|
|||||||
#!/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)
|
|
@ -1,38 +0,0 @@
|
|||||||
#!/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)
|
|
@ -1,26 +0,0 @@
|
|||||||
#!/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'
|
|
@ -1,54 +0,0 @@
|
|||||||
#!/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"
|
|
@ -1,33 +0,0 @@
|
|||||||
#!/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
|
|
@ -1,38 +0,0 @@
|
|||||||
#!/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]"
|
|
@ -1,32 +0,0 @@
|
|||||||
#!/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)
|
|
@ -1,70 +0,0 @@
|
|||||||
#!/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)
|
|
@ -1,48 +0,0 @@
|
|||||||
#!/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)
|
|
@ -1,37 +0,0 @@
|
|||||||
#!/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)
|
|
@ -1,52 +0,0 @@
|
|||||||
#!/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]"
|
|
@ -1,51 +0,0 @@
|
|||||||
#!/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)]))
|
|
@ -1,28 +0,0 @@
|
|||||||
#!/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)
|
|
@ -1,25 +0,0 @@
|
|||||||
#!/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"
|
|
@ -1,17 +0,0 @@
|
|||||||
#!/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))
|
|
@ -1,41 +0,0 @@
|
|||||||
#!/bin/python
|
|
||||||
|
|
||||||
import math
|
|
||||||
import os
|
|
||||||
import random
|
|
||||||
import re
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# Complete the 'largestRepackaged' function below.
|
|
||||||
#
|
|
||||||
# The function is expected to return a LONG_INTEGER.
|
|
||||||
# The function accepts INTEGER_ARRAY arrivingPackets as parameter.
|
|
||||||
#
|
|
||||||
|
|
||||||
def largestRepackaged(arrivingPackets):
|
|
||||||
|
|
||||||
packet_size = arrivingPackets[0]
|
|
||||||
packets = arrivingPackets[1:]
|
|
||||||
largest_packet = 0
|
|
||||||
remaining = 0
|
|
||||||
|
|
||||||
for packet in packets:
|
|
||||||
print packet
|
|
||||||
if remaining:
|
|
||||||
packet += remaining
|
|
||||||
remaining = 0
|
|
||||||
|
|
||||||
if packet % 2 != 0:
|
|
||||||
remaining = packet % 2
|
|
||||||
packet -= remaining
|
|
||||||
|
|
||||||
if packet > largest_packet:
|
|
||||||
largest_packet = packet
|
|
||||||
|
|
||||||
return largest_packet
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
arrivingPackets= [5, 1, 2, 4, 7, 5]
|
|
||||||
|
|
||||||
print(largestRepackaged(arrivingPackets))
|
|
@ -1,22 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
|
|
||||||
def balance_par_str_with_stack(str1):
|
|
||||||
i, stack = 0, []
|
|
||||||
|
|
||||||
while i < len(str1):
|
|
||||||
symbol = str1[i]
|
|
||||||
if symbol == "(":
|
|
||||||
stack.append(symbol)
|
|
||||||
elif symbol == ")":
|
|
||||||
stack.pop()
|
|
||||||
i += 1
|
|
||||||
return not stack
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
print(balance_par_str_with_stack('((()))'))
|
|
||||||
print(balance_par_str_with_stack('(()'))
|
|
@ -1,50 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
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)
|
|
@ -1,165 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
from collections import deque
|
|
||||||
|
|
||||||
class Node(object):
|
|
||||||
|
|
||||||
def __init__(self, item=None):
|
|
||||||
|
|
||||||
self.item = item
|
|
||||||
self.left = None
|
|
||||||
self.right = None
|
|
||||||
|
|
||||||
|
|
||||||
def _add(self, value):
|
|
||||||
new_node = Node(value)
|
|
||||||
if not self.item:
|
|
||||||
self.item = new_node
|
|
||||||
else:
|
|
||||||
if value > self.item:
|
|
||||||
self.right = self.right and self.right._add(value) or new_node
|
|
||||||
elif value < self.item:
|
|
||||||
self.left = self.left and self.left._add(value) or new_node
|
|
||||||
else:
|
|
||||||
print("BSTs do not support repeated items.")
|
|
||||||
return self
|
|
||||||
|
|
||||||
|
|
||||||
def _search(self, value):
|
|
||||||
if self.item == value:
|
|
||||||
return True
|
|
||||||
elif self.left and value < self.item:
|
|
||||||
return self.left._search(value)
|
|
||||||
elif self.right and value > self.item:
|
|
||||||
return self.right._search(value)
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def _isLeaf(self):
|
|
||||||
return not self.right and not self.left
|
|
||||||
|
|
||||||
|
|
||||||
def _printPreorder(self):
|
|
||||||
print self.item
|
|
||||||
|
|
||||||
if self.left:
|
|
||||||
self.left._printPreorder()
|
|
||||||
|
|
||||||
if self.right:
|
|
||||||
self.right._printPreorder()
|
|
||||||
|
|
||||||
|
|
||||||
def _preorder_array(self):
|
|
||||||
nodes = []
|
|
||||||
if self.item:
|
|
||||||
nodes.append(self.item)
|
|
||||||
if self.left:
|
|
||||||
nodes.extend(self.left._preorder_array())
|
|
||||||
if self.right:
|
|
||||||
nodes.extend(self.right._preorder_array())
|
|
||||||
return nodes
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BST(object):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.root = None
|
|
||||||
|
|
||||||
def add(self, value):
|
|
||||||
if not self.root:
|
|
||||||
self.root = Node(value)
|
|
||||||
else:
|
|
||||||
self.root._add(value)
|
|
||||||
|
|
||||||
def printPreorder(self):
|
|
||||||
if self.root:
|
|
||||||
self.root._printPreorder()
|
|
||||||
|
|
||||||
def search(self, value):
|
|
||||||
if self.root:
|
|
||||||
return self.root._search(value)
|
|
||||||
|
|
||||||
def preorder_array(self):
|
|
||||||
if self.root:
|
|
||||||
return self.root._preorder_array()
|
|
||||||
else:
|
|
||||||
return 'Tree is empty.'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def BFT(tree):
|
|
||||||
current = tree.root
|
|
||||||
nodes = []
|
|
||||||
queue = deque()
|
|
||||||
queue.append(current)
|
|
||||||
|
|
||||||
while queue:
|
|
||||||
current = queue.popleft()
|
|
||||||
nodes.append(current.item)
|
|
||||||
if current.left:
|
|
||||||
queue.append(current.left)
|
|
||||||
if current.right:
|
|
||||||
queue.append(current.right)
|
|
||||||
|
|
||||||
return nodes
|
|
||||||
|
|
||||||
|
|
||||||
def preorder(tree, nodes=None):
|
|
||||||
nodes = nodes or []
|
|
||||||
if tree:
|
|
||||||
nodes.append(tree.item)
|
|
||||||
if tree.left:
|
|
||||||
preorder(tree.left, nodes)
|
|
||||||
if tree.right:
|
|
||||||
preorder(tree.right, nodes)
|
|
||||||
return nodes
|
|
||||||
|
|
||||||
|
|
||||||
def postorder(tree, nodes=None):
|
|
||||||
nodes = nodes or []
|
|
||||||
if tree:
|
|
||||||
if tree.left:
|
|
||||||
nodes = postorder(tree.left, nodes)
|
|
||||||
if tree.right:
|
|
||||||
nodes = postorder(tree.right, nodes)
|
|
||||||
nodes.append(tree.item)
|
|
||||||
|
|
||||||
return nodes
|
|
||||||
|
|
||||||
|
|
||||||
def inorder(tree, nodes=None):
|
|
||||||
nodes = nodes or []
|
|
||||||
if tree:
|
|
||||||
if tree.left:
|
|
||||||
nodes = inorder(tree.left, nodes)
|
|
||||||
nodes.append(tree.item)
|
|
||||||
if tree.right:
|
|
||||||
nodes = inorder(tree.right, nodes)
|
|
||||||
return nodes
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
bst = BST()
|
|
||||||
l = [10, 5, 6, 3, 8, 2, 1, 11, 9, 4]
|
|
||||||
for i in l:
|
|
||||||
bst.add(i)
|
|
||||||
|
|
||||||
print
|
|
||||||
print "Searching for nodes 16 and 6:"
|
|
||||||
print bst.search(16)
|
|
||||||
print bst.search(6)
|
|
||||||
|
|
||||||
print
|
|
||||||
print 'Traversals:'
|
|
||||||
print 'Original: ', l
|
|
||||||
print 'Preorder: ', preorder(bst.root)
|
|
||||||
print 'Postorder: ', postorder(bst.root)
|
|
||||||
print 'Inorder: ', inorder(bst.root)
|
|
||||||
print 'BSF: ', BFT(bst)
|
|
@ -1,38 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
from collections import Counter
|
|
||||||
|
|
||||||
def check_if_anagram(word1, word2):
|
|
||||||
counter = Counter()
|
|
||||||
|
|
||||||
for c in word1:
|
|
||||||
counter[c] += 1
|
|
||||||
|
|
||||||
for c in word2:
|
|
||||||
counter[c] -= 1
|
|
||||||
|
|
||||||
for values in counter.values():
|
|
||||||
if values != 0:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
word1 = 'abc'
|
|
||||||
word2 = 'bca'
|
|
||||||
assert(check_if_anagram(word1, word2) == True)
|
|
||||||
|
|
||||||
word2 = 'bcd'
|
|
||||||
assert(check_if_anagram(word1, word2) == False)
|
|
||||||
|
|
||||||
word1 = ''
|
|
||||||
word2 = ''
|
|
||||||
assert(check_if_anagram(word1, word2) == True)
|
|
||||||
|
|
||||||
word1 = 'a'
|
|
||||||
word2 = 'a'
|
|
||||||
assert(check_if_anagram(word1, word2) == True)
|
|
@ -1,32 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
def combination(array):
|
|
||||||
if len(array) < 2:
|
|
||||||
return set(array)
|
|
||||||
|
|
||||||
result = set()
|
|
||||||
for index, item in enumerate(array):
|
|
||||||
new_array = array[:index] + array[index+1:]
|
|
||||||
result.add(item)
|
|
||||||
for perm in combination(new_array):
|
|
||||||
new_item = ''.join(sorted(item + perm))
|
|
||||||
result.add(new_item)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
array = ['a', 'b', 'c']
|
|
||||||
result = set(['a', 'ac', 'ab', 'abc', 'bc', 'c', 'b'])
|
|
||||||
assert(combination(array) == result)
|
|
||||||
|
|
||||||
array = ['']
|
|
||||||
result = set([''])
|
|
||||||
assert(combination(array) == result)
|
|
||||||
|
|
||||||
array = ['a']
|
|
||||||
result = set(['a'])
|
|
||||||
assert(combination(array) == result)
|
|
@ -1,45 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
|
|
||||||
class HashTable(object):
|
|
||||||
def __init__(self, slots=10):
|
|
||||||
self.slots = slots
|
|
||||||
self.table = []
|
|
||||||
self.create_table()
|
|
||||||
|
|
||||||
# Get the slot
|
|
||||||
def hash_key(self, value):
|
|
||||||
return hash(value)%self.slots
|
|
||||||
|
|
||||||
# When creating the table, add list struct
|
|
||||||
# to each slot
|
|
||||||
def create_table(self):
|
|
||||||
for i in range(self.slots):
|
|
||||||
self.table.append([])
|
|
||||||
|
|
||||||
# Method to add a item in the right slot
|
|
||||||
def add_item(self, value):
|
|
||||||
key = self.hash_key(value)
|
|
||||||
self.table[key].append(value)
|
|
||||||
|
|
||||||
# Aux: print table
|
|
||||||
def print_table(self):
|
|
||||||
for key in range(self.slots):
|
|
||||||
print "Key is {0}, value is {1}.".format(key, self.table[key])
|
|
||||||
|
|
||||||
# Aux: find item
|
|
||||||
def find_item(self, item):
|
|
||||||
item_hash = self.hash_key(item)
|
|
||||||
return item in self.table[item_hash]
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
dic = HashTable(5)
|
|
||||||
for i in range(1, 40, 2):
|
|
||||||
dic.add_item(i)
|
|
||||||
|
|
||||||
dic.print_table()
|
|
||||||
assert(dic.find_item(20) == False)
|
|
||||||
assert(dic.find_item(21) == True)
|
|
@ -1,60 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
|
|
||||||
class Node(object):
|
|
||||||
def __init__(self, value, next=None):
|
|
||||||
self.value = value
|
|
||||||
self.next = next
|
|
||||||
|
|
||||||
|
|
||||||
class LinkedList(object):
|
|
||||||
def __init__(self):
|
|
||||||
self.head = None
|
|
||||||
|
|
||||||
def _add(self, value):
|
|
||||||
self.head = Node(value, self.head)
|
|
||||||
|
|
||||||
def _printList(self):
|
|
||||||
node = self.head
|
|
||||||
while node:
|
|
||||||
print node.value
|
|
||||||
node = node.next
|
|
||||||
|
|
||||||
def _find(self, index):
|
|
||||||
prev = None
|
|
||||||
node = self.head
|
|
||||||
i = 0
|
|
||||||
while node and i < index:
|
|
||||||
prev = node
|
|
||||||
node = node.next
|
|
||||||
i += 1
|
|
||||||
return node, prev, i
|
|
||||||
|
|
||||||
def _delete(self, prev, node):
|
|
||||||
if not prev:
|
|
||||||
self.head = node.next
|
|
||||||
else:
|
|
||||||
prev.next = node.next
|
|
||||||
|
|
||||||
def deleteNode(self, index):
|
|
||||||
node, prev, i = self._find(index)
|
|
||||||
if index == i:
|
|
||||||
self._delete(prev, node)
|
|
||||||
else:
|
|
||||||
print('Node with index {} not found'.format(index))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
ll = LinkedList()
|
|
||||||
for i in range(1, 5):
|
|
||||||
ll._add(i)
|
|
||||||
|
|
||||||
print('The list is:')
|
|
||||||
ll._printList()
|
|
||||||
|
|
||||||
print('The list after deleting node with index 2:')
|
|
||||||
ll.deleteNode(2)
|
|
||||||
ll._printList()
|
|
@ -1,32 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
|
|
||||||
def longest_common_substring(s1, s2):
|
|
||||||
p1 = 0
|
|
||||||
aux, lcp = '', ''
|
|
||||||
string1 = max(s1, s2)
|
|
||||||
string2 = min(s1, s2)
|
|
||||||
|
|
||||||
while p1 < len(string1):
|
|
||||||
p2 = 0
|
|
||||||
while p2 < len(string2) and p1+p2 < len(string1):
|
|
||||||
if string1[p1+p2] == string2[p2]:
|
|
||||||
aux += string1[p1+p2]
|
|
||||||
else:
|
|
||||||
if len(lcp) < len(aux):
|
|
||||||
lcp = aux
|
|
||||||
aux = ''
|
|
||||||
p2 += 1
|
|
||||||
p1 += 1
|
|
||||||
|
|
||||||
return lcp
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
str1 = 'hasfgeaae'
|
|
||||||
str2 = 'bafgekk'
|
|
||||||
result = 'fge'
|
|
||||||
assert(longest_common_substring(str1, str2) == result)
|
|
@ -1,31 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
|
|
||||||
def longest_increasing_subsequence(seq):
|
|
||||||
result, aux = [], []
|
|
||||||
seq.append(-float('infinity'))
|
|
||||||
|
|
||||||
for i, value in enumerate(seq[:-1]):
|
|
||||||
aux.append(value)
|
|
||||||
if value > seq[i+1]:
|
|
||||||
if len(result) < len(aux):
|
|
||||||
result = aux[:]
|
|
||||||
aux = []
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
seq = [10, -12, 2, 3, -3, 5, -1, 2, -10]
|
|
||||||
result = [-12, 2, 3]
|
|
||||||
assert(longest_increasing_subsequence(seq) == result)
|
|
||||||
|
|
||||||
seq = [2]
|
|
||||||
result = [2]
|
|
||||||
assert(longest_increasing_subsequence(seq) == result)
|
|
||||||
|
|
||||||
seq = []
|
|
||||||
result = []
|
|
||||||
assert(longest_increasing_subsequence(seq) == result)
|
|
@ -1,47 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
# AKA: do you believe in magic?
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
def merge_sort(array):
|
|
||||||
if len(array) < 2:
|
|
||||||
return array
|
|
||||||
|
|
||||||
# divide
|
|
||||||
mid = len(array)//2
|
|
||||||
left = merge_sort(array[:mid])
|
|
||||||
right = merge_sort(array[mid:])
|
|
||||||
|
|
||||||
# merge
|
|
||||||
result = []
|
|
||||||
i, j = 0, 0
|
|
||||||
|
|
||||||
while i < len(left) and j < len(right):
|
|
||||||
if left[i] < right[j]:
|
|
||||||
result.append(left[i])
|
|
||||||
i += 1
|
|
||||||
else:
|
|
||||||
result.append(right[j])
|
|
||||||
j+= 1
|
|
||||||
|
|
||||||
# make sure nothing is left behind
|
|
||||||
if left[i:]:
|
|
||||||
result.extend(left[i:])
|
|
||||||
if right[j:]:
|
|
||||||
result.extend(right[j:])
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
array = [3, 1, 6, 0, 7, 19, 7, 2, 22]
|
|
||||||
sorted = [0, 1, 2, 3, 6, 7, 7, 19, 22]
|
|
||||||
assert(merge_sort(array) == sorted)
|
|
||||||
|
|
||||||
array = []
|
|
||||||
assert(merge_sort(array) == array)
|
|
||||||
|
|
||||||
array = [1]
|
|
||||||
assert(merge_sort(array) == array)
|
|
@ -1,58 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
import string
|
|
||||||
|
|
||||||
def sanitize(sentence):
|
|
||||||
array = sentence.lower()
|
|
||||||
array = array.strip()
|
|
||||||
array = array.strip(string.punctuation)
|
|
||||||
return array
|
|
||||||
|
|
||||||
def check_if_palindrome(array):
|
|
||||||
if len(array) < 2:
|
|
||||||
return True
|
|
||||||
|
|
||||||
if array[0] == array[-1]:
|
|
||||||
return check_if_palindrome(array[1:-1])
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
def check_if_palindrome_iter(array):
|
|
||||||
i, j = 0, len(array)-1
|
|
||||||
|
|
||||||
while i <= j:
|
|
||||||
if array[i] != array[j]:
|
|
||||||
return False
|
|
||||||
i += 1
|
|
||||||
j -= 1
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
sentence = 'hello there'
|
|
||||||
array = sanitize(sentence)
|
|
||||||
assert(check_if_palindrome(array) == False)
|
|
||||||
assert(check_if_palindrome_iter(array) == False)
|
|
||||||
|
|
||||||
sentence = ''
|
|
||||||
array = sanitize(sentence)
|
|
||||||
assert(check_if_palindrome(array) == True)
|
|
||||||
assert(check_if_palindrome_iter(array) == True)
|
|
||||||
|
|
||||||
sentence = 'h'
|
|
||||||
array = sanitize(sentence)
|
|
||||||
assert(check_if_palindrome(array) == True)
|
|
||||||
assert(check_if_palindrome_iter(array) == True)
|
|
||||||
|
|
||||||
sentence = 'Noel sees Leon'
|
|
||||||
array = sanitize(sentence)
|
|
||||||
assert(check_if_palindrome(array) == True)
|
|
||||||
assert(check_if_palindrome_iter(array) == True)
|
|
||||||
|
|
||||||
sentence = 'Noel sees Leon!'
|
|
||||||
array = sanitize(sentence)
|
|
||||||
assert(check_if_palindrome(array) == True)
|
|
||||||
assert(check_if_palindrome_iter(array) == True)
|
|
@ -1,31 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
|
|
||||||
def permutation(array):
|
|
||||||
if len(array) < 2:
|
|
||||||
return [array]
|
|
||||||
|
|
||||||
result = []
|
|
||||||
for index, letter in enumerate(array):
|
|
||||||
new_array = array[:index] + array[index+1:]
|
|
||||||
for perm in permutation(new_array):
|
|
||||||
result.append(letter + perm)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
word = 'abc'
|
|
||||||
result = ['abc', 'acb', 'bac', 'bca', 'cab', 'cba']
|
|
||||||
assert(permutation(word) == result)
|
|
||||||
|
|
||||||
word = ''
|
|
||||||
result = ['']
|
|
||||||
assert(permutation(word) == result)
|
|
||||||
|
|
||||||
word = 'a'
|
|
||||||
result = ['a']
|
|
||||||
assert(permutation(word) == result)
|
|
@ -1,47 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
|
|
||||||
class Queue(object):
|
|
||||||
def __init__(self):
|
|
||||||
self.enq = []
|
|
||||||
self.deq = []
|
|
||||||
|
|
||||||
def enqueue(self, item):
|
|
||||||
return self.enq.append(item)
|
|
||||||
|
|
||||||
def deque(self):
|
|
||||||
if not self.deq:
|
|
||||||
while self.enq:
|
|
||||||
self.deq.append(self.enq.pop())
|
|
||||||
return self.deq.pop()
|
|
||||||
|
|
||||||
def peak(self):
|
|
||||||
if not self.deq:
|
|
||||||
while self.enq:
|
|
||||||
self.deq.append(self.enq.pop())
|
|
||||||
if self.deq:
|
|
||||||
return self.deq[-1]
|
|
||||||
|
|
||||||
def size(self):
|
|
||||||
return len(self.enq) + len(self.deq)
|
|
||||||
|
|
||||||
def isempty(self):
|
|
||||||
return not (self.enq + self.deq)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
q = Queue()
|
|
||||||
for i in range(1,11):
|
|
||||||
q.enqueue(i)
|
|
||||||
print 'Size:', q.size()
|
|
||||||
print 'Is empty?', q.isempty()
|
|
||||||
print 'Peak: ', q.peak()
|
|
||||||
print
|
|
||||||
print 'Dequeuing...'
|
|
||||||
for i in range(10):
|
|
||||||
print q.deque()
|
|
||||||
print 'Size:', q.size()
|
|
||||||
print 'Is empty?', q.isempty()
|
|
||||||
print 'Peak: ', q.peak()
|
|
@ -1,31 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
def quick_sort(array):
|
|
||||||
if len(array) < 2:
|
|
||||||
return array
|
|
||||||
|
|
||||||
# partition
|
|
||||||
ipivot = len(array)//2
|
|
||||||
pivot = array[ipivot]
|
|
||||||
new_array = array[:ipivot] + array[ipivot+1:]
|
|
||||||
|
|
||||||
left = [x for x in new_array if x <= pivot]
|
|
||||||
right = [x for x in new_array if x > pivot]
|
|
||||||
|
|
||||||
return quick_sort(left) + [pivot] + quick_sort(right)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
array = [3, 1, 6, 0, 7, 19, 7, 2, 22]
|
|
||||||
sorted = [0, 1, 2, 3, 6, 7, 7, 19, 22]
|
|
||||||
assert(quick_sort(array) == sorted)
|
|
||||||
|
|
||||||
array = []
|
|
||||||
assert(quick_sort(array) == array)
|
|
||||||
|
|
||||||
array = [1]
|
|
||||||
assert(quick_sort(array) == array)
|
|
@ -1,40 +0,0 @@
|
|||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
def reverse_str_inplace(_str):
|
|
||||||
if len(_str) < 2:
|
|
||||||
return _str
|
|
||||||
return _str[-1] + reverse_str(_str[1:-1]) + _str[0]
|
|
||||||
|
|
||||||
|
|
||||||
def reverse_str(_str):
|
|
||||||
result = ''
|
|
||||||
j = len(_str) - 1
|
|
||||||
|
|
||||||
while j >= 0:
|
|
||||||
result += _str[j]
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
_str = ''
|
|
||||||
result = ''
|
|
||||||
assert(reverse_str(_str) == result)
|
|
||||||
assert(reverse_str_inplace(_str) == result)
|
|
||||||
|
|
||||||
_str = 'a'
|
|
||||||
result = 'a'
|
|
||||||
assert(reverse_str(_str) == result)
|
|
||||||
assert(reverse_str_inplace(_str) == result)
|
|
||||||
|
|
||||||
_str = 'abcde'
|
|
||||||
result = 'edcba'
|
|
||||||
assert(reverse_str(_str) == result)
|
|
||||||
assert(reverse_str_inplace(_str) == result)
|
|
||||||
|
|
||||||
_str = 'abcdef'
|
|
||||||
result = 'fedcba'
|
|
||||||
assert(reverse_str(_str) == result)
|
|
||||||
assert(reverse_str_inplace(_str) == result)
|
|
@ -1,40 +0,0 @@
|
|||||||
|
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
__author__ = "bt3"
|
|
||||||
|
|
||||||
|
|
||||||
class Stack(object):
|
|
||||||
def __init__(self):
|
|
||||||
self.content = []
|
|
||||||
|
|
||||||
def push(self, value):
|
|
||||||
self.content.append(value)
|
|
||||||
|
|
||||||
def pop(self):
|
|
||||||
if self.content:
|
|
||||||
return self.content.pop()
|
|
||||||
else:
|
|
||||||
return 'Empty List. '
|
|
||||||
|
|
||||||
def size(self):
|
|
||||||
return len(self.content)
|
|
||||||
|
|
||||||
def isEmpty(self):
|
|
||||||
return not bool(self.content)
|
|
||||||
|
|
||||||
def peek(self):
|
|
||||||
if self.content:
|
|
||||||
return self.content[-1]
|
|
||||||
else:
|
|
||||||
print('Stack is empty.')
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
q = Stack()
|
|
||||||
|
|
||||||
for i in range(10):
|
|
||||||
q.push(i)
|
|
||||||
for i in range(11):
|
|
||||||
print q.pop()
|
|
Loading…
x
Reference in New Issue
Block a user