{-|
Module      : Main
Description : Day 8 solution
Copyright   : (c) Eric Mertens, 2015
License     : ISC
Maintainer  : emertens@gmail.com

<https://adventofcode.com/2015/day/8>

-}
module Main where

import Advent.Input (getInputLines)

-- |
-- >>> :main
-- 1350
-- 2085
main :: IO ()
IO ()
main =
  do [String]
ws <- Int -> Int -> IO [String]
getInputLines Int
2015 Int
8
     Int -> IO ()
forall a. Show a => a -> IO ()
print ([Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (String -> Int
part1 (String -> Int) -> [String] -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
ws))
     Int -> IO ()
forall a. Show a => a -> IO ()
print ([Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (String -> Int
part2 (String -> Int) -> [String] -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [String]
ws))

part1 :: String -> Int
part1 :: String -> Int
part1 String
str = Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [Int] -> Int
forall a. Num a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum (String -> [Int]
forall {a}. Num a => String -> [a]
aux (String -> String
forall a. HasCallStack => [a] -> [a]
init (String -> String
forall a. HasCallStack => [a] -> [a]
tail String
str)))
  where
  aux :: String -> [a]
aux (Char
'\\':Char
'"'    :String
xs) = a
1 a -> [a] -> [a]
forall a. a -> [a] -> [a]
: String -> [a]
aux String
xs
  aux (Char
'\\':Char
'\\'   :String
xs) = a
1 a -> [a] -> [a]
forall a. a -> [a] -> [a]
: String -> [a]
aux String
xs
  aux (Char
'\\':Char
'x':Char
_:Char
_:String
xs) = a
3 a -> [a] -> [a]
forall a. a -> [a] -> [a]
: String -> [a]
aux String
xs
  aux (Char
_           :String
xs) = String -> [a]
aux String
xs
  aux []                = []

part2 :: String -> Int
part2 :: String -> Int
part2 String
str = Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ((Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
isExpand String
str)
  where
  isExpand :: Char -> Bool
isExpand Char
x = Char
x Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
"\\\""