Skip to main content

oxilean_std/array/
types.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4use super::functions::*;
5
6/// A fixed-capacity circular (ring) buffer backed by a flat array.
7///
8/// Supports O(1) push-front, push-back, pop-front, and pop-back.
9/// Useful for implementing deques and sliding-window algorithms.
10#[allow(dead_code)]
11pub struct CircularBuffer {
12    data: Vec<i64>,
13    head: usize,
14    tail: usize,
15    len: usize,
16    cap: usize,
17}
18#[allow(dead_code)]
19impl CircularBuffer {
20    /// Create a new circular buffer with the given capacity.
21    pub fn new(cap: usize) -> Self {
22        CircularBuffer {
23            data: vec![0; cap],
24            head: 0,
25            tail: 0,
26            len: 0,
27            cap,
28        }
29    }
30    /// Return the number of elements currently stored.
31    pub fn len(&self) -> usize {
32        self.len
33    }
34    /// Return `true` if the buffer contains no elements.
35    pub fn is_empty(&self) -> bool {
36        self.len == 0
37    }
38    /// Return `true` if the buffer is at full capacity.
39    pub fn is_full(&self) -> bool {
40        self.len == self.cap
41    }
42    /// Push an element to the back. Returns `false` if the buffer is full.
43    pub fn push_back(&mut self, val: i64) -> bool {
44        if self.is_full() {
45            return false;
46        }
47        self.data[self.tail] = val;
48        self.tail = (self.tail + 1) % self.cap;
49        self.len += 1;
50        true
51    }
52    /// Pop an element from the front. Returns `None` if empty.
53    pub fn pop_front(&mut self) -> Option<i64> {
54        if self.is_empty() {
55            return None;
56        }
57        let val = self.data[self.head];
58        self.head = (self.head + 1) % self.cap;
59        self.len -= 1;
60        Some(val)
61    }
62    /// Peek at the front element without removing it.
63    pub fn front(&self) -> Option<i64> {
64        if self.is_empty() {
65            None
66        } else {
67            Some(self.data[self.head])
68        }
69    }
70}
71/// A simple sparse table for O(1) range-minimum queries (RMQ).
72///
73/// Build time: O(n log n). Query time: O(1).
74/// Works for idempotent operations (min, max, gcd).
75#[allow(dead_code)]
76pub struct SparseTable {
77    table: Vec<Vec<i64>>,
78    log2: Vec<usize>,
79    n: usize,
80}
81#[allow(dead_code)]
82impl SparseTable {
83    /// Build the sparse table from a slice.
84    pub fn build(data: &[i64]) -> Self {
85        let n = data.len();
86        if n == 0 {
87            return SparseTable {
88                table: vec![],
89                log2: vec![],
90                n: 0,
91            };
92        }
93        let mut log2 = vec![0usize; n + 1];
94        for i in 2..=n {
95            log2[i] = log2[i / 2] + 1;
96        }
97        let k = log2[n] + 1;
98        let mut table = vec![vec![i64::MAX; n]; k];
99        table[0][..n].copy_from_slice(data);
100        for j in 1..k {
101            for i in 0..=n.saturating_sub(1 << j) {
102                table[j][i] = table[j - 1][i].min(table[j - 1][i + (1 << (j - 1))]);
103            }
104        }
105        SparseTable { table, log2, n }
106    }
107    /// Query the minimum over the inclusive range `[lo, hi]`.
108    pub fn query_min(&self, lo: usize, hi: usize) -> i64 {
109        if lo > hi || hi >= self.n {
110            return i64::MAX;
111        }
112        let j = self.log2[hi - lo + 1];
113        self.table[j][lo].min(self.table[j][hi + 1 - (1 << j)])
114    }
115}
116/// Difference array for O(1) range-update, O(n) reconstruction.
117///
118/// Supports range additions: add `val` to all elements in `[lo, hi]`.
119#[allow(dead_code)]
120pub struct DifferenceArray {
121    diff: Vec<i64>,
122}
123#[allow(dead_code)]
124impl DifferenceArray {
125    /// Build a difference array from an initial data slice.
126    pub fn build(data: &[i64]) -> Self {
127        let n = data.len();
128        let mut diff = vec![0i64; n + 1];
129        if n > 0 {
130            diff[0] = data[0];
131        }
132        for i in 1..n {
133            diff[i] = data[i] - data[i - 1];
134        }
135        DifferenceArray { diff }
136    }
137    /// Add `val` to all elements in the inclusive range `[lo, hi]`.
138    pub fn range_add(&mut self, lo: usize, hi: usize, val: i64) {
139        self.diff[lo] += val;
140        if hi + 1 < self.diff.len() {
141            self.diff[hi + 1] -= val;
142        }
143    }
144    /// Reconstruct the full array from the difference array.
145    pub fn reconstruct(&self) -> Vec<i64> {
146        let n = self.diff.len() - 1;
147        let mut result = vec![0i64; n];
148        if n == 0 {
149            return result;
150        }
151        result[0] = self.diff[0];
152        for i in 1..n {
153            result[i] = result[i - 1] + self.diff[i];
154        }
155        result
156    }
157}
158/// Prefix-sum array over a slice of integers.
159///
160/// Supports O(1) range-sum queries after O(n) construction.
161///
162/// # Example
163/// ```
164/// # use oxilean_std::array::PrefixSum;
165/// let ps = PrefixSum::build(&[1, 2, 3, 4, 5]);
166/// assert_eq!(ps.range_sum(1, 3), 9); // 2 + 3 + 4
167/// ```
168#[allow(dead_code)]
169pub struct PrefixSum {
170    prefix: Vec<i64>,
171}
172#[allow(dead_code)]
173impl PrefixSum {
174    /// Build a prefix-sum structure from a slice.
175    ///
176    /// `prefix[0] = 0`, `prefix[i+1] = prefix[i] + data[i]`.
177    pub fn build(data: &[i64]) -> Self {
178        let mut prefix = vec![0i64; data.len() + 1];
179        for (i, &x) in data.iter().enumerate() {
180            prefix[i + 1] = prefix[i] + x;
181        }
182        PrefixSum { prefix }
183    }
184    /// Query the inclusive range sum `data[lo..=hi]`.
185    ///
186    /// Returns the sum of elements from index `lo` to `hi` inclusive.
187    /// Panics if `lo > hi` or indices are out of range.
188    pub fn range_sum(&self, lo: usize, hi: usize) -> i64 {
189        self.prefix[hi + 1] - self.prefix[lo]
190    }
191    /// Number of original data elements.
192    pub fn len(&self) -> usize {
193        self.prefix.len() - 1
194    }
195    /// Returns `true` if there are no data elements.
196    pub fn is_empty(&self) -> bool {
197        self.len() == 0
198    }
199}