static int fib(int n) { return n > 1 ? fib(n - 1) + fib(n - 2) : n; }
Func<int, int> fib = Y<int,int>(f => n => n > 1 ? f(n - 1) + f(n - 2) : n);
Y
defined, for example, like this: static Func<A, R> Y<A, R>(Func<Func<A, R>, Func<A, R>> f) { Func<A, R> g = null; g = f(a=>g(a)); return g; }
x*x
is considered faster than Math.Pow(x,2)
? Because for the integer degree, you can not only do without the Taylor series, but also optimize the calculation for large degrees by creating temporary variables. For example, x 4 can be considered as int y = x * x; return y * y;
int y = x * x; return y * y;
- and the greater the degree, the greater the savings.short
. public static long IntPower(int x, short power) { if (power == 0) return 1; if (power == 1) return x; int n = 15; while ((power <<= 1) >= 0) n--; long tmp = x; while (--n > 0) tmp = tmp * tmp * (((power <<= 1) < 0) ? x : 1); return tmp; }
struct mtx2x2 { public int _11, _12, _21, _22; public static mtx2x2 operator*(mtx2x2 lhs, mtx2x2 rhs) { return new mtx2x2 { _11 = lhs._11*rhs._11 + lhs._12*rhs._21, _12 = lhs._11*rhs._12 + lhs._12*rhs._22, _21 = lhs._21*rhs._11 + lhs._22*rhs._21, _22 = lhs._21*rhs._12 + lhs._22*rhs._22 }; } }
private static readonly mtx2x2 fibMtx = new mtx2x2 {_11 = 1, _12 = 1, _21 = 1}; private static readonly mtx2x2 identity = new mtx2x2 {_11 = 1, _22 = 1};
IntPower()
method for 2 × 2 matrices: public static mtx2x2 IntPower(mtx2x2 x, short power) { if (power == 0) return identity; if (power == 1) return x; int n = 15; while ((power <<= 1) >= 0) n--; mtx2x2 tmp = x; while (--n > 0) tmp = (tmp * tmp) * (((power <<= 1) < 0) ? x : identity); return tmp; }
static int fibm(short n) { return IntPower(fibMtx, (short)(n-1))._11; }
fib(40)
considered 4 seconds, and fibm(40)
is displayed immediately. ■Source: https://habr.com/ru/post/83303/
All Articles