
Hey all, So I have a two part question (I'm new to haskell, so you can throw all your mugs at me). a) I want to write a function that generates lists of lists of size $n$. All having the property that sum lst = sum [1..n]. a-1) After that, I want to remove all permutations. My idea of doing this is to get all lists from the first function and create a new list with the property that "if sorted list A is not in the list, add it." b-2) I think that's too much questions, but I want to get the hang of this quickly (it was kickass for the few things I've tried out). Thanks, \/\/

Am 09.09.2010 22:55, schrieb Wanas:
Hey all,
So I have a two part question (I'm new to haskell, so you can throw all your mugs at me).
a) I want to write a function that generates lists of lists of size $n$. All having the property that sum lst = sum [1..n]. a-1) After that, I want to remove all permutations. My idea of doing this is to get all lists from the first function and create a new list with the property that "if sorted list A is not in the list, add it."
b-2) I think that's too much questions, but I want to get the hang of this quickly (it was kickass for the few things I've tried out).
Something like this? import Data.List newList :: Int -> [[Int]] newList n = myNub [ l | l <- undefined -- not really sure how you want -- to generate these lists :) , sum l == sum [1..n] ] myNub :: (Ord a) => [[a]] -> [[a]] myNub = nubBy (\a b -> sort a == sort b) - Nils

On Fri, Sep 10, 2010 at 1:06 AM, Nils Schweinsberg
Something like this?
import Data.List
newList :: Int -> [[Int]] newList n = myNub [ l | l <- undefined -- not really sure how you want -- to generate these lists :) , sum l == sum [1..n] ]
myNub :: (Ord a) => [[a]] -> [[a]] myNub = nubBy (\a b -> sort a == sort b)
- Nils
So I've checked out this code, and it doesn't compile on ghci. My version, without the "undefined" portion is(which still doesn't work): import Data.List newList :: Int -> [[Int]] newList n = myNub [ l | l <- [1..n], sum l == sum [1..n] ] myNub :: (Ord a) => [[a]] -> [[a]] myNub = nubBy (\a b -> sort a == sort b) Maybe there's something in the syntax that I'm not quite getting... \/\/

On Fri, Sep 10, 2010 at 12:24:39PM +0300, Wanas wrote:
On Fri, Sep 10, 2010 at 1:06 AM, Nils Schweinsberg
wrote: Something like this?
import Data.List
newList :: Int -> [[Int]] newList n = myNub [ l | l <- undefined -- not really sure how you want -- to generate these lists :) , sum l == sum [1..n] ]
myNub :: (Ord a) => [[a]] -> [[a]] myNub = nubBy (\a b -> sort a == sort b)
- Nils
So I've checked out this code, and it doesn't compile on ghci. My version, without the "undefined" portion is(which still doesn't work):
import Data.List
newList :: Int -> [[Int]] newList n = myNub [ l | l <- [1..n], sum l == sum [1..n] ]
The reason this doesn't compile is that l <- [1..n] means l will take on each of the values 1 through n in turn. So l is of type Int. But then you do 'sum l' which requires l to be a list. So clearly that does not typecheck. But I'm not quite sure I understand what you actually want l to be. Do you want it to run through all lists of a certain length with elements chosen from [1..n]? In that case you could do something like import Control.Monad -- for replicateM ... [ l | l <- replicateM n [1..n], ... ] which will generate all length-n lists with elements chosen from [1..n]. If you wanted all lists with lengths from 1 to n and elements chosen from 1 to n, you could do [ l | len <- [1..n], l <- replicateM len [1..n], ... ] As others have pointed out there are likely far more efficient ways to do what you want, but I'm just trying to help you get this code to work first, even if it's inefficient. -Brent

On Thursday 09 September 2010 22:55:14, Wanas wrote:
Hey all,
So I have a two part question (I'm new to haskell, so you can throw all your mugs at me).
a) I want to write a function that generates lists of lists of size $n$. All having the property that sum lst = sum [1..n]. a-1) After that, I want to remove all permutations. My idea of doing this is to get all lists from the first function and create a new list with the property that "if sorted list A is not in the list, add it."
It's better to not create equivalent lists from the beginning. For n = 12, for example, there are almost 500 million (479001600) permutations of [1 .. 12], that's a lot of wasted work if you create them all and throw away all but one. Assuming that the list elements should be positive (or at least non- negative), what you want is to create the partitions of a target sum with a given length. Such a partition can be represented as a list of pairs (number, multiplicity) with the properties a) the sum of the multiplicities is the target length sum (map snd partition) == targetLength b) the sum of (number * multiplicity) is the target sum sum [n * m | (n,m) <- partition] == targetSum Such a representation is unique if you demand that the numbers (map fst partition) form a strictly decreasing (or increasing, but decreasing is simpler to construct) list and all multiplicities are strictly positive. So you want a function buildPartitions :: Integer -> Integer -> Integer -> [[(Integer,Integer)]] buildPartitions targetSum targetLength maxNumber should create the list of all essentially different partitions of targetSum into exactly targetLength positive (non-negative) numbers not greater than maxNumber. There are two sorts of such partitions, those containing maxNumber and those which don't, hence buildPartitions targetSum targetLength maxNumber = listOne ++ listTwo where listTwo = buildPartitions targetSum targetLength (maxNumber - 1) and listOne is constructed per - for all multiplicities mul from 1 to some limit - for all partitions part of (targetSum - mul*maxNumber) with length (targetLength - mul) into positive numbers < maxNumber - prefix (maxNumber, mul) to part Of course, for there to be any such partitions, some conditions have to be met: targetSum <= targetLength*maxNumber targetSum >= targetLength (if the numbers have to be strictly positive) With these conditions in mind for the recursive call, you can efficiently generate the list of all essentially different partitions via buildPartitions targetSum targetLength maxNumber = [(maxNumber, mul) : part | mul <- [1 .. maxMul] , part <- buildPartitions newSum newLength newMax] ++ buildPartitions targetSum targetLength (maxNumber-1) with appropriate values of maxMul and newMax (newMax can often be smaller than maxNumber-1) and a few cases to end the recursion (when no or only one partition is possible). Then you have to flatten the [(Integer, Integer)] lists into [Integer] lists, for example per flatten ps = [n | (n,m) <- ps, _ <- [1 .. m]]
b-2) I think that's too much questions, but I want to get the hang of this quickly (it was kickass for the few things I've tried out).
Thanks, \/\/

Hello Wanas, Friday, September 10, 2010, 12:55:14 AM, you wrote:
a) I want to write a function that generates lists of lists of size $n$. All having the property that sum lst = sum [1..n]. a-1) After that, I want to remove all permutations. My idea of
you have very interesting questions. hopefully it was already answered at http://www.haskell.org/haskellwiki/Homework_help -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Although it was phrased as one, it wasn't. If it were a homework question,
wouldn't you think that I'd be trained to do it or have a TA to ask?
But who said that you're accusing me of anything :) Thanks for your concern,
Bulat.
\/\/
On Fri, Sep 10, 2010 at 1:47 AM, Bulat Ziganshin
Hello Wanas,
Friday, September 10, 2010, 12:55:14 AM, you wrote:
a) I want to write a function that generates lists of lists of size $n$. All having the property that sum lst = sum [1..n]. a-1) After that, I want to remove all permutations. My idea of
you have very interesting questions. hopefully it was already answered at http://www.haskell.org/haskellwiki/Homework_help
-- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On Sep 10, 2010, at 8:55 AM, Wanas wrote:
Hey all,
So I have a two part question (I'm new to haskell, so you can throw all your mugs at me).
a) I want to write a function that generates lists of lists of size $n$. All having the property that sum lst = sum [1..n]. a-1) After that, I want to remove all permutations. My idea of doing this is to get all lists from the first function and create a new list with the property that "if sorted list A is not in the list, add it."
It's not completely clear to me what you want. Here's my take on it: S0 = {L | L is a list of positive integers and sum L = n} L1 ~~ L2 iff L2 is a permutation of L1 You want to enumerate S0/~~. Staring at this for a bit, what you want is ENUMERATING THE PARTITIONS OF AN INTEGER. Look this up in almost any combinatorics book and you will find an algorithm that you can adapt. There's stuff in Knuth, AOCP, Vol 4, for example. A good reference is "The Theory of Partitions", by G. E. Andrews, Cambridge University Press, 1998. Rung-Bin Lin has reported in "Efficient Data Structures for Storing the Partitions of an Integer" on a data structure for representing all the partitions of an integer n in O(n**2) space, taking O(n**2) time to construct it, so a list of lists might not be the best way to do it in Haskell. What you want to do is to generate the partitions in a canonical order with no duplicates in the first place. Something along these lines: the partiions of n are the partitions of n into pieces no bigger than n with [] appended. the partitions of n into pieces no bigger than k with xx appended are the partitions of n-k into pieces no bigger than k with k::xx appended followed by the partitions of n into pieces no bigger than k-1 with xx appended *with* some termination clauses which I haven't shown.

I should've mentioned that the maximum number in such a list is n. That's
why it stuck me as 'a bit' inexpensive.
\/\/
On Fri, Sep 10, 2010 at 5:02 AM, Richard O'Keefe
On Sep 10, 2010, at 8:55 AM, Wanas wrote:
Hey all,
So I have a two part question (I'm new to haskell, so you can throw all your mugs at me).
a) I want to write a function that generates lists of lists of size $n$. All having the property that sum lst = sum [1..n]. a-1) After that, I want to remove all permutations. My idea of doing this is to get all lists from the first function and create a new list with the property that "if sorted list A is not in the list, add it."
It's not completely clear to me what you want. Here's my take on it: S0 = {L | L is a list of positive integers and sum L = n} L1 ~~ L2 iff L2 is a permutation of L1 You want to enumerate S0/~~.
Staring at this for a bit, what you want is ENUMERATING THE PARTITIONS OF AN INTEGER. Look this up in almost any combinatorics book and you will find an algorithm that you can adapt. There's stuff in Knuth, AOCP, Vol 4, for example. A good reference is "The Theory of Partitions", by G. E. Andrews, Cambridge University Press, 1998.
Rung-Bin Lin has reported in "Efficient Data Structures for Storing the Partitions of an Integer" on a data structure for representing all the partitions of an integer n in O(n**2) space, taking O(n**2) time to construct it, so a list of lists might not be the best way to do it in Haskell.
What you want to do is to generate the partitions in a canonical order with no duplicates in the first place. Something along these lines:
the partiions of n are the partitions of n into pieces no bigger than n with [] appended.
the partitions of n into pieces no bigger than k with xx appended are the partitions of n-k into pieces no bigger than k with k::xx appended followed by the partitions of n into pieces no bigger than k-1 with xx appended
*with* some termination clauses which I haven't shown.
participants (6)
-
Brent Yorgey
-
Bulat Ziganshin
-
Daniel Fischer
-
Nils Schweinsberg
-
Richard O'Keefe
-
Wanas