use std::{collections::HashMap, marker::PhantomData};
use std::hash::Hash;
use std::iter::FromIterator;
use serde::{Deserialize, Serialize};
use super::binary_search::{find_in_sorted_sequence, find_in_sorted_sequence_within_bounds, contains_subset};
use super::functions::evaluate::{IdentityFunction, EvaluateFunction, ReferencedEvaluator};
use super::iterators::general::MapByTransformTrait;
use super::order::{is_sorted_strictly, OrderOperatorAuto};
use std::ops::Index;
pub fn can_be_obtained_by_deleting_ith_element_unsafe< T: Eq >( a: & Vec<T>, b: & Vec<T> ) -> Option<usize> {
println!("move this into an outer function");
if b.len() != a.len() + 1 { return None }
for ordinal in 0 .. a.len() {
if a[ ordinal ] != b[ ordinal ] { for ordinal_2 in ordinal .. a.len() {
if a[ ordinal_2 ] != b[ ordinal_2 + 1 ] {
return None
}
}
return Some(ordinal)
}
}
return Some( b.len() - 1 ) }
#[derive(Clone,Debug,PartialEq,PartialOrd,Eq,Hash,Ord)]
pub struct SortedVec< T: Ord > {
sequence: Vec< T >
}
impl < T: Ord >
SortedVec
< T >
{
pub fn new( sequence: Vec< T > ) -> Result< Self, Vec< T > > {
if ! is_sorted_strictly( &sequence, &OrderOperatorAuto ){
return Err::< Self, Vec< T > >( sequence );
}
Ok( SortedVec { sequence } )
}
pub fn from_iter< I: IntoIterator< Item=T > >( sequence: I ) -> Result< Self, Vec< T > > {
SortedVec::new( sequence.into_iter().collect() )
}
pub fn into_vec( self ) -> Vec< T > { self.sequence }
pub fn vec( &self ) -> & Vec< T > { & self.sequence }
pub fn find( &self, element: &T ) -> Option< usize > {
find_in_sorted_sequence( self.vec(), element )
}
pub fn find_in_range( &self, element: &T, lower: Option<usize>, upper: Option<usize> ) -> Option< usize > {
find_in_sorted_sequence_within_bounds( self.vec(), element, lower, upper )
}
pub fn len( &self ) -> usize { self.sequence.len() }
pub fn contains( &self, element: &T ) -> bool {
find_in_sorted_sequence( self.vec(), element ).is_some()
}
pub fn contains_subset( &self, subset: & SortedVec<T> ) -> bool {
contains_subset( self.vec(), subset.vec() )
}
pub fn includes_into( &self, superset: & SortedVec<T> ) -> bool {
contains_subset( superset.vec(), self.vec() )
}
pub fn can_be_obtained_by_deleting_the_ith_element_of_the_following( &self, superset: & SortedVec< T > ) -> Option< usize > {
can_be_obtained_by_deleting_ith_element_unsafe( self.vec(), superset.vec() )
}
pub fn can_obtain_the_following_by_deleting_the_ith_element_of_self( &self, subset: & SortedVec< T > ) -> Option< usize > {
can_be_obtained_by_deleting_ith_element_unsafe( subset.vec(), self.vec() )
}
}
impl < T >
Index< usize > for
SortedVec
< T >
where
T: Ord
{
type Output = T;
fn index( & self, index: usize ) -> & Self::Output { &self.sequence[ index ] }
}
#[derive(Clone,Debug)]
pub struct CombinationsReverse< T, F > {
combination: Vec< usize >,
num_elements: usize,
is_empty: bool,
remap: F,
phantom_element: PhantomData<T>,
}
impl CombinationsReverse
< usize, IdentityFunction > {
pub fn new( num_elements: usize, sequence_length: usize, ) -> Self {
let remap = IdentityFunction::new();
if sequence_length <= num_elements {
let combination: Vec<usize> = ( num_elements - sequence_length .. num_elements ).collect();
let is_empty = false;
CombinationsReverse { combination, num_elements, is_empty, remap, phantom_element:PhantomData }
} else {
let combination: Vec<usize> = vec![];
let is_empty = true;
CombinationsReverse { combination, num_elements, is_empty, remap, phantom_element:PhantomData }
}
}
}
impl < 'a, T >
CombinationsReverse
< T, &'a Vec<T> >
where
T: Clone
{
pub fn from_vec( sequence_length: usize, elements: &'a Vec< T > ) -> Self
{
let num_elements = elements.len();
CombinationsReverse::remap_elements( num_elements, sequence_length, elements )
}
}
impl < T, F >
CombinationsReverse
< T, F >
{
pub fn remap_elements( num_elements: usize, sequence_length: usize, remap: F ) -> Self {
if sequence_length <= num_elements {
let combination: Vec<usize> = ( num_elements - sequence_length .. num_elements ).collect();
let is_empty = false;
CombinationsReverse { combination, num_elements, is_empty, remap, phantom_element: PhantomData }
} else {
let combination: Vec<usize> = vec![];
let is_empty = true;
CombinationsReverse { combination, num_elements, is_empty, remap, phantom_element: PhantomData }
}
}
fn can_decrement( &self, index: usize ) -> bool {
if index == 0 { self.combination[0] > 0 }
else { self.combination[index-1] + 1 < self.combination[index] }
}
}
impl < T, F >
Iterator for
CombinationsReverse
< T, F >
where
F: Clone + EvaluateFunction< usize, T >
{
type Item = Vec< T >;
fn next( &mut self ) -> Option< Self::Item > {
if self.is_empty { return None }
let return_val = self.combination.iter().cloned()
.map_by_transform( ReferencedEvaluator::new( &self.remap ) )
.collect();
let m = self.combination.len();
for k in ( 0 .. m ).rev() {
if self.can_decrement(k) {
self.combination[k] -= 1;
let offset = self.num_elements - m;
for l in k+1 .. m { self.combination[l] = offset + l }
return Some( return_val )
}
}
self.is_empty = true;
Some( return_val )
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct BijectiveSequence< T >
where T : Hash + Eq
{
ord_to_val: Vec< T >,
val_to_ord: HashMap< T, usize >
}
impl < T > BijectiveSequence < T >
where T: Clone + Hash + Eq
{
pub fn hashmap_element_to_ordinal( &self ) -> & HashMap< T, usize > { & self.val_to_ord }
pub fn vec_elements_in_order( &self ) -> & Vec < T > { & self.ord_to_val }
pub fn len( &self ) -> usize { self.ord_to_val.len() }
pub fn is_empty( &self ) -> bool { self.len() == 0 }
pub fn has_ordinal_for_element( &self, key_ref: &T ) -> bool { self.val_to_ord.contains_key( key_ref ) }
pub fn ordinal_for_element( &self, a: &T ) -> Option< usize > {
self.val_to_ord.get( a ).copied()
}
pub fn element_for_ordinal( &self, k: usize ) -> T {
self.ord_to_val[ k ].clone()
}
pub fn element_result_for_ordinal( &self, k: usize ) -> Result<T, usize> {
if k < self.ord_to_val.len() {
Ok( self.ord_to_val[ k ].clone() )
} else {
Err( k )
}
}
pub fn reverse_ordinals( &mut self ) {
( &mut self.ord_to_val ).reverse();
let num_pairs_minus_one = self.ord_to_val.len() - 1;
for val in self.val_to_ord.values_mut() {
*val = num_pairs_minus_one - *val;
}
}
pub fn new() -> BijectiveSequence< T > {
BijectiveSequence{ ord_to_val: Vec::new(), val_to_ord: HashMap::new() }
}
pub fn from_vec( vec: Vec< T > ) -> Result< BijectiveSequence< T >, T >
{
use std::collections::hash_map::Entry;
let mut hash = HashMap::with_capacity(vec.len());
for (i, val) in vec.iter().cloned().enumerate() {
match hash.entry(val.clone()) {
Entry::Vacant(e) => { e.insert(i); }
Entry::Occupied(_) => { return Err(val); }
}
}
Ok(BijectiveSequence{ ord_to_val: vec, val_to_ord: hash })
}
pub fn from_iter< I: IntoIterator<Item=T>>(iter: I) -> Result< BijectiveSequence< T >, T > {
let vec = Vec::from_iter( iter );
BijectiveSequence::from_vec( vec )
}
pub fn push( &mut self, new_element: T ) -> Result<(), T> {
if self.val_to_ord.contains_key(&new_element) {
return Err(new_element);
}
self.val_to_ord.insert(new_element.clone(), self.len());
self.ord_to_val.push(new_element);
Ok(())
}
}
pub fn ordinate_unique_vals < FilRaw > ( v: & Vec< FilRaw > ) -> BijectiveSequence< FilRaw >
where FilRaw: Ord + Hash + Clone
{
let mut a = v.clone();
let mut b = HashMap::new();
a.sort(); a.dedup();
for (i, t) in a.iter().enumerate() {
b.insert( t.clone(), i );
}
BijectiveSequence { ord_to_val: a, val_to_ord: b }
}
pub fn reverse_hash_sequential< T: Hash + std::cmp::Eq + Clone >(
vec: & Vec< T >
)
->
HashMap< T, usize >
{
let mut rev_hash = HashMap::new();
for (i, t) in vec.iter().enumerate() {
rev_hash.insert( t.clone(), i );
}
rev_hash
}
#[cfg(test)]
mod doc_test_drafts {
use itertools::assert_equal;
#[test]
fn test_bimap_from_vec() {
use crate::utilities::sequences_and_ordinals::BijectiveSequence;
let bimap = BijectiveSequence::from_vec( vec![ 'a', 'b' ] ).unwrap();
assert_eq!( 0, bimap.ordinal_for_element( &'a' ).unwrap() );
assert_eq!( 'b', bimap.element_for_ordinal( 1 ) );
assert_eq!(
BijectiveSequence::from_vec( vec![ 4, 3, 3, ] ),
Err(3) );
}
#[test]
fn test_bimap_reverse() {
use crate::utilities::sequences_and_ordinals::BijectiveSequence;
use itertools::Itertools;
let mut a = BijectiveSequence::from_vec( vec![ 1, 2, 3 ] ).unwrap();
let internal_ord_to_val = a.vec_elements_in_order().iter().cloned();
itertools::assert_equal( internal_ord_to_val , vec![ 1, 2, 3] );
let mut internal_val_ord_pairs = a.hashmap_element_to_ordinal().iter().map(|(&x,&y)| (x, y)).collect_vec();
internal_val_ord_pairs.sort();
itertools::assert_equal( internal_val_ord_pairs, vec![ (1,0), (2,1), (3,2) ] );
a.reverse_ordinals();
let internal_ord_to_val = a.vec_elements_in_order().iter().cloned();
itertools::assert_equal( internal_ord_to_val , vec![ 3, 2, 1] );
let mut internal_val_ord_pairs = a.hashmap_element_to_ordinal().iter().map(|(&x,&y)| (x, y)).collect_vec();
internal_val_ord_pairs.sort();
itertools::assert_equal( internal_val_ord_pairs, vec![ (1,2), (2,1), (3,0) ] );
}
}