Skip to content

Instantly share code, notes, and snippets.

@travisby
Created December 5, 2015 15:31
Show Gist options
  • Save travisby/5e7ead0467e9bea892ba to your computer and use it in GitHub Desktop.
Save travisby/5e7ead0467e9bea892ba to your computer and use it in GitHub Desktop.
module Main where
import Data.Maybe
import Data.List
main = do
content <- getContents
-- get rid of \n
let c = init content
putStr "Single Santa traveled: "
print . length . nub . strToAddresses $ c
putStr "Double Santa traveled: "
let (santaDirections, robosantaDirections) = splitList c
print . length . nub $ strToAddresses santaDirections ++ strToAddresses robosantaDirections
data Address = Address Int Int
instance Eq Address where
(Address x1 y1) == (Address x2 y2) = x1 == x2 && y1 == y2
data Direction = North | South | East | West
charToDirection :: Char -> Maybe Direction
charToDirection '^' = Just North
charToDirection 'v' = Just South
charToDirection '>' = Just East
charToDirection '<' = Just West
charToDirection _ = Nothing
move :: Address -> Direction -> Address
move (Address x y) North = Address x (y + 1)
move (Address x y) South = Address x (y - 1)
move (Address x y) East = Address (x + 1) y
move (Address x y) West = Address (x - 1) y
strToAddresses :: String -> [Address]
strToAddresses xs = foldr (((\ d (x : xs) -> move x d : x : xs) . fromJust) . charToDirection) [Address 0 0] xs
splitList :: [a] -> ([a], [a])
splitList xs = splitListHelper xs ([], [])
-- inefficient way to split a list on odds and evens!
-- length is a slow operation
splitListHelper :: [a] -> ([a], [a]) -> ([a], [a])
splitListHelper [] xs = xs
splitListHelper (x:xs) (ys, zs)
| length ys == length zs = splitListHelper xs (x:ys, zs)
| otherwise = splitListHelper xs (ys, x:zs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment