Solve Regex task
This commit is contained in:
parent
d6029978c7
commit
7b4b2593ac
|
@ -7,6 +7,9 @@ data Regex
|
|||
= Empty
|
||||
| Epsilon
|
||||
| Symbol Char
|
||||
| Sequence Regex Regex
|
||||
| Star Regex
|
||||
| Choice Regex Regex
|
||||
-- | Sequence, Star, Choice fehlen noch.
|
||||
deriving Show
|
||||
|
||||
|
@ -26,7 +29,13 @@ data Regex
|
|||
tails (\s -> length s >= 1) "abcde" == ["bcde","cde","de","e",""]
|
||||
-}
|
||||
tails :: (String -> Bool) -> String -> [String]
|
||||
tails f s = error "fixme"
|
||||
tails f s = concatMap
|
||||
(\x -> if f (take x s) then [(drop x s)] else [])
|
||||
[0..(length s)]
|
||||
|
||||
-- >>> tails (\s -> length s >= 1) "abcde"
|
||||
-- ["bcde","cde","de","e",""]
|
||||
--
|
||||
|
||||
{- Helper function 2:
|
||||
By repeatedly calling the tails function, this function checks if
|
||||
|
@ -41,7 +50,16 @@ segmentable f s
|
|||
| s == "" = True
|
||||
| "" `elem` leads = True
|
||||
| leads == [] = False
|
||||
| otherwise = error "fixme"
|
||||
| otherwise = or (map (\x -> segmentable f x) leads)
|
||||
where
|
||||
leads = tails f s
|
||||
|
||||
-- >>> segmentable (\s -> length s == 2) "abcde"
|
||||
-- False
|
||||
--
|
||||
-- >>> segmentable (\s -> length s == 2) "abcd"
|
||||
-- True
|
||||
--
|
||||
|
||||
{- Helper function 3:
|
||||
Given two predicates and a string, this function checks if it is
|
||||
|
@ -54,7 +72,22 @@ segmentable f s
|
|||
combinable (\s -> length s == 2) (\s -> length s == 3) "123456" == False
|
||||
-}
|
||||
combinable :: (String -> Bool) -> (String -> Bool) -> String -> Bool
|
||||
combinable f g s = error "fixme"
|
||||
combinable f g s =
|
||||
or (
|
||||
map
|
||||
(\x -> f (take x s) && g (drop x s))
|
||||
(reverse [0..len])
|
||||
)
|
||||
where
|
||||
len = length s
|
||||
|
||||
-- >>> combinable (\s -> length s == 2) (\s -> length s == 3) "12345"
|
||||
-- >>> combinable (\s -> length s == 2) (\s -> length s == 3) "1234"
|
||||
-- >>> combinable (\s -> length s == 2) (\s -> length s == 3) "123456"
|
||||
-- True
|
||||
-- False
|
||||
-- False
|
||||
--
|
||||
|
||||
{-
|
||||
Matching a particular string to a regex a regex now simply means to check
|
||||
|
@ -62,12 +95,12 @@ combinable f g s = error "fixme"
|
|||
-}
|
||||
match :: Regex -> String -> Bool
|
||||
match r s = case r of
|
||||
Empty -> error "fixme"
|
||||
Epsilon -> error "fixme"
|
||||
Symbol c -> error "fixme"
|
||||
Choice r1 r2 -> error "fixme"
|
||||
Sequence r1 r2 -> error "fixme"
|
||||
Star r1 -> error "fixme"
|
||||
Empty -> s == ""
|
||||
Epsilon -> False
|
||||
Symbol c -> s == [c]
|
||||
Choice r1 r2 -> (match r1 s || match r2 s)
|
||||
Sequence r1 r2 -> combinable (match r1) (match r2) s
|
||||
Star r1 -> segmentable (match r1) s
|
||||
{-
|
||||
Examples/test-cases
|
||||
-}
|
||||
|
@ -101,24 +134,49 @@ r4 = Sequence (Symbol 'a') $ Star $ Choice (Symbol 'a') (Symbol 'b')
|
|||
|
||||
shouldBeTrue1 :: Bool
|
||||
shouldBeTrue1 = match r1 "abbbbaccca"
|
||||
-- >>> match r1 "abbbbaccca"
|
||||
-- True
|
||||
--
|
||||
|
||||
shouldBeFalse1 :: Bool
|
||||
shouldBeFalse1 = match r1 "abbcc"
|
||||
-- >>> match r1 "abbcc"
|
||||
-- False
|
||||
--
|
||||
|
||||
|
||||
shouldBeTrue2 :: Bool
|
||||
shouldBeTrue2 = match r2 "abbbbacccabxxxx"
|
||||
-- >>> match r2 "abbbbacccabxxxx"
|
||||
-- True
|
||||
--
|
||||
|
||||
shouldBeFalse2 :: Bool
|
||||
shouldBeFalse2 = match r2 "abbxxxacc"
|
||||
-- >>> match r2 "abbxxxacc"
|
||||
-- False
|
||||
--
|
||||
|
||||
shouldBeTrue3 :: Bool
|
||||
shouldBeTrue3 = match r3 "ab"
|
||||
-- >>> match r3 "ab"
|
||||
-- True
|
||||
--
|
||||
|
||||
shouldBeFalse3 :: Bool
|
||||
shouldBeFalse3 = match r3 "aba"
|
||||
-- >>> match r3 "aba"
|
||||
-- False
|
||||
--
|
||||
|
||||
shouldBeTrue4 :: Bool
|
||||
shouldBeTrue4 = match r4 "abbbab"
|
||||
-- >>> match r4 "abbbab"
|
||||
-- True
|
||||
--
|
||||
|
||||
shouldBeFalse4 :: Bool
|
||||
shouldBeFalse4 :: Bool
|
||||
shouldBeFalse4 = match r4 "abbabc"
|
||||
-- >>> match r4 "abbabc"
|
||||
-- False
|
||||
--
|
||||
|
|
Loading…
Reference in a new issue