how to generate integer partitions of a specific size - list

I am trying to write this function
variation_models' nlocations =
let location_list = [1..nlocations-4]
in [[x1, x2, x3, x4, x5] |
x1 <- location_list,
x2 <- location_list,
x3 <- location_list,
x4 <- location_list,
x5 <- location_list,
both_conditions (adds_up_to nlocations) num_orderedq [x1, x2, x3, x4, x5]]
but have any number of x's. I want variation_models 5 15 to have a valid answer of [1,1,1,1,11].
My current attempt is
variation_models ncars nlocations =
filter (both_conditions (adds_up_to nlocations) num_orderedq) $
replicateM ncars [1..nlocations-ncars+1]
but replicateM seems to make the function take up more and more memory.
Any Ideas on how to write a replacement for replicateM so that it does not consume as much memory?
The rest of the definitions used:
import Control.Monad
orderedq f [] = True
orderedq f (x:[]) = True
orderedq f (x:y:zs) = f x y && orderedq f (y:zs)
num_orderedq = orderedq (<=)
adds_up_to n xs = n == sum xs
both_conditions f g xs = f xs && g xs
variation_models ncars nlocations =
filter (both_conditions (adds_up_to nlocations) num_orderedq) $
replicateM ncars [1..nlocations-ncars+1]
variation_models' nlocations =
let location_list = [1..nlocations-4]
in [[x1, x2, x3, x4, x5] |
x1 <- location_list,
x2 <- location_list,
x3 <- location_list,
x4 <- location_list,
x5 <- location_list,
both_conditions (adds_up_to nlocations) num_orderedq [x1, x2, x3, x4, x5]]

It looks like you are using replicateM to generate integer partitions.
integer_partitions :: Int -> Int -> [[Int]]
integer_partitions 0 _ = []
integer_partitions 1 n = [[n]]
integer_partitions k n =
do x <- [1..n - k + 1]
map (x:) (integer_partitions (k - 1) (n - x))
It seems to have better memory characteristics then the more general replicateM

Related

I need to combine all elements in a list using only prelude and no other modules in Haskell

n is the first argument, and a list is the second. The elements can be can selected several times and in different order.
So it will look something like:
com 1 [1,2,3] = [ [1], [2], [3] ]
com 2 [1,2,3] = [[1,1],[1,2],[1,3],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3]]
Ive written these and they work but i need a general function
com :: Int -> [t] -> [[t]]
com x [] = []
com 1 ys = [[z]| z <- ys]
com 2 ys = [z:q:[] | z <- ys, q <- ys]
I think it will look something like this:
com x ys
| x < 0 = []
| otherwise qs = [ z:[] | z <- ys ] com (x-1) qs
all help appreciated
You started good:
com :: Int -> [t] -> [[t]]
com x [] = {- [] -} [[]] -- thanks to #cirdec for spotting this
com 1 ys = [ [z] | z <- ys]
com 2 ys = [ [z,q] | z <- ys, q <- ys] -- <<----
now continue with it for a while:
com 3 ys = [ [y,z,q] | y <- ys, z <- ys, q <- ys]
= [ y:[z,q] | y <- ys, z <- ys, q <- ys]
= [ y:[z,q] | y <- ys, [z,q] <- [ [z,q] | z <- ys, q <- ys]] -- <<----
= [ y:r2 | y <- ys, r2 <- [ [z,q] | z <- ys, q <- ys]] -- <<----
= [ y:r2 | y <- ys, r2 <- ...... ]
right? We can always replace equals by equals, in Haskell!
com 4 ys = [ [x,y,z,q] | x <- ys, y <- ys, z <- ys, q <- ys]
= [ x:[y,z,q] | x <- ys, y <- ys, z <- ys, q <- ys]
= ....
= [ x:r3 | x <- ys, r3 <- ...... ]
can you continue this? can you finish up this line of thought?
com n ys | n > 4 = [ x:r | x <- ys, r <- .... (n-1) .... ]

Replace one or more elements in a nested list

I am trying to achieve this:
Given OldList, replace any item if the item fulfills a goal (oldNew); if not, do not replace the item.
Return a NewList with replaced items that has the same structure (i.e. same nesting) as OldList.
I get it to work (see my code) for the special case OldList = [a, b, c] but I would like to write a predicate that generalizes across list lengths and nested lists, e.g. also for OldList = [a, [b, c, [d, e]]].
Thanks in advance!
/JC
oldNew(fruit, banana).
oldNew(car, ferrari).
replace(OldList, NewList):-
[X1, X2, X3] = OldList,
(oldNew(X1, Y1); Y1 = X1),
(oldNew(X2, Y2); Y2 = X2),
(oldNew(X3, Y3); Y3 = X3),
(oldNew(X1, Y1); oldNew(X2, Y2), oldNew(X3, Y3)),
NewList = [Y1, Y2, Y3].
EDIT1:
Got it to work with arbitrary list lengths; but i still don't know how to handle nested lists.
replace2(OldList, NewList):-
[H | T] = OldList,
oldNew(H, NewHead),
NewList = [NewHead | T].
replace2(OldList, NewList):-
[H | T] = OldList,
replace2(T, NewTail),
NewList = [H | NewTail].
Usually, the pattern matching is made explicit in the head. The code is clearer:
replace2([], []).
replace2([H|T], [Ht|Tt]) :-
( oldNew(H, Ht)
-> true
; is_list(H)
-> replace2(H, Ht)
; H = Ht
),
replace2(T, Tt).
In SWI-Prolog libraries apply and yall allow for slightly shorter code:
replace2(L, T) :- maplist([H,Ht]>>
( oldNew(H, Ht)
-> true
; is_list(H)
-> replace2(H, Ht)
; H = Ht
), L, T).
You can see the bracketed disjunction has been copy and pasted from the former definition. It's a lambda application...
?- replace2([aa, car, apple, fruit, any, [aa, car, apple, banana, any]], T).
T = [aa, ferrari, apple, banana, any, [aa, ferrari, apple|...]].

Is there a way to generate a series of list comprehensions programmatically in Haskell?

In my ongoing attempt to get better at Haskell, I'm attempting to solve a problem where I'd like to create a series of list comprehensions of this form:
m2 = [[x1,x2] | x1 <- [2..110], x2 <- [x1..111]]
m3 = [[x1,x2,x3] | x1 <- [2..22], x2 <- [x1..22], x3 <- [x2..24]]
m4 = [[x1,x2,x3,x4] | x1 <- [2..10], x2 <- [x1..10], x3 <- [x2..10], x4 <- [x3..12]]
...
Where x1 <= x2 ... <= xn, the number following m is the length of the sublists, and the first n - 1 terms are bounded by the same upper bound, while the nth term is bounded by some larger number.
I could certainly write all of it out by hand, but that's not particularly good practice. I'm wondering if there's a way to generate these lists up to a particular maximum m value. My immediate thought was Template Haskell, but I don't know enough about it to determine whether it's usable. Is there some other solution that's escaping me?
In pseudo-Haskell, what I'm looking for is some method that does something like:
mOfN n bound term = [ [x1..xn] | x1 <- [2..bound], x2 <- [x1..bound], ..., xn <- [x(n-1)..term] ]
The main issue is that I can't figure out how I would dynamically create x1,x2, etc.
Is this what you are looking for?
import Data.List (tails)
mofn 0 xs = [ [] ]
mofn m xs = [ y:zs | (y:ys) <- tails xs, zs <- mofn (m-1) ys ]
i.e. mofn 3 [1..5] is:
[[1,2,3],[1,2,4],[1,2,5],[1,3,4],[1,3,5],[1,4,5],[2,3,4],[2,3,5],[2,4,5],[3,4,5]]
The key is the tails function which returns successive tails of a list.
Update
Is this what you are looking for?
mofn' 1 lo hi bnd = [ [x] | x <- [lo..bnd] ]
mofn' k lo hi bnd = [ x:ys | x <- [lo..hi], ys <- mofn' (k-1) x hi bnd ]
mofn' 3 1 3 5 is:
[[1,1,1], [1,1,2], [1,1,3], [1,1,4], [1,1,5],
[1,2,2], [1,2,3], [1,2,4], [1,2,5],
[1,3,3], [1,3,4], [1,3,5],
[2,2,2], [2,2,3], [2,2,4], [2,2,5],
[2,3,3], [2,3,4], [2,3,5],
[3,3,3], [3,3,4], [3,3,5]
]

OCaml how to manipulate tuples?

Let's say I have a tuple:
let x = (1,3)
I want to add 1 to only the first value of the tuple. How would I do that?
You use pattern matching to deconstruct the tuple and then construct the updated one:
let (x1, x2) = x in (x1 + 1, x2)
Patterm matching is a typical idiom. Another way would be with fst and snd:
# let x = (1,3);;
val x : int * int = (1, 3)
# let y = (fst x + 1, snd x);;
val y : int * int = (2, 3)

Apply a function of two inputs to every element in a list - Haskell

I have a function
f :: Int -> Int -> Int
and I have a list of arbitrary length but for the sake of the example:
[x1,x2,x3]
I need to apply f to the list such that the resulting list looks like this:
[f x1 x1 + f x1 x2 + f x1 x3 , f x2 x1 + f x2 x2 + f x2 x3 , f x3 x1 + f x3 x2 + f x3 x3]
I know that
map f [x1,x2,x3] will give [f x1, f x2, f x3]
but this doesn't seem like much help here.
What's the best way to do it?
You could use a list comprehension, to illustrate try the following expression under ghci,
fun f xs = map sum [[ f x y | y <- xs] | x <- xs]
A solution without list comprehensions:
Use map twice.
map (\x -> sum $ map (f x) xs) xs
You can use applicative functors to do it this way :
import Control.Applicative
let l = ["a", "b", "c"]
(++) <$> l <*> l
That will return ["aa","ab","ac","ba","bb","bc","ca","cb","cc"].
To explain a little bit further, (++) <$> l will map the function (++) on every element of l, thus returning [("a"++), ("b"++), ("c"++)]. Then, using <*> will apply all of these functions to all of the elements of l.
See the documentation about applicative functors for more details. http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Applicative.html