Reputation: 2518
I am trying to split a Array containing I and Os, if a certain pattern occurs.
lets assume i have an input, looking like this:
data Bit = O | I deriving (Eq, Show)
let b = [I,I,O,O,O,O,O,I,I,O,O,O,I,O]
that is what i am generating, when encoding [[Bool]] -> [Bit]
corresponding input to my encode function would be let a = [[True, False, False, True],[False, False],[False]]
Now my objective is to decode what ive generated,so i need a function that gets me from b to a.
But i can't come up with a way to split b list into 3 sublists, every time it reads either I,O or I,I. Every Odd letter stands for following member or starting array member. I am basically copying utf unicode encoding.
So i am trying to build a function that would get me from b to a. After some time i came up with this:
split :: [Bit] -> [[Bit]]
split (x1:x2:xs) = if (x1 == I)
then [x2 : split xs]
else x2 : split xs
And i cant figure out, how to split the list into sublist. Any kind of advice/help/code is greatly appreciated
EDIT:
split :: [Bit] ->[[Bit]]
split [] = []
split xs = case foo xs of (ys,I,x2) -> -- generate new subarray like [...,[x2]]
(ys,O,x2) -> -- append existing subarray with value x2 [.....,[previous values]++x2]
foo :: [a] -> ([a],x1,x2)
foo x1:x2:input = (input,x1,x2)
those 2 comments are the last thing i need to figure out. after that im done :)
if feeding b
into function split
, i want this ouput: [[I,O,O,I],[O,O],[O]]
final step would be to get from b to [[True, False, False, True],[False, False],[False]]
Upvotes: 1
Views: 379
Reputation: 1543
If I got it right, you need something like:
split [] = []
split xs = case foo xs of (ys,r) -> r : split ys
foo :: [a] -> ([a],r)
foo = undefined
In foo
, the list should get partially consumed and returns the rest of the list and the value to collect.
EDIT:
data Bit = O | I deriving (Eq, Show)
sampleA = [[True, False, False, True],[False, False],[False]]
sampleB = [I,I,O,O,O,O,O,I,I,O,O,O,I,O]
type TwoBit = (Bit,Bit)
twobit (x:y:xs) = (x,y) : twobit xs
twobit _ = []
split :: [TwoBit] -> [[Bool]]
split [] = []
split xs = case spli xs of (ys,r) -> r : split ys
where
spli :: [TwoBit] -> ([TwoBit],[Bool])
spli (x:xs) = case span (not . pterm) xs of
(ys,zs) -> (zs, map ptrue $ x:ys)
pterm x = (I,O) == x || (I,I) == x
ptrue x = (O,I) == x || (I,I) == x
splitTB = split . twobit
main = print $ splitTB sampleB == sampleA
PS Functions that look like s -> (s,a)
could also be represented as State monad.
Upvotes: 1
Reputation: 135406
I would start with if (x1 == 1) ...
If x1
is a Bit
that can be either I
or O
, why are you comparing its equality against a Num
, 1
?
Upvotes: 2