In today’s Programming Praxis, our task is to calculate the total distance traveled by Santa based on data published by NORAD. Let’s get started, shall we?

First, some imports:

import Data.List.HT
import Text.HJson
import Text.HJson.Query

The easiest version of the algorithm to calculate the distance between two coordinated can be found here. I’ve made a few small adjustments to get rid of some duplication. The Scheme solution rounds off the result, but I don’t believe that is correct. Granted, it doesn’t result in a big deviation (3 miles on a total of almost 200000), but rounding off should be saved until the end.

dist :: RealFloat a => (a, a) -> (a, a) -> a
dist (lat1, lng1) (lat2, lng2) =
let toRad d = d * pi / 180
haversin x = sin (toRad $ x / 2) ^ 2
a = haversin (lat2 - lat1) +
cos (toRad lat1) * cos (toRad lat2) * haversin (lng2 - lng1)
in 2 * 6371 * atan2 (sqrt a) (sqrt (1 - a))

Rather than hunting through the string ourselves for the coordinates, we use a Json library.

coords :: Json -> [(Double, Double)]
coords = map ((\[JString lat, JString lng] -> (read lat, read lng)) .
getFromKeys ["lat", "lng"]) . getFromArr

The total distance can be easily calculated by summing the distances between the subsequent points of the route.

totalMiles :: RealFloat a => [(a, a)] -> Int
totalMiles = round . (* 0.621371192) . sum . mapAdjacent dist

All that’s left to do is to read in the route and print out the result.

main :: IO ()
main = either print (print . totalMiles . coords) . fromString .
drop 16 =<< readFile "santa.txt"

Initially there was a much larger difference between my version and the provided answer. It turns out that the route on page 2 is different from the current route published by NORAD, resulting in a difference of about 2000 miles. Using the same route as the Scheme version reduced this to 3, due to the rounding error present in the provided solution.

### Like this:

Like Loading...

*Related*

Tags: bonsai, christmas, code, Haskell, kata, praxis, programming, santa, tracking

This entry was posted on December 24, 2010 at 3:22 pm and is filed under Programming Praxis. You can follow any responses to this entry through the RSS 2.0 feed.
You can leave a response, or trackback from your own site.

December 24, 2010 at 3:45 pm |

Santa must have changed his route. Merry Christmas!