1 /* This file is part of the Amalthea library. 2 * 3 * Copyright (C) 2019, 2021 Eugene 'Vindex' Stulin 4 * 5 * Distributed under the Boost Software License 1.0 or (at your option) 6 * the GNU Lesser General Public License 3.0 or later. 7 */ 8 9 module amalthea.math; 10 11 unittest { 12 assert(0 == gcd(0, 0)); 13 assert(gcd(4, 0) == 4 && 4 == gcd(0, 4)); 14 assert(gcd(1, 1) == 1); 15 assert(gcd(1, 0) == 1 && gcd(0, 1) == 1); 16 assert(gcd(1, 2) == 1 && gcd(2, 1) == 1); 17 assert(gcd(70, 105) == 35 && gcd(105, 70) == 35); 18 } 19 /******************************************************************************* 20 * Greatest common divisor. 21 */ 22 ulong gcd(ulong a, ulong b) { 23 if (a == 0) { 24 return b; 25 } 26 if (b == 0) { 27 return a; 28 } 29 while (a != b) { 30 if (a > b) { 31 a -= b; 32 } else { 33 b -= a; 34 } 35 } 36 return a; 37 } 38 39 40 /******************************************************************************* 41 * Least common multiple. 42 */ 43 ulong lcm(ulong a, ulong b) { 44 return a*b / gcd(a, b); 45 } 46 47 48 /******************************************************************************* 49 * This function checks if a number is prime. 50 */ 51 bool isPrimeNumber(ulong n) { 52 if (n < 2) { 53 return false; 54 } 55 for (ulong i = 2; i <= n/2; ++i) { 56 if (n%i == 0) { 57 return false; 58 } 59 } 60 return true; 61 } 62 63 64 /******************************************************************************* 65 * Returns generator of Fibonacci numbers. 66 */ 67 FibonacciRange!T fibonacci(T=long)() 68 if (is(T : ulong)) { 69 return FibonacciRange!T(); 70 } 71 unittest { 72 import std.range : take; 73 import std.array : array; 74 auto fibSequence = array(take(fibonacci, 8)); 75 assert(fibSequence == [1, 1, 2, 3, 5, 8, 13, 21]); 76 } 77 78 79 80 /******************************************************************************* 81 * Range of Fibonacci numbers for the 'fibonacci' function. 82 */ 83 struct FibonacciRange(T) if (is(T : ulong)) { 84 private: 85 T prevValue = 0; 86 T currValue = 1; 87 88 public: 89 @property empty() const { 90 return false; 91 } 92 93 T popFront() { 94 currValue += prevValue; 95 prevValue = currValue - prevValue; 96 return prevValue; 97 } 98 99 T front() const { 100 return currValue; 101 } 102 } 103 104 105 /******************************************************************************* 106 * Logarithm. 107 */ 108 real logarithm(real b, real n) { 109 import std.math : log; 110 return log(b)/log(n); 111 } 112 unittest { 113 assert(logarithm(1024*1024, 1024) == 2); 114 }