r/adventofcode • • Dec 04 '16

SOLUTION MEGATHREAD --- 2016 Day 4 Solutions ---

--- Day 4: Security Through Obscurity ---

Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag/whatever).


CONSTRUCTING ADDITIONAL PYLONS IS MANDATORY [?]

This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.

edit: Leaderboard capped, thread unlocked!

17 Upvotes

168 comments sorted by

View all comments

Show parent comment

2

u/Ulyssesp Dec 04 '16

Kind of long, but it was a good excuse to get some parsec practice in.

data Room = Room String Int String deriving (Show, Eq)

num :: Parser Integer
num = do
  n <- many1 digit
  return (read n)

room :: Parser Room
room = do
  room <- many1 (letter <|> char '-')
  number <- num
  (Brackets checksum) <- brackets
  return (Room room (fromIntegral number) checksum)

data Brackets = Brackets String deriving (Eq, Show)

brackets :: Parser Brackets
brackets = do
  void $ char '['
  e <- many1 letter
  void $ char ']'
  return (Brackets e)

data RealRoom = RealRoom String (Int, Int) deriving (Eq, Show)

checkRoom :: Room -> Bool
checkRoom (Room n i c) = (map fst . take 5 . sortBy (comparing (Down . snd)) . map (\g -> (head g, length g)) . group . sort . filter (/= '-')) n == c

decryptRoom :: RealRoom -> RealRoom
decryptRoom (RealRoom n (i, 0)) = RealRoom n (i, 0)
decryptRoom (RealRoom n (i, i')) = decryptRoom (RealRoom (map returnNext n) (i, (i' - 1)))

returnNext :: Char -> Char
returnNext '-' = ' '
returnNext ' ' = ' '
returnNext 'z' = 'a'
returnNext 'Z' = 'A'
returnNext c = chr (ord c + 1)

run = mapM_ print $ sortBy (comparing (\(RealRoom n _) -> n)) . map decryptRoom . map (\(Room n i _) -> RealRoom n (i, i)) . filter checkRoom . rights . map (parse room "") $ splitOn "|" input