* 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;
}