diff options
[FP/HW4] Added a complete solution to exercise 1
1 files changed, 65 insertions, 0 deletions
| -rw-r--r-- | Year 2/Functional Programming/hw4.hs | 65 |
diff --git a/Year 2/Functional Programming/hw4.hs b/Year 2/Functional Programming/hw4.hs new file mode 100644 index 0000000..c0c4d1a --- /dev/null +++ b/Year 2/Functional Programming/hw4.hs @@ -0,0 +1,65 @@ +-- Exercise 1 + +import Data.List + +subtr :: String -> String -> String +subtr a b = filter (\c -> not (c `elem` b)) a + +subRange :: [a] -> Int -> Int -> [a] +subRange l start end = (take (end - start + 1) (drop start l)) + +findNotContain :: [String] -> String -> String +findNotContain arr ch = (filter (\s -> not (ch `isSubstrUn` s)) arr) !! 0 + where + isSubstrUn :: String -> String -> Bool + isSubstrUn a b = all (\c -> c `elem` b) a + +decode :: String -> Int +decode i = read $ find_a [] (sortBy (\s1 s2 -> compare (length s1) (length s2)) (take 10 (words i))) (drop 11 (words i)) + where + -- 7-1 = segment a + find_a seg nums parse = find_bd [subtr (nums!!1) (nums!!0)] nums parse + + -- 4-1 = segments b and d + find_bd seg nums parse = find_eg (seg ++ [subtr (nums!!2) (nums!!0)]) nums parse + + -- 8-4-a = segments e and g + find_eg seg nums parse = find_d (seg ++ [subtr (subtr (nums!!9) (nums!!2)) (seg!!0)]) nums parse + + -- From the 6-segment numbers, only number 0 has one of b and d (so we search for number that doesn't have both), and 8-0 = d + add_d seg d = head seg : (subtr (seg!!1) d) : d : drop 2 seg + find_d seg nums parse = find_c (add_d seg (subtr (nums!!9) (findNotContain (subRange nums 6 8) (seg!!1)))) nums parse + + -- From the 6-segment numbers, only number 6 has one of c and f (so we search for number that doesn't have both; number 1 uses both), and 8-6 = c + add_c seg c nums = take 2 seg ++ [c] ++ drop 2 seg ++ [subtr (nums!!0) c] + find_c seg nums parse = find_e (add_c seg (subtr (nums!!9) (findNotContain (subRange nums 6 8) (nums!!0))) nums) nums parse + + -- From the 6-segment numbers, only number 9 has one of e and g, and 8-9 = e + add_e seg e = take 4 seg ++ [e, seg!!5, subtr (seg!!4) e] + find_e seg nums parse = parseNumbers (add_e seg (subtr (nums!!9) (findNotContain (subRange nums 6 8) (seg!!4)))) parse + + parseNumbers _ [] = [] + parseNumbers seg parse = (parseDigit seg (head parse)) : parseNumbers seg (tail parse) + where + parseDigit seg d + | length d == 2 = '1' + | length d == 3 = '7' + | length d == 4 = '4' + | length d == 7 = '8' + | length d == 5 = if (seg!!1!!0) `elem` d then '5' + else if (seg!!4!!0) `elem` d then '2' + else '3' + | otherwise = if not ((seg!!2!!0) `elem` d) then '6' + else if not ((seg!!4!!0) `elem` d) then '9' + else '0' + + + +-- main + +main :: IO() +main = do + sample <- readFile "sample.txt" + print(sum (map (\l -> decode l) (lines sample))) + input <- readFile "input.txt" + print(sum (map (\l -> decode l) (lines input))) |
