add positional integer radix transform

This commit is contained in:
Michael Sippel 2021-04-29 01:32:59 +02:00
parent c53f07e762
commit 0feaee454c
Signed by: senvas
GPG key ID: F96CF119C34B64A6
7 changed files with 307 additions and 26 deletions

75
nested/src/integer/add.rs Normal file
View file

@ -0,0 +1,75 @@
use {
std::sync::{Arc, RwLock},
crate::{
core::{InnerViewPort, OuterViewPort, ObserverBroadcast},
sequence::{SequenceView, VecBuffer},
projection::ProjectionHelper
}
};
fn posint_add(
radix: usize,
a: impl SequenceView<Item = usize>,
b: impl SequenceView<Item = usize>
) -> Vec<usize> {
let mut carry = 0;
let mut result = Vec::new();
for digit_idx in 0 .. std::cmp::max(a.len().unwrap_or(0), b.len().unwrap_or(0)) {
let sum =
a.get(&digit_idx).unwrap_or(0) +
b.get(&digit_idx).unwrap_or(0) +
carry;
result.push(sum % radix);
carry =
if sum > radix {
sum - radix
} else {
0
};
}
if carry > 0 {
result.push(carry);
}
result
}
pub struct Add {
radix: usize,
a: Arc<dyn SequenceView<Item = usize>>, // PosInt, Little Endian
b: Arc<dyn SequenceView<Item = usize>>, // PosInt, Little Endian
c: VecBuffer<usize>,
proj_helper: ProjectionHelper<Self>
}
impl Add {
pub fn new(
radix: usize,
a: OuterViewPort<dyn SequenceView<Item = usize>>,
b: OuterViewPort<dyn SequenceView<Item = usize>>,
c: InnerViewPort<RwLock<Vec<usize>>>//<dyn SequenceView<Item = usize>>
) -> Arc<RwLock<Self>> {
let mut proj_helper = ProjectionHelper::new();
let add = Arc::new(RwLock::new(
Add {
radix,
a: proj_helper.new_sequence_arg(a, |s: &mut Self, _digit_idx| s.update()),
b: proj_helper.new_sequence_arg(b, |s: &mut Self, _digit_idx| s.update()),
c: VecBuffer::new(c),
proj_helper
}
));
add
}
fn update(&mut self) {
self.c.clear();
for digit in posint_add(self.radix, self.a.clone(), self.b.clone()) {
self.c.push(digit);
}
}
}

View file

@ -0,0 +1,9 @@
pub mod radix;
pub mod add;
pub use {
radix::RadixProjection,
add::Add
};

View file

@ -0,0 +1,99 @@
use {
std::sync::{Arc, RwLock},
crate::{
core::{
View,
ViewPort,
Observer,
ObserverBroadcast,
InnerViewPort,
OuterViewPort
},
sequence::{SequenceView, VecBuffer}
}
};
pub struct RadixProjection {
src_radix: usize,
dst_radix: usize,
src_digits: Option<Arc<dyn SequenceView<Item = usize>>>,
dst_digits: RwLock<VecBuffer<usize>>
}
impl RadixProjection {
pub fn new(
src_radix: usize,
dst_radix: usize,
src_digits: OuterViewPort<dyn SequenceView<Item = usize>>,
dst_digits: InnerViewPort<RwLock<Vec<usize>>>
) -> Arc<RwLock<Self>> {
let proj = Arc::new(RwLock::new(
RadixProjection {
src_radix,
dst_radix,
src_digits: None,
dst_digits: RwLock::new(VecBuffer::new(dst_digits))
}
));
src_digits.add_observer(proj.clone());
proj
}
fn machine_int(&self) -> usize {
let mut val = 0;
let mut r = 1;
for i in 0 .. self.src_digits.len().unwrap_or(0) {
val += r * self.src_digits.get(&i).unwrap();
r *= self.src_radix;
}
val
}
// recalculate everything
fn update(&self) {
let mut dst = self.dst_digits.write().unwrap();
dst.clear();
let mut val = self.machine_int();
while val > 0 {
dst.push(val % self.dst_radix);
val /= self.dst_radix;
}
}
fn update_dst_digit(&mut self, idx: usize) {
/*
let v = 0; // calculate new digit value
// which src-digits are responsible?
if idx < self.dst_digits.len() {
self.dst_digits.get_mut(idx) = v;
} else if idx == self.dst_digits.len() {
self.dst_digits.push(v);
} else {
// error
}
*/
}
}
impl Observer<dyn SequenceView<Item = usize>> for RadixProjection {
fn reset(&mut self, view: Option<Arc<dyn SequenceView<Item = usize>>>) {
eprintln!("reset");
self.src_digits = view;
}
fn notify(&self, idx: &usize) {
// todo:
// src digit i changed.
// which dst-digits does it affect?
// update dst-digit j:
// ...but for now the easy way
self.update();
}
}

View file

@ -1,39 +1,18 @@
#![feature(trait_alias)]
pub mod core;
pub mod projection;
pub mod singleton;
pub mod index;
pub mod grid;
pub mod sequence;
pub mod singleton;
pub mod terminal;
pub mod projection;
pub mod integer;
pub mod string_editor;
pub mod leveled_term_view;
/* maybe?
pub use {
cgmath::{Vector2, Point2},
termion::event::{Event, Key},
crate::{
core::{View, Observer, ObserverExt, ObserverBroadcast, ViewPort, OuterViewPort},
index::{ImplIndexView},
terminal::{
TerminalView,
TerminalAtom,
TerminalStyle,
TerminalEvent,
Terminal,
TerminalCompositor
},
sequence::{VecBuffer, SequenceView},
grid::{GridOffset, GridWindowIterator},
singleton::{SingletonView, SingletonBuffer},
string_editor::{StringEditor, insert_view::StringInsertView},
leveled_term_view::LeveledTermView
}
};
*/
pub fn magic_header() {
eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>");
}