2
\$\begingroup\$

My task is to code something that prints out this:

enter image description here

This is what I have done so far.

diag matrix = diag2 [] [] matrix where
 diag2 [] [] [] = [] 
 diag2 xss [] (zs:zss) = diag2 [] (reverse $ zs:xss) zss
 diag2 xss ((y:ys):yss) zss = y : diag2 (ys:xss) yss zss 
 diag2 xss ([] :yss) zss = diag2 xss yss zss
 diag2 xss [] [] = diag2 [] (reverse xss) []

Is there an easier way to code this? Also, how can I solve it if this is a very big matrix?

Tunaki
9,3011 gold badge31 silver badges46 bronze badges
asked May 28, 2016 at 15:33
\$\endgroup\$
3
  • \$\begingroup\$ The problem statement is not clear. Are you trying to calculate the traversal order, or draw a picture, or what? Will you use the contents of an input matrix or just the element numbers? \$\endgroup\$ Commented May 28, 2016 at 19:44
  • \$\begingroup\$ Oh I'm sorry. It should print out: [1,2,6,3,7,11,4...] and so on. \$\endgroup\$ Commented May 29, 2016 at 12:12
  • \$\begingroup\$ If you just want the numbers, you can solve this without representing the matrix at all, by simple arithmetic. \$\endgroup\$ Commented Jun 25, 2016 at 2:10

2 Answers 2

1
\$\begingroup\$

One inefficiency of your solution is that is calls reverse. This means that it will have to traverse an entire row. It also means it won't work with infinite lists.

The best implementation I've found is Data.Universe.Helpers.diagonals from the universe-base package.

It can even operate on an infinite list of infinite lists:

import Data.Universe.Helpers
import Control.Monad
mat = [ [i..] | i <- [1..] ]
example n = forM_ (take n $ diagonals mat) $ print

e.g.:

ghci> example 4
[1]
[2,2]
[3,3,3]
[4,4,4,4]

More info available at this SO answer: https://stackoverflow.com/a/32469565/866915

answered May 29, 2016 at 13:47
\$\endgroup\$
1
1
\$\begingroup\$
concat . concat . transpose . (zipWith (++) (iterate ([] :) [])) . map (map (: [])) 

seems and seams the easiest zigzag to me: this boxes all matrix elements as singleton lists to enable us to prepend increasingly many empty cells at each row head to right shift the rows diagonally, then in transposition we read out the shifted columns and unbox them pettily until you have your desired result

let fivesquare = [[e+f|e<-[1..5]]|f<-[0,5..20]]; zigzag = concat . concat . transpose . (zipWith (++) (iterate ([] :) [])) . map (map (: [])) in zigzag fivesquare
[1,2,6,3,7,11,4,8,12,16,5,9,13,17,21,10,14,18,22,15,19,23,20,24,25]

this should presumably get bulletproven for endless matrices if possible with some interspersed

... takeWhile (not . null ...
answered Jun 11, 2016 at 3:48
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.