From ec0fa6265314f148f0c003be463714a98c94bcbd Mon Sep 17 00:00:00 2001 From: SRetip Date: Mon, 25 Mar 2024 18:01:08 +0200 Subject: [PATCH 1/2] almoust ready --- module/move/willbe/src/entity/features.rs | 75 ++++++++++++++--------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/module/move/willbe/src/entity/features.rs b/module/move/willbe/src/entity/features.rs index 3099f8fbd9..70b2328a5d 100644 --- a/module/move/willbe/src/entity/features.rs +++ b/module/move/willbe/src/entity/features.rs @@ -2,6 +2,7 @@ mod private { use crate::*; use std::collections::{ BTreeSet, HashSet }; + use error_tools::err; // aaa : for Petro : don't use cargo_metadata and Package directly, use facade // aaa : ✅ use error_tools::for_app::{ bail, Result }; @@ -67,7 +68,7 @@ mod private .cloned() .collect(); - if esimate_with( filtered_features.len(), power, with_all_features, with_none_features, enabled_features, package.features().len() ) > variants_cap as usize + if estimate_with( filtered_features.len(), power, with_all_features, with_none_features, enabled_features, package.features().len() ) > variants_cap as usize { bail!( "Feature powerset longer then cap." ) } @@ -100,42 +101,58 @@ mod private Ok( features_powerset ) } - - fn esimate_with( filtered_length : usize, power : usize, with_all : bool, with_none : bool, enabled : &[ String ], unfiltred_length : usize ) -> usize + pub fn estimate_with + ( + n : usize, + power : usize, + with_all_features : bool, + with_none_features : bool, + enabled_features : &[ String ], + total_features : usize + ) -> usize { - let mut e = esimate( filtered_length, power); - if !enabled.is_empty() && with_none - { - e += 1; - } - if with_all && power + enabled.len() >= unfiltred_length - { - e += 1; - } - e - } + let mut estimate = 0; + let mut binom = 1; + let power = power.min( n ); - fn esimate( filtered_length : usize, power : usize ) -> usize - { - let mut r = 0; - for p in 1..power + for k in 0..=power { - r += factorial( filtered_length ) / (factorial(p) * factorial( filtered_length - p ) ); + estimate += binom; + binom = binom * ( n - k ) / ( k + 1 ); } - r - } - fn factorial( n : usize ) -> usize - { - return if n == 1 - { - 1 - } - else + if with_all_features { estimate += 1; } + if with_none_features { estimate += 1; } + + if !enabled_features.is_empty() { - n * factorial(n - 1) + let len = enabled_features.len(); + let combinations = ( 0..=len.min( total_features ) ).map( | k | + { + let mut binom = 1; + for i in 0..k + { + binom = binom * ( len - i ) / ( i + 1 ); + } + binom + }).sum::< usize >(); + estimate += combinations; } + + estimate } + + // fn factorial( n : usize ) -> Result< usize > + // { + // return if n <= 1 + // { + // Ok( 1 ) + // } + // else + // { + // n.checked_mul( factorial( n - 1 )? ).ok_or_else( || err!( "Too big value" ) ) + // } + // } } crate::mod_interface! From 46572e1e2ff242e68babb7de60c92d0a20ef1b5e Mon Sep 17 00:00:00 2001 From: SRetip Date: Tue, 26 Mar 2024 11:55:36 +0200 Subject: [PATCH 2/2] ready --- module/move/willbe/src/entity/features.rs | 18 +++++------------- .../move/willbe/tests/inc/entity/features.rs | 11 +++++++++++ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/module/move/willbe/src/entity/features.rs b/module/move/willbe/src/entity/features.rs index 70b2328a5d..a292b131b1 100644 --- a/module/move/willbe/src/entity/features.rs +++ b/module/move/willbe/src/entity/features.rs @@ -101,6 +101,7 @@ mod private Ok( features_powerset ) } + /// Calculate estimate for `features_powerset.length` pub fn estimate_with ( n : usize, @@ -109,7 +110,8 @@ mod private with_none_features : bool, enabled_features : &[ String ], total_features : usize - ) -> usize + ) + -> usize { let mut estimate = 0; let mut binom = 1; @@ -141,22 +143,12 @@ mod private estimate } - - // fn factorial( n : usize ) -> Result< usize > - // { - // return if n <= 1 - // { - // Ok( 1 ) - // } - // else - // { - // n.checked_mul( factorial( n - 1 )? ).ok_or_else( || err!( "Too big value" ) ) - // } - // } + } crate::mod_interface! { /// Features protected use features_powerset; + protected use estimate_with; } diff --git a/module/move/willbe/tests/inc/entity/features.rs b/module/move/willbe/tests/inc/entity/features.rs index 3ee575389a..dd4db5bff8 100644 --- a/module/move/willbe/tests/inc/entity/features.rs +++ b/module/move/willbe/tests/inc/entity/features.rs @@ -6,6 +6,7 @@ use the_module::features::features_powerset; use std::collections::HashMap; use serde::Deserialize; use the_module::workspace::WorkspacePackage; +use willbe::features::estimate_with; /// Constructs a mock `Package` with specified features for testing. fn mock_package( features : Vec< ( &str, Vec< &str > ) > ) -> WorkspacePackage @@ -254,4 +255,14 @@ fn case_6() assert!( result.contains( &vec![ "f2".to_string() ].into_iter().collect()) ); assert_eq!( result.len(), 2 ); +} + +#[ test ] +fn estimate() +{ + assert_eq!( estimate_with( 5, 2, false, false, &[], 0 ), 16 ); + assert_eq!( estimate_with( 5, 2, true, false, &[], 0 ), 17 ); + assert_eq!( estimate_with( 5, 2, false, true, &[], 0 ), 17 ); + assert_eq!( estimate_with( 5, 2, false, false, &[ "feature1".to_string(), "feature2".to_string() ], 2 ), 20 ); + assert_eq!( estimate_with( 5, 2, true, true, &[ "feature1".to_string(), "feature2".to_string() ], 2 ), 22 ); } \ No newline at end of file