I want a function that changes (1 to 0) on a list of lists, when number of 1’s in that line/column isn’t even. I have done these functions:
1) Sees if the lines in a list are even or not:
parityLine :: [[Int]] -> [Bool]
parityLine [] =[]
parityLine (x:xs)
|sum(x) `mod` 2 == 0 = True:(parityLine(xs))
|otherwise = False:(parityLine(xs))
2) Sum the corresponding elements on a list of lists:
sumPositions :: [[Int]] -> [Int]
sumPositions [] = []
sumPositions (x:xs) = foldl (zipWith (+)) (repeat 0) (x:xs)
3) Sees if the columns in a list are even or not:
parityColumn :: [Int] -> [Bool]
parityColumn [] = []
parityColumn (x:xs)
|head(x:xs) `mod` 2 == 0 = True:parityColumn(xs)
|otherwise = False:parityColumn(xs)
4) Does the operation or with two boolean lists:
bol :: [Bool] -> [Bool] -> [[Bool]]
bol [] _ = []
bol (x:xs) (y:ys)= (map (||x) (y:ys)):(bol xs (y:ys))
5) Correct List:
correct :: [[Int]] -> [[Bool]]
correct [] = []
correct (x:xs)=(bol(parityLine (x:xs))(parityColumn(sumPositions(x:xs))))
So what I want is to alter the function correct to [[Int]]->[[Int]] that does this:
My Int list(x:xs) With my correct function applied
[[0,0,1,1], [[True,True,True,True],
[1,0,1,1], [True,True,False,True],
[0,1,0,1], [True,True,True,True]
[1,1,1,1]] [True,True,True,True]]
Now I can see that in the second line third column, False, so I have to correct that number 1 to have a number of 1’s even. If there is more than one False in that list, I only want to correct one of these 1’s.
As a result, I want that function correct returns:
[[0,0,1,1],
[1,0,0,1],
[0,1,0,1],
[1,1,1,1]]
Thanks.
I’ll give an answer that starts where you are rather than from scratch, so we’re doing it more your way than mine.
First let’s do it for a single element:
(You could use guards for that, but my phone doesn’t have the vertical bar character!)
Next we can do it for a list of lists:
EDIT: You’d like to only change one, so we’ll need a way of making subsequent
Falses intoTrues:I’ve used the function
const :: a -> b -> a. For example,const 5 'c'is just5. I could shorten that definition tomakeTrue = map (const True). Once you get used to thinking that way, you’ll find the shorter version clearer.(==False)could be written more simply asnot, but less clearly perhaps.so for example
So now we can have