Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commite3701da1f4e6d2e67c321766c0545c32014ab7b2 (patch)
Author
 Syndamia <kamen@syndamia.com>
2023-01-07 18:08:31 +0200
Committer
 Syndamia <kamen@syndamia.com>
2023-01-07 18:08:31 +0200
Filesbf83fb600d0c11606ab6dde5762425260438f042
uni-projects-e3701da1f4e6d2e67c321766c0545c32014ab7b2.tar
uni-projects-e3701da1f4e6d2e67c321766c0545c32014ab7b2.tar.gz
uni-projects-e3701da1f4e6d2e67c321766c0545c32014ab7b2.zip
Parent3143b2022ce868b043810d9b27f9837cec746291 (diff)
[FP/HW4] Drastically simplified exercise 1 and added comments
1 files changed, 23 insertions, 35 deletions
-rw-r--r--Year 2/Functional Programming/hw4.hs58
diff --git a/Year 2/Functional Programming/hw4.hs b/Year 2/Functional Programming/hw4.hs
index c0c4d1a..8e35f4d 100644
--- a/Year 2/Functional Programming/hw4.hs
+++ b/Year 2/Functional Programming/hw4.hs
@@ -1,42 +1,30 @@
--- Exercise 1
+-- Задача 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
+hasAllCharsIn :: String -> String -> Bool
+hasAllCharsIn 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))
+decode i = read $ parseNumbers (getSegments $ 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
+ -- След като написах огромна имплементация, която намира всеки сегмент какъв му е знака, забелязах че
+ -- може да използваме само "групи" сегменти, за да различим всички цифри с еднакви дължини.
+ -- Тоест, вземаме двойките сегменти bd, eg и cf (наименования от "работещия" циферблат), като не се интересуваме от тяхната наредба,
+ -- и казваме че двойка се съдържа в дадена цифра, ако и двете букви се съдържат в цифрата (тоест, ако има само b, но не d, значи не съдържа bd).
+ --
+ -- За 1, 4, 7, 8 не разглеждаме това свойство, понеже тях ги различаваме по дължина.
+ -- При 5 сегментни цифри, забелязваме че 2 съдържа eg, 5 съдържа bd, 3 не съдържа нищо (и трите съдържат cf, но това не ни интересува)
+ -- При 6 сегментни цифри, забелязваме че 6 съдържа bd и eg, 9 съдържа bd и cf, 0 съдържа eg и cf
- -- 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
+ getSegments nums = [subtr (nums!!2) (nums!!0), -- сегменти b и d
+ subtr (subtr (nums!!9) (nums!!1)) (nums!!2), -- сегменти e и g
+ nums!!0] -- сегменти c и f
parseNumbers _ [] = []
parseNumbers seg parse = (parseDigit seg (head parse)) : parseNumbers seg (tail parse)
@@ -46,12 +34,12 @@ decode i = read $ find_a [] (sortBy (\s1 s2 -> compare (length s1) (length s2))
| 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'
+ | length d == 5 = if (seg!!0) `hasAllCharsIn` d then '5' -- ако bd се съдържа
+ else if (seg!!1) `hasAllCharsIn` d then '2' -- ако eg се съдържа
+ else '3'
+ | otherwise = if not ((seg!!0) `hasAllCharsIn` d) then '0' -- ако bd не се съдържа (съдържа eg и cf)
+ else if (seg!!2) `hasAllCharsIn` d then '9' -- ако cf се съдържа (и bd се съдържа)
+ else '6'