Reputation: 1
I have to make a function that finds specific sublists.
function :: Integer -> Integer -> [[Integer]]
function n m = …
m
is smaller then n
the program exits.(mod (sum [1..n]) m) /= 0
then again error.[1..n]
For example, if the numbers are n = 6
and m = 7
. List is [1,2,3,4,5,6]
The answer is [[6,1],[5,2],[4,3]]
.
function 6 7
>>> [[6,1],[5,2],[4,3]]
Order is not necessary. So on I have made these steps. Any help would be useful.Also example codes would be useful. If anyone can solve this problem, I would appreciate it. Code with solution would be very useful for me.
function :: Integer -> Integer -> [[Integer]]
function n m
|m < n = error "m is smaller than n"
|(mod (sum [1..n]) m) /= 0 = error "list sum doesn't devide with m"
|otherwise = …
Upvotes: 0
Views: 1879
Reputation: 15965
I would go and create all lists with sum property, for example using list comprehension. And then filtering by the uniqueness property, by something like:
note that the result is depending on how you have sorted all sublists - so the solution is not a unique longest list of sublists, but just one of many results possible with sum and "uniqueness" property.
just something to start and think about i only collect easy two element lists and otherwise take one maximal list.
The next improvements would be to make a function collecting not only easy but all two element lists and then generalize this to get sublists of a given length, maybe you want to have a look a bit at elementary combinatorics.
module Sublists where
import Data.List ((\\))
subLists :: Int -> Int -> [[Int]]
subLists n = subLists' ([],[1..n])
subLists' :: ([[Int]],[Int]) -> Int -> [[Int]]
subLists' aa m = fst (mLSubLists (tLSubLists aa m) m)
_subLists :: ([Int] -> Int -> [Int]) -> ([[Int]],[Int]) -> Int -> ([[Int]],[Int])
_subLists _ yx@(_,[ ]) _ = yx
_subLists _ yx@(_,[_]) _ = yx
_subLists f yx@(yy,xx) m | sum xx < m = yx
| otherwise = if tt == []
then yx
else _subLists f (tt:yy,xx\\tt) m
where tt = f xx m
tLSubLists :: ([[Int]],[Int]) -> Int -> ([[Int]],[Int])
tLSubLists = _subLists twoList
mLSubLists :: ([[Int]],[Int]) -> Int -> ([[Int]],[Int])
mLSubLists = _subLists manyList
twoList :: [Int] -> Int -> [Int]
twoList [ ] _ = []
twoList [_] _ = []
twoList xx@(x:xs) m | (x + l) < m = []
| x == l = []
| (x + l) `rem` m == 0 = [x,l]
| otherwise = twoList ii m
where l = last xs
ii = init xx
manyList :: [Int] -> Int -> [Int]
manyList xx m | s < m = []
| s == m = xx
| s `rem` m == 0 = xx
| otherwise = manyList xs m
where s = sum xx
xs = tail xx
and some test cases:
import Sublists
import Test.HUnit
import Data.List ((\\))
main = testAll
testAll = runTestTT $ TestList tests
tests :: [Test]
tests = [
"n=6 m=7" ~: "subLists" ~: [[3,4],[2,5],[1,6]]
~=? subLists 6 7,
"n=6 m=7" ~: "twoList" ~: [1,6]
~=? twoList [1..6] 7,
"n=6 m=7" ~: "twoList" ~: [2,5]
~=? twoList ([1..6]\\[1,6]) 7,
"n=6 m=7" ~: "twoList" ~: [3,4]
~=? twoList (([1..6]\\[1,6])\\[2,5]) 7,
"n=6 m=7" ~: "manyList" ~: [2,3,4,5]
~=? manyList [1..5] 7,
"dummy" ~: "dummy" ~: "result"
~=? (\_ -> "result") "function"
]
Upvotes: 1
Reputation: 54584
The function subsequences
in Data.List
might be helpful, e.g.
subsequences "abc" == ["","a","b","ab","c","ac","bc","abc"]
Then you "just" need to filter out all sub-lists that don't match your criterias.
Upvotes: 0