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.
source to share
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.
source to share
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
.
source to share