add positional integer radix transform
This commit is contained in:
parent
c53f07e762
commit
0feaee454c
7 changed files with 307 additions and 26 deletions
|
@ -5,5 +5,6 @@ members = [
|
||||||
"terminal/ansi_parser",
|
"terminal/ansi_parser",
|
||||||
"math/str2int",
|
"math/str2int",
|
||||||
"math/int2str",
|
"math/int2str",
|
||||||
|
"math/radix_transform",
|
||||||
"math/fib"
|
"math/fib"
|
||||||
]
|
]
|
||||||
|
|
13
math/radix_transform/Cargo.toml
Normal file
13
math/radix_transform/Cargo.toml
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
[package]
|
||||||
|
name = "radix_transform"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
nested = { path = "../../nested" }
|
||||||
|
|
||||||
|
[dependencies.async-std]
|
||||||
|
version = "1.9.0"
|
||||||
|
features = ["unstable", "attributes"]
|
105
math/radix_transform/src/main.rs
Normal file
105
math/radix_transform/src/main.rs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
|
||||||
|
use {
|
||||||
|
std::sync::{Arc, RwLock},
|
||||||
|
nested::{
|
||||||
|
core::{
|
||||||
|
View,
|
||||||
|
ViewPort,
|
||||||
|
Observer,
|
||||||
|
ObserverBroadcast,
|
||||||
|
InnerViewPort,
|
||||||
|
OuterViewPort
|
||||||
|
},
|
||||||
|
sequence::{SequenceView, VecBuffer},
|
||||||
|
integer::{RadixProjection}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#[async_std::main]
|
||||||
|
async fn main() {
|
||||||
|
nested::magic_header();
|
||||||
|
eprintln!(" Convert Radix of Positional Integer");
|
||||||
|
nested::magic_header();
|
||||||
|
|
||||||
|
let mut args = std::env::args();
|
||||||
|
args.next().expect("Arg $0 missing!");
|
||||||
|
|
||||||
|
eprintln!("
|
||||||
|
$1: src_radix
|
||||||
|
( ℕ )
|
||||||
|
( PositionalInt 10 LittleEndian )
|
||||||
|
( Sequence (Digit 10) )
|
||||||
|
( Sequence Ascii )
|
||||||
|
( ArgString )
|
||||||
|
");
|
||||||
|
let src_radix_str = args.next().expect("Arg $1 required!");
|
||||||
|
|
||||||
|
|
||||||
|
eprintln!("
|
||||||
|
$2: dst_radix
|
||||||
|
( ℕ )
|
||||||
|
( PositionalInt 10 LittleEndian )
|
||||||
|
( Sequence (Digit 10) )
|
||||||
|
( Sequence Ascii )
|
||||||
|
( ArgString )
|
||||||
|
");
|
||||||
|
let dst_radix_str = args.next().expect("Arg $2 required!");
|
||||||
|
|
||||||
|
eprintln!("
|
||||||
|
>0: n
|
||||||
|
( ℕ ) ~~ <1
|
||||||
|
( PositionalInt src_radix LittleEndian )
|
||||||
|
( Sequence (Digit src_radix) )
|
||||||
|
( Sequence MachineInt )
|
||||||
|
( PipeStream bincode (SequenceDiff MachineInt) )
|
||||||
|
");
|
||||||
|
|
||||||
|
eprintln!("
|
||||||
|
<1: n
|
||||||
|
( ℕ ) ~~ >0
|
||||||
|
( PositionalInt dst_radix LittleEndian )
|
||||||
|
( Sequence (Digit dst_radix) )
|
||||||
|
( Sequence MachineInt )
|
||||||
|
( PipeStream bincode (SequenceDiff MachineInt) )
|
||||||
|
");
|
||||||
|
|
||||||
|
nested::magic_header();
|
||||||
|
|
||||||
|
let src_radix = usize::from_str_radix(&src_radix_str, 10).expect("could not parse src_radix");
|
||||||
|
let dst_radix = usize::from_str_radix(&dst_radix_str, 10).expect("could not parse dst_radix");
|
||||||
|
|
||||||
|
let src_digits_port = ViewPort::new();
|
||||||
|
let dst_digits_port = ViewPort::new();
|
||||||
|
|
||||||
|
let mut src_digits = VecBuffer::<usize>::new(src_digits_port.inner());
|
||||||
|
|
||||||
|
let proj = RadixProjection::new(
|
||||||
|
src_radix,
|
||||||
|
dst_radix,
|
||||||
|
src_digits_port.outer().to_sequence(),
|
||||||
|
dst_digits_port.inner()
|
||||||
|
);
|
||||||
|
|
||||||
|
// output dst digits
|
||||||
|
let writer = {
|
||||||
|
use std::{
|
||||||
|
fs::File,
|
||||||
|
io::{Read, Write},
|
||||||
|
os::unix::io::FromRawFd
|
||||||
|
};
|
||||||
|
|
||||||
|
dst_digits_port.outer().serialize_json(unsafe { std::fs::File::from_raw_fd(1) })
|
||||||
|
};
|
||||||
|
|
||||||
|
// start reading src digits
|
||||||
|
{
|
||||||
|
use async_std::{
|
||||||
|
fs::File,
|
||||||
|
io::{Read, Write},
|
||||||
|
os::unix::io::FromRawFd
|
||||||
|
};
|
||||||
|
|
||||||
|
src_digits.from_json(unsafe { async_std::fs::File::from_raw_fd(0) }).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
75
nested/src/integer/add.rs
Normal file
75
nested/src/integer/add.rs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
nested/src/integer/mod.rs
Normal file
9
nested/src/integer/mod.rs
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
|
||||||
|
pub mod radix;
|
||||||
|
pub mod add;
|
||||||
|
|
||||||
|
pub use {
|
||||||
|
radix::RadixProjection,
|
||||||
|
add::Add
|
||||||
|
};
|
||||||
|
|
99
nested/src/integer/radix.rs
Normal file
99
nested/src/integer/radix.rs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,39 +1,18 @@
|
||||||
#![feature(trait_alias)]
|
#![feature(trait_alias)]
|
||||||
|
|
||||||
pub mod core;
|
pub mod core;
|
||||||
|
pub mod projection;
|
||||||
|
|
||||||
|
pub mod singleton;
|
||||||
pub mod index;
|
pub mod index;
|
||||||
pub mod grid;
|
pub mod grid;
|
||||||
pub mod sequence;
|
pub mod sequence;
|
||||||
pub mod singleton;
|
|
||||||
pub mod terminal;
|
pub mod terminal;
|
||||||
pub mod projection;
|
pub mod integer;
|
||||||
|
|
||||||
pub mod string_editor;
|
pub mod string_editor;
|
||||||
pub mod leveled_term_view;
|
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() {
|
pub fn magic_header() {
|
||||||
eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>");
|
eprintln!("<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue