mardi 11 mai 2021

Construct a cartesian product of two lists with a random number added to each pair

I'm trying to get to the following output:

[(1,5,54), (1,6,34), (1,7,16), (2,5,59), (2,6,29), (2,7,71), (3,5,44), (3,6,67), (3,7,24)]

which is the cartesian product of [1..3], [5..7] where each resulting tuple gets a random number as its third element.

I've tried the following code

hello :: IO [(Int, Int, Int)]
hello = do
    g <- getStdGen
    let zyx = do
            x <- [1..3]
            y <- [5..7]
            z <- take 1 $ randomRs (1, 100) g
            pure (x, y, z)
    pure zyx

The problem is that this generates one single random number and repeats it all along (let's say it was 42 this time):

[(1,5,42), (1,6,42), (1,7,42), (2,5,42), (2,6,42), (2,7,42), (3,5,42), (3,6,42), (3,7,42)]

Then I thought, sure, let's actually generate length [1..3] * length [5..7] numbers instead:

-- ...
z <- take (length [1..3] * length [5..7]) randomRs (1, 100) g
-- ...

but now this combines the list of random numbers into the product:

[(1,5,66),(1,5,41) ... (1,6,66),(1,6,41) ... (1,7,66),(1,7,41)]

Is it possible to get to the desired output in a direct manner, that avoids constructing the list of two-tuples initially and then sort-of zipping it with a same-length list of random numbers generated with randomRs?




Aucun commentaire:

Enregistrer un commentaire