-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay1.hs
57 lines (47 loc) · 1.85 KB
/
Day1.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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
module Days.Day1 (day1) where
import Data.Char (digitToInt, isNumber)
import qualified Data.Map as M
import Data.Text (Text, pack, replace, unpack)
import Finite (dayn)
import Solution (Solution(..))
day1 :: Solution
day1 = Solution {day=dayn 1, partA=partA1, partB=partB1, common=commonDayOne}
numMap :: M.Map Data.Text.Text Data.Text.Text
numMap = M.fromList $ ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"] `zip` map (Data.Text.pack . show) [1..9::Int]
commonDayOne :: String -> [String]
commonDayOne = lines
partA1 :: [String] -> Int
partA1 input = foldr (\v acc -> read [head v, last v] + acc) 0 newinput
where
newinput = map filterNums input
filterNums = filter isNumber
data Var
= Var
{ num :: Int
, numbersTill :: Int
}
deriving (Show)
instance Eq Var where
a == b = numbersTill a == numbersTill b
instance Ord Var where
compare a b = numbersTill a `compare` numbersTill b
partB1 :: [String] -> Int
partB1 = foldr (\v acc -> let var = getVar v in read (first var ++ last' var) + acc) 0
where
first = getThing takeWhile False
last' = getThing takeWhileEnd True
getVar = flip variations numMap
takeWhileEnd :: (a -> Bool) -> [a] -> [a]
takeWhileEnd f = takeWhile f . reverse
getThing :: Foldable t => ((Char -> Bool) -> [Char] -> t a) -> Bool -> [[Char]] -> String
getThing hof rev = show . num . minimum .
map (\var ->
let len = length . hof (not . isNumber) $ var
revd = if rev then reverse var else var
num = digitToInt (revd !! max 0 len)
in Var num len
)
variations :: String -> M.Map Data.Text.Text Data.Text.Text -> [String]
variations s = M.foldrWithKey' (\k v acc -> sreplace k v s : acc ) []
where
sreplace n r = Data.Text.unpack . Data.Text.replace n r . Data.Text.pack