|
| 1 | +-- https://www.reddit.com/r/dailyprogrammer/comments/3l61vx/20150916_challenge_232_intermediate_where_should/ |
| 2 | +-- This code doesn't provide optimal solution |
| 3 | +-- Only gives an estimate in O(nlog(n)) time |
| 4 | + |
| 5 | +import Data.List |
| 6 | + |
| 7 | +main = do |
| 8 | + inputN <- getLine |
| 9 | + let n = read inputN |
| 10 | + coords <- readCoords n |
| 11 | + let tx = maxX coords |
| 12 | + bx = minX coords |
| 13 | + ty = maxY coords |
| 14 | + by = minY coords |
| 15 | + topLeft = (bx, ty) |
| 16 | + topRight = (tx, ty) |
| 17 | + bottomRight = (tx, by) |
| 18 | + dists = [(x, (dist topLeft x) + (dist topRight x) + (dist bottomRight x)) | x <- coords] |
| 19 | + putStrLn $ show $ smallestDiff dists |
| 20 | + |
| 21 | + |
| 22 | + |
| 23 | +readCoords :: (Floating a, Read a) => Int -> IO [(a, a)] |
| 24 | +readCoords n = |
| 25 | + if n == 0 |
| 26 | + then return [] |
| 27 | + else do |
| 28 | + input <- getLine |
| 29 | + let coord = read input |
| 30 | + rest <- readCoords (n-1) |
| 31 | + return $ coord : rest |
| 32 | + |
| 33 | +dist :: Floating a => (a, a) -> (a, a) -> a |
| 34 | +dist (x1, y1) (x2, y2) = |
| 35 | + (x1 - x2)^2 + (y1 - y2)^2 |
| 36 | + |
| 37 | +maxX coords = maximum [x | (x, _) <- coords] |
| 38 | +maxY coords = maximum [y | (_, y) <- coords] |
| 39 | +minX coords = minimum [x | (x, _) <- coords] |
| 40 | +minY coords = minimum [y | (_, y) <- coords] |
| 41 | + |
| 42 | +smallestDiff :: (Floating a, Floating b, Ord c, Floating c) => [((a, b), c)] -> ((a, b), (a, b)) |
| 43 | +smallestDiff dists = |
| 44 | + smallestDiff' (sortOn snd dists) ((0, 0), (0, 0)) (100000) |
| 45 | + |
| 46 | +smallestDiff' :: (Ord c, Floating c) => [((a, b), c)] -> ((a, b), (a, b)) -> c -> ((a, b), (a, b)) |
| 47 | +smallestDiff' [_] best bestDiff = best |
| 48 | +smallestDiff' dists best bestDiff = |
| 49 | + let rem = tail dists |
| 50 | + (coord1, dist1) = head dists |
| 51 | + (coord2, dist2) = head rem |
| 52 | + diff = dist2 - dist1 |
| 53 | + in |
| 54 | + if diff < bestDiff |
| 55 | + then smallestDiff' rem (coord1, coord2) diff |
| 56 | + else smallestDiff' rem best bestDiff |
| 57 | + |
0 commit comments