mirror of
https://github.com/autistic-symposium/master-algorithms-py.git
synced 2025-05-02 06:46:18 -04:00
clean up
This commit is contained in:
parent
1ef64d6e17
commit
e0eb554dfd
279 changed files with 24267 additions and 0 deletions
0
First_edition_2014/ebook_src/builtin_structures/__init__.py
Executable file
0
First_edition_2014/ebook_src/builtin_structures/__init__.py
Executable file
51
First_edition_2014/ebook_src/builtin_structures/anagram.py
Executable file
51
First_edition_2014/ebook_src/builtin_structures/anagram.py
Executable 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
First_edition_2014/ebook_src/builtin_structures/balance.txt
Executable file
9
First_edition_2014/ebook_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
First_edition_2014/ebook_src/builtin_structures/balance_symbols.py
Executable file
40
First_edition_2014/ebook_src/builtin_structures/balance_symbols.py
Executable 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()
|
||||
|
|
@ -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()
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
64
First_edition_2014/ebook_src/builtin_structures/convert_numerical_bases.py
Executable file
64
First_edition_2014/ebook_src/builtin_structures/convert_numerical_bases.py
Executable file
|
@ -0,0 +1,64 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
''' convert an integer to a string in any base'''
|
||||
|
||||
def convert_from_dec_to_any_base(number, base):
|
||||
'''
|
||||
>>> number, base = 9, 2
|
||||
>>> convert_from_dec_to_any_base(number, base)
|
||||
'1001'
|
||||
'''
|
||||
|
||||
convertString = '012345679ABCDEF'
|
||||
|
||||
if number < base:
|
||||
return convertString[number]
|
||||
|
||||
else:
|
||||
return convert_from_dec_to_any_base(number//base, base) + \
|
||||
convertString[number%base]
|
||||
|
||||
|
||||
|
||||
def convert_from_decimal_to_binary(number, base):
|
||||
'''
|
||||
>>> number, base = 9, 2
|
||||
>>> convert_from_decimal_to_binary(number, base)
|
||||
1001
|
||||
'''
|
||||
|
||||
multiplier, result = 1, 0
|
||||
|
||||
while number > 0:
|
||||
result += number%base*multiplier
|
||||
multiplier *= 10
|
||||
number = number//base
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
def convert_from_decimal_larger_bases(number, base):
|
||||
'''
|
||||
>>> number, base = 31, 16
|
||||
>>> convert_from_decimal_larger_bases(number, base)
|
||||
'1F'
|
||||
'''
|
||||
strings = "0123456789ABCDEFGHIJ"
|
||||
result = ""
|
||||
|
||||
while number > 0:
|
||||
digit = number%base
|
||||
result = strings[digit] + result
|
||||
number = number//base
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
83
First_edition_2014/ebook_src/builtin_structures/convert_str_2_int.py
Executable file
83
First_edition_2014/ebook_src/builtin_structures/convert_str_2_int.py
Executable file
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
def conv_int2str(int1):
|
||||
'''
|
||||
>>> conv_str2int('367')
|
||||
367
|
||||
>>> conv_str2int('0')
|
||||
0
|
||||
>>> conv_str2int('-10')
|
||||
-10
|
||||
>>> conv_str2int('1e5')
|
||||
100000
|
||||
'''
|
||||
|
||||
aux_dict = {key:value for key in range(10) for value in '0123456789'[key]}
|
||||
|
||||
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()
|
||||
|
||||
return sign + ''.join(aux_ls)
|
||||
|
||||
|
||||
|
||||
def conv_str2int(str1):
|
||||
'''
|
||||
>>> 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] == '-':
|
||||
sign = -1
|
||||
str1 = str1[1:]
|
||||
else:
|
||||
sign = 1
|
||||
|
||||
dec, result = 1, 0
|
||||
|
||||
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])
|
||||
result = number*10**exp_num
|
||||
break
|
||||
result += aux_dict[aux]*dec
|
||||
dec *= 10
|
||||
|
||||
return result*sign
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
26
First_edition_2014/ebook_src/builtin_structures/count_unique_words_On2.py
Executable file
26
First_edition_2014/ebook_src/builtin_structures/count_unique_words_On2.py
Executable file
|
@ -0,0 +1,26 @@
|
|||
#!/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 + "\"'"
|
||||
|
||||
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] = +1
|
||||
|
||||
for word in sorted(words):
|
||||
print("'{0}' occurs {1} times.".format(word, words[word]))
|
||||
|
49
First_edition_2014/ebook_src/builtin_structures/delete_duplicate_char_str.py
Executable file
49
First_edition_2014/ebook_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()
|
60
First_edition_2014/ebook_src/builtin_structures/fibonacci.py
Executable file
60
First_edition_2014/ebook_src/builtin_structures/fibonacci.py
Executable file
|
@ -0,0 +1,60 @@
|
|||
#!/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
|
||||
|
||||
|
||||
def fib_rec(n):
|
||||
'''
|
||||
>>> fib_rec(2)
|
||||
1
|
||||
>>> fib_rec(5)
|
||||
5
|
||||
>>> fib_rec(7)
|
||||
13
|
||||
'''
|
||||
if n < 3:
|
||||
return 1
|
||||
return fib_rec(n - 1) + fib_rec(n - 2)
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
||||
fib = fib_generator()
|
||||
print(next(fib))
|
||||
print(next(fib))
|
||||
print(next(fib))
|
||||
print(next(fib))
|
|
@ -0,0 +1,35 @@
|
|||
#!/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]]
|
||||
>>> find_0_MxN(m1)
|
||||
[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
|
||||
>>> m2 = [[1, 2, 3, 4], [0, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
|
||||
>>> find_0_MxN(m2)
|
||||
[[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:
|
||||
index.append((row, col))
|
||||
for i in index:
|
||||
row = i[0]
|
||||
col = i[1]
|
||||
for i in range(len(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
First_edition_2014/ebook_src/builtin_structures/find_dice_probabilities.py
Executable file
32
First_edition_2014/ebook_src/builtin_structures/find_dice_probabilities.py
Executable 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
First_edition_2014/ebook_src/builtin_structures/find_edit_distance.py
Executable file
43
First_edition_2014/ebook_src/builtin_structures/find_edit_distance.py
Executable 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()
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
First_edition_2014/ebook_src/builtin_structures/find_gcd.py
Executable file
29
First_edition_2014/ebook_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
First_edition_2014/ebook_src/builtin_structures/find_if_substr.py
Executable file
36
First_edition_2014/ebook_src/builtin_structures/find_if_substr.py
Executable 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
First_edition_2014/ebook_src/builtin_structures/find_if_unique_char.py
Executable file
32
First_edition_2014/ebook_src/builtin_structures/find_if_unique_char.py
Executable 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
First_edition_2014/ebook_src/builtin_structures/find_largest_sum.py
Executable file
42
First_edition_2014/ebook_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()
|
34
First_edition_2014/ebook_src/builtin_structures/find_longest_inc_subseq.py
Executable file
34
First_edition_2014/ebook_src/builtin_structures/find_longest_inc_subseq.py
Executable file
|
@ -0,0 +1,34 @@
|
|||
#!/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]
|
||||
>>> find_long_con_inc([1, 3, 4, -13, 2, 5, 8, -1, 2,-17])
|
||||
[-13, 2, 5, 8]
|
||||
'''
|
||||
|
||||
res, aux = [], []
|
||||
seq.append(-float('infinity'))
|
||||
|
||||
for i, n in enumerate(seq[:-1]):
|
||||
aux.append(n)
|
||||
if n > seq[i+1]:
|
||||
if len(res) < len(aux):
|
||||
res = aux[:]
|
||||
aux = []
|
||||
|
||||
return res
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
|
@ -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
First_edition_2014/ebook_src/builtin_structures/find_non_repeating_number.py
Executable file
33
First_edition_2014/ebook_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()
|
|
@ -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()
|
|
@ -0,0 +1,27 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
from collections import Counter
|
||||
|
||||
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
|
||||
'''
|
||||
|
||||
dcounter = Counter()
|
||||
for word in seq.split():
|
||||
dcounter[word] += 1
|
||||
|
||||
return dcounter.most_common(N)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
29
First_edition_2014/ebook_src/builtin_structures/get_float_rep_bin.py
Executable file
29
First_edition_2014/ebook_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
First_edition_2014/ebook_src/builtin_structures/interserction_two_arrays.py
Executable file
63
First_edition_2014/ebook_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()
|
54
First_edition_2014/ebook_src/builtin_structures/max_subarray_stocks.py
Executable file
54
First_edition_2014/ebook_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)
|
|
@ -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
First_edition_2014/ebook_src/builtin_structures/palindrome.py
Executable file
33
First_edition_2014/ebook_src/builtin_structures/palindrome.py
Executable 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
First_edition_2014/ebook_src/builtin_structures/permutations.py
Executable file
70
First_edition_2014/ebook_src/builtin_structures/permutations.py
Executable 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()
|
37
First_edition_2014/ebook_src/builtin_structures/permutations_alphanumeric.py
Executable file
37
First_edition_2014/ebook_src/builtin_structures/permutations_alphanumeric.py
Executable 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()
|
||||
|
47
First_edition_2014/ebook_src/builtin_structures/primes.py
Executable file
47
First_edition_2014/ebook_src/builtin_structures/primes.py
Executable file
|
@ -0,0 +1,47 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
'''
|
||||
find prime factors of a number.
|
||||
'''
|
||||
|
||||
import math
|
||||
import random
|
||||
|
||||
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
|
||||
|
||||
|
||||
''' return a n-bit prime '''
|
||||
def generate_prime(number=3):
|
||||
while 1:
|
||||
p = random.randint(pow(2, number-2), pow(2, number-1)-1)
|
||||
p = 2 * p + 1
|
||||
if find_prime_factors(p):
|
||||
return p
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
||||
|
28
First_edition_2014/ebook_src/builtin_structures/prod_other_ints.py
Executable file
28
First_edition_2014/ebook_src/builtin_structures/prod_other_ints.py
Executable 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
First_edition_2014/ebook_src/builtin_structures/ransom_note.py
Executable file
34
First_edition_2014/ebook_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
First_edition_2014/ebook_src/builtin_structures/reverse_string.py
Executable file
37
First_edition_2014/ebook_src/builtin_structures/reverse_string.py
Executable 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
First_edition_2014/ebook_src/builtin_structures/reverse_words.py
Executable file
45
First_edition_2014/ebook_src/builtin_structures/reverse_words.py
Executable 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()
|
||||
|
30
First_edition_2014/ebook_src/builtin_structures/rotate_NxN.py
Executable file
30
First_edition_2014/ebook_src/builtin_structures/rotate_NxN.py
Executable file
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
def rotate_NxN(m):
|
||||
n = len(m)
|
||||
for layer in range(n//2):
|
||||
first = layer
|
||||
last = n - 1 - layer
|
||||
for i in range(first, last):
|
||||
offset = i - first
|
||||
top = m[first][i]
|
||||
m[first][i] = m[last-offset][first]
|
||||
m[last-offset][first] = m[last][last-offset]
|
||||
m[last][last-offset] = m[i][last]
|
||||
m[i][last] = top
|
||||
return m
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
m = [[1,2],[3,4]]
|
||||
mr = [[3,1],[4,2]]
|
||||
assert(rotate_NxN(m) == mr)
|
||||
m2 = [[1,2,3],[4,5,6],[7,8,9]]
|
||||
print(rotate_NxN(m2))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
#!/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. '''
|
||||
|
||||
|
||||
import timeit
|
||||
import random
|
||||
|
||||
for i in range(10000,1000001,20000):
|
||||
''' this experiment confirm that the contains operator for lists is O(n) and for dict is O(1) '''
|
||||
t = timeit.Timer("random.randrange(%d) in x"%i, "from __main__ import random,x")
|
||||
x = list(range(i))
|
||||
lst_time = t.timeit(number=1000)
|
||||
x = {j:None for j in range(i)}
|
||||
d_time = t.timeit(number=1000)
|
||||
print("%d,%10.3f,%10.3f" % (i, lst_time, d_time))
|
||||
|
||||
|
||||
""" There results are:
|
||||
10000, 0.192, 0.002
|
||||
30000, 0.600, 0.002
|
||||
50000, 1.000, 0.002
|
||||
70000, 1.348, 0.002
|
||||
90000, 1.755, 0.002
|
||||
110000, 2.194, 0.002
|
||||
130000, 2.635, 0.002
|
||||
150000, 2.951, 0.002
|
||||
170000, 3.405, 0.002
|
||||
190000, 3.743, 0.002
|
||||
210000, 4.142, 0.002
|
||||
230000, 4.577, 0.002
|
||||
250000, 4.797, 0.002
|
||||
270000, 5.371, 0.002
|
||||
290000, 5.690, 0.002
|
||||
310000, 5.977, 0.002
|
||||
|
||||
so we can see the linear tile for lists, and constant for dict!
|
||||
|
||||
Big-O Efficiency of Python Dictionary Operations
|
||||
Operation Big-O Efficiency
|
||||
copy O(n)
|
||||
get item O(1)
|
||||
set item O(1)
|
||||
delete item O(1)
|
||||
contains (in) O(1)
|
||||
iteration O(n)
|
||||
"""
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
#!/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. '''
|
||||
|
||||
|
||||
def test1():
|
||||
l = []
|
||||
for i in range(1000):
|
||||
l = l + [i]
|
||||
|
||||
def test2():
|
||||
l = []
|
||||
for i in range(1000):
|
||||
l.append(i)
|
||||
|
||||
def test3():
|
||||
l = [i for i in range(1000)]
|
||||
|
||||
def test4():
|
||||
l = list(range(1000))
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import timeit
|
||||
t1 = timeit.Timer("test1()", "from __main__ import test1")
|
||||
print("concat ",t1.timeit(number=1000), "milliseconds")
|
||||
t2 = timeit.Timer("test2()", "from __main__ import test2")
|
||||
print("append ",t2.timeit(number=1000), "milliseconds")
|
||||
t3 = timeit.Timer("test3()", "from __main__ import test3")
|
||||
print("comprehension ",t3.timeit(number=1000), "milliseconds")
|
||||
t4 = timeit.Timer("test4()", "from __main__ import test4")
|
||||
print("list range ",t4.timeit(number=1000), "milliseconds")
|
||||
|
||||
|
||||
|
||||
""" The results are:
|
||||
('concat ', 2.366791009902954, 'milliseconds')
|
||||
('append ', 0.16743111610412598, 'milliseconds')
|
||||
('comprehension ', 0.06446194648742676, 'milliseconds')
|
||||
('list range ', 0.021029949188232422, 'milliseconds')
|
||||
|
||||
|
||||
So we see the following pattern for lists:
|
||||
|
||||
Operation Big-O Efficiency
|
||||
index [] O(1)
|
||||
index assignment O(1)
|
||||
append O(1)
|
||||
pop() O(1)
|
||||
pop(i) O(n)
|
||||
insert(i,item) O(n)
|
||||
del operator O(n)
|
||||
iteration O(n)
|
||||
contains (in) O(n)
|
||||
get slice [x:y] O(k)
|
||||
del slice O(n)
|
||||
set slice O(n+k)
|
||||
reverse O(n)
|
||||
concatenate O(k)
|
||||
sort O(n log n)
|
||||
multiply O(nk)
|
||||
"""
|
||||
|
42
First_edition_2014/ebook_src/builtin_structures/search_entry_matrix.py
Executable file
42
First_edition_2014/ebook_src/builtin_structures/search_entry_matrix.py
Executable file
|
@ -0,0 +1,42 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
''' Search an Entry in a Matrix where the Rows and columns are Sorted
|
||||
In this 2D matrix, every row is increasingly sorted from left to right,
|
||||
and every column is increasingly sorted from top to bottom.
|
||||
The runtime is O(m+n).
|
||||
'''
|
||||
|
||||
def find_elem_matrix_bool(m1, value):
|
||||
|
||||
found = False
|
||||
row = 0
|
||||
col = len(m1[0]) - 1
|
||||
|
||||
while row < len(m1) and col >= 0:
|
||||
|
||||
if m1[row][col] == value:
|
||||
found = True
|
||||
break
|
||||
elif m1[row][col] > value:
|
||||
col-=1
|
||||
else:
|
||||
row+=1
|
||||
|
||||
return found
|
||||
|
||||
|
||||
|
||||
def test_find_elem_matrix_bool(module_name='this module'):
|
||||
m1 = [[1,2,8,9], [2,4,9,12], [4,7,10,13], [6,8,11,15]]
|
||||
assert(find_elem_matrix_bool(m1,8) == True)
|
||||
assert(find_elem_matrix_bool(m1,3) == False)
|
||||
m2 = [[0]]
|
||||
assert(find_elem_matrix_bool(m2,0) == True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_find_elem_matrix_bool()
|
||||
|
34
First_edition_2014/ebook_src/builtin_structures/simple_str_comprension.py
Executable file
34
First_edition_2014/ebook_src/builtin_structures/simple_str_comprension.py
Executable file
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
__author__ = "bt3"
|
||||
|
||||
|
||||
from collections import Counter
|
||||
|
||||
def str_comp(s):
|
||||
'''
|
||||
>>> s1 = 'aabcccccaaa'
|
||||
>>> str_comp(s1)
|
||||
'a2b1c5a3'
|
||||
>>> str_comp('')
|
||||
''
|
||||
'''
|
||||
|
||||
count, last = 1, ''
|
||||
list_aux = []
|
||||
for i, c in enumerate(s):
|
||||
if last == c:
|
||||
count += 1
|
||||
else:
|
||||
if i != 0:
|
||||
list_aux.append(str(count))
|
||||
list_aux.append(c)
|
||||
count = 1
|
||||
last = c
|
||||
list_aux.append(str(count))
|
||||
return ''.join(list_aux)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
doctest.testmod()
|
|
@ -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