1
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
92
93
94
95
96
97
98
99
100
101
102
103
use std::cmp::{min,max};
use std::ops::Range;
use crate::Pair;
pub fn normalize_pair(pair: Pair) -> Pair {
return (min(pair.0, pair.1), max(pair.0, pair.1))
}
pub fn pair_index(pair: Pair, base: u32) -> usize {
let pair = normalize_pair(pair);
let base = base as usize;
let lower = pair.0 as usize;
let upper = pair.1 as usize;
((base - lower + 1)..(base+1)).sum::<usize>() + (upper - lower)
}
fn carry_digits(computed: usize, base: usize) -> Pair {
let carry = computed / base;
let result = computed - (carry * base);
(result as u8, carry as u8)
}
pub struct ArithmeticPrecomputation {
base: usize,
lower: Range<usize>,
upper: Range<usize>,
current_lower: usize
}
impl ArithmeticPrecomputation {
pub fn new(base: u32) -> Self {
let base = base as usize;
let mut lower = 0..base;
let upper = 0..base;
let current_lower = lower.next().unwrap();
Self { base, lower, upper, current_lower }
}
}
pub struct ConversionFromNativeInteger {
integer: usize,
base: usize
}
pub struct BaseConversion {
}
impl Iterator for ArithmeticPrecomputation {
type Item = (Pair, Pair);
fn next(&mut self) -> Option<Self::Item> {
let mut upper = self.upper.next();
if upper.is_none() {
self.current_lower = self.lower.next()?;
self.upper = self.current_lower..self.base;
upper = self.upper.next();
}
let upper = upper.unwrap();
let addition = self.current_lower + upper;
let multiplication = self.current_lower * upper;
Some((
carry_digits(addition, self.base),
carry_digits(multiplication, self.base)
))
}
}
#[cfg(test)]
pub mod test {
use super::*;
#[test]
fn generates_valid_precomputation_tables() {
assert_eq!(
ArithmeticPrecomputation::new(3).collect::<Vec<(Pair, Pair)>>(),
vec!(
((0, 0), (0, 0)),
((1, 0), (0, 0)),
((2, 0), (0, 0)),
((2, 0), (1, 0)),
((0, 1), (2, 0)),
((1, 1), (1, 1)),
)
);
}
}