Problem 2 "Even Fibonacci numbers"

Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

問 2 「偶数のフィボナッチ数」

フィボナッチ数列の項は前の2つの項の和である. 最初の2項を 1, 2 とすれば, 最初の10項は以下の通りである.

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

数列の項の値が400万以下のとき, 値が偶数の項の総和を求めよ.

struct TripleBox {
    i: u64,
    j: u64,
    k: u64,
}

impl TripleBox {
    fn shift(&mut self) {
        self.i = self.j + self.k;
        self.j = self.k + self.i;
        self.k = self.i + self.j;
    }
}

fn main() {
    let mut sum = 0;
    let mut tb = TripleBox { i: 0, j: 1, k: 1 };
    while tb.i <= 4_000_000 {
        sum += tb.i;
        tb.shift()
    }
    println!("{}", sum);
    assert_eq!(sum, 4613732)
}

struct LuckyClover {
    a: u64,
    b: u64,
    c: u64,
    d: u64,
}

impl LuckyClover {
    fn multiply(&mut self, other: &LuckyClover) {
        let a = self.a * other.a + self.b * other.c;
        let b = self.a * other.b + self.b * other.d;
        let c = self.c * other.a + self.d * other.c;
        let d = self.c * other.b + self.d * other.d;
        self.a = a;
        self.b = b;
        self.c = c;
        self.d = d;
    }
    fn identity_matrix() -> LuckyClover {
        LuckyClover {
            a: 1,
            b: 0,
            c: 0,
            d: 1,
        }
    }
}

fn main() {
    let multiplier = LuckyClover {
        a: 1,
        b: 1,
        c: 1,
        d: 0,
    };
    let cubed = {
        let mut i = LuckyClover::identity_matrix();
        i.multiply(&multiplier);
        i.multiply(&multiplier);
        i.multiply(&multiplier);
        std::mem::drop(multiplier);
        i
    };
    let mut sum = 0;
    let mut fibmatrix = LuckyClover::identity_matrix();
    while fibmatrix.b <= 4_000_000 {
        sum += fibmatrix.b;
        fibmatrix.multiply(&cubed);
    }
    println!("{}", sum);
    assert_eq!(sum, 4613732)
}
package main

import "fmt"

type Matrix struct {
	a, b, c, d uint64
}

func (m *Matrix) multiply(o Matrix) {
	m.a, m.b, m.c, m.d =
		m.a*o.a+m.b*o.c,
		m.a*o.b+m.b*o.d,
		m.c*o.a+m.d*o.c,
		m.c*o.b+m.d*o.d
}

func identityMatrix() Matrix {
	return Matrix{a: 1, b: 0, c: 0, d: 1}
}

func cube() Matrix {
	i := identityMatrix()
	fib := Matrix{a: 1, b: 1, c: 1, d: 0}
	i.multiply(fib)
	i.multiply(fib)
	i.multiply(fib)
	return i
}

func Example() {
	i := identityMatrix()
	c := cube()
	sum := uint64(0)
	for i.b <= 4_000_000 {
		sum += i.b
		i.multiply(c)
	}
	fmt.Println(sum)
	// Output: 4613732
}
→ Go playground
function assert(condition: any, msg?: string): asserts condition {
  if (!condition) {
    throw new Error(msg)
  }
}

class Matrix {
  a: number;
  b: number;
  c: number;
  d: number;
  constructor() {
    this.a = 1;
    this.b = 0;
    this.c = 0;
    this.d = 1;
  }
  multiplyLiteral(o: { a: number; b: number; c: number; d: number }) {
    const a = this.a * o.a + this.b * o.c;
    const b = this.a * o.b + this.b * o.d;
    const c = this.c * o.a + this.d * o.c;
    const d = this.c * o.b + this.d * o.d;
    this.a = a;
    this.b = b;
    this.c = c;
    this.d = d;
  }
  multiplyMatrix(o: Matrix) {
    this.multiplyLiteral(o);
  }
}

function cube(): Matrix {
  let i = new Matrix();
  const fib = { a: 1, b: 1, c: 1, d: 0 };
  i.multiplyLiteral(fib);
  i.multiplyLiteral(fib);
  i.multiplyLiteral(fib);
  return i;
}

let i = new Matrix();
const c = cube();
let sum = 0;
while (i.b <= 4_000_000) {
  sum += i.b;
  i.multiplyMatrix(c);
} 
console.log(sum);
assert(sum === 4613732);
→ TypeScript playground