Created
October 17, 2012 05:36
-
-
Save showell/3903868 to your computer and use it in GitHub Desktop.
procedural/functional python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def num_ways_to_score(target_score, scores): | |
ways_to_score = 0 | |
counts = [0] * len(scores) | |
while True: | |
score = sum([scores[i] * count for i, count in enumerate(counts)]) | |
if score == target_score: | |
ways_to_score += 1 | |
print counts | |
i = 0 | |
if score > target_score: | |
for i, cnt in enumerate(counts): | |
if cnt > 0: | |
counts[i] = 0 | |
i += 1 | |
break | |
if i == len(counts): | |
break | |
if i == 0: | |
score = sum([scores[j] * count for j, count in enumerate(counts)]) | |
score -= scores[0] * counts[0] | |
diff = target_score - score | |
jump = diff / scores[0] | |
if jump == 0: | |
jump = 1 | |
else: | |
jump = 1 | |
counts[i] += jump | |
return ways_to_score | |
print "\nBasketball" | |
scores = [1,2,3] | |
score = 8 | |
solution = num_ways_to_score(score, scores) | |
print score, solution | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# The interpretation of the problem here is that you are at the | |
# center of a cube, and it's n units from the center to the surface, | |
# and you want to enumerate all paths that go to a point on the surface | |
# without reversing direction in any dimension. Diagonal moves | |
# aren't allowed; every step in the path is magnitude 1 and | |
# parallel to one of the three axes. Paths are allowed to continue | |
# along the surface, as long as you don't reverse directions. | |
directions = dict( | |
L = ('x', -1), | |
R = ('x', 1), | |
D = ('y', -1), | |
U = ('y', 1), | |
B = ('z', -1), | |
F = ('z', 1), | |
) | |
def generate_paths(n): | |
def gen_paths(path, coords): | |
if any(abs(coord) > n for coord in coords.values()): | |
return | |
if any(abs(coord) == n for coord in coords.values()): | |
yield path | |
for direction, delta_info in directions.items(): | |
axis, delta = delta_info | |
# make sure we don't backtrack, take advantage | |
# that product of two negative numbers is positive | |
if delta * coords.get(axis, 0) >= 0: | |
new_path = path + direction | |
new_coords = coords.copy() | |
new_coords[axis] = new_coords.get(axis, 0) + 1 | |
for newer_path in gen_paths(new_path, new_coords): | |
yield newer_path | |
return gen_paths('', {}) | |
def run(): | |
for n in [1,2,3,4]: | |
solutions = generate_paths(n) | |
num_solutions = sum(1 for solution in solutions) | |
print 'n=%d: %d solutions' % (n, num_solutions) | |
run() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Problem: Take first 20 integers, filter for even | |
# numbers, triple them, filter for numbers greater | |
# than 10, print them as a list. | |
# unix-ish pseudocode: | |
# count 20 | filter is_even | triple | filter gt10 | echo | |
def procedural1(): | |
print '--- procedural1' | |
# simple, but no abstraction, deep nesting | |
result = [] | |
for i in range(20): | |
if i % 2 == 0: | |
j = i * 3 | |
if j > 10: | |
result.append(j) | |
print 'result:', result | |
def procedural2(): | |
print '--- procedural2' | |
# simple functions | |
def is_even(i): return i % 2 == 0 | |
def triple(i): return i * 3 | |
def is_greater_than_10(i): return i > 10 | |
numbers = range(20) | |
# more testable/debuggable | |
print numbers | |
print is_even(9) | |
print triple(5) | |
print is_greater_than_10(11) | |
# higher abstraction, but still very imperative/nested | |
result = [] | |
for n in numbers: | |
if is_even(n): | |
triple_n = triple(n) | |
if is_greater_than_10(triple_n): | |
result.append(triple_n) | |
print 'result:', result | |
def functional1(): | |
print '--- functional1' | |
def is_even(i): return i % 2 == 0 | |
def triple(i): return i * 3 | |
def is_greater_than_10(i): return i > 10 | |
numbers = range(20) | |
# higher level list operations makes for very flat code | |
evens = filter(is_even, numbers) | |
triples = map(triple, evens) | |
result = filter(is_greater_than_10, triples) | |
# highly debuggable | |
print numbers | |
print is_even(9) | |
print triple(5) | |
print is_greater_than_10(11) | |
print evens | |
print triples | |
print 'result:', result | |
def functional2(): | |
print '--- functional2' | |
def is_even(i): return i % 2 == 0 | |
def triple(i): return i * 3 | |
def is_greater_than_10(i): return i > 10 | |
numbers = range(20) | |
# absurd level of abstraction | |
def filter_evens(lst): return filter(is_even, lst) | |
def map_to_triples(lst): return map(triple, lst) | |
def filter_bigs(lst): return filter(is_greater_than_10, lst) | |
# And the essential loop is a one-liner, but it reads | |
# inside out | |
result = filter_bigs( | |
map_to_triples( | |
filter_evens( | |
numbers) | |
) | |
) | |
print 'result:', result | |
def functional3(): | |
print '--- functional3' | |
def is_even(i): return i % 2 == 0 | |
def triple(i): return i * 3 | |
def is_greater_than_10(i): return i > 10 | |
numbers = range(20) | |
# it's awkward to have to create these for now, but | |
# we'll fix them | |
def filter_evens(lst): return filter(is_even, lst) | |
def map_to_triples(lst): return map(triple, lst) | |
def filter_bigs(lst): return filter(is_greater_than_10, lst) | |
def pipeline_sugar(lst, *funcs): | |
for f in funcs: | |
lst = f(lst) | |
return lst | |
# now a one-liner for the essential logic that reads forward | |
result = pipeline_sugar( | |
numbers, | |
filter_evens, | |
map_to_triples, | |
filter_bigs | |
) | |
print 'result:', result | |
def functional4(): | |
print '--- functional4' | |
def is_even(i): return i % 2 == 0 | |
def triple(i): return i * 3 | |
def is_greater_than_10(i): return i > 10 | |
numbers = range(20) | |
# high-level building blocks | |
def pipeline_sugar(lst, *funcs): | |
for f in funcs: | |
lst = f(lst) | |
return lst | |
def filterer(f): | |
return lambda lst: filter(f, lst) | |
def mapper(f): | |
return lambda lst: map(f, lst) | |
# now a one-liner for the essential logic that reads forward | |
result = pipeline_sugar( | |
numbers, | |
filterer(is_even), | |
mapper(triple), | |
filterer(is_greater_than_10) | |
) | |
print 'result:', result | |
procedural1() | |
procedural2() | |
functional1() | |
functional2() | |
functional3() | |
functional4() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment