diff --git a/src/.#main.rs b/src/.#main.rs deleted file mode 100644 index f999404..0000000 --- a/src/.#main.rs +++ /dev/null @@ -1 +0,0 @@ -teppy@HAWAII.11316:1721112783 \ No newline at end of file diff --git a/src/finum.rs b/src/finum.rs index 5253d95..e630dae 100644 --- a/src/finum.rs +++ b/src/finum.rs @@ -24,6 +24,9 @@ impl FiNum { pub fn one() -> Self { FiNum(1u64<<32) } + pub fn is_tiny(self) -> bool { + self.0>0u64 && self.0<=1u64 + } pub fn is_zero(self) -> bool { self.0==0 } diff --git a/src/main.rs b/src/main.rs index 916f46a..cd77424 100644 --- a/src/main.rs +++ b/src/main.rs @@ -176,22 +176,30 @@ impl RoyaltyTree { self.tree[index].lazy=FiNum::zero(); } else { let lazy=self.tree[index].lazy; - println!("Index is {}",index); - self.raw_dump(); +// println!("Index is {}, lazy.0 {}",index,lazy.value()); +// self.raw_dump(); let d1=if lazy>0.into() { lazy*self.weight_here(index)/self.weight_here_below(index) } else { FiNum::zero() }; let d02=lazy-d1; let index_left =wt_left (index).unwrap(); let index_right=wt_right(index).unwrap(); let d0=if d02>0.into() { d02*self.weight_here_below(index_left)/self.weight_below(index) } else { FiNum::zero() }; let d2=d02-d0; - assert!(lazy==d0+d1+d2,"Distributing amounts that don't add up."); - self.tree[index_left ].lazy+=d0; - self.tree[index_right].lazy+=d2; + self.sanity(); + if !self.weight_here_below(index_left ).is_zero() { self.tree[index_left ].lazy+=d0; } else { self.spare_change+=d0; } + if !self.weight_here_below(index_right).is_zero() { self.tree[index_right].lazy+=d2; } else { self.spare_change+=d2; } self.tree[index].acc+=d1; self.tree[index].lazy=FiNum::zero(); } +// println!("Royalty at {} is {}",index,self.tree[index].acc); self } + fn sanity(&self) { + for i in 0..self.tree.len() { + assert!(!self.weight_here_below(i).is_tiny(),"Weight at {} is tiny",i); + assert!(!self.tree[i].acc .is_tiny(),"Acc at {} is tiny",i); + assert!(!self.tree[i].lazy.is_tiny(),"Lazy at {} is tiny",i); + } + } fn get_royalty(&mut self, index: usize) -> FiNum { let mut f=self.forefather(); while f!=index { @@ -208,10 +216,11 @@ impl RoyaltyTree { if self.weight_here_below(ff).is_zero() { self.spare_change+=amount } else { self.tree[ff].lazy+=amount }; } } + // We really need two methods: remove an order and redistribute, remove some and return captured amount fn remove_order_id(&mut self, id: usize) { // And zero out in the tree let pos=*self.order_finder.get(&id).unwrap(); self.order_finder.remove(&id); - let weight=self.tree[pos].weight; + let weight=self.weight_here(pos); self.sub_weight(pos,weight); } fn sub_weight(&mut self, index: usize, weight: FiNum) { @@ -258,7 +267,7 @@ impl RoyaltyTree { } fn raw_dump(&mut self) { for index in 0..self.tree.len() { - println!("Index {}: Weight {} Lazy {} Acc {} Order_ID {}",index,self.tree[index].weight,self.tree[index].lazy,self.tree[index].acc,self.tree[index].order_id); + println!("Index {}: Weight {} Lazy {} Acc {} Order_ID {}",index,self.tree[index].weight,self.tree[index].lazy.value(),self.tree[index].acc,self.tree[index].order_id); } } } @@ -738,13 +747,15 @@ fn wt_forefather(max_index:usize) -> usize { fn royalty_stuff() { + let mut rng: StdRng=StdRng::seed_from_u64(13u64); let mut rt=RoyaltyTree::new(); - for index in 0..10 { - rt.add_weight(index,FiNum::new_i32(10)); - rt.add_royalty(FiNum::new_i32(24)) - } - for index in 0..rt.tree.len() { - println!("Index: {} Weight_here {} Weight_below {} Weight_here_below {}",index,rt.weight_here(index),rt.weight_below(index),rt.weight_here_below(index)); + for i in 1..1000 { + match rng.gen_range(0..10) { + 0 => rt.add_weight(rng.gen_range(0..32),FiNum::new(rng.gen_range(0..101))), + 1 => rt.add_royalty(FiNum::new(rng.gen_range(0..10))), + 2 => rt.sub_royalty(FiNum::new(rng.gen_range(0..10))), + _ => (), + } } } @@ -1001,7 +1012,7 @@ fn interactive(m: &mut Market, mut out: Option) { ["login", username] => { if let Some(t)=m.trader_name2num.get_mut(*username) { trader=*t; println!("Logged in as {}",m.traders[trader].name) } else { println!("Trader {} not found.",username) } Command::None - }, + }, ["whoami" ] => { println!("Logged in as {}, id {}",m.traders[trader].name,trader ); Command::None } ["showorders"] => { println!("Showing all orders for {}",m.traders[trader].name);