Bekijk de onderstaande video om te zien hoe je onze site als een web app op je startscherm installeert.
Opmerking: Deze functie is mogelijk niet beschikbaar in sommige browsers.
<?php
/**
* @Author: Erik Roelofs
* @Created: 29 03 2009
* @Email: Erik@Ruigekonijnen.nl
*
* A Math Helper with a few functions to help with mathematical problems
* Right now supports:
* determinePrime() to figure out if a number is a prime ( not for HUGE numbers )
* factorize() to break a number into primes
* combinations() to determine the number of possible ways to take X objects from a collection of Y objects
*
* Might be updated later.
*/
class mathhelper {
/**
* In how many ways can we take $amount objects from $collection
* if we don't mind the order?
*
* @param integer $collection
* @param ingeger $amount
*
* @return integer (or float, if really big) $iAmountOfCombinations
*/
function combinations( $collection, $amount ) {
// formal:
// n! / ( k! ( n - k )! )
// we're going to drop the largest set of the two, and remove all those numbers from $aCollectionNumbers
// get the largest number
$bottom = max ( $amount, $collection - $amount );
// create the top range, which runs from (highest number dropped +1) to (collection)
// that is: numbers that exist exactly in both top and bottom of the calculation.
$aTopNumbers = range( $bottom + 1, $collection );
// create the bottom range, which runs from 1 to the collection minus the highest number dropped
$aBottomNumbers = range ( 1, $collection - $bottom );
// determine the factor list at the top of the division
$aTop = array();
foreach ( $aTopNumbers as $i ) {
$aNewFactors = self::factorize( $i );
foreach ( $aNewFactors as $factor => $amount_factors ) {
if ( isset ( $aTop[ $factor ] ) ) {
$aTop[ $factor ] += $amount_factors;
}
else {
$aTop[ $factor ] = $amount_factors;
}
}
}
// determine the factor list at the bottom of the division
$aBottom = array();
foreach ( $aBottomNumbers as $i ) {
$aNewFactors = self::factorize( $i );
foreach ( $aNewFactors as $factor => $amount_factors ) {
if ( isset ( $aBottom[ $factor ] ) ) {
$aBottom[ $factor ] += $amount_factors;
}
else {
$aBottom[ $factor ] = $amount_factors;
}
}
}
// now we simplify. first, clean as many factors that exist in both Collection and Amount as possible
foreach ( $aBottom as $factor => $amount ) {
if ( isset ( $aTop[ $factor ] ) ) {
// at least some factors exist
if ( $aTop[ $factor ] > $amount ) {
// collection has more of them. remove a set from collection and all from amount
$aTop[ $factor ] -= $amount;
unset ( $aBottom[ $factor ] );
}
elseif ( $aTop[ $factor ] == $amount ) {
// they have equal; unset both
unset ( $aTop[ $factor ] );
unset ( $aBottom[ $factor ] );
}
else {
// amount has more of them; unset from collection, lower amount
unset ( $aTop[ $factor ] );
$aBottom[ $factor ] -= $amount;
}
}
}
// calculate what's left of N!
$topFaculty = 1;
foreach ( $aTop as $factor => $amount ) {
$topFaculty *= pow ( $factor, $amount );
}
// then calculate what's left of K!(N-K)!
$bottomFaculty = 1;
foreach ( $aBottom as $factor => $amount ) {
$bottomFaculty *= pow ( $factor, $amount );
}
// and divide them.
return $topFaculty / $bottomFaculty;
}
/**
* Crunch a number into all the primes that it's made up out of.
*
* @param positive integer $number
* @return array with key $factor and value $amount of times this factor is in the number
*
* (Example: factorizing 12 would give
* array (
* 2 => 2,
* 3 => 1
* )
* because 12 is 2 x 2 x 3 )
*/
function factorize ( $number ) {
if ( !is_numeric ( $number ) || $number < 1 ) {
throw new Exception ( "Cannot factorize for non-positive number: " . $number );
}
// 1 is an exception
if ( $number == 1 ) {
return array( 1 => 1 );
}
$return = array();
// divide by each prime as often as possible.
foreach ( self::$primelist as $prime ) {
while ( $number % $prime == 0 ) {
// divisable.
if ( isset ( $return[ $prime ] ) ) {
$return[ $prime ]++;
}
else {
$return[ $prime ] = 1;
}
$number /= $prime;
}
// done?
if ( $number == 1 ) {
return $return;
}
}
// not done... we need a bigger primes list.
$new_primes = self::expandPrimeListUpTo( $number );
// continue.
foreach ( $new_primes as $prime ) {
while ( $number % $prime == 0 ) {
// divisable.
if ( isset ( $return[ $prime ] ) ) {
$return[ $prime ]++;
}
else {
$return[ $prime ] = 1;
}
$number /= $prime;
}
// done?
if ( $number == 1 ) {
return $return;
}
}
// unable to factorize? :/
throw new Exception ( 'Was not able to factorize ' . $number . '; what the hell?' );
}
/**
* Determine if a number is a prime
*
* @return 0 if the number is a prime, or the lowest divisor if it isn't.
*/
function determinePrime ( $number ) {
// if this is negative or NaN, exception.
if ( !is_numeric ( $number ) || $number < 1 ) {
throw new Exception ( 'Not a positive integer: ' . $number );
}
// 1 is not a prime, and a special case.'
if ( $number == 1 ) {
return 0;
}
// if in our determined list; then it's fine.
if ( isset ( self::$primelist[ $number ] ) ) {
return 0;
}
// match against all known primes.
foreach ( self::$primelist as $prime ) {
// divisable; thus not a prime
if ( $number % $prime == 0 ) {
return $prime;
}
}
// add more primes
$new_primes = self::expandPrimeListUpTo ( (int) ceil ( sqrt ( $number ) ) );
// now the list is full; check again if our original was a prime.
foreach ( $new_primes as $prime ) {
// divisable; thus not a prime
if ( $number % $prime == 0 ) {
return $prime;
}
}
// it is a prime ;)
return 0;
}
/**
* Will fill the internal list of primes up to $number
*
* @param integer $number
* @return array of primes added.
*/
private function expandPrimeListUpTo( $number ) {
$return = array();
// fill the list further
// hop in jumps of 2 (odds only; and primetop is always odd.)
for ( $i = self::$primetop ; $i <= $number ; $i+=2 ) {
// determine if this number is a prime.
foreach ( self::$primelist as $prime ) {
$is_prime = true;
if ( $i % $prime == 0 ) {
// it is not a prime; skip it.
$is_prime = false;
break;
}
}
if ( $is_prime ) {
// add this prime, continue.
self::$primelist[ $i ] = $i;
self::$primetop = $i;
$return[] = $i;
}
}
return $return;
}
/**
* The class uses this array to speed up factorizing and prime number determinitation.
* You can put in more primes to make it go even faster for larger numbers.
* The downside is that it'll start taking up more memory too.
* $primetop is the highest prime in the array, keep it up to date if you add more primes or results may become unpredictable.
*
*/
static $primetop = 997;
static $primelist =
array (
2 => 2,
3 => 3,
5 => 5,
7 => 7,
11 => 11,
13 => 13,
17 => 17,
19 => 19,
23 => 23,
29 => 29,
31 => 31,
37 => 37,
41 => 41,
43 => 43,
47 => 47,
53 => 53,
59 => 59,
61 => 61,
67 => 67,
71 => 71,
73 => 73,
79 => 79,
83 => 83,
89 => 89,
97 => 97,
101 => 101,
103 => 103,
107 => 107,
109 => 109,
113 => 113,
127 => 127,
131 => 131,
137 => 137,
139 => 139,
149 => 149,
151 => 151,
157 => 157,
163 => 163,
167 => 167,
173 => 173,
179 => 179,
181 => 181,
191 => 191,
193 => 193,
197 => 197,
199 => 199,
211 => 211,
223 => 223,
227 => 227,
229 => 229,
233 => 233,
239 => 239,
241 => 241,
251 => 251,
257 => 257,
263 => 263,
269 => 269,
271 => 271,
277 => 277,
281 => 281,
283 => 283,
293 => 293,
307 => 307,
311 => 311,
313 => 313,
317 => 317,
331 => 331,
337 => 337,
347 => 347,
349 => 349,
353 => 353,
359 => 359,
367 => 367,
373 => 373,
379 => 379,
383 => 383,
389 => 389,
397 => 397,
401 => 401,
409 => 409,
419 => 419,
421 => 421,
431 => 431,
433 => 433,
439 => 439,
443 => 443,
449 => 449,
457 => 457,
461 => 461,
463 => 463,
467 => 467,
479 => 479,
487 => 487,
491 => 491,
499 => 499,
503 => 503,
509 => 509,
521 => 521,
523 => 523,
541 => 541,
547 => 547,
557 => 557,
563 => 563,
569 => 569,
571 => 571,
577 => 577,
587 => 587,
593 => 593,
599 => 599,
601 => 601,
607 => 607,
613 => 613,
617 => 617,
619 => 619,
631 => 631,
641 => 641,
643 => 643,
647 => 647,
653 => 653,
659 => 659,
661 => 661,
673 => 673,
677 => 677,
683 => 683,
691 => 691,
701 => 701,
709 => 709,
719 => 719,
727 => 727,
733 => 733,
739 => 739,
743 => 743,
751 => 751,
757 => 757,
761 => 761,
769 => 769,
773 => 773,
787 => 787,
797 => 797,
809 => 809,
811 => 811,
821 => 821,
823 => 823,
827 => 827,
829 => 829,
839 => 839,
853 => 853,
857 => 857,
859 => 859,
863 => 863,
877 => 877,
881 => 881,
883 => 883,
887 => 887,
907 => 907,
911 => 911,
919 => 919,
929 => 929,
937 => 937,
941 => 941,
947 => 947,
953 => 953,
967 => 967,
971 => 971,
977 => 977,
983 => 983,
991 => 991,
997 => 997,
);
}
?>
We gebruiken essentiële cookies om deze site te laten werken, en optionele cookies om de ervaring te verbeteren.