module Main where
import System.Random as Random
maxSubSumSeq :: [Int] -> Maybe (Int, Int)
maxSubSumSeq xs | null xs = Nothing
| otherwise = let len = length xs in Just $ maxSubSumSeq' xs 1 (div (1+len) 2) len
maxSubSumSeq' :: [Int] -> Int -> Int -> Int -> (Int, Int)
maxSubSumSeq' xs i c j | i == j = (i, j)
| i == c = let leftValue = xs !! (i-1)
rightSubSeqIndex = maxSubSumSeq' xs (c+1) (div (c+1+j) 2) j
rightMaxSubSumSeq = takeSubList (fst rightSubSeqIndex) (snd rightSubSeqIndex) xs
rightValue = sum rightMaxSubSumSeq
sums = [(leftValue,(i,c)), (leftValue+rightValue,(i,snd rightSubSeqIndex)), (rightValue,rightSubSeqIndex)]
in snd $ maximum sums
| otherwise = let leftSubSeqIndex = maxSubSumSeq' xs i (div (i+c) 2) c
leftMaxSubSumSeq = takeSubList (fst leftSubSeqIndex) (snd leftSubSeqIndex) xs
leftValue = sum leftMaxSubSumSeq
rightSubSeqIndex = maxSubSumSeq' xs (c+1) (div (c+1+j) 2) j
rightMaxSubSumSeq = takeSubList (fst rightSubSeqIndex) (snd rightSubSeqIndex) xs
rightValue = sum rightMaxSubSumSeq
midValue = sum $ takeSubList (fst leftSubSeqIndex) (snd rightSubSeqIndex) xs
sums = [(leftValue,leftSubSeqIndex), (midValue,(fst leftSubSeqIndex,snd rightSubSeqIndex)), (rightValue,rightSubSeqIndex)]
in snd $ maximum sums
takeSubList :: Int -> Int -> [Int] -> [Int]
takeSubList = (\i j xs -> take (j-i+1) $ drop (i-1) xs)
makeOutPutStr :: Maybe (Int, Int) -> [Int] -> String -> String
makeOutPutStr value xs name = case value of
Nothing -> "invalid value"
Just index -> let subseq = takeSubList (fst index) (snd index) xs
in name ++ " maxsubseq index is: " ++ show index ++ " it's maxsumseq is: " ++ show subseq ++ " sum is: "++ show (sum $ subseq)
testValue1 = [-2,11,-4,13,-5,-2]
testValue2 = [-6,2,4,-7,5,3,2,-1,6,-9,10,-2]
main :: IO()
main = do
let testValue1Index = maxSubSumSeq testValue1
let testValue2Index = maxSubSumSeq testValue2
putStrLn $ makeOutPutStr testValue1Index testValue1 "testValue1"
putStrLn $ makeOutPutStr testValue2Index testValue2 "testValue2"
return ()
import System.Random as Random
maxSubSumSeq :: [Int] -> Maybe (Int, Int)
maxSubSumSeq xs | null xs = Nothing
| otherwise = let len = length xs in Just $ maxSubSumSeq' xs 1 (div (1+len) 2) len
maxSubSumSeq' :: [Int] -> Int -> Int -> Int -> (Int, Int)
maxSubSumSeq' xs i c j | i == j = (i, j)
| i == c = let leftValue = xs !! (i-1)
rightSubSeqIndex = maxSubSumSeq' xs (c+1) (div (c+1+j) 2) j
rightMaxSubSumSeq = takeSubList (fst rightSubSeqIndex) (snd rightSubSeqIndex) xs
rightValue = sum rightMaxSubSumSeq
sums = [(leftValue,(i,c)), (leftValue+rightValue,(i,snd rightSubSeqIndex)), (rightValue,rightSubSeqIndex)]
in snd $ maximum sums
| otherwise = let leftSubSeqIndex = maxSubSumSeq' xs i (div (i+c) 2) c
leftMaxSubSumSeq = takeSubList (fst leftSubSeqIndex) (snd leftSubSeqIndex) xs
leftValue = sum leftMaxSubSumSeq
rightSubSeqIndex = maxSubSumSeq' xs (c+1) (div (c+1+j) 2) j
rightMaxSubSumSeq = takeSubList (fst rightSubSeqIndex) (snd rightSubSeqIndex) xs
rightValue = sum rightMaxSubSumSeq
midValue = sum $ takeSubList (fst leftSubSeqIndex) (snd rightSubSeqIndex) xs
sums = [(leftValue,leftSubSeqIndex), (midValue,(fst leftSubSeqIndex,snd rightSubSeqIndex)), (rightValue,rightSubSeqIndex)]
in snd $ maximum sums
takeSubList :: Int -> Int -> [Int] -> [Int]
takeSubList = (\i j xs -> take (j-i+1) $ drop (i-1) xs)
makeOutPutStr :: Maybe (Int, Int) -> [Int] -> String -> String
makeOutPutStr value xs name = case value of
Nothing -> "invalid value"
Just index -> let subseq = takeSubList (fst index) (snd index) xs
in name ++ " maxsubseq index is: " ++ show index ++ " it's maxsumseq is: " ++ show subseq ++ " sum is: "++ show (sum $ subseq)
testValue1 = [-2,11,-4,13,-5,-2]
testValue2 = [-6,2,4,-7,5,3,2,-1,6,-9,10,-2]
main :: IO()
main = do
let testValue1Index = maxSubSumSeq testValue1
let testValue2Index = maxSubSumSeq testValue2
putStrLn $ makeOutPutStr testValue1Index testValue1 "testValue1"
putStrLn $ makeOutPutStr testValue2Index testValue2 "testValue2"
return ()