Skip to content

Commit 48352f5

Browse files
committed
list rotation and WxPytris
1 parent 9f7ca8b commit 48352f5

File tree

4 files changed

+164
-0
lines changed

4 files changed

+164
-0
lines changed

2008/list_rotation.py

+144
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# This file lists some Python functions for rotating a list
2+
# to the left. The emphasis is functions that don't use extra
3+
# space.
4+
# For an explanation, see
5+
# http://eli.thegreenplace.net/2008/08/29/space-efficient-list-rotation/
6+
#
7+
# Based on chapter 2 of "Programming Pearls" by Jon Bentley
8+
#
9+
# Eli Bendersky (http://eli.thegreenplace.net)
10+
#
11+
12+
13+
def rotate_naive(lst, dist):
14+
""" A 'naive' (space inefficient) rotation function.
15+
The slice operations create new lists.
16+
"""
17+
lst[:] = lst[dist:len(lst)] + lst[0:dist]
18+
19+
20+
def gcd(a, b):
21+
""" Greatest common divisor of a and b
22+
Using Euclid's algorithm
23+
"""
24+
while b:
25+
a, b = b, a % b
26+
return a
27+
28+
29+
def rotate_juggle(lst, dist):
30+
""" An iterative 'juggle' method
31+
"""
32+
n = len(lst)
33+
34+
for i in xrange(gcd(dist, n)):
35+
t = lst[i]
36+
j = i
37+
while 1:
38+
k = (j + dist) % n
39+
if k == i: break
40+
lst[j] = lst[k]
41+
j = k
42+
lst[j] = t
43+
44+
45+
def sublist_swap(lst, a, b, m):
46+
""" Swaps (in-place) the elements:
47+
lst[a:a+m) with lst[b:b+m)
48+
Without using extra space.
49+
50+
Assumes that all the indices point inside the list.
51+
"""
52+
for i in xrange(m):
53+
lst[a + i], lst[b + i] = lst[b + i], lst[a + i]
54+
55+
56+
def rotate_swap(lst, dist):
57+
""" A 'recursive' sub-list swapping method.
58+
"""
59+
n = len(lst)
60+
61+
if dist == 0 or dist == n:
62+
return
63+
i = p = dist
64+
j = n - p
65+
66+
while i != j:
67+
if i > j:
68+
sublist_swap(lst, p - i, p, j)
69+
i -= j
70+
else:
71+
sublist_swap(lst, p - i, p + j - i, i)
72+
j -= i
73+
74+
sublist_swap(lst, p - i, p, i)
75+
76+
77+
def sublist_reverse(lst, a, b):
78+
""" Reverses (in-place) the elements lst[a:b]
79+
"""
80+
while b > a:
81+
lst[a], lst[b] = lst[b], lst[a]
82+
b -= 1
83+
a += 1
84+
85+
86+
def rotate_reverse(lst, dist):
87+
""" Uses reversing to rotate the list.
88+
"""
89+
n = len(lst)
90+
sublist_reverse(lst, 0, dist - 1)
91+
sublist_reverse(lst, dist, n - 1)
92+
sublist_reverse(lst, 0, n - 1)
93+
94+
95+
import timeit
96+
97+
def benchmark():
98+
setup = """
99+
from __main__ import rotate_naive, rotate_juggle, rotate_reverse, rotate_swap
100+
101+
lst = range(1000000)
102+
dist = 100000
103+
"""
104+
105+
N = 10
106+
print "Naive:", timeit.Timer(stmt='rotate_naive(lst, dist)', setup=setup).timeit(N)
107+
print "Juggle:", timeit.Timer(stmt='rotate_juggle(lst, dist)', setup=setup).timeit(N)
108+
print "Swap:", timeit.Timer(stmt='rotate_swap(lst, dist)', setup=setup).timeit(N)
109+
print "Reverse:", timeit.Timer(stmt='rotate_reverse(lst, dist)', setup=setup).timeit(N)
110+
111+
112+
import unittest
113+
114+
class TestListRotation(unittest.TestCase):
115+
def do_test_list(self, func, lst, dist, newlst):
116+
mylst = lst[:]
117+
func(mylst, dist)
118+
self.assertEqual(mylst, newlst)
119+
120+
def run_tests(self, func):
121+
self.do_test_list(func, [], 0, [])
122+
self.do_test_list(func, [1], 0, [1])
123+
self.do_test_list(func, [1, 2], 0, [1, 2])
124+
self.do_test_list(func, [1, 2], 2, [1, 2])
125+
self.do_test_list(func, [1, 2], 1, [2, 1])
126+
self.do_test_list(func, [1, 2, 3], 1, [2, 3, 1])
127+
self.do_test_list(func, [1, 2, 3], 2, [3, 1, 2])
128+
129+
N = 500
130+
for i in range(N):
131+
self.do_test_list(func, range(N), i, range(i, N) + range(i))
132+
133+
def test_rotates(self):
134+
self.run_tests(rotate_naive)
135+
self.run_tests(rotate_juggle)
136+
self.run_tests(rotate_swap)
137+
self.run_tests(rotate_reverse)
138+
139+
140+
141+
if __name__ == '__main__':
142+
# Uncomment one of the following
143+
#~ unittest.main()
144+
benchmark()

2008/wxpytris/lib.zip

38.4 KB
Binary file not shown.

2008/wxpytris/wxpytris.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import sys
2+
import wx
3+
4+
sys.path.insert(0, 'lib.zip')
5+
from lib.TetrisGame import TetrisGame
6+
7+
8+
if __name__ == '__main__':
9+
app = wx.PySimpleApp()
10+
frame = TetrisGame(None)
11+
frame.Show(True)
12+
app.MainLoop()
13+
14+
15+
16+
17+
18+
19+

2008/wxpytris/wxpytris_highscores

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
KGxwMAooUydxJwpwMQpJNDUKdHAyCmEu

0 commit comments

Comments
 (0)