Summary Files Commits Branches @commit @diff @stats
path: root / Year 2 / Functional Programming
diff options
context:
space:
mode:
Commit3143b2022ce868b043810d9b27f9837cec746291 (patch)
Author
 Syndamia <kamen@syndamia.com>
2023-01-07 17:22:05 +0200
Committer
 Syndamia <kamen@syndamia.com>
2023-01-07 17:22:05 +0200
Files9b2cfe6a32d97addea2eadfc98b21d684e280f92 /Year 2/Functional Programming
uni-projects-3143b2022ce868b043810d9b27f9837cec746291.tar
uni-projects-3143b2022ce868b043810d9b27f9837cec746291.tar.gz
uni-projects-3143b2022ce868b043810d9b27f9837cec746291.zip
Parent5e595c4055876c4169e6eb7a9bcbbe67787e69ce (diff)
[FP/HW4] Added a complete solution to exercise 1
1 files changed, 65 insertions, 0 deletions
-rw-r--r--Year 2/Functional Programming/hw4.hs65
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)))