Permalink
Browse files

add peak finding

  • Loading branch information...
1 parent d9e0aae commit 77b4c0117d833ee1b48e6f0459077266c83da1b3 @drewverlee committed Feb 6, 2014
Showing with 184 additions and 0 deletions.
  1. +13 −0 README.md
  2. +65 −0 peak_finding/1dpeak.py
  3. +106 −0 peak_finding/2dpeak.py
View
13 README.md
@@ -49,6 +49,19 @@ an accompanying graph so you could get a better idea what went wrong
Take a look at the Readme in the file for more!
+Peak Finding Algorithm
+=============================================================================
++ peak_finding/
++ description [here](http://courses.csail.mit.edu/6.006/spring11/rec/rec02.pdf)
++ 6006: algorithms
++ MIT
++ I completed all the lectures and I'm currently about halfway through the
+assignments.
+
+MIT 6006 is a goldmine of information. [Erik Demaine](http://erikdemaine.org/classes/)
+is my hero. This fuled my passion for algorithms. Ok enough sentiment. Peak finding
+is a great exercises becuase there are so many ways to do it. Try it ourself!
+
Linear Algebra ... with code??!?
==============================================================================
View
65 peak_finding/1dpeak.py
@@ -0,0 +1,65 @@
+"""
+ File : 1dpeak.py
+ Author : Drew Verlee
+ Date : 29.06.13.
+ GitHub : https://github.com/Midnightcoffee/
+Description : quick peak find
+"""
+
+import unittest
+
+
+def peak_find(A):
+ """
+ given an array returns a peak
+ [1, 3, 2] => 3
+ [4, 3, 3,5] => 4 or 5
+ """
+
+ if len(A) == 1:
+ return A[0]
+ start = 0
+ end = len(A)
+ middle = (start + end)/2
+ right = middle + 1
+ left = middle - 1
+
+ if right < end and A[right] > A[middle]:
+ return peak_find(A[middle:end])
+ elif left >= start and A[left] > A[middle]:
+ return peak_find(A[start:middle])
+ else:
+ return A[middle]
+
+class TestPeakFind(unittest.TestCase):
+ """test a one d peak find"""
+ msg = 'failed to find peak on '
+
+ def test_one(self):
+ A = [3]
+ s = peak_find(A)
+ self.assertEqual(3, s, self.msg + 'only element, returned {0}'.format(s))
+
+ def test_peak_on_left(self):
+ A = [1,2,3]
+ s = peak_find(A)
+ self.assertEqual(3, s, self.msg + 'left, returned {0}'.format(s))
+
+ def test_peak_on_right(self):
+ A = [3,2,1]
+ s = peak_find(A)
+ self.assertEqual(3, s, self.msg + 'right, returned {0}'.format(s))
+
+ def test_peak_in_middle(self):
+ A = [1,3,2]
+ s = peak_find(A)
+ self.assertEqual(3, s, self.msg + 'middle, returned {0}'.format(s))
+
+ def test_several_peaks(self):
+ A = [3,1,3,1,3]
+ s = peak_find(A)
+ self.assertEqual(3, s, self.msg + 'left, returned {0}'.format(s))
+
+
+if __name__ == '__main__':
+ unittest.main()
View
106 peak_finding/2dpeak.py
@@ -0,0 +1,106 @@
+"""
+ File : 2dpeak.py
+ Author : Drew Verlee
+ Date : 29.06.13.
+ GitHub : https://github.com/Midnightcoffee/
+Description : Program and tests for finding peak in a Matrix, inspired by
+ lecture : http://ocw.mit.edu/courses/electrical-engineering-and-computer-
+ science/6-006-introduction-to-algorithms-fall-2011/lecture-videos/lecture-1-
+ algorithmic-thinking-peak-finding/
+"""
+
+import unittest
+# You will need python 2.7, to run simple type: python 2dpeak.py
+
+# Note this probable isn't the efficient because:
+# A) its recursive
+# B) I copy over the matrix
+# some random things I didn't test for
+# TODO make sure we have matrix, with equal length rows etc..
+# TODO make sure we have numbers, and that they are positive
+# TODO other edge cases?
+
+def two_peak(M):
+ """find a peak in a matrix
+
+ :M: Matrix
+ :returns: location of peak (i,j) in the (M)atrix
+ : Example:
+ 1 2 2
+ 1 [3] 2
+ 1 2 2
+ """
+
+ # find out how many columns and rows we have
+ columns = len(M[0])
+ # pick middle column j = M/2
+ j = len(M[0])/2
+ # find a global max on column j at (i,j)
+ gm = max(M[j])
+ i = M[j].index(gm)
+ # label some key concepts
+ left = j - 1
+ right = j + 1
+
+ # pick left columns if (i, j-1) is > (i,j)
+ if left >= 0 and M[i][left] > M[i][j]:
+ NM = []
+ for ir, r in enumerate(M): # row
+ NM.append([])
+ for ic, c in enumerate(r): # index, column
+ if ic < j:
+ NM[ir].append(c)
+ return two_peak(NM)
+ # pick right columns if (i, j+1) is > (i,j)
+ elif right < columns and M[i][right] > M[i][j]:
+ NM = []
+ for ir, r in enumerate(M): # row
+ NM.append([])
+ for ic, c in enumerate(r): # index, column
+ if ic > j:
+ NM[ir].append(c)
+ return two_peak(NM)
+ else:
+ return M[i][j]
+ # otherwise we found a peak
+
+
+class TestTwoPeak(unittest.TestCase):
+ """a peak is the highest number above, below, right and left"""
+ msg = 'failed to find the peak {0} in {1}, found {2}'
+
+ def test_small_matrix(self):
+ M = [
+ [1,2,3],
+ [1,3,2]
+ ]
+ correct_peak = 3
+ found_peak = two_peak(M)
+ self.assertEqual(correct_peak, found_peak,
+ self.msg.format(correct_peak, M, found_peak))
+
+ def test_medium_matrix(self):
+ M = [
+ [1,2,3],
+ [1,3,2],
+ [3,2,1]
+ ]
+ correct_peak = 3
+ found_peak = two_peak(M)
+ self.assertEqual(correct_peak, found_peak,
+ self.msg.format(correct_peak, M, found_peak))
+
+ def test_large_matrix(self):
+ M = [
+ [1,2,3,2],
+ [1,3,2,1],
+ [3,2,1,1],
+ [3,2,1,1]
+ ]
+ correct_peak = 3
+ found_peak = two_peak(M)
+ self.assertEqual(correct_peak, found_peak,
+ self.msg.format(correct_peak, M, found_peak))
+
+if __name__ == '__main__':
+ unittest.main()

0 comments on commit 77b4c01

Please sign in to comment.