mirror of
https://github.com/autistic-symposium/master-algorithms-py.git
synced 2025-06-17 03:19:22 -04:00
cleaning up and organizing old problems (builtin)
This commit is contained in:
parent
6afe96fa4d
commit
3fdbc2a605
106 changed files with 480 additions and 1472 deletions
37
src/builtin_structures/alpha_permutation.py
Normal file
37
src/builtin_structures/alpha_permutation.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
''' Write code to generate all possible case permutations of a given
|
||||
lower-cased string
|
||||
'''
|
||||
|
||||
def alpha_permutation(string):
|
||||
'''
|
||||
>>> alpha_permutation('0ab')
|
||||
['0Ab', '0Ab', '0ab', '0ab', '0Ba', '0Ba', '0ba', '0ba', 'ab0', 'a0b', 'a0b', 'b0a', 'b0a', 'ba0']
|
||||
>>> alpha_permutation('')
|
||||
''
|
||||
'''
|
||||
|
||||
if len(string) < 2:
|
||||
return string
|
||||
|
||||
result = []
|
||||
|
||||
for i, c in enumerate(string):
|
||||
rest = string[i+1:] + string[:i]
|
||||
for cc in alpha_permutation(rest):
|
||||
if cc.isalpha():
|
||||
result.append(c.upper() + cc)
|
||||
result.append(c + cc)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
51
src/builtin_structures/anagram.py
Normal file
51
src/builtin_structures/anagram.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
from collections import Counter
|
||||
|
||||
def is_anagram(s1, s2):
|
||||
'''
|
||||
>>> is_anagram('cat', 'tac')
|
||||
True
|
||||
>>> is_anagram('cat', 'hat')
|
||||
False
|
||||
'''
|
||||
counter = Counter()
|
||||
for c in s1:
|
||||
counter[c] += 1
|
||||
|
||||
for c in s2:
|
||||
counter[c] -= 1
|
||||
|
||||
for i in counter.values():
|
||||
if i:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
''' verify if words are anagrams by comparing a sum of Unicode code
|
||||
point of the character'''
|
||||
|
||||
def get_unicode_sum(word):
|
||||
s = 0
|
||||
for p in word:
|
||||
s += ord(p)
|
||||
return s
|
||||
|
||||
|
||||
def is_anagram2(word1, word2):
|
||||
'''
|
||||
>>> is_anagram2('cat', 'tac')
|
||||
True
|
||||
>>> is_anagram2('cat', 'hat')
|
||||
False
|
||||
'''
|
||||
return get_unicode_sum(word1) == get_unicode_sum(word2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
9
src/builtin_structures/balance.txt
Executable file
9
src/builtin_structures/balance.txt
Executable file
|
@ -0,0 +1,9 @@
|
|||
__author__ = "bt3"
|
||||
|
||||
|
||||
This is the classic "you have 8 balls/coins, which are the same weight, except for one which is slightly heavier than the others. You also have an old-style balance. What is the fewest number of weighings to find the heavy coin/ball?
|
||||
|
||||
Answer: 2! You need to use every information available:
|
||||
Weight 3 x 3 balls/coins.
|
||||
If they weight the same: weight the 2 balls/coins left outside.
|
||||
Else, measure 2 of the 3 heavier balls/coins.
|
40
src/builtin_structures/balance_symbols.py
Normal file
40
src/builtin_structures/balance_symbols.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
'''
|
||||
Given a N different open and close braces in a string "( { [ } ] )".
|
||||
How do you check whether the string has matching braces.
|
||||
'''
|
||||
|
||||
from collections import Counter
|
||||
def check_if_balance(string):
|
||||
'''
|
||||
>>> check_if_balance('{[[(])}]')
|
||||
True
|
||||
>>> check_if_balance('{[[()}]')
|
||||
False
|
||||
>>> check_if_balance('')
|
||||
True
|
||||
'''
|
||||
table = Counter()
|
||||
for i in string:
|
||||
|
||||
index = str(ord(i))[0]
|
||||
if i in '{[(':
|
||||
table[index] += 1
|
||||
|
||||
elif i in ')}]':
|
||||
table[index] -= 1
|
||||
|
||||
for i in table.values():
|
||||
if i !=-0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
71
src/builtin_structures/check_if_2_numbers_sum_to_k.py
Executable file
71
src/builtin_structures/check_if_2_numbers_sum_to_k.py
Executable file
|
@ -0,0 +1,71 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
"""
|
||||
Given an integer x and an unsorted array of integers, describe an
|
||||
algorithm to determine whether two of the numbers add up to x.
|
||||
|
||||
1. Using hash tables.
|
||||
2. Sorting the array and keeping two pointers in the array, one in
|
||||
the beginning and one in the end. Whenever the sum of the current
|
||||
two integers is less than x, move the first pointer forwards, and
|
||||
whenever the sum is greater than x, move the second pointer
|
||||
backwards. O(nln n).
|
||||
3. Create a BST with x minus each element in the array.
|
||||
Check whether any element of the array appears in the BST.
|
||||
It takes O(nlog n) times two.
|
||||
"""
|
||||
|
||||
from collections import defaultdict, Counter
|
||||
|
||||
def check_sum(array, k):
|
||||
'''
|
||||
>>> check_sum([3, 2, 6, 7, 9, 1], 8)
|
||||
[(6, 2), (1, 7)]
|
||||
>>> check_sum([5, 2, 6, 7, 9, 1], 4)
|
||||
[]
|
||||
>>>
|
||||
'''
|
||||
|
||||
dict = defaultdict()
|
||||
res = []
|
||||
|
||||
for i in array:
|
||||
if k-i in dict:
|
||||
res.append((i, k-i))
|
||||
del dict[k-i]
|
||||
else:
|
||||
dict[i] = 1
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def check_sum2(array, k):
|
||||
'''
|
||||
>>> check_sum2([1, 4, 2, 7, 1, 3, 10, 15, 3, 1], 6)
|
||||
set([(3, 3)])
|
||||
>>> check_sum2([1, 4, 2, 7, 1, 3, 10, 15, 3, 1], 0)
|
||||
set([])
|
||||
'''
|
||||
|
||||
dict = Counter()
|
||||
res = set()
|
||||
|
||||
for i in array:
|
||||
dict[i] += 1
|
||||
|
||||
for i in array:
|
||||
if dict[k-i] > 0:
|
||||
if i == k-i and dict[k-i] > 1:
|
||||
res.add((i, k-i))
|
||||
dict[k-i] -= 2
|
||||
elif i == k-i:
|
||||
res.add((i, k-i))
|
||||
dict[k-i] -= 1
|
||||
|
||||
return res
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
36
src/builtin_structures/check_if_3_numbers_sum_to_zero.py
Normal file
36
src/builtin_structures/check_if_3_numbers_sum_to_zero.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
''' Determine if an Array of integers contains 3 numbers that sum to 0 '''
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
def find_3_number(array):
|
||||
'''
|
||||
>>> find_3_number([1,5,56,11,-3,-12])
|
||||
1 11 -12
|
||||
True
|
||||
>>> find_3_number([] )
|
||||
False
|
||||
'''
|
||||
hash_ = defaultdict()
|
||||
for i in array:
|
||||
hash_[i] = 1
|
||||
|
||||
for i, x in enumerate(array):
|
||||
for y in array[i+1:]:
|
||||
if -(x+y) in hash_:
|
||||
print x, y, -(x+y)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
35
src/builtin_structures/check_non_overlapping_intervals.py
Normal file
35
src/builtin_structures/check_non_overlapping_intervals.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
'''
|
||||
given an array of intervals, return max number of non-overlapping intervals
|
||||
'''
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
def non_overlapping(array):
|
||||
'''
|
||||
>>> non_overlapping([(1,2), (2,5), (1, 6)])
|
||||
[[(1, 2), (2, 5)]]
|
||||
>>> non_overlapping([(1,4), (2,5), (3, 6)])
|
||||
[]
|
||||
'''
|
||||
total = []
|
||||
|
||||
for i, t in enumerate(array):
|
||||
start = t[0]
|
||||
end = t[1]
|
||||
for tt in array[i+1:] :
|
||||
if end <= tt[0]:
|
||||
total.append([(start, end), (tt[0], tt[1])])
|
||||
|
||||
return total
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
23
src/builtin_structures/combinations.py
Executable file
23
src/builtin_structures/combinations.py
Executable file
|
@ -0,0 +1,23 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
def comb_str(l1):
|
||||
|
||||
if len(l1) < 2:
|
||||
return l1
|
||||
|
||||
result = []
|
||||
for i, c in enumerate(l1):
|
||||
result.append(c)
|
||||
for comb in comb_str(l1[i+1:]):
|
||||
result.append(c + comb)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
l1 = ['a', 'b', 'c']
|
||||
print comb_str(l1)
|
|
@ -1,9 +1,10 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
#!/usr/bin/env python
|
||||
|
||||
''' two routines to convert str to int and int to str:
|
||||
- bc: negative str, zero, exp numbers (ex. 1e5), other bases, NAN
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
def conv_int2str(int1):
|
||||
'''
|
||||
>>> conv_str2int('367')
|
||||
367
|
||||
>>> conv_str2int('0')
|
||||
|
@ -12,46 +13,59 @@
|
|||
-10
|
||||
>>> conv_str2int('1e5')
|
||||
100000
|
||||
>>> conv_int2str(0)
|
||||
'0'
|
||||
>>> conv_int2str(1e5)
|
||||
'100000'
|
||||
>>> conv_int2str(367)
|
||||
'367'
|
||||
>>> conv_int2str(-10)
|
||||
'-10'
|
||||
'''
|
||||
'''
|
||||
|
||||
def conv_int2str(int1):
|
||||
aux_dict = {key:value for key in range(10) for value in '0123456789'[key]}
|
||||
if int1 == 0: return '0' # REMEMBER TO HANDLE 0
|
||||
if int1 < 0: # REMEMBER TO HANDLE NEGATIVE
|
||||
|
||||
if int1 == 0:
|
||||
return '0'
|
||||
elif int1 < 0:
|
||||
sign = '-'
|
||||
int1 = int1*(-1)
|
||||
else:
|
||||
sign = ''
|
||||
|
||||
|
||||
aux_ls = []
|
||||
|
||||
while int1 > 0:
|
||||
c = int1%10
|
||||
int1 = int1//10
|
||||
cadd = aux_dict[c]
|
||||
aux_ls.append(cadd)
|
||||
aux_ls.reverse() # REMEMBER TO REVERSE
|
||||
|
||||
aux_ls.reverse()
|
||||
|
||||
return sign + ''.join(aux_ls)
|
||||
|
||||
|
||||
|
||||
|
||||
def conv_str2int(str1):
|
||||
if not str1: return None
|
||||
'''
|
||||
>>> conv_int2str(0)
|
||||
'0'
|
||||
>>> conv_int2str(1e5)
|
||||
'100000'
|
||||
>>> conv_int2str(367)
|
||||
'367'
|
||||
>>> conv_int2str(-10)
|
||||
'-10'
|
||||
'''
|
||||
if not str1:
|
||||
return None
|
||||
|
||||
aux_dict = {key:value for value in range(10) for key in '0123456789'[value]}
|
||||
if str1[0] == '-':
|
||||
|
||||
if str1[0] == '-':
|
||||
sign = -1
|
||||
str1 = str1[1:] # REMEMBER TO CUT THE SIGN FROM THE STR
|
||||
else:
|
||||
str1 = str1[1:]
|
||||
else:
|
||||
sign = 1
|
||||
|
||||
dec, result = 1, 0
|
||||
for i in range(len(str1)-1, -1, -1): # REMEMBER TO FINISH IN -1, NOT 0, AND
|
||||
aux = str1[i] # AND DO THE STEPS -1
|
||||
|
||||
for i in range(len(str1)-1, -1, -1):
|
||||
aux = str1[i]
|
||||
if aux == 'e':
|
||||
exp_num = conv_str2int(str1[i+1:])
|
||||
number = conv_str2int(str1[:i])
|
||||
|
@ -59,8 +73,9 @@ def conv_str2int(str1):
|
|||
break
|
||||
result += aux_dict[aux]*dec
|
||||
dec *= 10
|
||||
|
||||
return result*sign
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
|
@ -1,21 +1,26 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
import collections
|
||||
import string
|
||||
import sys
|
||||
|
||||
|
||||
def count_unique_word():
|
||||
|
||||
words = collections.defaultdict(int)
|
||||
strip = string.whitespace + string.punctuation + string.digits + "\"'"
|
||||
|
||||
strip = string.whitespace + string.punctuation + string.digits + "\"'"
|
||||
|
||||
for filename in sys.argv[1:]:
|
||||
with open(filename) as file:
|
||||
for line in file:
|
||||
for line in file:
|
||||
for word in line.lower().split():
|
||||
word = word.strip(strip)
|
||||
if len(word) > 2:
|
||||
words[word] = +1
|
||||
|
||||
for word in sorted(words):
|
||||
print("'{0}' occurs {1} times.".format(word, words[word]))
|
||||
|
||||
|
49
src/builtin_structures/delete_duplicate_char_str.py
Executable file
49
src/builtin_structures/delete_duplicate_char_str.py
Executable file
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
''' find and delete all the duplicate characters in a string '''
|
||||
|
||||
from collections import Counter
|
||||
|
||||
def delete_unique(str1):
|
||||
'''
|
||||
>>> delete_unique("Trust no one")
|
||||
'on'
|
||||
>>> delete_unique("Mulder?")
|
||||
''
|
||||
'''
|
||||
|
||||
str_strip = ''.join(str1.split())
|
||||
repeat = Counter()
|
||||
|
||||
for c in str_strip:
|
||||
repeat[c] += 1
|
||||
|
||||
result = ''
|
||||
for c, count in repeat.items():
|
||||
if count > 1:
|
||||
result += c
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def removing_duplicates_seq(str1):
|
||||
'''
|
||||
>>> delete_unique("Trust no one")
|
||||
'on'
|
||||
>>> delete_unique("Mulder?")
|
||||
''
|
||||
'''
|
||||
seq = str1.split()
|
||||
result = set()
|
||||
for item in seq:
|
||||
if item not in result:
|
||||
#yield item
|
||||
result.add(item)
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
|
@ -1,33 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
from collections import Counter
|
||||
|
||||
def Counter_example():
|
||||
''' show some examples for Counter '''
|
||||
''' it is a dictionary that maps the items to the number of occurences '''
|
||||
seq1 = [1, 2, 3, 5, 1, 2, 5, 5, 2, 5, 1, 4]
|
||||
seq_counts = Counter(seq1)
|
||||
print(seq_counts)
|
||||
|
||||
''' we can increment manually or use the update() method '''
|
||||
seq2 = [1, 2, 3]
|
||||
seq_counts.update(seq2)
|
||||
print(seq_counts)
|
||||
|
||||
seq3 = [1, 4, 3]
|
||||
for key in seq3:
|
||||
seq_counts[key] += 1
|
||||
print(seq_counts)
|
||||
|
||||
''' also, we can use set operations such as a-b or a+b '''
|
||||
seq_counts_2 = Counter(seq3)
|
||||
print(seq_counts_2)
|
||||
print(seq_counts + seq_counts_2)
|
||||
print(seq_counts - seq_counts_2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
Counter_example()
|
||||
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
def OrderedDict_example():
|
||||
''' show some examples for OrderedDict '''
|
||||
''' keep the order of insertion.
|
||||
maintains a doubly linked list, so size is more than twice than normal dict'''
|
||||
|
||||
|
||||
pairs = [('a', 1), ('b',2), ('c',3)]
|
||||
|
||||
d1 = {}
|
||||
for key, value in pairs:
|
||||
if key not in d1:
|
||||
d1[key] = []
|
||||
d1[key].append(value)
|
||||
for key in d1:
|
||||
print(key, d1[key])
|
||||
|
||||
d2 = OrderedDict(pairs)
|
||||
for key in d2:
|
||||
print(key, d2[key])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
OrderedDict_example()
|
||||
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
def defaultdict_example():
|
||||
''' show some examples for defaultdicts '''
|
||||
pairs = {('a', 1), ('b',2), ('c',3)}
|
||||
|
||||
d1 = {}
|
||||
for key, value in pairs:
|
||||
if key not in d1:
|
||||
d1[key] = []
|
||||
d1[key].append(value)
|
||||
print(d1)
|
||||
|
||||
d2 = defaultdict(list)
|
||||
for key, value in pairs:
|
||||
d2[key].append(value)
|
||||
print(d2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
defaultdict_example()
|
||||
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
import string
|
||||
|
||||
def delete_unique_word(str1):
|
||||
''' find and delete all the duplicate characters in a string '''
|
||||
|
||||
# create ordered dict
|
||||
table_c = { key : 0 for key in string.ascii_lowercase}
|
||||
|
||||
# fill the table with the chars in the string
|
||||
for i in str1:
|
||||
table_c[i] += 1
|
||||
|
||||
# scan the table to find times chars > 1
|
||||
for key, value in table_c.items():
|
||||
if value > 1:
|
||||
str1 = str1.replace(key, "")
|
||||
|
||||
return str1
|
||||
|
||||
|
||||
def test_delete_unique_word():
|
||||
str1 = "google"
|
||||
assert(delete_unique_word(str1) == 'le')
|
||||
print('Tests passed!')
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_delete_unique_word()
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
def hash_func(astring, tablesize):
|
||||
sum = 0
|
||||
for pos in range(len(astring)):
|
||||
sum = sum + ord(astring[pos])
|
||||
return sum%tablesize
|
||||
|
||||
|
||||
def find_anagram_hash_function(word1, word2):
|
||||
''' verify if words are anagrams by comparying hash functions'''
|
||||
tablesize = 11
|
||||
return hash_func(word1, tablesize) == hash_func(word2, tablesize)
|
||||
|
||||
|
||||
|
||||
|
||||
def test_find_anagram_hash_function(module_name='this module'):
|
||||
word1 = 'buffy'
|
||||
word2 = 'bffyu'
|
||||
word3 = 'bffya'
|
||||
assert(find_anagram_hash_function(word1, word2) == True)
|
||||
assert(find_anagram_hash_function(word1, word3) == False)
|
||||
|
||||
s = 'Tests in {name} have {con}!'
|
||||
print(s.format(name=module_name, con='passed'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_anagram_hash_function()
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
from collections import Counter, defaultdict
|
||||
|
||||
def find_dice_probabilities(S, n_faces=6):
|
||||
''' given 2 dice, determine number of ways to sum S if all dice are rolled '''
|
||||
|
||||
if S > 2*n_faces or S < 2: return None
|
||||
|
||||
cdict = Counter()
|
||||
ddict = defaultdict(list)
|
||||
|
||||
for dice1 in range(1, n_faces+1):
|
||||
for dice2 in range(1, n_faces+1):
|
||||
t = [dice1, dice2]
|
||||
cdict[dice1+dice2] += 1
|
||||
ddict[dice1+dice2].append( t)
|
||||
|
||||
return [cdict[S], ddict[S]]
|
||||
|
||||
|
||||
def test_find_dice_probabilities(module_name='this module'):
|
||||
n_faces = 6
|
||||
S = 5
|
||||
results = find_dice_probabilities(S, n_faces)
|
||||
print(results)
|
||||
assert(results[0] == len(results[1]))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_dice_probabilities()
|
|
@ -1,38 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
def usual_dict(dict_data):
|
||||
newdata = {}
|
||||
for k, v in dict_data:
|
||||
if k in newdata:
|
||||
newdata[k].append(v)
|
||||
else:
|
||||
newdata[k] = [v]
|
||||
return newdata
|
||||
|
||||
|
||||
def setdefault_dict(dict_data):
|
||||
newdata = {}
|
||||
for k, v in dict_data:
|
||||
newdata.setdefault(k, []).append(v)
|
||||
return newdata
|
||||
|
||||
|
||||
def test_setdef(module_name='this module'):
|
||||
dict_data = (('key1', 'value1'),
|
||||
('key1', 'value2'),
|
||||
('key2', 'value3'),
|
||||
('key2', 'value4'),
|
||||
('key2', 'value5'),)
|
||||
print(usual_dict(dict_data))
|
||||
print(setdefault_dict(dict_data))
|
||||
|
||||
s = 'Tests in {name} have {con}!'
|
||||
print(s.format(name=module_name, con='passed'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_setdef()
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
import string
|
||||
|
||||
|
||||
def verify_two_strings_are_anagrams(str1, str2):
|
||||
""" find whether two words are anagrams. Since sets do not count occurency, and sorting is O(nlogn)
|
||||
we will use hash tables. We scan the first string and add all the character occurences. Then we
|
||||
scan the second tring and decrease all the caracther occurences. If all the counts are zero, it is
|
||||
an anagram"""
|
||||
|
||||
# create the hash table
|
||||
ana_table = {key:0 for key in string.ascii_lowercase}
|
||||
|
||||
# scan first string
|
||||
for i in str1:
|
||||
ana_table[i] += 1
|
||||
|
||||
# scan second string
|
||||
for i in str2:
|
||||
ana_table[i] -= 1
|
||||
|
||||
# verify whether all the entries are 0
|
||||
if len(set(ana_table.values())) < 2: return True
|
||||
else: return False
|
||||
|
||||
|
||||
def test_verify_two_strings_are_anagrams():
|
||||
str1 = 'marina'
|
||||
str2 = 'aniram'
|
||||
assert(verify_two_strings_are_anagrams(str1, str2) == True)
|
||||
str1 = 'google'
|
||||
str2 = 'gouglo'
|
||||
assert(verify_two_strings_are_anagrams(str1, str2) == False)
|
||||
print('Tests passed!')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_verify_two_strings_are_anagrams()
|
||||
|
||||
|
||||
|
||||
|
44
src/builtin_structures/fibonacci.py
Normal file
44
src/builtin_structures/fibonacci.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
def fib_generator():
|
||||
a, b = 0, 1
|
||||
|
||||
while True:
|
||||
yield b
|
||||
a, b = b, a+b
|
||||
|
||||
|
||||
def fib(n):
|
||||
'''
|
||||
>>> fib(2)
|
||||
1
|
||||
>>> fib(5)
|
||||
5
|
||||
>>> fib(7)
|
||||
13
|
||||
'''
|
||||
if n < 3:
|
||||
return 1
|
||||
|
||||
a, b = 0, 1
|
||||
count = 1
|
||||
|
||||
while count < n:
|
||||
count += 1
|
||||
a, b = b, a+b
|
||||
|
||||
return b
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
||||
fib = fib_generator()
|
||||
print(next(fib))
|
||||
print(next(fib))
|
||||
print(next(fib))
|
||||
print(next(fib))
|
|
@ -1,8 +1,8 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
|
||||
def find_0_MxN(m):
|
||||
''' find 0s in a matrix and replace the col and row to 0s:
|
||||
>>> m1 = [[1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14,15,16]]
|
||||
|
@ -13,6 +13,7 @@ def find_0_MxN(m):
|
|||
[[0, 2, 3, 4], [0, 0, 0, 0], [0, 10, 11, 12], [0, 14, 15, 16]]
|
||||
'''
|
||||
index = []
|
||||
|
||||
for row in range(len(m)):
|
||||
for col in range(len(m[0])):
|
||||
if m[row][col] == 0:
|
||||
|
@ -24,9 +25,10 @@ def find_0_MxN(m):
|
|||
m[row][i] = 0
|
||||
for i in range(len(m[0])):
|
||||
m[i][col] = 0
|
||||
|
||||
return m
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
32
src/builtin_structures/find_dice_probabilities.py
Normal file
32
src/builtin_structures/find_dice_probabilities.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
'''
|
||||
given 2 dice, determine number of ways to sum S if all dice are rolled
|
||||
'''
|
||||
|
||||
from collections import Counter, defaultdict
|
||||
|
||||
def find_dice_probabilities(S=5, n_faces=6):
|
||||
if S > 2*n_faces or S < 2:
|
||||
return None
|
||||
|
||||
cdict = Counter()
|
||||
ddict = defaultdict(list)
|
||||
|
||||
for dice1 in range(1, n_faces+1):
|
||||
for dice2 in range(1, n_faces+1):
|
||||
t = [dice1, dice2]
|
||||
cdict[dice1+dice2] += 1
|
||||
ddict[dice1+dice2].append( t)
|
||||
|
||||
return [cdict[S], ddict[S]]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
results = find_dice_probabilities()
|
||||
assert(results[0] == len(results[1]))
|
43
src/builtin_structures/find_edit_distance.py
Normal file
43
src/builtin_structures/find_edit_distance.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
''' computes the edit distance between two strings '''
|
||||
|
||||
|
||||
def find_edit_distance(str1, str2):
|
||||
'''
|
||||
>>> s = 'sunday'
|
||||
>>> t = 'saturday'
|
||||
>>> find_edit_distance(s, t)
|
||||
3
|
||||
'''
|
||||
|
||||
m = len(str1)
|
||||
n = len(str2)
|
||||
diff = lambda c1, c2: 0 if c1 == c2 else 1
|
||||
|
||||
E = [[0] * (n + 1) for i in range(m + 1)]
|
||||
|
||||
for i in range(m + 1):
|
||||
E[i][0] = i
|
||||
|
||||
for j in range(1, n + 1):
|
||||
E[0][j] = j
|
||||
|
||||
for i in range(1, m + 1):
|
||||
for j in range(1, n + 1):
|
||||
E[i][j] = min(E[i-1][j] + 1, E[i][j-1] + 1, E[i-1][j-1] + diff(str1[i-1], str2[j-1]))
|
||||
|
||||
return E[m][n]
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
||||
|
||||
|
||||
|
29
src/builtin_structures/find_first_non_repetead_char.py
Normal file
29
src/builtin_structures/find_first_non_repetead_char.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
from collections import Counter
|
||||
|
||||
def find_non_rep_char(s1):
|
||||
'''
|
||||
>>> s1 = 'aabbcceff'
|
||||
>>> find_non_rep_char(s1)
|
||||
e
|
||||
>>> find_non_rep_char('ccc')
|
||||
'''
|
||||
|
||||
aux_dict = Counter()
|
||||
|
||||
for i in s1:
|
||||
aux_dict[i] += 1
|
||||
|
||||
for k, v in aux_dict.items():
|
||||
if v < 2:
|
||||
print k
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
29
src/builtin_structures/find_gcd.py
Executable file
29
src/builtin_structures/find_gcd.py
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
|
||||
def finding_gcd(a, b):
|
||||
''' implements the greatest common divider algorithm '''
|
||||
while(b != 0):
|
||||
result = b
|
||||
a, b = b, a % b
|
||||
return result
|
||||
|
||||
|
||||
def test_finding_gcd():
|
||||
number1 = 21
|
||||
number2 = 12
|
||||
assert(finding_gcd(number1, number2) == 3)
|
||||
print('Tests passed!')
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_finding_gcd()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
36
src/builtin_structures/find_if_is_substr.py
Normal file
36
src/builtin_structures/find_if_is_substr.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
def find_substr(s1, s2):
|
||||
|
||||
if len(s1) < len(s2):
|
||||
bs = s2
|
||||
ss = s1
|
||||
else:
|
||||
bs = s1
|
||||
ss = s2
|
||||
|
||||
ps = 0
|
||||
|
||||
for c in bs:
|
||||
|
||||
if ss[ps] == c:
|
||||
ps += 1
|
||||
else:
|
||||
ps = 0
|
||||
|
||||
if ps == len(ss)-1:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
s1 = 'buffy is a vampire slayer'
|
||||
s2 = 'vampire'
|
||||
s3 = 'angel'
|
||||
assert(find_substr(s2, s1) == True)
|
||||
assert(find_substr(s3, s1) == False)
|
32
src/builtin_structures/find_if_unique_char.py
Normal file
32
src/builtin_structures/find_if_unique_char.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
|
||||
import collections
|
||||
|
||||
def find_if_unique_chars(word):
|
||||
"""
|
||||
>>> find_if_unique_chars('abcde')
|
||||
True
|
||||
>>> find_if_unique_chars('abcae')
|
||||
False
|
||||
"""
|
||||
|
||||
unique = True
|
||||
|
||||
counter = collections.Counter()
|
||||
|
||||
for c in word:
|
||||
if not counter[c]:
|
||||
counter[c] += 1
|
||||
else:
|
||||
unique = False
|
||||
|
||||
return unique
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
42
src/builtin_structures/find_largest_sum.py
Executable file
42
src/builtin_structures/find_largest_sum.py
Executable file
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
|
||||
'''
|
||||
You are given an array of integers (both positive and negative).
|
||||
Find the contiguous sequence with the largest sum.
|
||||
'''
|
||||
|
||||
|
||||
def find_largest_sum(array):
|
||||
'''
|
||||
>>> find_largest_sum([-1, 2, -3, 5, 3, 1, -16, 7, 1, -13, 1])
|
||||
9
|
||||
>>> find_largest_sum([])
|
||||
0
|
||||
>>> find_largest_sum([1])
|
||||
1
|
||||
'''
|
||||
|
||||
sum_ = 0
|
||||
sum_here = 0
|
||||
|
||||
for i in array:
|
||||
|
||||
sum_here += i
|
||||
|
||||
if sum_here < 0:
|
||||
sum_here = 0
|
||||
|
||||
if sum_ < sum_here:
|
||||
sum_ = sum_here
|
||||
|
||||
return sum_
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
32
src/builtin_structures/find_long_con_inc_subseq.py
Normal file
32
src/builtin_structures/find_long_con_inc_subseq.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
''' find the longest continuous increasing subsequence'''
|
||||
|
||||
|
||||
def find_long_con_inc(seq):
|
||||
'''
|
||||
>>> find_long_con_inc([1, -2, 3, 5, 1, -1, 4, -1, 6])
|
||||
[-2, 3, 5]
|
||||
>>> find_long_con_inc([1, 3, -2, 3, 5, 6])
|
||||
[-2, 3, 5, 6]
|
||||
'''
|
||||
|
||||
aux = []
|
||||
result = []
|
||||
seq.append(-float('infinity'))
|
||||
|
||||
for i, pivot in enumerate(seq[:-1]):
|
||||
aux.append(pivot)
|
||||
if pivot > seq[i+1]:
|
||||
if len(aux) > len(result):
|
||||
result = aux
|
||||
aux = []
|
||||
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
38
src/builtin_structures/find_longest_str_unique_chars.py
Normal file
38
src/builtin_structures/find_longest_str_unique_chars.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
'''
|
||||
given a string, find longest string with unique characters
|
||||
'''
|
||||
|
||||
def find_longest(string):
|
||||
'''
|
||||
>>> find_longest('abfgrhgtrdsandwejfhdasjcbdsjvrejwghireeej')
|
||||
'wejfhdas'
|
||||
>>> find_longest('abcabcabcabcdefabcccc')
|
||||
'defabc'
|
||||
'''
|
||||
maxs = ''
|
||||
result = ''
|
||||
|
||||
for c in string:
|
||||
if c in result:
|
||||
if len(maxs) < len(result):
|
||||
maxs = result
|
||||
result = ''
|
||||
else:
|
||||
result += c
|
||||
|
||||
if result and len(maxs) < len(result):
|
||||
maxs = result
|
||||
|
||||
return maxs
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
33
src/builtin_structures/find_non_repeating_number.py
Executable file
33
src/builtin_structures/find_non_repeating_number.py
Executable file
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
def find_unique_number(array):
|
||||
'''
|
||||
>>> find_unique_number([1, 3, 6, 1, 5, 6, 9, 3, 7])
|
||||
[1, 6, 3]
|
||||
>>> find_unique_number([1, 3, 5, 6, 9, 7])
|
||||
[]
|
||||
'''
|
||||
|
||||
table = defaultdict()
|
||||
total = []
|
||||
|
||||
for i in array:
|
||||
if i in table:
|
||||
total.append(i)
|
||||
else:
|
||||
table[i] = 1
|
||||
|
||||
return total
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
37
src/builtin_structures/find_prime_factors.py
Normal file
37
src/builtin_structures/find_prime_factors.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
'''
|
||||
find prime factors of a number.
|
||||
'''
|
||||
|
||||
import math
|
||||
|
||||
def find_prime_factors(n):
|
||||
'''
|
||||
>>> find_prime_factors(14)
|
||||
[2, 7]
|
||||
>>> find_prime_factors(19)
|
||||
[]
|
||||
'''
|
||||
|
||||
divisors = [d for d in range(2, n//2 + 1) if n % d == 0]
|
||||
primes = [d for d in divisors if is_prime(d)]
|
||||
|
||||
return primes
|
||||
|
||||
|
||||
def is_prime(n):
|
||||
for j in range(2, int(math.sqrt(n))):
|
||||
if (n % j) == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
42
src/builtin_structures/find_product_without_division.py
Normal file
42
src/builtin_structures/find_product_without_division.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
'''Given an array of numbers, replace each number with the product of all
|
||||
the numbers in the array except the number itself *without* using division
|
||||
'''
|
||||
|
||||
|
||||
def find_product_without_division(seq):
|
||||
'''
|
||||
>>> seq = [2,3,4]
|
||||
>>> find_product_without_division(seq)
|
||||
[12, 8, 6]
|
||||
'''
|
||||
|
||||
forw = []
|
||||
bacw = []
|
||||
|
||||
for i in range(len(seq)):
|
||||
|
||||
prod_f, prod_b = 1, 1
|
||||
|
||||
for next in range(i+1, len(seq)):
|
||||
prod_f *= seq[next]
|
||||
|
||||
for before in range(0, i):
|
||||
prod_b *= seq[before]
|
||||
|
||||
forw.append(prod_f)
|
||||
bacw.append(prod_b)
|
||||
|
||||
for i in range(len(seq)):
|
||||
seq[i] = forw[i] * bacw[i]
|
||||
|
||||
return seq
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
from collections import Counter
|
||||
|
||||
|
@ -8,24 +8,20 @@ def find_top_N_recurring_words(seq, N):
|
|||
''' find the top N recurring words in a file:
|
||||
1) use a hash table to find counts
|
||||
2) sort the list on base of the maximum counts
|
||||
3) return the last N words '''
|
||||
3) return the last N words
|
||||
'''
|
||||
|
||||
dcounter = Counter()
|
||||
for word in seq.split():
|
||||
dcounter[word] += 1
|
||||
dcounter[word] += 1
|
||||
|
||||
return dcounter.most_common(N)
|
||||
|
||||
|
||||
|
||||
def test_find_top_N_recurring_words(module_name='this module'):
|
||||
seq = 'buffy angel monster xander a willow gg buffy the monster super buffy angel'
|
||||
N = 3
|
||||
assert(find_top_N_recurring_words(seq, N) == [('buffy', 3), ('monster', 2), ('angel', 2)])
|
||||
|
||||
s = 'Tests in {name} have {con}!'
|
||||
print(s.format(name=module_name, con='passed'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_top_N_recurring_words()
|
||||
seq = 'buffy angel monster xander a willow gg buffy the monster super buffy angel'
|
||||
N = 3
|
||||
assert(find_top_N_recurring_words(seq, N) == [('buffy', 3), ('monster', 2), ('angel', 2)])
|
||||
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
"""
|
||||
Two numbers out of n numbers from 1 to n are missing.
|
||||
The remaining n-2 numbers are in the array but not sorted.
|
||||
Find the missing numbers The sum1 is the sum of all the elements in n.
|
||||
The sum2 is the sum of all the elements in n-2. sum1 - sum2 = num1 + num2 = s.
|
||||
The prod1 is the prod of all the elements in n. The prod2 is the prod of all
|
||||
the elements in n-2. prod1/prod2 = num1*num2 =p.
|
||||
Runtime is O(n), because it scan 3 times. Space is O(1)
|
||||
|
||||
In case of finding one integer, Let the missing number be M. We know that
|
||||
the sum of first N natural numbers is N*(N+1)/2. Traverse through the array
|
||||
once and calculate the sum. This is the sum of first N natural numbers -
|
||||
M or S=N*(N+1)/2 - M. Therefore M = N*(N+1)/2 - S.
|
||||
"""
|
||||
|
||||
import math
|
||||
|
||||
def find_two_missing_numbers(l1):
|
||||
'''
|
||||
>>> l1 = [1, 3, 5]
|
||||
>>> find_two_missing_numbers(l1)
|
||||
(4, 2)
|
||||
'''
|
||||
|
||||
n_min_2 = len(l1)
|
||||
n = n_min_2 + 2
|
||||
sum1, sum2, prod1, prod2 = 0, 0, 1, 1
|
||||
sum2 = sum(l1[:])
|
||||
sum1 = sum(range(1,n+1))
|
||||
s = sum1 - sum2
|
||||
|
||||
for i in range(1, n-1):
|
||||
prod1 = prod1*i
|
||||
prod2 = prod2*l1[i-1]
|
||||
|
||||
prod1 = prod1*n*(n-1)
|
||||
p = prod1/prod2
|
||||
num1 = (s + math.sqrt(s*s - 4*p))/2
|
||||
num2 = (s - math.sqrt(s*s - 4*p))/2
|
||||
|
||||
return int(num1), int(num2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
36
src/builtin_structures/generate_prime.py
Executable file
36
src/builtin_structures/generate_prime.py
Executable file
|
@ -0,0 +1,36 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
import math
|
||||
import random
|
||||
import sys
|
||||
from finding_prime import finding_prime_sqrt
|
||||
|
||||
|
||||
def generate_prime(number=3):
|
||||
''' return a n-bit prime '''
|
||||
while 1:
|
||||
p = random.randint(pow(2, number-2), pow(2, number-1)-1)
|
||||
p = 2 * p + 1
|
||||
if finding_prime_sqrt(p):
|
||||
return p
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) < 2:
|
||||
print ("Usage: generate_prime.py number")
|
||||
sys.exit()
|
||||
else:
|
||||
number = int(sys.argv[1])
|
||||
print(generate_prime(number))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
29
src/builtin_structures/get_float_rep_bin.py
Executable file
29
src/builtin_structures/get_float_rep_bin.py
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
''' 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 exit 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'
|
63
src/builtin_structures/interserction_two_arrays.py
Executable file
63
src/builtin_structures/interserction_two_arrays.py
Executable file
|
@ -0,0 +1,63 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
def intersection_two_arrays_sets(seq1, seq2):
|
||||
'''
|
||||
>>> intersection_two_arrays_sets([1,2,3,5,7,8], [3,5,6])
|
||||
set([3, 5])
|
||||
>>> intersection_two_arrays_sets([1,2,7,8], [3,5,6])
|
||||
set([])
|
||||
'''
|
||||
# O(n)
|
||||
set1 = set(seq1)
|
||||
set2 = set(seq2)
|
||||
|
||||
return set1.intersection(set2) #same as list(set1 & set2)
|
||||
|
||||
|
||||
def intersection_two_arrays_On2(seq1, seq2):
|
||||
'''
|
||||
>>> intersection_two_arrays_On2([1,2,3,5,7,8], [3,5,6])
|
||||
[3, 5]
|
||||
>>> intersection_two_arrays_On2([1,2,7,8], [3,5,6])
|
||||
[]
|
||||
'''
|
||||
|
||||
final = []
|
||||
|
||||
for i in seq1:
|
||||
for j in seq2:
|
||||
if i == j:
|
||||
final.append(i)
|
||||
|
||||
return final
|
||||
|
||||
|
||||
def intersection_two_arrays_On(seq1, seq2):
|
||||
'''
|
||||
>>> intersection_two_arrays_On([1,2,3,5,7,8], [3,5,6])
|
||||
[5, 3]
|
||||
>>> intersection_two_arrays_On([1,2,7,8], [3,5,6])
|
||||
[]
|
||||
'''
|
||||
|
||||
final = []
|
||||
|
||||
while seq1 and seq2:
|
||||
|
||||
if seq1[-1] == seq2[-1]:
|
||||
final.append(seq1.pop())
|
||||
seq2.pop()
|
||||
elif seq1[-1] > seq2[-1]:
|
||||
seq1.pop()
|
||||
else:
|
||||
seq2.pop()
|
||||
|
||||
return final
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
|
@ -1,29 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
''' give all the combinations of a str or list:
|
||||
>>> l1 = (1, 2, 3)
|
||||
>>> comb_str(l1)
|
||||
[[1], [1, [2]], [1, [2, 3]], [1, [3]], [2], [2, 3], [3]]
|
||||
>>> comb_str([])
|
||||
[]
|
||||
'''
|
||||
|
||||
|
||||
|
||||
def comb_str(l1):
|
||||
if len(l1) < 2: return l1
|
||||
result = []
|
||||
for i in range(len(l1)):
|
||||
result.append([l1[i]])
|
||||
for comb in comb_str(l1[i+1:]):
|
||||
result.append([l1[i], comb])
|
||||
return result
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
import string
|
||||
import sys
|
||||
|
||||
def count_unique_word():
|
||||
''' list every word and number of times in alphabetical order for input files '''
|
||||
words = {} # create an empty dictionary
|
||||
strip = string.whitespace + string.punctuation + string.digits + "\"'"
|
||||
for filename in sys.argv[1:]:
|
||||
with open(filename) as file:
|
||||
for line in file:
|
||||
for word in line.lower().split():
|
||||
word = word.strip(strip)
|
||||
if len(word) > 2:
|
||||
words[word] = words.get(word,0) +1
|
||||
for word in sorted(words):
|
||||
print("'{0}' occurs {1} times.".format(word, words[word]))
|
||||
|
||||
|
||||
count_unique_word()
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
|
||||
def find_all_permutations_string(str1):
|
||||
''' print all the permutations of a given string, recursive so runtime is O(n*(n-1)) '''
|
||||
res = []
|
||||
if len(str1) == 1:
|
||||
res = [str1]
|
||||
else:
|
||||
for i, c in enumerate(str1):
|
||||
for perm in find_all_permutations_string(str1[:i] + str1[i+1:]):
|
||||
res += [c + perm]
|
||||
return res
|
||||
|
||||
|
||||
def find_all_permutations_string_crazy(str1):
|
||||
''' crazy simple way of find all the permutations of a string, also using recursion'''
|
||||
return [str1] if len(str1) == 1 else [c + perm for i, c in enumerate(str1) for perm in find_all_permutations_string_crazy(str1[:i]+str1[i+1:])]
|
||||
|
||||
|
||||
def find_all_permutations_string_stdlib(str1):
|
||||
''' find all the permutations of a string just using the available packages '''
|
||||
from itertools import permutations
|
||||
perms = [''.join(p) for p in permutations(str1)]
|
||||
return perms
|
||||
|
||||
|
||||
def test_find_all_permutations_string():
|
||||
str1 = "abc"
|
||||
perm_set = {'abc', 'bac', 'cab', 'acb', 'cba', 'bca'}
|
||||
assert(set(find_all_permutations_string(str1)) == perm_set)
|
||||
assert(set(find_all_permutations_string_crazy(str1)) == perm_set)
|
||||
assert(set(find_all_permutations_string_stdlib(str1)) == perm_set)
|
||||
print('Tests passed!')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_all_permutations_string()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
|
||||
def find_closest_num_seq_unsorted(seq):
|
||||
''' Find the Closest two Numbers in a Sequence. If we do this without sorting
|
||||
first, the runtime will be O(n^2) '''
|
||||
dd = float("inf")
|
||||
for x in seq:
|
||||
for y in seq:
|
||||
if x == y: continue
|
||||
d = abs(x - y)
|
||||
if d < dd:
|
||||
xx, yy, dd = x, y, d
|
||||
return xx, yy
|
||||
|
||||
|
||||
def find_closest_num_seq_sorted(seq):
|
||||
''' However, if we sort first, we can achieve it with runtime O(n log n): '''
|
||||
seq.sort()
|
||||
print(seq)
|
||||
dd = float("inf")
|
||||
for i in range(len(seq) - 1):
|
||||
x, y = seq[i], seq[i+1]
|
||||
if x == y: continue
|
||||
d = abs(x-y)
|
||||
if d < dd:
|
||||
xx, yy, dd = x, y, d
|
||||
return xx, yy
|
||||
|
||||
|
||||
def test_find_closest_num_seq(module_name='this module'):
|
||||
import random
|
||||
seq = [random.randrange(100) for i in range(20)]
|
||||
print(seq)
|
||||
print(find_closest_num_seq_sorted(seq))
|
||||
print(find_closest_num_seq_unsorted(seq))
|
||||
|
||||
s = 'Tests in {name} have {con}!'
|
||||
print(s.format(name=module_name, con='passed'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_closest_num_seq()
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
def find_duplicate_num_array(l1):
|
||||
""" an array contains n numbers ranging from 0 to n-1. there are some numbers duplicated, but it is
|
||||
not clear how many. this code find a duplicate number in the array. """
|
||||
|
||||
""" A naive solution is to sort the input array, costing O(nlogn). Another solution is the utilization of a hash set. When the number is scanned, it is either in or not. It costs O(n) auxiliary memory to accomodate a hash set. A third solution, that only costs O(1) is consider that indexes in an array with length n are in the range n-1. If there were no duplication in the n numbers from 0 to n-1, we could rearange them sorted, so that each i has its ith number. Since there are duplicates, some locations are occupied by multiple numbers, other are vacant. So every number is scanned one by one, if it the number is not in the right i, it is compared to that from i, and the duplicate can be found, or we swap. Continue until a duplicate is found."""
|
||||
|
||||
for i in range(len(l1)):
|
||||
if l1[i] == i: continue
|
||||
elif l1[i] < 0 or l1[i] > len(l1)-1:
|
||||
return None
|
||||
elif l1[i] == l1[l1[i]]:
|
||||
return True
|
||||
else:
|
||||
aux = l1[l1[i]]
|
||||
l1[l1[i]] = l1[i]
|
||||
l1[i] = aux
|
||||
else:
|
||||
return False
|
||||
|
||||
def test_find_duplicate_num_array():
|
||||
a = [1,3,5,2,4,0]
|
||||
b = [1,3,5,2,1,0,4]
|
||||
c = [0,0]
|
||||
assert(find_duplicate_num_array(b) == True)
|
||||
assert(find_duplicate_num_array(a) == False)
|
||||
assert(find_duplicate_num_array(c) == True)
|
||||
print('Tests passed!')
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_duplicate_num_array()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
def find_edit_distance(str1, str2):
|
||||
''' computes the edit distance between two strings '''
|
||||
m = len(str1)
|
||||
n = len(str2)
|
||||
diff = lambda c1, c2: 0 if c1 == c2 else 1
|
||||
E = [[0] * (n + 1) for i in range(m + 1)]
|
||||
for i in range(m + 1):
|
||||
E[i][0] = i
|
||||
for j in range(1, n + 1):
|
||||
E[0][j] = j
|
||||
for i in range(1, m + 1):
|
||||
for j in range(1, n + 1):
|
||||
E[i][j] = min(E[i-1][j] + 1, E[i][j-1] + 1, E[i-1][j-1] + diff(str1[i-1], str2[j-1]))
|
||||
return E[m][n]
|
||||
|
||||
|
||||
def test_find_edit_distance():
|
||||
s = 'sunday'
|
||||
t = 'saturday'
|
||||
assert(find_edit_distance(s, t) == 3)
|
||||
print('Tests passed!')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_edit_distance()
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
''' find the first non-repetead char in a str.
|
||||
---> we use a dict to count occurences
|
||||
>>> find_non_rep_char("cut")
|
||||
'c'
|
||||
>>> s1 = 'google'
|
||||
>>> find_non_rep_char(s1)
|
||||
'l'
|
||||
>>> find_non_rep_char('ccc')
|
||||
>>> find_non_rep_char('')
|
||||
'''
|
||||
|
||||
from collections import Counter
|
||||
def find_non_rep_char(s1):
|
||||
aux_dict = Counter()
|
||||
for i in s1:
|
||||
aux_dict[i] += 1
|
||||
for i in s1:
|
||||
if aux_dict[i] < 2: return i # remember it's <2
|
||||
# not handling anything else: return None
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
''' Find if a s2 is a substring of a s1
|
||||
>>> s1 = 'buffy is a vampire slayer'
|
||||
>>> s2 = 'vampire'
|
||||
>>> s3 = 'angel'
|
||||
>>> isSubstr(s1, s2)
|
||||
True
|
||||
>>> isSubstr(s1, s3)
|
||||
False
|
||||
>>> s4 = 'pirevam'
|
||||
>>> find_substr(s2, s4)
|
||||
True
|
||||
>>> find_substr(s1, s4)
|
||||
False
|
||||
'''
|
||||
|
||||
def isSubstr(s1, s2):
|
||||
if s1 in s2 or s2 in s1: return True
|
||||
return False
|
||||
|
||||
|
||||
def find_substr(s1, s2):
|
||||
if s1 == '' or s2 == '': return True #empty str is always substr
|
||||
for i, c in enumerate(s1):
|
||||
if c == s2[0]:
|
||||
test_s1 = s1[i:]+s1[:i]
|
||||
return isSubstr(s2, test_s1)
|
||||
return False
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
def unique_char(s):
|
||||
if len(s) > 256: return False
|
||||
set_chars = set()
|
||||
for i in s:
|
||||
if i in set_chars:
|
||||
return False
|
||||
else:
|
||||
set_chars.add(i)
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def unique_char_no_add(s):
|
||||
if len(s) < 2: return True
|
||||
for i, c in enumerate(s):
|
||||
for j in s[i+1:]:
|
||||
if j == c:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def main():
|
||||
s1 = 'abcdefg'
|
||||
s2 = 'buffy'
|
||||
s3 = ''
|
||||
print(unique_char(s1))
|
||||
print(unique_char(s2))
|
||||
print(unique_char(s3))
|
||||
print(unique_char_no_add(s1) )
|
||||
print(unique_char_no_add(s2))
|
||||
print(unique_char_no_add(s3))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
def find_long_con_inc(seq):
|
||||
''' find the longest continuous increasing subsequence'''
|
||||
one_seq = []
|
||||
result = []
|
||||
|
||||
for i in range(0, len(seq)-1):
|
||||
pivot = seq[i]
|
||||
if pivot <= seq[i+1]:
|
||||
one_seq.append(pivot)
|
||||
else:
|
||||
one_seq.append(pivot)
|
||||
if len(one_seq) > len(result):
|
||||
result = one_seq
|
||||
one_seq = []
|
||||
return result
|
||||
|
||||
|
||||
def test_find_long_con_inc(module_name='this module'):
|
||||
seq = [1, -2, 3, 5, 1, -1, 4, -1, 6]
|
||||
long_con_inc = [-2,3,5]
|
||||
|
||||
assert(find_long_con_inc(seq) == long_con_inc )
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_long_con_inc()
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
def find_majority_in_seq(seq):
|
||||
''' find value which occurrence is greater than the total occurrence of all other elements '''
|
||||
times = 1
|
||||
result = seq[0]
|
||||
for i in range(len(seq)):
|
||||
if times == 0:
|
||||
result = seq[i]
|
||||
times = 1
|
||||
elif seq[i] == result:
|
||||
times +=1
|
||||
else:
|
||||
times -=1
|
||||
|
||||
if times == 0: return None
|
||||
else:
|
||||
count = 0
|
||||
for i, c in enumerate(seq):
|
||||
if c == result:
|
||||
count += 1
|
||||
return result, count
|
||||
|
||||
|
||||
def test_find_majority_in_seq():
|
||||
seq = [1, 1, 2, 3, 3, 3, 4, 4, 4, 4, 5, 6]
|
||||
seq2 = [1, 2, 3]
|
||||
assert(find_majority_in_seq(seq) == (4, 4))
|
||||
assert(find_majority_in_seq(seq2) == None)
|
||||
print('Tests passed!')
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_majority_in_seq()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"""
|
||||
>>> A = [1, 2, 3, 2, 2, 4, 2, 5, 2]
|
||||
>>> find_majority(A)
|
||||
(2, 5)
|
||||
>>> A = [1]
|
||||
>>> find_majority(A)
|
||||
(1, 1)
|
||||
>>> A = [1, 2, 3, 2, 5, 6, 7]
|
||||
>>> find_majority(A)
|
||||
No Majority Element.
|
||||
"""
|
||||
|
||||
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
def find_max_profit_On(seq):
|
||||
''' find the most profit from a seq with O(n) '''
|
||||
max_profit = 0
|
||||
min_value = seq[0]
|
||||
for i in range(1, len(seq)):
|
||||
profit_here = seq[i]- min_value
|
||||
if profit_here > max_profit:
|
||||
max_profit = profit_here
|
||||
else:
|
||||
if min_value > seq[i]:
|
||||
min_value = seq[i]
|
||||
|
||||
return max_profit
|
||||
|
||||
|
||||
def find_max_profit_On2(seq):
|
||||
''' find the most profit from a seq with O(n2) '''
|
||||
max_profit = 0
|
||||
for i in range(len(seq)-1):
|
||||
for j in range (i, len(seq)-1):
|
||||
if seq[j] - seq[i] > max_profit:
|
||||
max_profit = seq[j] - seq[i]
|
||||
return max_profit
|
||||
|
||||
|
||||
def test_find_max_profit():
|
||||
seq = [9,11,5,7,16,1]
|
||||
assert(find_max_profit_On(seq) == 11)
|
||||
assert(find_max_profit_On2(seq) == 11)
|
||||
seq = [1,15,2,3,4,3]
|
||||
assert(find_max_profit_On(seq) == 14)
|
||||
assert(find_max_profit_On2(seq) == 14)
|
||||
print('Tests passed!')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_max_profit()
|
||||
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
def find_max_subarray1(l1):
|
||||
''' calculate the greatest sum of subarrays from an array.
|
||||
An array with n elements has n(n+1)/2 subarrays so force brute cost O(n^2).
|
||||
What we can do is to check when a sum becomes a negative number or zero, and then discard, since
|
||||
this will not "add" anything to the new event... When the sum decreases, it gets the previous sum. '''
|
||||
sum_new, result = 0, 0
|
||||
for c in l1:
|
||||
result = max(result, sum_new)
|
||||
sum_new += c
|
||||
if sum_new <= 0: sum_new = 0
|
||||
return result
|
||||
|
||||
|
||||
|
||||
def find_max_subarray2(l1):
|
||||
''' find the contiguous subarray which has the largest sum (Kadane's algorithm in O(n))
|
||||
with extra O(n) space '''
|
||||
sum_old = [l1[0]]
|
||||
for c in l1:
|
||||
sum_old.append(max(c, sum_old [-1] + c))
|
||||
return max(sum_old)
|
||||
|
||||
|
||||
def test_find_max_subarray():
|
||||
l1 = [-2, 1, -3, 4, -1, 2, 1, -5, 4]
|
||||
l2 = [-1, 3, -5, 4, 6, -1, 2, -7, 13, -3]
|
||||
assert(find_max_subarray1(l1)) == 6)
|
||||
assert(find_max_subarray1(l2)) == 17)
|
||||
assert(find_max_subarray2(l1) == 6)
|
||||
assert(find_max_subarray2(l2) == 17)
|
||||
print('Tests passed!')
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_max_subarray()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
def find_palindrome_rec(s):
|
||||
''' recursive way of checking whether a str is a palindrome '''
|
||||
if len(s) > 1:
|
||||
if s[0] != s[-1]: return False
|
||||
else: find_palindrome_rec(s[1:-1])
|
||||
return True
|
||||
|
||||
|
||||
def test_find_palindrome_rec(module_name='this module'):
|
||||
str1 = 'radar'
|
||||
str2 = ""
|
||||
str3 = 'x'
|
||||
str4 = 'hello'
|
||||
assert(find_palindrome_rec(str1) == True)
|
||||
assert(find_palindrome_rec(str2) == True)
|
||||
assert(find_palindrome_rec(str3) == True)
|
||||
assert(find_palindrome_rec(str4) == False)
|
||||
s = 'Tests in {name} have {con}!'
|
||||
print(s.format(name=module_name, con='passed'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_palindrome_rec()
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
def find_product_without_division(seq):
|
||||
'''Given an array of numbers, replace each number with the product of all the numbers in the array except the number itself *without* using division '''
|
||||
forw = []
|
||||
bacw = []
|
||||
|
||||
for i in range(len(seq)):
|
||||
prod_f = 1
|
||||
prod_b = 1
|
||||
for next in range(i+1, len(seq)):
|
||||
prod_f *= seq[next]
|
||||
for before in range(0, i):
|
||||
prod_b *= seq[before]
|
||||
forw.append(prod_f)
|
||||
bacw.append(prod_b)
|
||||
|
||||
print(bacw)
|
||||
print(forw)
|
||||
for i in range(len(seq)):
|
||||
seq[i] = forw[i]*bacw[i]
|
||||
|
||||
return seq
|
||||
|
||||
|
||||
|
||||
def test_find_product_without_division():
|
||||
seq = [2,3,4]
|
||||
result = [12, 8, 6]
|
||||
print(find_product_without_division(seq))
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_product_without_division()
|
|
@ -1,41 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
def find_subst_in_str(str1, set1):
|
||||
sub_str1 = ''
|
||||
found = False
|
||||
|
||||
while set1:
|
||||
for c in str1:
|
||||
if c in set1:
|
||||
set1.remove(c)
|
||||
found = True
|
||||
if found == True:
|
||||
sub_str1 += c
|
||||
if len(set1) == 0: found = False
|
||||
return sub_str1
|
||||
|
||||
|
||||
|
||||
def test_find_subst_in_str(module_name='this module'):
|
||||
str1 = 'ydxahbcscdk'
|
||||
|
||||
set1 = {'a','b','c','d'}
|
||||
result = 'dxahbc'
|
||||
|
||||
assert( find_subst_in_str(str1, set1)==result)
|
||||
|
||||
set2 = {'a','b','c'}
|
||||
result2 = 'ahbc'
|
||||
assert( find_subst_in_str(str1, set2)==result2)
|
||||
|
||||
|
||||
s = 'Tests in {name} have {con}!'
|
||||
print(s.format(name=module_name, con='passed'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_subst_in_str()
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
import math
|
||||
|
||||
def find_two_missing_numbers(l1):
|
||||
""" Two numbers out of n numbers from 1 to n are missing. The remaining n-2 numbers are in the
|
||||
array but not sorted. Find the missing numbers The sum1 is the sum of all the elements in n. The
|
||||
sum2 is the sum of all the elements in n-2. sum1 - sum2 = num1 + num2 = s. The prod1 is the prod of
|
||||
all the elements in n. The prod2 is the prod of all the elements in n-2. prod1/prod2 = num1*num2 =
|
||||
p. Runtime is O(n), because it scan 3 times. Space is O(1)
|
||||
|
||||
- In case of finding one integer, Let the missing number be M. We know that the sum of first N
|
||||
natural numbers is N*(N+1)/2. Traverse through the array once and calculate the sum. This is the
|
||||
sum of first N natural numbers – M or S=N*(N+1)/2 – M. Therefore M = N*(N+1)/2 – S.
|
||||
"""
|
||||
|
||||
n_min_2 = len(l1)
|
||||
n = n_min_2 + 2
|
||||
sum1, sum2, prod1, prod2 = 0,0,1,1
|
||||
sum2 = sum(l1[:])
|
||||
sum1 = sum(range(1,n+1))
|
||||
s = sum1 - sum2
|
||||
|
||||
for i in range(1, n-1):
|
||||
prod1 = prod1*i
|
||||
prod2 = prod2*l1[i-1]
|
||||
|
||||
prod1 = prod1*n*(n-1)
|
||||
p = prod1/prod2
|
||||
num1 = (s + math.sqrt(s*s - 4*p))/2
|
||||
num2 = (s - math.sqrt(s*s - 4*p))/2
|
||||
|
||||
return num1, num2
|
||||
|
||||
|
||||
|
||||
def test_find_two_missing_numbers():
|
||||
l1 = [1, 3, 5]
|
||||
result = find_two_missing_numbers(l1)
|
||||
assert(result[0] == 2.0 or result[0] == 4.0)
|
||||
print('Tests passed!')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_two_missing_numbers()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
def greatest_sum_sub_array(l1):
|
||||
sum_new = 0
|
||||
results = []
|
||||
for i, c in enumerate(l1):
|
||||
sum_old = sum_new
|
||||
sum_new = sum_old + c
|
||||
if sum_new <= 0 or sum_new < sum_old:
|
||||
sum_new = 0
|
||||
results.append(sum_old)
|
||||
continue
|
||||
results.append(sum_new)
|
||||
results.sort()
|
||||
return results.pop()
|
||||
|
||||
def test_greatest_sum_sub_array():
|
||||
l1 = [1, -4, 20, -4, 5, 15, 3]
|
||||
assert(greatest_sum_sub_array(l1) == 23)
|
||||
print('Tests passed!')
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_greatest_sum_sub_array()
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
|
||||
def longest_common_substring(str1, str2):
|
||||
''' find the largest commom substring from 2 strings '''
|
||||
m = [[0 for i in range(len(str2) + 1)] for k in range(len(str1) + 1)]
|
||||
lcs = None
|
||||
max_len = 0
|
||||
for y in range(1, len(str1) + 1):
|
||||
for x in range(1, len(str2) + 1):
|
||||
m[y][x] = m[y - 1][x - 1] + 1 if (str1[y - 1] == str2[x - 1]) else 0
|
||||
|
||||
if m[y][x] > max_len:
|
||||
max_len = m[y][x]
|
||||
lcs = str1[(y - max_len):y]
|
||||
return max_len, lcs
|
||||
|
||||
|
||||
def test_longest_common_substring():
|
||||
str1 = 'buffy is a vampire slayer'
|
||||
str2 = 'aaas bampires vslay'
|
||||
assert(longest_common_substring(str1, str2) == (6, 'ampire'))
|
||||
print('Tests passed!')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_longest_common_substring()
|
||||
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
def merge_two_sorted_arrays(a1, a2):
|
||||
""" merge two sorted arrays, keeping the final sorted """
|
||||
if len(a1) >= len(a2):
|
||||
biga = a1
|
||||
smalla = a2
|
||||
else:
|
||||
biga = a2
|
||||
smalla = a1
|
||||
final = []
|
||||
count = 0
|
||||
for i in range(len(biga)):
|
||||
if count < len(smalla) and smalla[count] < biga[i]:
|
||||
final.append(smalla[count])
|
||||
count+=1
|
||||
final.append(biga[i])
|
||||
return final
|
||||
|
||||
def test_merge_two_sorted_arrays():
|
||||
a1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
a2 = [3, 6, 7]
|
||||
assert(merge_two_sorted_arrays(a1, a2) == [0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 7, 8, 9, 10])
|
||||
print('Tests passed!')
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_merge_two_sorted_arrays()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
''' give all the permutation of a str:
|
||||
>>> str1 = 'hat'
|
||||
>>> perm_str(str1)
|
||||
['hat', 'hta', 'aht', 'ath', 'tha', 'tah']
|
||||
>>> perm_str('')
|
||||
''
|
||||
'''
|
||||
|
||||
def perm_str(str1):
|
||||
if len(str1) < 2: return str1
|
||||
result = []
|
||||
for i in range(len(str1)):
|
||||
for perm in perm_str(str1[:i] + str1[i+1:]):
|
||||
result.append(str1[i] + perm)
|
||||
return result
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
def print_all_seq_with_cont_num(s):
|
||||
''' print all sequences with cont. numbers (2 at least) whose sum is a given s '''
|
||||
if s < 3: return s
|
||||
small = 1
|
||||
big = 2
|
||||
sum_here = big + small
|
||||
result = []
|
||||
|
||||
while small < (1+s)/2:
|
||||
sum_here = sum(range(small, big))
|
||||
if sum_here < s:
|
||||
big += 1
|
||||
elif sum_here > s:
|
||||
small +=1
|
||||
else:
|
||||
result.append(list(range(small, big)))
|
||||
big += 1
|
||||
|
||||
return result
|
||||
|
||||
def test_print_all_seq_with_cont_num():
|
||||
s = 15
|
||||
sum_set_for_s = [[1,2,3,4,5], [4,5,6], [7,8]]
|
||||
assert(print_all_seq_with_cont_num(s) == sum_set_for_s)
|
||||
s = 1
|
||||
assert(print_all_seq_with_cont_num(s)== 1)
|
||||
s = 0
|
||||
assert(print_all_seq_with_cont_num(s) == 0)
|
||||
print('Tests passed!')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_print_all_seq_with_cont_num()
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
''' remove the chars in a list from a string
|
||||
---> handle whitespaces!!!!
|
||||
>>> remove_char_str('I love google', 'oe')
|
||||
'I lv ggl'
|
||||
>>> remove_char_str('google', '')
|
||||
'google'
|
||||
>>> remove_char_str('google', 'google')
|
||||
''
|
||||
'''
|
||||
|
||||
|
||||
def remove_char_str(s1, charlist):
|
||||
set_aux = set(charlist)
|
||||
lt_aux = [] # we use list intead of concat. strs because it's more efficient
|
||||
for c in s1:
|
||||
if c not in set_aux:
|
||||
lt_aux.append(c)
|
||||
return ''.join(lt_aux) # IF NON CHARS, RETURN '' not NONE!
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
def removing_duplicates_seq(seq):
|
||||
''' if the values are hashable, we can use set and generators to remove duplicates
|
||||
in a sequence '''
|
||||
seen = set()
|
||||
for item in seq:
|
||||
if item not in seen:
|
||||
yield item
|
||||
seen.add(item)
|
||||
|
||||
def removing_duplicates_seq_not_hash(seq, key= None):
|
||||
''' if the item is not hashable, such as dictionaries '''
|
||||
seen = set()
|
||||
for item in seq:
|
||||
val = item if key is None else key[item]
|
||||
if item not in seen:
|
||||
yield item
|
||||
seen.add(val)
|
||||
|
||||
|
||||
|
||||
def test_removing_duplicates_seq():
|
||||
seq = [1, 2, 2, 2, 3, 3, 4, 4, 4]
|
||||
dict = {'a':1, 'b':2, 'a':2, 'a':1}
|
||||
assert(list(removing_duplicates_seq(seq)) == [1,2,3,4])
|
||||
assert(list(removing_duplicates_seq_not_hash(dict)) == ['a', 'b'])
|
||||
print('Tests passed!'.center(20, '*'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_removing_duplicates_seq()
|
||||
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
author = "Mari Wahl"
|
||||
email = "marina.w4hl@gmail.com"
|
||||
|
||||
|
||||
# timeit is used for benchmarking.
|
||||
from timeit import timeit
|
||||
|
||||
|
||||
def reverse_1(string):
|
||||
"""
|
||||
Slowest function. Use a list and str.join to reverse the string.
|
||||
:param string: the string to be reversed.
|
||||
:return: a reversed string.
|
||||
"""
|
||||
reversed_string = []
|
||||
# Iterates from the last to the first character.
|
||||
for i in range(len(string) - 1, -1, -1):
|
||||
# Appends the character to the list.
|
||||
reversed_string.append(string[i])
|
||||
return ''.join(reversed_string)
|
||||
|
||||
|
||||
def reverse_2(string):
|
||||
"""
|
||||
Same principle as reverse_1. One-liner cousin.
|
||||
:param string: the string to be reversed.
|
||||
:return: a reversed string.
|
||||
"""
|
||||
return ''.join([character for character in [string[i] for i in range(len(string) - 1, -1, -1)]])
|
||||
|
||||
|
||||
def reverse_3(string):
|
||||
"""
|
||||
Another one-liner. We make a list from the characters of the string and reverse it.
|
||||
:param string: the string to be reversed.
|
||||
:return: a reversed string.
|
||||
"""
|
||||
return ''.join([character for character in string][::-1])
|
||||
|
||||
# Overkill of elegance. A bit too passionate but it defines this lambda function well.
|
||||
# Simply returns the string backwards. As fast as concise.
|
||||
reverse_lambda = lambda s: s[::-1]
|
||||
|
||||
# We define some short strings to test our functions.
|
||||
strings = ('buffy', 'foo', 'bar')
|
||||
# We announce what we are doing.
|
||||
print(', '.join(strings), ' should appear reversed if the function is working.\n')
|
||||
print('{:<30}:'.format('Function name'), 'benchmarking result (lower is better):')
|
||||
# Iterate over a tuple of functions.
|
||||
for function in (reverse_1, reverse_2, reverse_3, reverse_lambda):
|
||||
name = function.__name__ if function.__name__ != "<lambda>" else 'reverse_lambda'
|
||||
# We print the function's name and its benchmark result.
|
||||
print("{:<30}:".format(name), timeit(name + "('string')", setup='from __main__ import ' + name))
|
||||
# We print the output so that we can check if the function is working as expected.
|
||||
print(', '.join(map(function, strings)), '\n')
|
||||
# We wait until the user wants to quit.
|
||||
input('Press Return to quit.')
|
|
@ -1,35 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
author = "Mari Wahl"
|
||||
email = "marina.w4hl@gmail.com"
|
||||
|
||||
|
||||
|
||||
def reverse_string_inplace_rec(s):
|
||||
''' takes a string and returns its reverse'''
|
||||
if s:
|
||||
s = s[-1] + reverse_string_inplace_rec(s[:-1])
|
||||
return s
|
||||
|
||||
def reverse_string_inplace(s):
|
||||
s = s[::-1]
|
||||
if s[0] == '\0':
|
||||
s = s[1:]
|
||||
s += '\0'
|
||||
return s
|
||||
|
||||
|
||||
|
||||
def test_reverse_string_inplace_rec(module_name='this module'):
|
||||
s = 'hello'
|
||||
s2 = 'buffy\0'
|
||||
assert(reverse_string_inplace(s) == 'olleh')
|
||||
assert(reverse_string_inplace(s2) == 'yffub\0')
|
||||
assert(reverse_string_inplace_rec(s) == 'olleh')
|
||||
|
||||
s = 'Tests in {name} have {con}!'
|
||||
print(s.format(name=module_name, con='passed'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_reverse_string_inplace_rec()
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
|
||||
#!/usr/bin/env python
|
||||
|
||||
author = "Mari Wahl"
|
||||
email = "marina.w4hl@gmail.com"
|
||||
|
||||
""" Here we want to invert the words in a string, without reverting
|
||||
the words.
|
||||
|
||||
Important things to remember:
|
||||
|
||||
1. python strings are immutable
|
||||
2. The last word doesn't not end by a space, so we need to make
|
||||
sure we get the last word too
|
||||
|
||||
The solution consists of two loops,
|
||||
1) revert all the characters with 2 pointers
|
||||
2) search for spaces and revert the words, two pointers too
|
||||
3) You can represent space as ' ' or as u'\u0020'
|
||||
4) Do we want to look to ! ; , . etc?
|
||||
|
||||
In the solutions bellow, we show how to do this logic, and how to use
|
||||
python's methods to do in a few lines
|
||||
"""
|
||||
|
||||
|
||||
# EXAMPLE NUMBER 1
|
||||
|
||||
def reverser(string1, p1=0, p2=None):
|
||||
if len(string1) < 2:
|
||||
return string1
|
||||
p2 = p2 or len(string1)-1
|
||||
while p1 < p2:
|
||||
aux = string1[p1]
|
||||
string1[p1] = string1[p2]
|
||||
string1[p2] = aux
|
||||
p1 += 1
|
||||
p2 -= 1
|
||||
|
||||
|
||||
|
||||
def reversing_words_setence_logic(string1):
|
||||
reverser(string1)
|
||||
p = 0
|
||||
start = 0
|
||||
while p < len(string1):
|
||||
if string1[p] == u"\u0020":
|
||||
reverser(string1,start,p-1)
|
||||
start = p+1
|
||||
p += 1
|
||||
reverser(string1,start,p-1)
|
||||
|
||||
return "".join(string1)
|
||||
|
||||
|
||||
|
||||
# EXAMPLE NUMBER 2 AND 3 USING PYTHON AWESOMESAUCE
|
||||
|
||||
def reversing_words_setence_py(str1):
|
||||
''' reverse the words in a sentence'''
|
||||
words = str1.split()
|
||||
rev_set = " ".join(reversed(words))
|
||||
return rev_set
|
||||
|
||||
def reversing_words_setence_py2(str1):
|
||||
"""
|
||||
Reverse the order of the words in a sentence.
|
||||
:param string: the string which words wilL be reversed.
|
||||
:return: the reversed string.
|
||||
"""
|
||||
words = str1.split(' ')
|
||||
words.reverse()
|
||||
return ' '.join(words)
|
||||
|
||||
|
||||
# EXAMPLE 4, VERY SILLY, USING BRUTE FORCE
|
||||
#
|
||||
def reverse_words_brute(string):
|
||||
"""
|
||||
Reverse the order of the words in a sentence.
|
||||
:param string: the string which words wil lbe reversed.
|
||||
:return: the reversed string.
|
||||
"""
|
||||
word, sentence = [], []
|
||||
for character in string:
|
||||
if character != ' ':
|
||||
word.append(character)
|
||||
else:
|
||||
# So we do not keep multiple whitespaces. An empty list evaluates to False.
|
||||
if word:
|
||||
sentence.append(''.join(word))
|
||||
word = []
|
||||
# So we do not keep multiple whitespaces. An empty list evaluates to False.
|
||||
if word != '':
|
||||
sentence.append(''.join(word))
|
||||
sentence.reverse()
|
||||
return ' '.join(sentence)
|
||||
|
||||
|
||||
|
||||
# TESTS
|
||||
|
||||
def test_reversing_words_sentence():
|
||||
str1 = "Buffy is a Vampire Slayer"
|
||||
assert(reversing_words_setence_py(str1) == "Slayer Vampire a is Buffy")
|
||||
assert(reversing_words_setence_py2(str1) == "Slayer Vampire a is Buffy")
|
||||
assert(reverse_words_brute(str1) == "Slayer Vampire a is Buffy")
|
||||
assert(reversing_words_setence_logic(list(str1)) == "Slayer Vampire a is Buffy")
|
||||
|
||||
print("Tests passed!")
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_reversing_words_sentence()
|
||||
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
def sum_two_numbers_sequence(seq, s):
|
||||
""" given an increasing sorted array and an integer s, find if there is a pair of two numbers in the array whose sum is s. It takes O(n). """
|
||||
l1 = seq[:]
|
||||
l2 = seq[:]
|
||||
l2.reverse()
|
||||
n1 = l1.pop()
|
||||
n2 = l2.pop()
|
||||
while l2 and l1:
|
||||
sum_here = n1 + n2
|
||||
if sum_here > s:
|
||||
n1 = l1.pop()
|
||||
elif sum_here < s:
|
||||
n2 = l2.pop()
|
||||
else:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
|
||||
def test_sum_two_numbers_sequence():
|
||||
l1 = [1,2,3,4,5,6,7,8]
|
||||
s = 7
|
||||
assert(sum_two_numbers_sequence(l1, s) == True)
|
||||
print('Tests passed!')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_sum_two_numbers_sequence()
|
||||
|
||||
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
|
||||
|
||||
def ver_perm(s1, s2):
|
||||
''' worst case O(nlogn + mlogm) = O(NlogN) '''
|
||||
if len(s1) != len(s2): return False
|
||||
s1 = sorted(s1)
|
||||
s2 = sorted(s2)
|
||||
return s1 == s2
|
||||
|
||||
from collections import Counter
|
||||
def ver_perm_dict(s1, s2):
|
||||
''' worst case O(n + n +2n) = O(n)'''
|
||||
if len(s1) != len(s2): return False
|
||||
dict_aux = Counter()
|
||||
for c in s1:
|
||||
dict_aux[c] += 1
|
||||
for c in s2:
|
||||
dict_aux[c] -= 1
|
||||
for item in dict_aux:
|
||||
if dict_aux[item]:
|
||||
return False
|
||||
return True
|
||||
|
||||
import time
|
||||
def main():
|
||||
s1 = 'ufyfbufyfb'
|
||||
s2 = 'buffybuffy'
|
||||
s3 = 'uuyfbuuyfb'
|
||||
s4 = ''
|
||||
start = time.time()
|
||||
print(ver_perm(s1, s2))
|
||||
print(ver_perm(s1, s3))
|
||||
print(ver_perm(s1, s4))
|
||||
final1 = time.time() - start
|
||||
|
||||
start = time.time()
|
||||
print(ver_perm_dict(s1, s2))
|
||||
print(ver_perm_dict(s1, s3))
|
||||
print(ver_perm_dict(s1, s4))
|
||||
final2 = time.time() - start
|
||||
|
||||
print(final2-final1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
76
src/builtin_structures/longest_common_prefix.py
Normal file
76
src/builtin_structures/longest_common_prefix.py
Normal file
|
@ -0,0 +1,76 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
'''
|
||||
Given two strings, write a function
|
||||
to calculate the longest common prefix (LCP) of the strings.
|
||||
'''
|
||||
|
||||
def lcp(s1, s2):
|
||||
'''
|
||||
>>> lcp('dabbd', 'aabbaa')
|
||||
3
|
||||
>>> lcp('abcd', 'hi')
|
||||
0
|
||||
'''
|
||||
|
||||
p1 = 0
|
||||
aux, lcp = '', ''
|
||||
string1 = min(s1, s2)
|
||||
string2 = max(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 len(lcp)
|
||||
|
||||
|
||||
|
||||
def lcppy(x):
|
||||
'''
|
||||
>>> lcppy([[3,2,1], [3,2,1,4,5]])
|
||||
[3, 2, 1]
|
||||
'''
|
||||
import os
|
||||
return os.path.commonprefix(x)
|
||||
|
||||
|
||||
def lcp2(s1, s2):
|
||||
'''
|
||||
>>> lcp2('dabbd', 'aabbaa')
|
||||
3
|
||||
>>> lcp2('abcd', 'hi')
|
||||
0
|
||||
'''
|
||||
m = [[0 for i in range(len(s2) + 1)] for k in range(len(s1) + 1)]
|
||||
|
||||
lcp = 0
|
||||
|
||||
for y in range(1, len(s1) + 1):
|
||||
for x in range(1, len(s2) + 1):
|
||||
if (s1[y - 1] == s2[x - 1]):
|
||||
m[y][x] = m[y - 1][x - 1] + 1
|
||||
else:
|
||||
m[y][x] = 0
|
||||
|
||||
if m[y][x] > lcp:
|
||||
lcp = m[y][x]
|
||||
return lcp
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
54
src/builtin_structures/max_subarray_stocks.py
Executable file
54
src/builtin_structures/max_subarray_stocks.py
Executable file
|
@ -0,0 +1,54 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
|
||||
def beating_stock(array):
|
||||
|
||||
imin = 0
|
||||
|
||||
# first deal is just buying in the next day (1)
|
||||
deal = [array[1] - array[imin], imin, 1]
|
||||
|
||||
for i, d in enumerate(array):
|
||||
|
||||
deal_here = d - array[imin]
|
||||
|
||||
if deal_here > deal[0]:
|
||||
deal = [deal_here, imin, i]
|
||||
|
||||
elif d < array[imin]:
|
||||
imin = i
|
||||
|
||||
return deal[0], array[deal[1]], array[deal[2]]
|
||||
|
||||
|
||||
def beating_stock2(array):
|
||||
|
||||
deal = 0
|
||||
min_value = array[0]
|
||||
|
||||
for i, d in enumerate(array):
|
||||
|
||||
deal_here = d - min_value
|
||||
|
||||
if deal_here > deal:
|
||||
deal = deal_here
|
||||
|
||||
else:
|
||||
if min_value > array[i]:
|
||||
min_value = array[i]
|
||||
|
||||
return deal
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
array = [7, 2, 3, 6, 5, 8, 5, 3, 4]
|
||||
|
||||
deal = beating_stock(array)
|
||||
print("Profit: %d, buying at %d, selling at %d." %(deal[0], deal[1], deal[2]))
|
||||
|
||||
deal = beating_stock2(array)
|
||||
print "Profit: " + str(deal)
|
15
src/builtin_structures/number_of_zeros_factorial.txt
Executable file
15
src/builtin_structures/number_of_zeros_factorial.txt
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
|
||||
How to know how many 0 are in 100!
|
||||
|
||||
You look for the primes that multiply to 10, i.e. 2 and 5.
|
||||
|
||||
There are more 5 than 2s so you can count the fives.
|
||||
|
||||
there is 100/5 = 20, so 20 5s. However, there are two 5s in 25, 50, 75 and 100.
|
||||
|
||||
result: 20+4 = 24
|
33
src/builtin_structures/palindrome.py
Normal file
33
src/builtin_structures/palindrome.py
Normal file
|
@ -0,0 +1,33 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
|
||||
from collections import defaultdict
|
||||
|
||||
def is_palindrome(array):
|
||||
'''
|
||||
>>> is_palindrome('subi no onibus')
|
||||
True
|
||||
>>> is_palindrome('helllo there')
|
||||
False
|
||||
>>> is_palindrome('h')
|
||||
True
|
||||
>>> is_palindrome('')
|
||||
True
|
||||
'''
|
||||
array = array.strip(' ')
|
||||
if len(array) < 2:
|
||||
return True
|
||||
|
||||
if array[0] == array[-1]:
|
||||
return is_palindrome(array[1:-1])
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
70
src/builtin_structures/permutations.py
Normal file
70
src/builtin_structures/permutations.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
|
||||
def perm(str1):
|
||||
'''
|
||||
>>> perm('123')
|
||||
['123', '132', '231', '213', '312', '321']
|
||||
'''
|
||||
|
||||
if len(str1) < 2:
|
||||
return str1
|
||||
|
||||
res = []
|
||||
for i, c in enumerate(str1):
|
||||
for cc in perm(str1[i+1:] + str1[:i]):
|
||||
res.append(c + cc)
|
||||
return res
|
||||
|
||||
|
||||
def perm2(str1):
|
||||
'''
|
||||
>>> perm2('123')
|
||||
['123', '132', '213', '231', '312', '321']
|
||||
'''
|
||||
from itertools import permutations
|
||||
return [''.join(p) for p in permutations(str1)]
|
||||
|
||||
|
||||
def ispermutation(s1, s2):
|
||||
'''
|
||||
>>> ispermutation('231', '123')
|
||||
True
|
||||
>>> ispermutation('231', '153')
|
||||
False
|
||||
'''
|
||||
|
||||
from collections import Counter
|
||||
aux = Counter()
|
||||
for i in s1:
|
||||
aux[i] += 1
|
||||
for i in s2:
|
||||
aux[i] -= 1
|
||||
for v in aux.values():
|
||||
if v != 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
def ispermutation2(s1, s2):
|
||||
'''
|
||||
>>> ispermutation2('231', '123')
|
||||
True
|
||||
>>> ispermutation2('231', '153')
|
||||
False
|
||||
'''
|
||||
if sorted(s1) == sorted(s2):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
28
src/builtin_structures/prod_other_ints.py
Normal file
28
src/builtin_structures/prod_other_ints.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
def get_products_of_all_except_at_index(array):
|
||||
'''
|
||||
>>> a = [1, 7, 3, 4]
|
||||
>>> get_products_of_all_except_at_index(a)
|
||||
[84, 12, 28, 21]
|
||||
'''
|
||||
total = 1
|
||||
for n in array:
|
||||
total *= n
|
||||
|
||||
new_array = []
|
||||
for n in array:
|
||||
if n is not 0:
|
||||
item = total/n
|
||||
new_array.append(item)
|
||||
else:
|
||||
new_array.append(n)
|
||||
|
||||
return new_array
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
34
src/builtin_structures/ransom_note.py
Executable file
34
src/builtin_structures/ransom_note.py
Executable file
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
|
||||
from collections import Counter
|
||||
|
||||
def check_if_ransom_note(magazines, note):
|
||||
count = Counter()
|
||||
pm, pn = 0, 0
|
||||
|
||||
while pn < len(note) and pm < len(magazines):
|
||||
char_note = note[pn]
|
||||
if count[char_note]>0:
|
||||
count[char_note] -= 1
|
||||
pn += 1
|
||||
else:
|
||||
char_magazine = magazines[pm]
|
||||
count[char_magazine] += 1
|
||||
pm +=1
|
||||
|
||||
return pn == len(note)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
magazines1 = "avfegthhgrebvkdsvnijnvyijfdmckdsmovkmmfvskumvl;cdkmioswckofjbkreenyukjemjgnmkmvkmnvdkmvkr g gmvdvmldm vldfkmbldkmlvdkm"
|
||||
magazines2 = "adfsfa"
|
||||
note = "you should disobey"
|
||||
|
||||
print(check_if_ransom_note(magazines1, note))
|
||||
print(check_if_ransom_note(magazines2, note))
|
37
src/builtin_structures/reverse_string.py
Normal file
37
src/builtin_structures/reverse_string.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
def revert(string):
|
||||
'''
|
||||
>>> s = 'hello'
|
||||
>>> revert(s)
|
||||
'olleh'
|
||||
>>> revert('')
|
||||
''
|
||||
'''
|
||||
return string[::-1]
|
||||
|
||||
|
||||
|
||||
def reverse_string_inplace(s):
|
||||
'''
|
||||
>>> s = 'hello'
|
||||
>>> reverse_string_inplace(s)
|
||||
'olleh'
|
||||
>>> reverse_string_inplace('')
|
||||
''
|
||||
'''
|
||||
if s:
|
||||
s = s[-1] + reverse_string_inplace(s[:-1])
|
||||
return s
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
45
src/builtin_structures/reverse_words.py
Normal file
45
src/builtin_structures/reverse_words.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
|
||||
def reversing_words(word):
|
||||
"""
|
||||
>>> reversing_words('buffy is awesome')
|
||||
'awesome is buffy'
|
||||
"""
|
||||
new_word = []
|
||||
|
||||
words = word.split(' ')
|
||||
for word in words[::-1]:
|
||||
new_word.append(word)
|
||||
|
||||
return " ".join(new_word)
|
||||
|
||||
|
||||
def reversing_words2(s):
|
||||
"""
|
||||
>>> reversing_words2('buffy is awesome')
|
||||
'awesome is buffy'
|
||||
"""
|
||||
words = s.split()
|
||||
return ' '.join(reversed(words))
|
||||
|
||||
|
||||
def reversing_words3(s):
|
||||
"""
|
||||
>>> reversing_words('buffy is awesome')
|
||||
'awesome is buffy'
|
||||
"""
|
||||
words = s.split(' ')
|
||||
words.reverse()
|
||||
return ' '.join(words)
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
def rotate_NxN(m):
|
||||
n = len(m)
|
||||
for layer in range(n//2):
|
||||
|
@ -16,7 +15,7 @@ def rotate_NxN(m):
|
|||
m[last][last-offset] = m[i][last]
|
||||
m[i][last] = top
|
||||
return m
|
||||
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
|
@ -25,7 +24,7 @@ def main():
|
|||
assert(rotate_NxN(m) == mr)
|
||||
m2 = [[1,2,3],[4,5,6],[7,8,9]]
|
||||
print(rotate_NxN(m2))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -1,9 +1,19 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
'''To use timeit you create a Timer object whose parameters are two Python statements. The first parameter is a Python statement that you want to time; the second parameter is a statement that will run once to set up the test. The timeit module will then time how long it takes to execute the statement some number of times. By default timeit will try to run the statement one million times. When its done it returns the time as a floating point value representing the total number of seconds. However, since it executes the statement a million times you can read the result as the number of microseconds to execute the test one time. You can also pass timeit a named parameter called number that allows you to specify how many times the test statement is executed. The following session shows how long it takes to run each of our test functions 1000 times. '''
|
||||
'''To use timeit you create a Timer object whose parameters are two Python
|
||||
statements. The first parameter is a Python statement that you want to time;
|
||||
the second parameter is a statement that will run once to set up the test.
|
||||
The timeit module will then time how long it takes to execute the statement
|
||||
some number of times. By default timeit will try to run the statement one
|
||||
million times. When its done it returns the time as a floating point value
|
||||
representing the total number of seconds. However, since it executes the
|
||||
statement a million times you can read the result as the number of
|
||||
microseconds to execute the test one time. You can also pass timeit a
|
||||
named parameter called number that allows you to specify how many times the
|
||||
test statement is executed. The following session shows how long it takes to
|
||||
run each of our test functions 1000 times. '''
|
||||
|
||||
|
||||
import timeit
|
||||
|
@ -19,7 +29,7 @@ for i in range(10000,1000001,20000):
|
|||
print("%d,%10.3f,%10.3f" % (i, lst_time, d_time))
|
||||
|
||||
|
||||
""" There rersults are:
|
||||
""" There results are:
|
||||
10000, 0.192, 0.002
|
||||
30000, 0.600, 0.002
|
||||
50000, 1.000, 0.002
|
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
'''To use timeit you create a Timer object whose parameters are two Python statements. The first parameter is a Python statement that you want to time; the second parameter is a statement that will run once to set up the test. The timeit module will then time how long it takes to execute the statement some number of times. By default timeit will try to run the statement one million times. When its done it returns the time as a floating point value representing the total number of seconds. However, since it executes the statement a million times you can read the result as the number of microseconds to execute the test one time. You can also pass timeit a named parameter called number that allows you to specify how many times the test statement is executed. The following session shows how long it takes to run each of our test functions 1000 times. '''
|
||||
|
|
@ -1,11 +1,19 @@
|
|||
#!/usr/bin/python3
|
||||
# mari von steinkirch @2013
|
||||
# steinkirch at gmail
|
||||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
|
||||
from collections import Counter
|
||||
|
||||
def str_comp(s):
|
||||
''' basic str compression with counts of repeated char'''
|
||||
'''
|
||||
>>> s1 = 'aabcccccaaa'
|
||||
>>> str_comp(s1)
|
||||
'a2b1c5a3'
|
||||
>>> str_comp('')
|
||||
''
|
||||
'''
|
||||
|
||||
count, last = 1, ''
|
||||
list_aux = []
|
||||
for i, c in enumerate(s):
|
||||
|
@ -17,16 +25,10 @@ def str_comp(s):
|
|||
list_aux.append(c)
|
||||
count = 1
|
||||
last = c
|
||||
list_aux.append(str(count))
|
||||
list_aux.append(str(count))
|
||||
return ''.join(list_aux)
|
||||
|
||||
|
||||
def main():
|
||||
s1 = 'aabcccccaaa'
|
||||
s2 = ''
|
||||
print(str_comp(s1)) # 'a2b1c5a3'
|
||||
print(str_comp(s2))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
import doctest
|
||||
doctest.testmod()
|
41
src/builtin_structures/sum_two_numbers_as_strings.py
Normal file
41
src/builtin_structures/sum_two_numbers_as_strings.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
'''
|
||||
find the sum of two integers represented as strings,
|
||||
return the sum as string, i.e "123" and "456" would return "579"
|
||||
'''
|
||||
|
||||
|
||||
def get_number(s):
|
||||
count = 1
|
||||
num = 0
|
||||
p = len(s) -1
|
||||
while p >= 0:
|
||||
num = num + int(s[p])*count
|
||||
count *= 10
|
||||
p -= 1
|
||||
return num
|
||||
|
||||
|
||||
def sum_string(s1, s2):
|
||||
'''
|
||||
>>> sum_string('10', '5')
|
||||
'15'
|
||||
>>> sum_string('0', '1')
|
||||
'1'
|
||||
>>> sum_string('123', '456')
|
||||
'579'
|
||||
'''
|
||||
|
||||
n1 = get_number(s1)
|
||||
n2 = get_number(s2)
|
||||
return str(n2 + n1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue