-
Notifications
You must be signed in to change notification settings - Fork 0
/
Day4.hs
41 lines (25 loc) · 1.15 KB
/
Day4.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import Text.Megaparsec
import Text.Megaparsec.String
import qualified Data.Map.Strict as Map
import Data.List
-- | parser for room descriptors
room :: Parser (String,Int,String)
room = (,,) <$> name <*> sid <*> checksum
where name = concat <$> (many lowerChar `sepBy` char '-')
sid = read <$> some numberChar
checksum = char '[' >> some lowerChar <* char ']'
-- | calculate checksum from room name
mkChecksum s = take 5 . map fst . sortBy (\a b -> compare (snd b) (snd a))
. Map.toList $ Map.fromListWith (+) (zip s (repeat 1))
-- | decrypt room description
decrypt (n,i,c) = (map shift n, i, c)
where shift x = toEnum $ ((fromEnum x - 97 + i) `mod` 26) + 97
main = do
let fn = "input-4-1.txt"
(Right rooms) <- parse (room `sepEndBy` newline) fn <$> readFile fn
let validRooms = filter (\(n,_,c) -> mkChecksum n == c) rooms
let result1 = sum . map (\(_,i,_) -> i) $ validRooms
let decryptedRooms = map decrypt validRooms
let (Just (_,result2,_)) = find (\(n,i,c) -> "pole" `isInfixOf` n) decryptedRooms
putStrLn $ "result part one: " ++ show result1
putStrLn $ "result part two: " ++ show result2