Skip to content

Instantly share code, notes, and snippets.

@chiroptical
Created June 16, 2018 22:08
Show Gist options
  • Save chiroptical/b6638759560e61d419314c67a128ab36 to your computer and use it in GitHub Desktop.
Save chiroptical/b6638759560e61d419314c67a128ab36 to your computer and use it in GitHub Desktop.
import Data.List.Split (splitOn)
main :: IO ()
main = do
contents <- getContents
let path = minPath $ csv3ToRoadSecs (lines contents)
let repr = pictoralRepr (pathStr path)
-- Need to deal with last character
let lastRepr = foldPaths repr (prev repr)
print $ "Minimum distance travelled: " ++ show (pathDist path)
print $ "Path travelled: " ++ pathStr path
print "Take the following path:"
print (top lastRepr)
print (mid lastRepr)
print (bot lastRepr)
type RoadSec = (Int, Int, Int)
type Path = (Int, String, Int)
csv3ToRoadSecs :: [String] -> [RoadSec]
csv3ToRoadSecs = map (toRoadSec . map (read::String->Int) . splitOn ",")
pathDist :: Path -> Int
pathDist (a, _, _) = a
pathStr :: Path -> String
pathStr (_, b, _) = reverse b
toRoadSec :: [Int] -> RoadSec
toRoadSec [x, y, z] = (x, y, z)
toRoadSec _ = error "RoadSec can only be built from 3 elements!"
minPath :: [RoadSec] -> Path
minPath ((a, b, c): xs) = foldl foldRoadSecs (min a b, takeWhich a b, c) xs
foldRoadSecs :: Path -> RoadSec -> Path
foldRoadSecs (m, p, c1) (a2, b2, c2)
| head p == 'a' = (m + min a2 crossB, takeWhich a2 crossB ++ p, c2)
| otherwise = (m + min b2 crossA, takeWhich crossA b2 ++ p, c2)
where
crossB = c1 + b2
crossA = c1 + a2
takeWhich :: Int -> Int -> String
takeWhich a b
| a < b = "a"
| otherwise = "b"
type PictoralRepr = (String, String, String, String)
pictoralRepr :: String -> PictoralRepr
pictoralRepr (x:xs) = foldl foldPaths ([x], "", "", "") (tail . splitOn "" $ xs)
foldPaths :: PictoralRepr -> String -> PictoralRepr
foldPaths (p, t, m, b) n
| p == "a" && n == "a" = (n, "|-" ++ t, " " ++ m, " " ++ b)
| p == "a" && n == "b" = (n, "|-" ++ t, "| " ++ m, "| " ++ b)
| p == "b" && n == "b" = (n, " " ++ t, " " ++ m, "|-" ++ b)
| otherwise = (n, "| " ++ t, "| " ++ m, "|-" ++ b)
prev :: PictoralRepr -> String
prev (p, _, _, _) = p
top :: PictoralRepr -> String
top (_, t, _, _) = reverse t
mid :: PictoralRepr -> String
mid (_, _, m, _) = reverse m
bot :: PictoralRepr -> String
bot (_, _, _, b) = reverse b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment