Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I need to construct an auxiliar function in Haskell that, for example: let's A be a matrix such as:

[[10,2, 3, 4]
,[5, 10,10,8]
,[9, 10,10,12]
,[10,14,15,16]] 

returns me a boolean if there is, at least, a triple followed tens list that are diagonal, thus:

*Main> [[10,2,3,4],[5,10,10,8],[9,10,10,12],[10,14,15,16]] 

result: True

because in the matrix above we have three 10's in main diagonal and three 10's in the other diagonal (in this case, both diagonals are main and secondary, respectively. But it doesn't have to be like that ) This code calculates the main diagonal of a matrix:

diagonal :: [[Int]] -> [Int]
diagonal [] = []
diagonal (x:xs) = head x : diagonal (map tail xs)

but i need to solve it for any diagonal and no necessarily for square matrix.

I also made a function to group 3 by 3, but i don't know how to "connect" with the previous idea:

group3in3:: Int -> [a] -> [[a]]
group3in3 _ [] = [[]]
group3in3n n xs
  |n > 0 = (take n xs) : (group3in3  n (drop n xs))
  |otherwise = error "Error" 

I don't have a lot of experience with Haskell. Any help would be appreciated.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
408 views
Welcome To Ask or Share your Answers For Others

1 Answer

Here are some hints. Suppose you wrote a function to check if there was a main diagonal of three 10s in the top-level corner:

cornertens :: [[Int]] -> Bool

This would give True for the following matrix, only checking for 10s in this exact position:

[[10, 0, 0, 0]
,[ 0,10, 0, 0]
,[ 0, 0,10, 0]
,[ 0, 0, 0, 0]]

Now, you could write a recursive function looking for this pattern not just in the top-left corner, but starting anywhere along the top row:

toptens :: [[Int]] -> Bool
toptens mtx = cornertens mtx || toptens (map tail mtx)

This definition won't quite work. It's a recursive function with no base case, so it's an infinite loop if the 10s aren't found, but you should be able to modify it slightly so it knows when to stop recursing. Once it's working, it should be able to find these 10s:

[[0, 10, 0, 0, 0]
,[0,  0,10, 0, 0]
,[0,  0, 0,10, 0]
,[0,  0, 0, 0, 0]]

but also not hang if the matrix is all-zeros.

Once you've got that, you should be able to write a recursive function that looks for this pattern not just anywhere along the top row, but starting in any row:

righthandtens :: [[Int]] -> Bool
righthandtens mtx = toptens mtx || righthandtens (tail mtx)

I've called tens in this orientation from top left to bottom right "right hand". Again, this needs to be modified to know when to stop, but once it's working, it'll find these 10s:

[[0,  0, 0, 0, 0]
,[0, 10, 0, 0, 0]
,[0,  0,10, 0, 0]
,[0,  0, 0,10, 0]

and any other 10s in this particular orientation. If you have a matrix with 10s in the other orientation:

[[0,  0, 10, 0]
,[0, 10,  0, 0]
,[10, 0,  0, 0]]

you can reverse its rows:

[[10, 0,  0, 0]
,[0, 10,  0, 0]
,[0,  0, 10, 0]]

to change the orientation letting you find it with righthandtens. This lets you define:

anytens mtx = righthandtens mtx || righthandtens (reverse mtx)

which should be able to find those 10s in any diagonal anywhere.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...