4

I'm trying to split a list into two so that when the input is

[1,2,3,5,6]

output would be

[1,2,3][5,6] 

but I can't seem to figure it out.

The best I can do is [1,3,6][2,5].

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
user2827677
  • 71
  • 1
  • 1
  • 2
  • 1
    Could you post the code you've already written? Without knowing what you're trying, it's impossible to point you in the right direction. Also, could you define your function a bit more? What if a different length list is inputted? What are the conditions for splitting a list? – bheklilr Sep 29 '13 at 04:57
  • 3
    [Hoogle is your friend](http://www.haskell.org/hoogle/?hoogle=Int+-%3E+[a]+-%3E+%28[a]%2C+[a]%29) – fjarri Sep 29 '13 at 05:03

1 Answers1

10

I am a beginner. So, please correct me if this is wrong or sub-optimal.

internalSplit :: [a] -> Int -> [a] -> [[a]]
split :: [a] -> [[a]]

internalSplit (first:rest) count firstPart
    | count == 0 = [firstPart, (first:rest)]
    | otherwise  = internalSplit rest (count - 1) (firstPart ++ [first])

split myList =
    let listLength = length myList
    in
        if listLength `mod` 2 == 0 then
            internalSplit myList (listLength `div` 2) []
        else
            internalSplit myList ((listLength `div` 2) + 1) []

main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

Output

[[1,2,3],[5,6]]
[[1,2,3],[4,5,6]]

Edit:

Managed to use builtin functions and came up with this

internalSplit :: [a] -> Int -> [[a]]
split :: [a] -> [[a]]

internalSplit myList splitLength = [(take splitLength myList), (drop splitLength myList)]

split myList =
    let listLength = length myList
    in
        if listLength `mod` 2 == 0 then
            internalSplit myList (listLength `div` 2)
        else
            internalSplit myList ((listLength `div` 2) + 1)

main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

Output

[[1,2,3],[5,6]]
[[1,2,3],[4,5,6]]

Edit 1:

internalSplit :: [a] -> Int -> ([a], [a])
split :: [a] -> ([a], [a])

internalSplit myList splitLength = splitAt splitLength myList

split myList =
    let listLength = length myList
    in
        if listLength `mod` 2 == 0 then
            internalSplit myList (listLength `div` 2)
        else
            internalSplit myList ((listLength `div` 2) + 1)

main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

Output

([1,2,3],[5,6])
([1,2,3],[4,5,6])

Edit2

As suggested by Bogdon in the comments section, this can be greatly simplified to this

split :: [a] -> ([a], [a])
split myList = splitAt (((length myList) + 1) `div` 2) myList
main = do
        print $ split [1, 2, 3, 5, 6]
        print $ split [1, 2, 3, 4, 5, 6]

Output

([1,2,3],[5,6])
([1,2,3],[4,5,6])
thefourtheye
  • 233,700
  • 52
  • 457
  • 497