projecteuler#2 Even Fibonacci numbers

* Solution.php

<?php
/**
 * https://projecteuler.net/problem=2
 * Even Fibonacci numbers
 */
class Solution {

    protected $bound;

    public function __construct($bound) {
        $this->bound = $bound;
    }

    public static function fibonacci(int $n) : int {
        if ($n < 1) {return 0;}
        if ($n === 1 || $n === 2) {return 1;}
        /** @var $base array */
        $base = [
            0 => [1, 1],
            1 => [1, 0]
        ];
        $res = self::matrixPower($base, $n-2);
        return $res[0][0] + $res[1][0];
    }

    public static function matrixPower(array $m, int $p) {
        /* init */
        $res = [];
        for ($i = 0; $i < count($m); $i++) {
            $res[$i] = [];
            for ($j = 0; $j < count($m[0]); $j++) {
                $res[$i][$j] = 0;
            }
        }
        /* Set res as the unit matrix equivalent to 1 of the integer. */
        for ($i = 0; $i < count($res); $i++)
            $res[$i][$i] = 1;

        $tmp = $m;
        for (; $p > 0; $p >>= 1) {
            if (($p & 0x01) !== 0) {
                $res = self::multiMatrix($res, $tmp);
            }
            $tmp = self::multiMatrix($tmp, $tmp);
        }

        return $res;
    }

    public static function multiMatrix(array $m1, array $m2) : array {
        if (count($m1[0]) !== count($m2)) {
            throw new LengthException("m1 columns count should equal m2 rows count");
        }
        $res = [];
        for ($i = 0; $i < count($m1); $i++) {
            $res[$i] = [];
            for ($j = 0; $j < count($m2[0]); $j++) {
                $res[$i][$j] = 0;
            }
        }

        for ($i = 0; $i < count($m1); $i++) {
            for ($j = 0; $j < count($m2[0]); $j++) {
                for ($k = 0; $k < count($m2); $k++) {
                    $res[$i][$j] += $m1[$i][$k] * $m2[$k][$j];
                }
            }
        }
        return $res;
    }

    public function sumEvenTerms() {
        $sum = 0;
        for ($i = 0; ; $i++) {
            $term = self::fibonacci($i);
            if ($term >= $this->bound) {
                break;
            }
            if ($term == $term >> 1 << 1) {
                $sum += $term;
            }
        }
        return $sum;
    }
}

* index.php

include './Solution.php';

/** @var $solution < 4 million */
$solution = new Solution(4000000);
echo $solution->sumEvenTerms().PHP_EOL;

* test

$ php index.php

4613732

javascript 指数

m, p都为整数

function pow(m, p) {
    if (p === 0) {return 1;}
    var t = m, res = 1;
    for (; p > 0; p >>= 1) {
        if (p & 0x01 !== 0) {
            res = res * t;
        }
        t = t * t;
    }
    return res;
}

猜你喜欢

转载自blog.csdn.net/fareast_mzh/article/details/82948077