Skip to content

Instantly share code, notes, and snippets.

@pta2002
Created December 13, 2017 18:42
Show Gist options
  • Save pta2002/ae21adafd96f5970f10fccf060735698 to your computer and use it in GitHub Desktop.
Save pta2002/ae21adafd96f5970f10fccf060735698 to your computer and use it in GitHub Desktop.
import Text.Parsec
import Text.Parsec.String
data Direction = U | D deriving Show
data Layer = Layer Int Int Int Direction deriving Show
-- parse
input = [ Layer 0 3 0 U, Layer 1 2 0 U, Layer 4 4 0 U, Layer 6 4 0 U ]
p_layer :: Parser Layer
p_layer = do
d <- read <$> many1 digit
char ':'
spaces
r <- read <$> many1 digit
return $ Layer d r 0 U
p_layers :: Parser [Layer]
p_layers = p_layer `sepBy` char '\n'
-- run
next :: Layer -> Layer
next l@(Layer _ 0 _ _) = l
next (Layer i l p U)
| p == (l - 1) = Layer i l (p-1) D
| otherwise = Layer i l (p+1) U
next (Layer i l p D)
| p == 0 = Layer i l (p+1) U
| otherwise = Layer i l (p-1) D
after :: Int -> [Layer] -> [Layer]
after n l = (iterate (map next) l) !! n
run ((Layer d r p _):[])
| p == 0 = d * r
| otherwise = 0
run ((Layer d r p _):l@((Layer d' _ _ _):xs))
| p == 0 = d * r + (run . after (d' - d) $ l)
| otherwise = run . after (d' - d) $ l
caught ((Layer d r p _):[])
| p == 0 = 1
| otherwise = 0
caught ((Layer d r p _):l@((Layer d' _ _ _):xs))
| p == 0 = 1 + (run . after (d' - d) $ l)
| otherwise = run . after (d' - d) $ l
p2 l = let r = caught l
in if r == 0 then 0 else (1 + (p2 $ after 1 l))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment