public
Description: Run programs in the Emacs buffer holding their source, seeing their output inline, interactively.
Homepage: http://wry.me/project/halp
Clone URL: git://github.com/darius/halp.git
halp / perfectmedians.lhs
100644 46 lines (32 sloc) 1.149 kb
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
Here's a problem from Brian Hayes's Computing Science column.
 
A perfect median of a sequence of consecutive integers is an element
where the sum of the preceding elements equals the sum of the
following ones.
 
> isPerfectMedian m n = sum [1..m-1] == sum [m+1..n]
 
--- isPerfectMedian 6 8
-- | True
--- isPerfectMedian 7 9
-- | False
 
Let's try finding some, in a really stupid way, to start.
 
> findMediansSlowly limit =
> [(m, n) | n <- [1..limit], m <- [1..n-1], isPerfectMedian m n]
 
--- findMediansSlowly 50
-- | [(6,8),(35,49)]
 
OK, a little bit cleverer now:
 
> faster limit =
> concat $ map (checkMedian limit) [2..limit]
 
> checkMedian limit m =
> let below = ((m-1) * m) `div` 2
> (n, above) = findAbove m below
> in if below == above
> then [(m, n)]
> else []
 
--- faster 500
-- | [(6,8),(35,49),(204,288)]
 
> findAbove m below =
> head $ dropWhile (\ (i, s) -> s < below)
> (iterate (\ (i, s) -> (i+1, s+i+1)) (m, 0))
 
--- findAbove 6 15
-- | (8,15)
 
(Pardon the horrible code; even I can write better, but the idea was
(to play with Halp as a tool and not focus on code quality.)