sql_cli/sql/generators/
prime_generators.rs

1use super::{create_single_column_table, create_two_column_table, TableGenerator};
2use crate::data::datatable::{DataColumn, DataTable, DataValue};
3use anyhow::Result;
4use std::sync::Arc;
5
6/// Generate prime numbers up to a limit
7pub struct GeneratePrimes;
8
9impl TableGenerator for GeneratePrimes {
10    fn name(&self) -> &str {
11        "GENERATE_PRIMES"
12    }
13
14    fn columns(&self) -> Vec<DataColumn> {
15        vec![DataColumn::new("prime")]
16    }
17
18    fn generate(&self, args: Vec<DataValue>) -> Result<Arc<DataTable>> {
19        if args.len() != 1 {
20            return Err(anyhow::anyhow!(
21                "GENERATE_PRIMES expects 1 argument (limit)"
22            ));
23        }
24
25        let limit = match &args[0] {
26            DataValue::Integer(n) => *n as usize,
27            DataValue::Float(f) => *f as usize,
28            _ => return Err(anyhow::anyhow!("GENERATE_PRIMES limit must be a number")),
29        };
30
31        let primes = sieve_of_eratosthenes(limit);
32        let values: Vec<DataValue> = primes
33            .into_iter()
34            .map(|p| DataValue::Integer(p as i64))
35            .collect();
36
37        Ok(create_single_column_table("primes", "prime", values))
38    }
39
40    fn description(&self) -> &str {
41        "Generate all prime numbers up to a given limit"
42    }
43
44    fn arg_count(&self) -> usize {
45        1
46    }
47}
48
49/// Generate prime factors of a number
50pub struct PrimeFactors;
51
52impl TableGenerator for PrimeFactors {
53    fn name(&self) -> &str {
54        "PRIME_FACTORS"
55    }
56
57    fn columns(&self) -> Vec<DataColumn> {
58        vec![DataColumn::new("factor"), DataColumn::new("power")]
59    }
60
61    fn generate(&self, args: Vec<DataValue>) -> Result<Arc<DataTable>> {
62        if args.len() != 1 {
63            return Err(anyhow::anyhow!("PRIME_FACTORS expects 1 argument (number)"));
64        }
65
66        let number = match &args[0] {
67            DataValue::Integer(n) => *n as u64,
68            DataValue::Float(f) => *f as u64,
69            _ => return Err(anyhow::anyhow!("PRIME_FACTORS argument must be a number")),
70        };
71
72        let factors = factorize(number);
73        let rows: Vec<(DataValue, DataValue)> = factors
74            .into_iter()
75            .map(|(factor, power)| {
76                (
77                    DataValue::Integer(factor as i64),
78                    DataValue::Integer(power as i64),
79                )
80            })
81            .collect();
82
83        Ok(create_two_column_table("factors", "factor", "power", rows))
84    }
85
86    fn description(&self) -> &str {
87        "Generate prime factorization of a number as (factor, power) pairs"
88    }
89
90    fn arg_count(&self) -> usize {
91        1
92    }
93}
94
95/// Generate Fibonacci sequence
96pub struct Fibonacci;
97
98impl TableGenerator for Fibonacci {
99    fn name(&self) -> &str {
100        "FIBONACCI"
101    }
102
103    fn columns(&self) -> Vec<DataColumn> {
104        vec![DataColumn::new("n"), DataColumn::new("value")]
105    }
106
107    fn generate(&self, args: Vec<DataValue>) -> Result<Arc<DataTable>> {
108        if args.len() != 1 {
109            return Err(anyhow::anyhow!("FIBONACCI expects 1 argument (count)"));
110        }
111
112        let count = match &args[0] {
113            DataValue::Integer(n) => *n as usize,
114            DataValue::Float(f) => *f as usize,
115            _ => return Err(anyhow::anyhow!("FIBONACCI count must be a number")),
116        };
117
118        let mut rows = Vec::new();
119        let mut a: u64 = 0;
120        let mut b: u64 = 1;
121
122        for i in 0..count {
123            rows.push((DataValue::Integer(i as i64), DataValue::Integer(a as i64)));
124
125            if i > 0 {
126                let next = a.saturating_add(b);
127                a = b;
128                b = next;
129            } else {
130                a = 1;
131            }
132        }
133
134        Ok(create_two_column_table("fibonacci", "n", "value", rows))
135    }
136
137    fn description(&self) -> &str {
138        "Generate Fibonacci sequence up to n terms"
139    }
140
141    fn arg_count(&self) -> usize {
142        1
143    }
144}
145
146/// Sieve of Eratosthenes to generate primes up to limit
147fn sieve_of_eratosthenes(limit: usize) -> Vec<usize> {
148    if limit < 2 {
149        return vec![];
150    }
151
152    let mut is_prime = vec![true; limit + 1];
153    is_prime[0] = false;
154    is_prime[1] = false;
155
156    for i in 2..=((limit as f64).sqrt() as usize) {
157        if is_prime[i] {
158            for j in ((i * i)..=limit).step_by(i) {
159                is_prime[j] = false;
160            }
161        }
162    }
163
164    is_prime
165        .into_iter()
166        .enumerate()
167        .filter_map(|(num, prime)| if prime { Some(num) } else { None })
168        .collect()
169}
170
171/// Factorize a number into prime factors
172fn factorize(mut n: u64) -> Vec<(u64, u32)> {
173    if n <= 1 {
174        return vec![];
175    }
176
177    let mut factors = Vec::new();
178
179    // Check for factor of 2
180    let mut power = 0;
181    while n % 2 == 0 {
182        power += 1;
183        n /= 2;
184    }
185    if power > 0 {
186        factors.push((2, power));
187    }
188
189    // Check odd factors from 3 onwards
190    let mut i = 3;
191    while i * i <= n {
192        power = 0;
193        while n % i == 0 {
194            power += 1;
195            n /= i;
196        }
197        if power > 0 {
198            factors.push((i, power));
199        }
200        i += 2;
201    }
202
203    // If n is still greater than 1, it's a prime factor
204    if n > 1 {
205        factors.push((n, 1));
206    }
207
208    factors
209}
210
211#[cfg(test)]
212mod tests {
213    use super::*;
214
215    #[test]
216    fn test_sieve_of_eratosthenes() {
217        assert_eq!(sieve_of_eratosthenes(10), vec![2, 3, 5, 7]);
218        assert_eq!(
219            sieve_of_eratosthenes(30),
220            vec![2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
221        );
222    }
223
224    #[test]
225    fn test_factorize() {
226        assert_eq!(factorize(12), vec![(2, 2), (3, 1)]);
227        assert_eq!(factorize(1260), vec![(2, 2), (3, 2), (5, 1), (7, 1)]);
228        assert_eq!(factorize(17), vec![(17, 1)]);
229    }
230}