mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
add CCInt.range{,',by} for iterating on integer ranges
This commit is contained in:
parent
47abc78a51
commit
e0287b9efe
2 changed files with 99 additions and 0 deletions
|
|
@ -39,6 +39,7 @@ let pow a b =
|
||||||
|
|
||||||
type 'a printer = Format.formatter -> 'a -> unit
|
type 'a printer = Format.formatter -> 'a -> unit
|
||||||
type 'a random_gen = Random.State.t -> 'a
|
type 'a random_gen = Random.State.t -> 'a
|
||||||
|
type 'a sequence = ('a -> unit) -> unit
|
||||||
|
|
||||||
let random n st = Random.State.int st n
|
let random n st = Random.State.int st n
|
||||||
let random_small = random 100
|
let random_small = random 100
|
||||||
|
|
@ -96,6 +97,76 @@ let to_string_binary n =
|
||||||
Q.int (fun n -> n = int_of_string (to_string_binary n))
|
Q.int (fun n -> n = int_of_string (to_string_binary n))
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
let range_by ~step i j yield =
|
||||||
|
let rec range i j yield =
|
||||||
|
if i=j then yield i
|
||||||
|
else (
|
||||||
|
yield i;
|
||||||
|
range (i+step) j yield
|
||||||
|
)
|
||||||
|
in
|
||||||
|
if step = 0 then
|
||||||
|
raise (Invalid_argument "CCList.range_by")
|
||||||
|
else if (if step > 0 then i>j else i<j) then ()
|
||||||
|
else range i ((j-i)/step*step + i) yield
|
||||||
|
|
||||||
|
(* note: the last test checks that no error occurs due to overflows. *)
|
||||||
|
(*$= & ~printer:Q.Print.(list int)
|
||||||
|
[0] (range_by ~step:1 0 0 |> Sequence.to_list)
|
||||||
|
[] (range_by ~step:1 5 0 |> Sequence.to_list)
|
||||||
|
[] (range_by ~step:2 1 0 |> Sequence.to_list)
|
||||||
|
[0;2;4] (range_by ~step:2 0 4 |> Sequence.to_list)
|
||||||
|
[0;2;4] (range_by ~step:2 0 5 |> Sequence.to_list)
|
||||||
|
[0] (range_by ~step:~-1 0 0 |> Sequence.to_list)
|
||||||
|
[] (range_by ~step:~-1 0 5 |> Sequence.to_list)
|
||||||
|
[] (range_by ~step:~-2 0 1 |> Sequence.to_list)
|
||||||
|
[5;3;1] (range_by ~step:~-2 5 1 |> Sequence.to_list)
|
||||||
|
[5;3;1] (range_by ~step:~-2 5 0 |> Sequence.to_list)
|
||||||
|
[0] (range_by ~step:max_int 0 2 |> Sequence.to_list)
|
||||||
|
*)
|
||||||
|
|
||||||
|
(*$Q
|
||||||
|
Q.(pair small_int small_int) (fun (i,j) -> \
|
||||||
|
let i = min i j and j = max i j in \
|
||||||
|
CCList.equal CCInt.equal \
|
||||||
|
(CCInt.range_by ~step:1 i j |> Sequence.to_list) \
|
||||||
|
(CCInt.range i j |> Sequence.to_list) )
|
||||||
|
*)
|
||||||
|
|
||||||
|
let range i j yield =
|
||||||
|
let rec up i j yield =
|
||||||
|
if i=j then yield i
|
||||||
|
else (
|
||||||
|
yield i;
|
||||||
|
up (i+1) j yield
|
||||||
|
)
|
||||||
|
and down i j yield =
|
||||||
|
if i=j then yield i
|
||||||
|
else (
|
||||||
|
yield i;
|
||||||
|
down (i-1) j yield
|
||||||
|
)
|
||||||
|
in
|
||||||
|
if i<=j then up i j yield else down i j yield
|
||||||
|
|
||||||
|
(*$= & ~printer:Q.Print.(list int)
|
||||||
|
[0;1;2;3;4;5] (range 0 5 |> Sequence.to_list)
|
||||||
|
[0] (range 0 0 |> Sequence.to_list)
|
||||||
|
[5;4;3;2] (range 5 2 |> Sequence.to_list)
|
||||||
|
*)
|
||||||
|
|
||||||
|
let range' i j yield =
|
||||||
|
if i<j then range i (j-1) yield
|
||||||
|
else if i=j then ()
|
||||||
|
else range i (j+1) yield
|
||||||
|
|
||||||
|
(*$= & ~printer:Q.Print.(list int)
|
||||||
|
[] (range' 0 0 |> Sequence.to_list)
|
||||||
|
[0;1;2;3;4] (range' 0 5 |> Sequence.to_list)
|
||||||
|
[5;4;3] (range' 5 2 |> Sequence.to_list)
|
||||||
|
*)
|
||||||
|
|
||||||
|
|
||||||
module Infix = struct
|
module Infix = struct
|
||||||
let (=) = Pervasives.(=)
|
let (=) = Pervasives.(=)
|
||||||
let (<>) = Pervasives.(<>)
|
let (<>) = Pervasives.(<>)
|
||||||
|
|
@ -103,6 +174,8 @@ module Infix = struct
|
||||||
let (>) = Pervasives.(>)
|
let (>) = Pervasives.(>)
|
||||||
let (<=) = Pervasives.(<=)
|
let (<=) = Pervasives.(<=)
|
||||||
let (>=) = Pervasives.(>=)
|
let (>=) = Pervasives.(>=)
|
||||||
|
let (--) = range
|
||||||
|
let (--^) = range'
|
||||||
end
|
end
|
||||||
include Infix
|
include Infix
|
||||||
let min = min
|
let min = min
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ val pow : t -> t -> t
|
||||||
|
|
||||||
type 'a printer = Format.formatter -> 'a -> unit
|
type 'a printer = Format.formatter -> 'a -> unit
|
||||||
type 'a random_gen = Random.State.t -> 'a
|
type 'a random_gen = Random.State.t -> 'a
|
||||||
|
type 'a sequence = ('a -> unit) -> unit
|
||||||
|
|
||||||
val random : int -> t random_gen
|
val random : int -> t random_gen
|
||||||
val random_small : t random_gen
|
val random_small : t random_gen
|
||||||
|
|
@ -51,6 +52,23 @@ val min : t -> t -> t
|
||||||
val max : t -> t -> t
|
val max : t -> t -> t
|
||||||
(** @since 0.17 *)
|
(** @since 0.17 *)
|
||||||
|
|
||||||
|
val range_by : step:t -> t -> t -> t sequence
|
||||||
|
(** [range_by ~step i j] iterates on integers from [i] to [j] included,
|
||||||
|
where the difference between successive elements is [step].
|
||||||
|
use a negative [step] for a decreasing list.
|
||||||
|
@raise Invalid_argument if [step=0]
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val range : t -> t -> t sequence
|
||||||
|
(** [range i j] iterates on integers from [i] to [j] included . It works
|
||||||
|
both for decreasing and increasing ranges
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val range' : t -> t -> t sequence
|
||||||
|
(** Same as {!range} but the second bound is excluded.
|
||||||
|
For instance [range' 0 5 = Sequence.of_list [0;1;2;3;4]]
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
(** {2 Infix Operators}
|
(** {2 Infix Operators}
|
||||||
|
|
||||||
@since 0.17 *)
|
@since 0.17 *)
|
||||||
|
|
@ -72,6 +90,14 @@ module Infix : sig
|
||||||
|
|
||||||
val (>=) : t -> t -> bool
|
val (>=) : t -> t -> bool
|
||||||
(** @since 0.17 *)
|
(** @since 0.17 *)
|
||||||
|
|
||||||
|
val (--) : t -> t -> t sequence
|
||||||
|
(** Alias to {!range}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val (--^) : t -> t -> t sequence
|
||||||
|
(** Alias to {!range'}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
end
|
end
|
||||||
|
|
||||||
include module type of Infix
|
include module type of Infix
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue