Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
ArrayExtra.ml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91(******************************************************************************) (* *) (* Baby *) (* *) (* François Pottier, Inria Paris *) (* *) (* Copyright 2024--2024 Inria. All rights reserved. This file is *) (* distributed under the terms of the GNU Library General Public *) (* License, with an exception, as described in the file LICENSE. *) (* *) (******************************************************************************) open Array let compress equal a = let n = length a in if n <= 1 then (* If the length of the array is 0 or 1, there is nothing to do. *) n else (* Now, prepare to copy the elements of the array downwards, in place, so as to eliminate duplicate elements. [last] is the last element that was read and kept. [!dst] is the number of elements that have been kept so far, so it is also the index of the slot that will be written next. *) let last = ref a.(0) in let dst = ref 1 in (* Let [src] scan the array. *) for src = 1 to n - 1 do assert (1 <= !dst && !dst <= src && src < n); assert (equal !last a.(src-1)); let current = a.(src) in if current = !last then (* Skip this element. *) () else begin (* Keep this element, copying it down to index [!dst]. *) if !dst < src then a.(!dst) <- current; last := current; incr dst end; assert (equal !last current); assert (equal !last a.(src)); done; !dst type run = int * int let rec foreach_increasing_run_in_slice compare yield accu a i n = assert (0 <= i && i <= n && n <= length a); if i = n then (* There are no more runs. *) accu else (* A new run begins at index [i]. *) let last = a.(i) and j = i + 1 in scan compare yield accu a i last j n and scan compare yield accu a i last j n = assert (0 <= i && i <= j && j <= n && n <= length a); if j = n then (* The run [i, j] ends here, and the loop ends as well. *) yield accu i j else let current = a.(j) in if compare last current < 0 then (* The current run continues. *) let last = current and j = j + 1 in scan compare yield accu a i last j n else (* The run [i, j] ends here, and the loop continues. *) let accu = yield accu i j in let last = current and i = j and j = j + 1 in scan compare yield accu a i last j n let foreach_increasing_run compare yield accu a = let i = 0 and n = length a in foreach_increasing_run_in_slice compare yield accu a i n let increasing_runs compare a = let yield runs i j = ((i, j) :: runs) in foreach_increasing_run compare yield [] a |> List.rev