atelierspierrot/library

View on GitHub
src/Library/Helper/Number.php

Summary

Maintainability
A
2 hrs
Test Coverage
<?php
/**
 * This file is part of the Library package.
 *
 * Copyleft (ↄ) 2013-2016 Pierre Cassat <me@e-piwi.fr> and contributors
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * The source code of this package is available online at 
 * <http://github.com/atelierspierrot/library>.
 */

namespace Library\Helper;

/**
 * Number helper
 *
 * As for all helpers, all methods are statics.
 *
 * For convenience, the best practice is to use:
 *
 *     use Library\Helper\Number as NumberHelper;
 *
 * @author  piwi <me@e-piwi.fr>
 */
class Number
{

    /**
     * Test if an integer is an "odd number"
     *
     * @param   int     $val
     * @return  bool
     */
    public static function isOdd($val = null)
    {
        if (is_null($val)) {
            return null;
        }
        return (bool) !($val % 2 == 0);
    }

    /**
     * Test if an integer is an "even number"
     *
     * @param   int     $val
     * @return  bool
     */
    public static function isEven($val = null)
    {
        if (is_null($val)) {
            return null;
        }
        return (bool) ($val % 2 == 0);
    }

    /**
     * Test if an integer is a "prime number"
     *
     * @param   int $val
     * @return  bool
     */
    public static function isPrime($val = null)
    {
        if (is_null($val)) {
            return null;
        }
        if (
            ($val<=1) ||
            ($val>2 && ($val%2)===0)
        ) {
            return false;
        }
        for ($i=2;$i<$val;$i++) {
            if (($val%$i)===0) {
                return false;
            }
        }
        return true;
    }

    /**
     * Get the `$val` element of the Fibonacci suite
     *
     * @param   int $val
     * @return  int
     */
    public static function getFibonacciItem($val = null)
    {
        if (is_null($val)) {
            return null;
        }
        if ($val==0) {
            return 0;
        } elseif ($val==1) {
            return 1;
        } elseif ($val>1) {
            return (self::getFibonacciItem($val-1) + self::getFibonacciItem($val-2));
        }
        return null;
    }

    /**
     * Luhn formula: get the Luhn digit of an integer
     *
     * 7992739871 => 3
     *
     * @see <http://en.wikipedia.org/wiki/Luhn_algorithm>
     * @param   int     $val
     * @return  int
     */
    public static function getLuhnKey($val = null)
    {
        if (is_null($val)) {
            return null;
        }
        $val = $val.'0';
        $length = strlen($val);
        $checksum = 0;
        for ($i=($length - 1); $i>=0; $i--) { 
            $digit = $val[$i];
            if ((($length - $i) % 2) == 0) {
                $digit = $digit * 2;
                if ($digit > 9) {
                    $digit = $digit - 9;
                }
            }
            $checksum += $digit;
        }
        $luhn_key = 10 - ( $checksum % 10 );
        if ($luhn_key == 10) {
            $luhn_key = 0;
        }
        return $luhn_key;
    }

    /**
     * Check that the last number in a suite is its Luhn key
     *
     * @param   int     $val    The number to check INCLUDING Luhn's key at last
     * @return  bool
     */
    public static function isLuhn($val = null)
    {
        if (is_null($val)) {
            return null;
        }
        $_num = substr($val, 0, strlen($val)-1);
        return (bool) (intval($val) == intval($_num.self::getLuhnKey($_num)));
    }

    /**
     * Calculate the sum of the digits of a number (its absolute entire value)
     *
     * @param $val
     * @return int
     */
    public static function getSumOfDigits($val = null)
    {
        if (is_null($val)) {
            return null;
        }
        $nbs = str_split(pow(abs($val), 1));
        $result = 0;
        foreach ($nbs as $nb) {
            $result += (int) $nb;
        }
        return $result;
    }

    /**
     * Test if a number is "self-describing":
     *
     * assuming digit positions are labeled 0 to N-1,
     * the digit in each position is equal to the number of times that digit appears in the number
     *
     * 2020 => true
     * 22 => false
     * 1210 => true
     *
     * @param $val
     * @return bool
     */
    public static function isSelfDescribing($val = null)
    {
        if (is_null($val)) {
            return null;
        }
        $val = (string) $val;
        for ($i=0; $i<strlen($val); $i++) {
            $_val   = $val{$i};
            $occ    = substr_count($val, $i);
            if ($_val != $occ) {
                return false;
            }
        }
        return true;
    }

    /**
     * Test if a series of numbers is a "Jolly Jumper":
     *
     * A sequence of n > 0 integers where the absolute values of the
     * differences between successive elements take on all possible values 1 through n - 1.
     *
     * @param array $items
     * @return bool
     */
    public static function isJollyJumperSeries(array $items = array())
    {
        if (empty($items)) {
            return null;
        }
        if (count($items)==1) {
            return true;
        }
        $diffs = array();
        for ($i=0; $i<count($items)-1; $i++) {
            $diffs[] = abs($items[$i] - $items[$i+1]);
        }
        $diffs = array_filter($diffs);
        $limit = min(max($diffs)+1, count($items));
        $isjj = true;
        for ($i=1; $i<$limit; $i++) {
            if (!in_array($i,$diffs)) {
                $isjj = false;
            }
        }
        return $isjj;
    }

    /**
     * Test if an integer is a "palindromic number"
     *
     * @param   int $val
     * @return  bool
    public static function isPalindromic($val = null)
    {
    if (is_null($val)) {
    return null;
    }
    $r = 0;
    $t = $val;
    while ($t>0) {
    $d = $t%10;
    $t = $t/10;
    $r = ($r*10) + $d;
    }
    return (bool) ($r==$val);
    }
     */

}