never executed always true always false
1 {-|
2 Module: Y2015.D12
3 Description: Advent of Code Day 12 Solutions.
4 License: MIT
5 Maintainer: @tylerjl
6
7 Solutions to the day 12 set of problems for <adventofcode.com>.
8 -}
9
10 {-# LANGUAGE OverloadedStrings #-}
11
12 module Y2015.D12 (jsonSum, jsonSumFixed) where
13
14 import Data.Aeson (Value(..), decode)
15 import Data.ByteString.Lazy (ByteString)
16 import Data.Foldable (foldl')
17 import Data.Scientific (floatingOrInteger)
18 import qualified Data.Vector as V
19 import qualified Data.HashMap.Strict as KM
20
21 -- |Sum all numbers in a JSON-like structure
22 jsonSum :: ByteString -- ^ JSON input string
23 -> Int -- ^ Summation of all nested numeric values
24 jsonSum = jSum . decode
25 where jSum Nothing = 0
26 jSum (Just v) = sumValue v
27
28 -- |Sums all numbers in a JSON-like structure with a specific filter
29 jsonSumFixed :: ByteString -- ^ JSON input string
30 -> Int -- ^ Summation of all nested numeric values
31 jsonSumFixed = jSum . decode
32 where jSum Nothing = 0
33 jSum (Just v) = sumValue $ filterV v
34
35 filterV :: Value -> Value
36 filterV o@(Object x) | r o = Null
37 | otherwise = Object (KM.map filterV x)
38 where r (String x') = x' == "red"
39 r (Object o') = any r $ KM.filter string o'
40 r _ = False
41 string (String _) = True
42 string _ = False
43 filterV (Array v) = Array (V.map filterV v)
44 filterV s@(String x) | x == "red" = Null
45 | otherwise = s
46 filterV v = v
47
48 sumValue :: Value -> Int
49 sumValue (Object o) = foldl' valAcc 0 o
50 sumValue (Number n) = case (floatingOrInteger n :: Either Double Int) of
51 Left _ -> 0
52 Right i -> i
53 sumValue (Array n) = V.foldl' valAcc 0 n
54 sumValue _ = 0
55
56 valAcc :: Int -> Value -> Int
57 valAcc = flip ((+) . sumValue)