PHP Classes
elePHPant
Icontem

File: Combinatory.class.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Andrea Giammarchi  >  Combinatory Logic  >  Combinatory.class.php  >  Download  
File: Combinatory.class.php
Role: Class source
Content type: text/plain
Description: Core class
Class: Combinatory Logic
Calculate and generate array element combinations
Author: By
Last change: Removed some reference (&$something) to make this class compatible with PHP 5.2 too now E_ALL and E_STRICT notice free
Date: 8 years ago
Size: 9,309 bytes
 

Contents

Class file image Download
<?php
/**
* Class Combinatory
* Creates and returns an Array with all possibilities for n vars with a k class.
* For more info about Combinatory Logic, visits this site:
* http://en.wikipedia.org/wiki/Combinatory_logic
* ------------------------------------------------------------------------
* EXAMPLES:
* $container = Array( '3', '1', '2' );
* $c = &new Combinatory('-'); // note that separator('-') is optional
* $matches = &$c->result( $container, 2, "Cn,k" ); // 2 is the class or combination possibility, Pn is the method
* // METHODS TO CALCULATE: Pn - Pn(k) - Dn,k - D'n,k - Cn,k - C'n,k
*
* echo count( $matches );
* echo '<pre>';
* var_dump( $matches );
* echo '</pre>';
*
* //OUTPUT
* 3
* array(3) {
* [0]=>
* string(3) "3-1"
* [1]=>
* string(3) "3-2"
* [2]=>
* string(3) "1-2"
* }
*
* ________________________________________________________________________
* @author Andrea Giammarchi
* @site www.3site.it
* @date 13/10/2004
* @last_mod 22/01/2007 17:20 - tested with PHP 5.2 E_STRICT, removed few notices
* @compatibility PHP4, 5, 5.2
* @version 1.0 tested
*/
class Combinatory {

   
// VARIABLES
    /**
     * 'private' var __loop:String Used to create code for evaluation
     * 'private' var __returnedValue:String Used to create code inside __loop
     * 'private' var __limit:Integer Number of Elements Array keys
     * 'private' var __matches:String Array with dedicated combinations
     * 'private' var __sep:String Combinations separator
     * 'private' var __delsep:Boolean delete Combinations separator
     * 'private' var __C:Array Used to check variables to exclude
     */
   
var $__loop;
    var
$__returnedValue;
    var
$__limit;
    var
$__matches;
    var
$__sep;
    var
$__delsep;
    var
$__C;

   
   
// CONSTRUCTOR
    /**
     * 'public' constructor
     * Assigns separator if there is one
     *
     * new Combinatory( [ $separator:String ] )
     *
     * @param String A separator that will divide found matches
     */
   
function Combinatory( $__sep = '' ) {
        if(
$__sep == '' ) {
           
$this->__sep = md5( microtime() );
           
$this->__delsep = true;
        }
        else {
           
$this->__sep = &$__sep;
           
$this->__delsep = false;
        }
    }


   
// PUBLIC METHODS
    /**
     * 'public' method
     * Resets and assigns internal variables then switch $type and returns
     * dedicated type method.
     * If type mismatch switch returns an Array with only one key and with error as value.
     *
     * Combinatory->result( $container:Array, $match:Integer, $type:String ):Array
     *
     * @param Array Elements container ( in Math, numbers of elements for n )
     * @param Integer Possibilities for elements in container ( in Math, the class as k )
     * @param String What type of matches do you need.
     * Options: Pn - Pn(k) - Dn,k - D'n,k - Cn,k - C'n,k
     * @return Array An array class $match with all matches possibilities
     */
   
function result( $container, $match, $type ) {
       
$this->__loop = '';
       
$this->__returnedValue = '';
       
$this->__limit = count( $container );
       
$this->__matches = Array();
       
$this->__C = Array();
        if(
$match < 2 || $this->__limit < $match ) {
            return Array(
'This is not a good idea, please change elements or $match value .' );
        }
        switch(
$type ) {
            case
'Pn':
                return
$this->__checkReturn( $this->__combinatory_Pn( $container, $match ) );
            case
'Pn(k)':
                return
$this->__checkReturn( $this->__combinatory_P1n( $container, $match ) );
            case
'Dn,k':
                return
$this->__checkReturn( $this->__sort( $this->__combinatory_Pn( $container, $match ) ) );
            case
'D\'n,k':
                return
$this->__checkReturn( $this->__sort( $this->__combinatory_P1n( $container, $match ) ) );
            case
'Cn,k':
                return
$this->__checkReturn( $this->__combinatory_C( $container, $match, '__combinatory_Pn' ) );
            case
'C\'n,k':
                return
$this->__checkReturn( $this->__combinatory_C( $container, $match, '__combinatory_P1n' ) );
            default:
                return Array(
'$type error: options are "Pn" or "Pn(k)" or "Dn,k" or "D\'n,k" or "Cn,k" or "C\'n,k" .' );
        }
    }


   
// PRIVATE METHODS
    /**
     * 'private' method
     * Checks if separator was created automatically then remove it if necessary.
     *
     * Combinatory->__checkReturn( &$container:Array ):Array
     *
     * @param Array Elements container
     * @return Array Array with or without separator ( if was created automatically )
     */
   
function __checkReturn( $container ) {
        if(
$this->__delsep === true ) {
            return
str_replace( $this->__sep, '', $container );
        }
        else {
            return
$container;
        }
    }
   
   
/**
     * 'private' method
     * Calls private __commonEvaluation method and returns private __codeCreator method
     *
     * Combinatory->__combinatory_P1n( &$match:Integer, &$container:Array ):Array
     *
     * @param Integer Possibilities for elements in container
     * @param Array Elements container
     * @return Array Array created from private __codeCreator method
     */
   
function __combinatory_P1n( &$container, $match ) {
       
$this->__commonEvaluation( $match );
        return
$this->__codeCreator( $container );
    }
   
   
/**
     * 'private' method
     * Creates if statement inside evaluation to filter matches, then calls private
     * __commonEvaluation method with if statement and returns private __codeCreator method
     *
     * Combinatory->__combinatory_Pn( &$match:Integer, &$container:Array ):Array
     *
     * @param Integer Possibilities for elements in container
     * @param Array Elements container
     * @return Array Array created from private __codeCreator method
     */
   
function __combinatory_Pn( &$container, &$match ) {
       
$__possibilities = 'if( ';
        for(
$a = 1; $a < $match; $a++ ) {
            for(
$b = ($match-1); $b >= 0; $b-- ) {
                if(
$a !== $b ) {
                   
$__possibilities .= '$_'.$a.' !== $_'.$b.' && ';
                }
            }
        }
       
$__possibilities = substr( $__possibilities, 0, -3 );
       
$this->__commonEvaluation( $match, $__possibilities.') { ', ' }' );
        return
$this->__codeCreator( $container );
    }
   
   
/**
     * 'private' method
     * Evaluates right method to call and assigns them to a conventional array that
     * will be filtered inside a for statement that checks if values is just used or not.
     * Then returns parsed and filtered Array.
     *
     * Combinatory->__combinatory_C( &$match:Integer, &$container:Array, $method:String ):Array
     *
     * @param Integer Possibilities for elements in container
     * @param Array Elements container
     * @param String Type of private method to use. Options: __combinatory_Pn / __combinatory_P1n
     * @return Array Array created from private __codeCreator method and parsed from this method
     */
   
function __combinatory_C( &$container, &$match, $method ) {
        eval(
'$cAr = $this->'.$method.'( $container, $match );' );
       
$nAr = Array();
        for(
$a = 0, $b = count( $cAr ); $a < $b; $a++ ) {
           
$fAr = $this->__sort( $fAr = explode( $this->__sep, $cAr[$a] ) );
            if(
in_Array( $fAr, $this->__C ) == false ) {
               
array_push( $this->__C, $fAr );
               
array_push( $nAr, $cAr[$a] );
            }
        }
        return
$nAr;
    }
   
   
/**
     * 'private' method
     * Evaluates code created from other method and returns an Array with
     * all elements found.
     *
     * Combinatory->__codeCreator( &$container:Array ):Array
     *
     * @param Array Elements container
     * @return Array A new array with all combinatory matches for elements in container
     */
   
function __codeCreator( &$container ) {
        eval(
$this->__loop );
        return
$this->__matches;
    }
   
   
/**
     * 'private' method
     * Loops over matches to create a multi-for statement String to evaluate
     * with private __codeCreator method.
     *
     * Combinatory->__commonEvaluation( &$match:Integer [, $pre:String [, $post:String ] ] ):Void
     *
     * @param Integer Possibilities for elements in container
     * @param String DEFAULT: '' - other vars check to add inside loop if needed
     * @param String DEFAULT: '' - end of other vars check inside loop if added
     * @return Void
     */
   
function __commonEvaluation( &$match, $pre = '', $post = '' ) {
        for(
$a = 0; $a < $match; $a++ ) {
           
$this->__loop .= 'for( $_'.$a.' = 0; $_'.$a.' < '.$this->__limit.'; $_'.$a.'++ ) { ';
           
$this->__returnedValue .= '$container[$_'.$a.'].\''.$this->__sep.'\'.';
        }
       
$rm = -( strlen( $this->__sep ) + 4 );
       
$this->__loop .= $pre.'array_push( $this->__matches, '.substr( $this->__returnedValue, 0, $rm ).' );'.$post;
        for(
$a = 0; $a < $match; $a++ ) {
           
$this->__loop .= ' }';
        }
    }
   
   
/**
     * 'private' method
     * Sort array and returns them.
     *
     * Combinatory->__sort( &$container:Array ):Array
     *
     * @param Array Elements container
     * @return Array Elements container sorted
     */
   
function __sort( $container ) {
       
sort( $container );
       
reset( $container );
        return
$container;
    }
}
?>