Programming Praxis – Tracking Santa

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.

Tags: , , , , , , , ,

One Response to “Programming Praxis – Tracking Santa”

  1. programmingpraxis Says:

    Santa must have changed his route. Merry Christmas!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: