# 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