-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcount_strings.hs
More file actions
105 lines (87 loc) · 2.38 KB
/
count_strings.hs
File metadata and controls
105 lines (87 loc) · 2.38 KB
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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
import Data.Maybe
import Data.Functor
import Debug.Trace
import Control.Monad
import Control.Monad.State
data RToken = RA
| RB
| ROp RToken RToken RToken
| RAnd --RToken RToken
| ROr --RToken RToken
| RStar
| RStart
| REnd
deriving (Eq, Show)
get_char :: State [Char] (Maybe Char)
get_char = do
rs <- get
case rs of
(x:xs) -> do
put xs
return $ Just x
[] -> return Nothing
lookahead_char :: State [Char] (Maybe Char)
lookahead_char = do
rs <- get
case rs of
(x:xs) -> return $ Just x
[] -> return Nothing
-- (aa)
parse :: State [Char] RToken
parse = do
let parse_token c = do
case c of
Just 'a' -> return RA
Just 'b' -> return RB
Just '|' -> return ROr
Just '(' -> return RStart
Just ')' -> return REnd
Just '*' -> return RStar
Nothing -> return REnd
Just RStart <- parse_token <$> get_char
ll <- parse_token <$> lookahead_char
l <- if ll == Just RStart
then parse
else do
get_char
return $ fromJust ll
oop <- parse_token <$> lookahead_char
op <- case oop of
Just RStart -> return RAnd
Just RAnd -> do
get_char
return RAnd
Just ROr -> do
get_char
return ROr
Just RStar -> return RStar
_ -> return RAnd
rr <- parse_token <$> lookahead_char
r <- if rr == Just RStart
then parse
else do
get_char
return (fromJust rr)
Just REnd <- parse_token <$> get_char
return $ ROp l op r
count :: Integer -> RToken -> (Integer, [Integer])
count 1 RA = (1, [1])
count _ RA = (0, [])
count 1 RB = (1, [1])
count _ RB = (0, [])
count n (ROp l ROr r) =
(\(lc, lv) (rc, rv) -> (lc + rc, lv ++ rv)) (count n l) (count n r)
count n (ROp l RAnd r) = undefined
count n (ROp l RStar RStar) = undefined
solve :: String -> Integer -> Integer
solve s n =
let parsed = evalState parse s
counted = count n parsed
in fst counted
main = do
t <- read <$> getLine
mapM_ (\_ -> do
[s, n] <- words <$> getLine
let nn = read n :: Integer
putStrLn $ show $ solve s nn
) [1..t]