Problem 23 Solution

Solution 1 - using elementAt and dropAt

randomSelect seed n list =
    let
        ( l, r, s ) =
            randSelect n ( [], list, seed )
    in
        ( l, s )


randSelect : Int -> ( List a, List a, Random.Seed ) -> ( List a, List a, Random.Seed )
randSelect n ( l, r, seed ) =
    if n > 0 then
        let
            ( idx, seed_ ) =
                Random.step (Random.int 1 (List.length r)) seed

            e =
                elementAt r idx

            r_ =
                dropAt r idx
        in
            case e of
                Nothing ->
                    ( l, r, seed )

                Just x ->
                    randSelect (n - 1) ( x :: l, r_, seed_ )
    else
        ( l, r, seed )


{-| return the nth item of a list (one-relative index)
-}
elementAt : List a -> Int -> Maybe a
elementAt list n =
    case list of
        [] ->
            Nothing

        x :: xs ->
            if n == 1 then
                Just x
            else
                elementAt xs (n - 1)


dropAt : List a -> Int -> List a
dropAt list n =
    case list of
        [] ->
            []

        x :: xs ->
            (List.take (n - 1) list) ++ (List.drop n list)

Solution 2 - Defining a new Random.Generator

import Random exposing (Generator, Seed, initialSeed, int, map, step)

manyOf : Seed -> Int -> List a -> List a -> ( List a, Seed )
manyOf seed n source acc =
    let
        ( x, seed2 ) =
            step (select source) seed
    in
        if n < 1 then
            ( acc, seed )
        else
            ( x
                ++ (Tuple.first
                        (manyOf seed2 (n - 1) (removeElements x source) acc)
                   )
            , seed2
            )


randomSelect : Seed -> Int -> List a -> ( List a, Seed )
randomSelect seed n source =
    manyOf seed n source []  


removeElements : List a -> List a -> List a
removeElements exclude source = 
    List.filter (\x -> not (List.member x exclude)) source

select : List a -> Generator (List a)
select list =
    Random.map (\y -> list |> drop y |> take 1) (int 0 ((length list) - 1))

Back to problem

results matching ""

    No results matching ""