Manually merging: - README.md: I added the description from universe/README.md into the heading of dotfiles/README.md. - .envrc: dotfiles/.envrc was a superset of universe/.envrc - .gitignore: Adding some of the ignored patterns from universe/.gitignore to dotfiles/.gitignore Everything else here should be a simple rename.
		
			
				
	
	
		
			181 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			181 lines
		
	
	
	
		
			4.5 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from collections import deque
 | |
| import unittest
 | |
| 
 | |
| ################################################################################
 | |
| # Solution
 | |
| ################################################################################
 | |
| 
 | |
| 
 | |
| def rev(xs, i, j):
 | |
|     """Reverse xs in place from [i, j]"""
 | |
|     while i < j:
 | |
|         xs[i], xs[j] = xs[j], xs[i]
 | |
|         i += 1
 | |
|         j -= 1
 | |
| 
 | |
| 
 | |
| def rotate(xs, n, i=None, j=None):
 | |
|     """Mutably rotates list, xs, n times. Positive n values rotate right while
 | |
|     negative n values rotate left. Rotate within window [i, j]."""
 | |
|     i = i or 0
 | |
|     j = j or len(xs) - 1
 | |
|     ct = j - i
 | |
| 
 | |
|     if n < 0:
 | |
|         n = abs(n)
 | |
|         p = i + n - 1
 | |
|         rev(xs, i, p)
 | |
|         rev(xs, p + 1, j)
 | |
|         rev(xs, i, j)
 | |
|     else:
 | |
|         p = j - (n - 1)
 | |
|         rev(xs, p, j)
 | |
|         rev(xs, i, p - 1)
 | |
|         rev(xs, i, j)
 | |
|     return xs
 | |
| 
 | |
| 
 | |
| def rev_words(xs, i, j):
 | |
|     if j + 1 == len(xs):
 | |
|         return 0
 | |
| 
 | |
|     while j + 1 < len(xs):
 | |
|         while j + 1 < len(xs) and xs[j + 1] != ' ':
 | |
|             j += 1
 | |
| 
 | |
|         rev(xs, i, j)
 | |
|         j += 2
 | |
|         i = j
 | |
| 
 | |
|     return 0
 | |
| 
 | |
| 
 | |
| def reverse_words(xs):
 | |
|     # first reverse everything
 | |
|     rev(xs, 0, len(xs) - 1)
 | |
|     return rev_words(xs, 0, 0)
 | |
| 
 | |
| 
 | |
| def reverse_words_bak(xs, i=None, j=None):
 | |
|     i = i or 0
 | |
|     j = j or len(xs) - 1
 | |
|     w0, w1 = [], []
 | |
| 
 | |
|     if i >= j:
 | |
|         return 0
 | |
| 
 | |
|     pi = i
 | |
|     while pi < len(xs) and xs[pi] != ' ':
 | |
|         w0.append(xs[pi])
 | |
|         pi += 1
 | |
| 
 | |
|     if pi == len(xs):
 | |
|         return 0
 | |
| 
 | |
|     pj = j
 | |
|     while xs[pj] != ' ':
 | |
|         w1.append(xs[pj])
 | |
|         pj -= 1
 | |
| 
 | |
|     d = len(w0) - len(w1)
 | |
| 
 | |
|     rotate(xs, -1 * d, i, j)
 | |
| 
 | |
|     for k in range(len(w1)):
 | |
|         xs[i + k] = w1[len(w1) - 1 - k]
 | |
| 
 | |
|     for k in range(len(w0)):
 | |
|         xs[j - k] = w0[len(w0) - 1 - k]
 | |
| 
 | |
|     while i != j and xs[i] != ' ' and xs[j] != ' ':
 | |
|         i += 1
 | |
|         j -= 1
 | |
| 
 | |
|     if i == j:
 | |
|         return 0
 | |
| 
 | |
|     elif xs[i] == ' ':
 | |
|         while j > 0 and xs[j] != ' ':
 | |
|             j -= 1
 | |
|         if j == 0:
 | |
|             return 0
 | |
|     elif xs[j] == ' ':
 | |
|         while i < len(xs) and xs[i] != ' ':
 | |
|             i += 1
 | |
|         if i == len(xs):
 | |
|             return 0
 | |
|     return reverse_words(xs, i + 1, j - 1)
 | |
| 
 | |
| 
 | |
| ################################################################################
 | |
| # Tests
 | |
| ################################################################################
 | |
| class Test(unittest.TestCase):
 | |
|     def test_rev(self):
 | |
|         xs = [1, 2, 3, 4, 5]
 | |
|         rev(xs, 0, len(xs) - 1)
 | |
|         self.assertEqual(xs, [5, 4, 3, 2, 1])
 | |
| 
 | |
|     def test_rotate(self):
 | |
|         ys = [1, 2, 3, 4, 5]
 | |
|         xs = ys[:]
 | |
|         self.assertEqual(rotate(xs, 1, 1, 3), [1, 4, 2, 3, 5])
 | |
|         xs = ys[:]
 | |
|         self.assertEqual(rotate(xs, -1, 1, 3), [1, 3, 4, 2, 5])
 | |
|         xs = ys[:]
 | |
|         self.assertEqual(rotate(xs, 1), [5, 1, 2, 3, 4])
 | |
|         xs = ys[:]
 | |
|         self.assertEqual(rotate(xs, -1), [2, 3, 4, 5, 1])
 | |
|         xs = ys[:]
 | |
|         self.assertEqual(rotate(xs, -2), [3, 4, 5, 1, 2])
 | |
|         xs = ys[:]
 | |
|         self.assertEqual(rotate(xs, -5), [1, 2, 3, 4, 5])
 | |
|         xs = ys[:]
 | |
|         self.assertEqual(rotate(xs, 5), [1, 2, 3, 4, 5])
 | |
|         xs = ys[:]
 | |
|         self.assertEqual(rotate(xs, 3), [3, 4, 5, 1, 2])
 | |
| 
 | |
|     def test_one_word(self):
 | |
|         message = list('vault')
 | |
|         reverse_words(message)
 | |
|         expected = list('vault')
 | |
|         self.assertEqual(message, expected)
 | |
| 
 | |
|     def test_two_words(self):
 | |
|         message = list('thief cake')
 | |
|         reverse_words(message)
 | |
|         expected = list('cake thief')
 | |
|         self.assertEqual(message, expected)
 | |
| 
 | |
|     def test_three_words(self):
 | |
|         message = list('one another get')
 | |
|         reverse_words(message)
 | |
|         expected = list('get another one')
 | |
|         self.assertEqual(message, expected)
 | |
| 
 | |
|     def test_multiple_words_same_length(self):
 | |
|         message = list('rat the ate cat the')
 | |
|         reverse_words(message)
 | |
|         expected = list('the cat ate the rat')
 | |
|         self.assertEqual(message, expected)
 | |
| 
 | |
|     def test_multiple_words_different_lengths(self):
 | |
|         message = list('at rat house')
 | |
|         reverse_words(message)
 | |
|         expected = list('house rat at')
 | |
|         self.assertEqual(message, expected)
 | |
| 
 | |
|     def test_multiple_words_different_lengths(self):
 | |
|         message = list('yummy is cake bundt chocolate')
 | |
|         reverse_words(message)
 | |
|         expected = list('chocolate bundt cake is yummy')
 | |
|         self.assertEqual(message, expected)
 | |
| 
 | |
|     def test_empty_string(self):
 | |
|         message = list('')
 | |
|         reverse_words(message)
 | |
|         expected = list('')
 | |
|         self.assertEqual(message, expected)
 | |
| 
 | |
| 
 | |
| unittest.main(verbosity=2)
 |