fork download
  1. #!/usr/bin/env stack
  2. -- stack --resolver=lts-8.2 --install-ghc runghc
  3. {-
  4. Knight's Metric
  5. ========
  6.  
  7. - https://r...content-available-to-author-only...d.it/6coqwk
  8. - I tried to come up with something instead of using a search algorithm,
  9. - but the end result is wrong.
  10. -}
  11. module Main where
  12.  
  13. import Data.List
  14. import Text.Printf
  15.  
  16. type Point = (Int, Int)
  17.  
  18. euclideanDistance :: Point -> Point -> Float
  19. euclideanDistance (x1, y1) (x2, y2) =
  20. sqrt $ fromIntegral ((x2 - x1) ^ 2 + (y2 - y1) ^ 2)
  21.  
  22. potentialMoves =
  23. [(-2, -1), (-2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2), (2, -1), (2, 1)]
  24.  
  25. knightMoves :: Point -> Point -> [Point]
  26. knightMoves s@(sx, sy) d@(dx, dy)
  27. | s == d = []
  28. | otherwise = m : knightMoves n d
  29. where
  30. ((n, m):_) =
  31. sortOn
  32. (\(n@(nx, ny), _) ->
  33. if (dx - nx, dy - ny) `elem` potentialMoves
  34. then 0
  35. else euclideanDistance d n) $
  36. [((sx + x, sy + y), (x, y)) | (x, y) <- potentialMoves]
  37.  
  38. main :: IO ()
  39. main = interact (unlines . map (output . input . words) . lines)
  40. where
  41. input (x:y:[]) = knightMoves (0, 0) ((read x), (read y))
  42. output [] = "0"
  43. output (points) =
  44. printf
  45. "%d\n%s"
  46. (length points)
  47. (intercalate "\n" $ map (\(x, y) -> printf "%d %d" x y) $ points)
Success #stdin #stdout 0s 8388607KB
stdin
0 0
3 7
9 8
13 12
stdout
0
4
1 2
1 2
-1 2
2 1
7
2 1
1 2
2 1
1 2
2 1
-1 2
2 -1
11
2 1
1 2
2 1
1 2
2 1
1 2
2 1
1 2
2 -1
-2 -1
1 2