-
Notifications
You must be signed in to change notification settings - Fork 0
/
zebra.py
79 lines (67 loc) · 2.51 KB
/
zebra.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# ----------------
# User Instructions
#
# Modify the timedcalls(n, fn, *args) function so that it calls
# fn(*args) repeatedly. It should call fn n times if n is an integer
# and up to n seconds if n is a floating point number.
import itertools
def imright(h1, h2):
"House h1 is immediately right of h2 if h1-h2 == 1."
return h1-h2 == 1
def nextto(h1, h2):
"Two houses are next to each other if they differ by 1."
return abs(h1-h2) == 1
def zebra_puzzle():
"Return a tuple (WATER, ZEBRA indicating their house numbers."
houses = first, _, middle, _, _ = [1, 2, 3, 4, 5]
orderings = list(itertools.permutations(houses)) # 1
return next((WATER, ZEBRA)
for (red, green, ivory, yellow, blue) in orderings
if imright(green, ivory)
for (Englishman, Spaniard, Ukranian, Japanese, Norwegian) in orderings
if Englishman is red
if Norwegian is first
if nextto(Norwegian, blue)
for (coffee, tea, milk, oj, WATER) in orderings
if coffee is green
if Ukranian is tea
if milk is middle
for (OldGold, Kools, Chesterfields, LuckyStrike, Parliaments) in orderings
if Kools is yellow
if LuckyStrike is oj
if Japanese is Parliaments
for (dog, snails, fox, horse, ZEBRA) in orderings
if Spaniard is dog
if OldGold is snails
if nextto(Chesterfields, fox)
if nextto(Kools, horse)
)
import time
def timedcall(fn, *args):
"Call function with args; return the time in seconds and result."
t0 = time.clock()
result = fn(*args)
t1 = time.clock()
return t1-t0, result
def average(numbers):
"Return the average (arithmetic mean) of a sequence of numbers."
return sum(numbers) / float(len(numbers))
def timedcalls(n, fn, *args):
"""Call fn(*args) repeatedly: n times if n is an int, or up to
n seconds if n is a float; return the min, avg, and max time"""
times = []
if isinstance(n, float):
t1 = t0 = time.clock()
while t1-t0 < n:
ts = time.clock()
fn(*args)
t1 = time.clock()
times.append(t1-ts)
else:
for _ in range(n):
t0 = time.clock()
fn(*args)
t1 = time.clock()
times.append(t1-t0)
return min(times), average(times), max(times)
print zebra_puzzle()