Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Turn these haskell Int lists into a different one

Tags:

list

haskell

I have the following Int lists:

t1 = [1000, 1001, 1002, 1003, 1004]
t2 = [2000, 2001, 2002]
t3 = [3000, 3001, 3002, 3003]

The lists size are variable, they are not just 3 like in this example. They can have 1 element or many more. Then I have this:

tAll = [t1, t2, t3]

I need a function that "turns" tAll into something like this:

[[1, 1000, 2000, 3000],
[2, 1001, 2001, 3001],
[3, 1002, 2002, 3002],
[4, 1003, 0, 3003], 
[5, 1004, 0, 0]]

Is there an easy way to do this?

EDIT: I'm sorry, I posted this in a hurry and it was not exactly what I wanted. I updated the code above...

like image 674
rfgamaral Avatar asked Dec 18 '08 19:12

rfgamaral


2 Answers

Here is a one-liner for you, if you're still interested:

zipWith (:) [1..] $ take (maximum $ map length tAll) 
                         (transpose (map (++repeat 0) tAll))

edit: OK, it's better to write it with two lines :)

like image 100
mattiast Avatar answered Nov 30 '22 10:11

mattiast


Well, this is the Haskell beginner's way to write it, but since it's doing explicit recursion there is probably a better way. :-)

head0 [] = 0
head0 xs = head xs

tail0 [] = []
tail0 xs = tail xs

nreorder n ts
  | all null ts = []
  | otherwise   = (n : map head0 ts) : nreorder (n+1) (map tail0 ts)

And nreorder 1 tAll prints the list you want. You can avoid those indices by doing the following instead:

reorder ts
  | all null ts = []
  | otherwise   = (map head0 ts) : reorder (map tail0 ts)

so that reorder tAll = [[1000,2000,3000],[1001,2001,3001],[1002,2002,3002],[1003,0,3003],[1004,0,0]], and (slightly cleaned up thanks to mattiast):

nreorder ts = zipWith (:) [1..] (reorder tAll)

so that nreorder tAll prints the list you want.

like image 40
ShreevatsaR Avatar answered Nov 30 '22 09:11

ShreevatsaR