Skip to content

Commit

Permalink
Add skipFactorial() function (#11)
Browse files Browse the repository at this point in the history
- add **skipFactorial(n, skip);** experimental
- Fix URL in examples
- minor edits
  • Loading branch information
RobTillaart authored Jan 6, 2024
1 parent eafed1f commit e45f754
Show file tree
Hide file tree
Showing 18 changed files with 272 additions and 52 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,16 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.2.0] - 2024-01-06
- add **skipFactorial(n, skip);** experimental
- Fix URL in examples
- minor edits

----

## [0.1.8] - 2023-11-22
- update readme.md


## [0.1.7] - 2023-03-15
- update readme.md
- update GitHub actions
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2010-2023 Rob Tillaart
Copyright (c) 2010-2024 Rob Tillaart

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
51 changes: 42 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,52 @@ but accuracy is less than the **dfactorial()**, see example.
### SemiFactorial

SemiFactorials are like factorials but skipping every other.
SemiFactorials are written as a number with two exclamation marks.

SemiFactorial are defined for
- **odd** values: n!! == n x (n-2) x (n-4) ... x 1
- **even** values: n!! == n x (n-2) x (n-4) ... x 2

Example 12!! = 12 x 10 x 8 x 6 x 4 x 2 = 46080

- **uint32_t semiFactorial(n)** exact up to 20!!
- **uint64_t semiFactorial64(n)** exact up to 33!! (Print 64 bit integers with my printHelpers)
- **uint64_t semiFactorial64(n)** exact up to 33!! (Print 64 bit integers with printHelpers library)
- **double dSemiFactorial(n)** not exact up to 56!! (4 byte) or 300!! (8 byte)

SemiFactorial are defined for
- **odd** values: n x (n-2) x (n-4) ... x 1
- **even** values: n x (n-2) x (n-4) ... x 2


Notes:
```n! = n!! x (n-1)!!``` this formula allows to calculate the value of n! indirectly
```
n! = n!! x (n-1)!!
```
This formula allows to calculate the value of n! indirectly.


### SkipFactorial (experimental)

- **uint32_t skipFactorial(uint32_t n, uint32_t skip)**
- **uint64_t skipFactorial64(uint32_t n, uint32_t skip)**
- **double dSkipFactorial(uint32_t n, uint32_t skip)**

SkipFactorials are like factorials and semiFactorials but they skip **skip** numbers.
- **skipFactorial(12, 4)** = 12 x 8 x 4 = 384
- **skipFactorial(17, 5)** = 17 x 12 x 7 x 2 = 2856
- **skipFactorial(n, 1)** == **factorial(n)**
- **skipFactorial(n, 2)** == **semiFactorial(n)**

As the maximum depends on both n and step sizze there is no single maximum for n.
This is similar to combinations and permutations.

An indicative table of maxima per function call, the larger the skip, the larger the maximum n.
Note that for skip <= 10 n still is an 8 bit number.

| function | n, 2 | n, 3 | n, 4 | n, 5 | n, 10 | notes |
|:------------------|:-------:|:-------:|:-------:|:-------:|:-------:|:--------|
| skipFactorial | 20 | 27 | 32 | 40 | 69 | max expected smaller than 7 x skip when skip > 10.
| skipFactorial64 | 33 | 45 | 55 | 66 | 115 | max expected smaller than 12 x skip when skip > 10.
| dSkipFactorial | 56 | 77 | 95 | 115 | 200 | float (4 bytes) max expected smaller than 20 x skip when skip > 10.
| dSkipFactorial | 300 | | | | | double (8 bytes)

Note that for the function the **max / skip** is decreasing when **skip grows**.


### Combinations
Expand Down Expand Up @@ -184,9 +218,8 @@ See examples

- investigate a bigFloat class to do math for permutations and combinations to substantially larger values.
- Look for ways to extend the scope
- **skipFactorial(uint32_t n, uint32_t skip)** == n x (n-skip) x (n -skip -skip) ... x S (depends on size of skip)
- e.g. skipFactorial(12, 4) = 12 x 8 x 4.
- skipFactorial(n, 2) == semiFactorial(n);
- fill table for skipFactorial for **double**


#### Wont

Expand Down
7 changes: 5 additions & 2 deletions examples/bigCombinations/bigCombinations.ino
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();

Serial.println("dcombinations(n, k); ");
delay(10);
Expand Down Expand Up @@ -63,7 +66,7 @@ void setup()
Serial.print(expo);
Serial.println();
}
//Serial.println();
// Serial.println();
}
duration1 = micros() - start;
Serial.println(duration1);
Expand All @@ -78,5 +81,5 @@ void loop()
}


// -- END OF FILE --
// -- END OF FILE --

7 changes: 5 additions & 2 deletions examples/bigFactorial/bigFactorial.ino
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


#include "statHelpers.h"
#include "printHelpers.h" // to print large numbers....
#include "printHelpers.h" // to print large numbers ...


uint32_t start, duration1, duration2, duration3;
Expand All @@ -17,6 +17,9 @@ void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();

uint32_t m = 10000001;
double mant = 0;
Expand Down Expand Up @@ -77,5 +80,5 @@ void loop()
}


// -- END OF FILE --
// -- END OF FILE --

9 changes: 7 additions & 2 deletions examples/bigPermutations/bigPermutations.ino
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();


///////////////////////////////////////////

Expand Down Expand Up @@ -123,7 +127,8 @@ void setup()
Serial.println();
*/

// pick 1000 persons from 4294967295 (maxLong)

// pick 1000 persons from 4294967295 (maxLong)
double mant = 0;
uint32_t expo = 0;
bigPermutations(4294967295, 1000, mant, expo);
Expand All @@ -141,5 +146,5 @@ void loop()
}


// -- END OF FILE --
// -- END OF FILE --

16 changes: 10 additions & 6 deletions examples/combinations/combinations.ino
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();


Serial.println("combinations(n, k)");
delay(10);
Expand All @@ -35,7 +39,7 @@ void setup()
// Serial.print(combinations(n, k));
// Serial.println();
}
//Serial.println();
// Serial.println();
}
duration1 = micros() - start;
Serial.println(duration1);
Expand All @@ -57,7 +61,7 @@ void setup()
// Serial.print(combinations(n, k));
// Serial.println();
}
//Serial.println();
// Serial.println();
}
duration1 = micros() - start;
Serial.println(duration1);
Expand All @@ -80,7 +84,7 @@ void setup()
// Serial.print(print64(combinations64(n, k)));
// Serial.println();
}
//Serial.println();
// Serial.println();
}
duration1 = micros() - start;
Serial.println(duration1);
Expand All @@ -101,7 +105,7 @@ void setup()
// Serial.print(print64(combinations64(n, k)));
// Serial.println();
}
//Serial.println();
// Serial.println();
}
duration1 = micros() - start;
Serial.println(duration1);
Expand All @@ -126,7 +130,7 @@ void setup()
// Serial.print(comb(n, k));
// Serial.println();
}
//Serial.println();
// Serial.println();
}
duration1 = micros() - start;
Serial.println(duration1);
Expand All @@ -141,5 +145,5 @@ void loop()
}


// -- END OF FILE --
// -- END OF FILE --

8 changes: 6 additions & 2 deletions examples/factorial/factorial.ino
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


#include "statHelpers.h"
#include "printHelpers.h" // to print large numbers....
#include "printHelpers.h" // to print large numbers....


uint32_t start, duration1, duration2;
Expand All @@ -17,6 +17,10 @@ void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();


int m = 35;
if (sizeof(double) == 8) m = 175;
Expand Down Expand Up @@ -94,5 +98,5 @@ void loop()
}


// -- END OF FILE --
// -- END OF FILE --

8 changes: 6 additions & 2 deletions examples/factorial_performance/factorial_performance.ino
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


#include "statHelpers.h"
#include "printHelpers.h" // to print large numbers....
#include "printHelpers.h" // to print large numbers....


uint32_t start, duration1, duration2, duration3;
Expand All @@ -17,6 +17,10 @@ void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();


int m = 35;
int decimals = 7;
Expand Down Expand Up @@ -67,5 +71,5 @@ void loop()
}


// -- END OF FILE --
// -- END OF FILE --

8 changes: 6 additions & 2 deletions examples/nextPermutation/nextPermutation.ino
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ void setup()
{
Serial.begin(115200);
Serial.println(__FILE__);

Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();

Serial.println("120 permutations + print");
do
Expand All @@ -32,6 +34,7 @@ void setup()
}
while (nextPermutation<char>(hello, 5));


////////////////////////////////////////////////////////////////

Serial.println("timing 720 permutations + print");
Expand All @@ -52,6 +55,7 @@ void setup()
Serial.println(duration1);
delay(10);


////////////////////////////////////////////////////////////////

start = micros();
Expand All @@ -70,5 +74,5 @@ void loop()
}


// -- END OF FILE --
// -- END OF FILE --

31 changes: 19 additions & 12 deletions examples/perm1/perm1.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,29 @@
// FILE: perm1.ino
// AUTHOR: Rob Tillaart
// DATE: 2010-11-23
// PUPROSE: demo permutations
// PURPOSE: demo permutations
// URL: https://github.com/RobTillaart/statHelpers
//
//
// WARNING TAKES LONG
// ========================================================================
// ESP32 @ 240 MHz string length 8 ==> ~8100 milliseconds => printing!!
// UNO no printing string length 8 ==> ~431 milliseconds
// UNO no printing string length 10 ==> ~38763 milliseconds
// WARNING TAKES LONG
// ========================================================================
// ESP32 @ 240 MHz string length 8 ==> ~8100 milliseconds => printing!!
// UNO no printing string length 8 ==> ~431 milliseconds
// UNO no printing string length 10 ==> ~38763 milliseconds


char permstring[12] = "0123456789"; // can be made slightly longer
#include "statHelpers.h"

char permstring[12] = "0123456789"; // can be made slightly longer

uint32_t start, stop;


void permutate(char * array, uint8_t n)
{
if (n == 0) // end reached print the string
if (n == 0) // end reached print the string
{
// Serial.println(array); // process permutation
// Serial.println(array); // process permutation
return;
}

Expand All @@ -46,7 +49,12 @@ void permutate(char * array, uint8_t n)
void setup()
{
Serial.begin(500000);

Serial.println(__FILE__);
Serial.print("STATHELPERS_LIB_VERSION: ");
Serial.println(STATHELPERS_LIB_VERSION);
Serial.println();


Serial.println("Will take some time..");
Serial.print("perm1 strlen: ");
Serial.println(strlen(permstring));
Expand All @@ -65,5 +73,4 @@ void loop()
}


// -- END OF FILE --

// -- END OF FILE --
Loading

0 comments on commit e45f754

Please sign in to comment.