forked from colonelpanic/dotfiles
Add a bunch of python exercises
This commit is contained in:
parent
0737728d99
commit
561474b941
43
dotfiles/lib/python/add_up_to.py
Normal file
43
dotfiles/lib/python/add_up_to.py
Normal file
@ -0,0 +1,43 @@
|
||||
def count_unique_sums2(number, maximum_size):
|
||||
maximum_to_try = min(number, maximum_size) + 1
|
||||
the_range = list(range(1, maximum_to_try))
|
||||
|
||||
all_sums = []
|
||||
for max_in_sum in the_range:
|
||||
if max_in_sum == number:
|
||||
all_sums.extend([[number]])
|
||||
continue
|
||||
new_sums = count_unique_sums(number-max_in_sum, max_in_sum)
|
||||
all_sums.extend(
|
||||
[
|
||||
sum_so_far + [max_in_sum]
|
||||
for sum_so_far in new_sums
|
||||
]
|
||||
)
|
||||
|
||||
return all_sums
|
||||
|
||||
|
||||
unique_sum_counts = {}
|
||||
|
||||
|
||||
def count_unique_sums(number, maximum_size):
|
||||
if (number, maximum_size) in unique_sum_counts:
|
||||
return unique_sum_counts[(number, maximum_size)]
|
||||
|
||||
maximum_to_try = min(number, maximum_size) + 1
|
||||
the_range = list(range(1, maximum_to_try))
|
||||
|
||||
sum_count = 0
|
||||
for max_in_sum in the_range:
|
||||
if max_in_sum == number:
|
||||
sum_count += 1
|
||||
continue
|
||||
sum_count += count_unique_sums(number-max_in_sum, max_in_sum)
|
||||
|
||||
unique_sum_counts[(number, maximum_size)] = sum_count
|
||||
return sum_count
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(count_unique_sums(100, 100))
|
84
dotfiles/lib/python/lru_cache.py
Normal file
84
dotfiles/lib/python/lru_cache.py
Normal file
@ -0,0 +1,84 @@
|
||||
class Node(object):
|
||||
def __init__(self, key, value, next_node=None, prev_node=None):
|
||||
self.key = key
|
||||
self.value = value
|
||||
self.next_node = next_node
|
||||
self.prev_node = prev_node
|
||||
|
||||
def print_list(self):
|
||||
print("{0} - {1}".format(self.key, self.value))
|
||||
if self.next_node is not None:
|
||||
assert self == self.next_node.prev_node
|
||||
self.next_node.print_list()
|
||||
else:
|
||||
print("next node is None")
|
||||
if self.prev_node is not None:
|
||||
assert self.prev_node.next_node == self
|
||||
|
||||
|
||||
class LRUCache(object):
|
||||
def __init__(self, capacity):
|
||||
self.capacity = capacity
|
||||
self.cache = {}
|
||||
self.head = None
|
||||
self.tail = None
|
||||
|
||||
def put(self, key, value):
|
||||
"""
|
||||
If key already exists, replace the current value with the new value.
|
||||
If the key doesn't exist, add the new key/value entry to the cache.
|
||||
If the addition of the new entry causes the number of entries to exceed
|
||||
num_entries, remove the oldest entry based on the last time the entry is
|
||||
accessed (either through put or get).
|
||||
"""
|
||||
if key in self.cache:
|
||||
node = self.cache[key]
|
||||
node.value = value
|
||||
self.move_to_tail(node)
|
||||
return
|
||||
|
||||
if len(self.cache) >= self.capacity:
|
||||
old_head = self.remove_from_head()
|
||||
del self.cache[old_head.key]
|
||||
|
||||
new_node = Node(key, value)
|
||||
self.set_new_tail(new_node)
|
||||
self.cache[key] = new_node
|
||||
|
||||
def set_new_tail(self, node):
|
||||
node.prev_node = self.tail
|
||||
if self.tail is not None:
|
||||
self.tail.next_node = node
|
||||
self.tail = node
|
||||
if self.head is None:
|
||||
self.head = node
|
||||
|
||||
def move_to_tail(self, node):
|
||||
if node is self.tail:
|
||||
return
|
||||
if node.prev_node is None: # This is the head
|
||||
if node.next_node is not None:
|
||||
self.head = node.next_node
|
||||
node.next_node.prev_node = None
|
||||
else:
|
||||
node.prev_node.next_node = node.next_node
|
||||
node.next_node.prev_node = node.prev_node
|
||||
|
||||
node.prev_node = self.tail
|
||||
self.tail.next_node = node
|
||||
self.tail = node
|
||||
self.tail.next_node = None
|
||||
|
||||
def remove_from_head(self):
|
||||
previous_head = self.head
|
||||
self.head = self.head.next_node
|
||||
self.head.prev_node = None
|
||||
return previous_head
|
||||
|
||||
def get(self, key):
|
||||
"""Return the value associated with the key, or None if the key doesn't
|
||||
exist."""
|
||||
node = self.cache.get(key)
|
||||
if node is not None:
|
||||
self.move_to_tail(node)
|
||||
return node.value
|
29
dotfiles/lib/python/powerset.py
Normal file
29
dotfiles/lib/python/powerset.py
Normal file
@ -0,0 +1,29 @@
|
||||
import collections
|
||||
import copy
|
||||
|
||||
|
||||
def powerset(elems):
|
||||
counts = collections.defaultdict(int)
|
||||
for elem in elems:
|
||||
counts[elem] += 1
|
||||
return powerset_helper(counts.items())
|
||||
|
||||
|
||||
def powerset_helper(elems):
|
||||
last_generation = [[]]
|
||||
for (elem, count) in elems:
|
||||
next_generation = last_generation
|
||||
for _ in range(count):
|
||||
new_generation = []
|
||||
for subset in last_generation:
|
||||
new_subset = copy.copy(subset)
|
||||
new_subset.append(elem)
|
||||
new_generation.append(new_subset)
|
||||
next_generation.extend(new_generation)
|
||||
last_generation = new_generation
|
||||
last_generation = next_generation
|
||||
return last_generation
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(len(powerset(range(23))))
|
31
dotfiles/lib/python/score_parentheses.py
Executable file
31
dotfiles/lib/python/score_parentheses.py
Executable file
@ -0,0 +1,31 @@
|
||||
#! /usr/bin/env python
|
||||
import sys
|
||||
|
||||
def score_parentheses(input_string, index=0):
|
||||
if index >= len(input_string):
|
||||
return (0, index)
|
||||
if input_string[index] == '(':
|
||||
index += 1
|
||||
else:
|
||||
raise Exception("Invalid parentheses")
|
||||
|
||||
children_score, index = score_children(input_string, index)
|
||||
|
||||
if input_string[index] == ')':
|
||||
index += 1
|
||||
else:
|
||||
raise Exception("Invalid parentheses")
|
||||
|
||||
return (children_score * 2 if children_score > 0 else 1, index)
|
||||
|
||||
def score_children(input_string, index=0):
|
||||
input_length = len(input_string)
|
||||
children_score = 0
|
||||
while index < input_length and input_string[index] == '(':
|
||||
child_score, index = score_parentheses(input_string, index)
|
||||
children_score += child_score
|
||||
return (children_score, index)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print (score_children(sys.argv[1]))
|
0
dotfiles/lib/python/sliding_median.py
Normal file
0
dotfiles/lib/python/sliding_median.py
Normal file
86
dotfiles/lib/python/sudoku.py
Normal file
86
dotfiles/lib/python/sudoku.py
Normal file
@ -0,0 +1,86 @@
|
||||
goodpuzzle = [
|
||||
[1,2,3,4,5,6,7,8,9],
|
||||
[4,5,6,7,8,9,1,2,3],
|
||||
[7,8,9,1,2,3,4,5,6],
|
||||
[2,3,4,5,6,7,8,9,1],
|
||||
[5,6,7,8,9,1,2,3,4],
|
||||
[8,9,1,2,3,4,5,6,7],
|
||||
[3,4,5,6,7,8,9,1,2],
|
||||
[6,7,8,9,1,2,3,4,5],
|
||||
[9,1,2,3,4,5,6,7,8]
|
||||
]
|
||||
|
||||
badpuzzle1 = [
|
||||
[1,2,3,4,5,6,7,9,8],
|
||||
[4,5,6,7,8,9,1,2,3],
|
||||
[7,8,9,1,2,3,4,5,6],
|
||||
[2,3,4,5,6,7,8,9,1],
|
||||
[5,6,7,8,9,1,2,3,4],
|
||||
[8,9,1,2,3,4,5,6,7],
|
||||
[3,4,5,6,7,8,9,1,2],
|
||||
[6,7,8,9,1,2,3,4,5],
|
||||
[9,1,2,3,4,5,6,7,8]
|
||||
]
|
||||
|
||||
badpuzzle2 = [
|
||||
[1,2,3,4,5,6,7,2,9],
|
||||
[4,5,6,7,8,9,1,8,3],
|
||||
[7,8,9,1,2,3,4,5,6],
|
||||
[2,3,4,5,6,7,8,9,1],
|
||||
[5,6,7,8,9,1,2,3,4],
|
||||
[8,9,1,2,3,4,5,6,7],
|
||||
[3,4,5,6,7,8,9,1,2],
|
||||
[6,7,8,9,1,2,3,4,5],
|
||||
[9,1,2,3,4,5,6,7,8]
|
||||
]
|
||||
|
||||
badpuzzle3 = [
|
||||
[1,2,3,4,5,6,7,8,9],
|
||||
[4,5,6,7,8,9,1,2,3],
|
||||
[7,8,9,1,2,3,4,5,6],
|
||||
[2,3,4,5,6,7,8,9,1],
|
||||
[5,6,7,8,9,1,2,3,4],
|
||||
[3,4,5,6,7,8,9,1,2],
|
||||
[8,9,1,2,3,4,5,6,7],
|
||||
[6,7,8,9,1,2,3,4,5],
|
||||
[9,1,2,3,4,5,6,7,8]
|
||||
]
|
||||
|
||||
|
||||
one_to_nine = set(range(1, 10))
|
||||
|
||||
|
||||
def is_valid_sudoku_puzzle(sudoku_grid):
|
||||
for row in sudoku_grid:
|
||||
if set(row) != one_to_nine:
|
||||
return False
|
||||
|
||||
for i in range(9):
|
||||
column = [sudoku_grid[j][i] for j in range(9)]
|
||||
if set(column) != one_to_nine:
|
||||
return False
|
||||
|
||||
for i in range(3):
|
||||
for j in range(3):
|
||||
subgrid_elements = get_subgrid_elements(i, j, sudoku_grid)
|
||||
if set(subgrid_elements) != one_to_nine:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def get_subgrid_elements(subgrid_row, subgrid_column, sudoku_grid, subgrid_size=3):
|
||||
subgrid_row_start = subgrid_row * subgrid_size
|
||||
subgrid_column_start = subgrid_column * subgrid_size
|
||||
|
||||
subgrid_elements = []
|
||||
for i in range(subgrid_row_start, subgrid_row_start + subgrid_size):
|
||||
subgrid_elements += sudoku_grid[i][subgrid_column_start:subgrid_column_start+subgrid_size]
|
||||
|
||||
return subgrid_elements
|
||||
|
||||
|
||||
print(is_valid_sudoku_puzzle(goodpuzzle))
|
||||
print(is_valid_sudoku_puzzle(badpuzzle1))
|
||||
print(is_valid_sudoku_puzzle(badpuzzle2))
|
||||
print(is_valid_sudoku_puzzle(badpuzzle3))
|
Loading…
Reference in New Issue
Block a user