Create an entire list of given length between two values ​​(OCaml or other languages)

I am new to ocaml and am trying to write code to generate all lists of numbers between two values.

For example, if I call this function generate

, I want to get something like this:

let generate ~min ~max ~length (* Maybe other arguments *) =
    (* The code *)
;;

generate ~min:0 ~max:3 ~length:4;;

      

Must come back

[
[0;0;0];
[1;0;0];
[2;0;0];
[3;0;0];
[0;1;0];

      

Etc,

[3;2;3];
[0;3;3];
[1;3;3];
[2;3;3];
[3;3;3];
]

      

I've already tried code like this:

open Core.Std;;

type next_list =
    | Complete of int list
    | Partial of int list
    | Result of (int array) list
;;

let rec next ~r ~min ~max ~l =
    let detox = function | Partial a -> a | _ -> assert false in
    match l with
    | Partial (hd :: tl) when hd <= max -> Partial (hd + 1 :: tl)
    | Partial (hd :: tl) when hd = max + 1 -> next ~r ~min ~max
    ~l:(Partial (min :: (detox (next ~r ~min ~max ~l:(Partial tl))) ))
    | Complete (hd :: tl) when hd <= max -> next ~r:([l] :: r) ~min ~max
    ~l:(Complete (hd + 1 :: tl))
    | Complete (hd :: tl) when hd = max + 1 -> next ~r ~min ~max
    ~l:(Complete (min :: (detox (next ~r ~min ~max ~l:(Partial tl)))))
    (*| Partial [] -> next ~r ~min ~max ~l:(Result r)*)
    | Result a -> Result a

      

It can be distributed over several functions if needed, this is not a problem.
I am also interested in non-ocaml code or idea.

Thank you for your help.

This is my first question on Stackoverflow, feel free to say, not my question.

+3


source to share


2 answers


here's some solution: First, define what takes 2 lists l1 and l2 as input and creates a list of list where each element is l2 padded with 1 element from l1:

 let enumerate l ll = List.fold ~init:[] ~f:(fun op x -> (x::ll)::op) l;;

      

enumerate [0; 1; 2; 3] [4; five; 6] ;; -: int list list = [[3; 4; five; 6]; [2; 4; five; 6]; [1; 4; five; 6]; [0; 4; five; 6]]

Now generate:

   let rec generate length ll =
     if length=1 then List.fold ~init:[] ~f:(fun op x -> [x]::op) ll
     else 
       let result = generate (length-1) ll in
       List.fold ~init:[] ~f:(fun op x -> (enumerate ll x)@op) result;;

      



and the following is used:

generate 2 [1;2;3];; (* instead of generate ~min:1 ~max:3 ~length:2 *)

      

Some explanations: List.fold ~ init: [] ~ f: (fun op x β†’ [x] :: op) ll => this creates the original list of list (singleton)

And second, it takes each from a list of length -1 and enumerates.

+1


source


Here's a hint:

let count_prefix low high lists =
  ???

let generate min max length =
  let rec recur low high len =
    if len = 0 then []
    else count_prefix low high (recur low high (len - 1)) in
  recur min max length

      

count_prefix

must return a list that is elements lists

prefixed with numbers low

before high

. If lists

empty, it should return a list of lists containing numbers low

- high

. I.e:



count_prefix 0 3 [] => [[0]; [1]; [2]]
count_prefix 0 3 [[10];[20]] => [[0; 10]; [0; 20]; [1; 10]; [1; 20]; [2; 10]; [2; 20]]

      

Complete the definition count_prefix

.

0


source







All Articles