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