Login   Register  
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: 7 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 md5microtime() );
            
$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 || $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$__possibilities0, -);
        
$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 ) + );
        
$this->__loop .= $pre.'array_push( $this->__matches, '.substr$this->__returnedValue0$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;
    }
}
?>