using System.Linq; using Developpez.Dotnet.Collections; namespace Developpez.Dotnet { /// /// Cette classe fournit des outils pour effectuer des calculs sur des grands nombres, /// au delà de la limite des 64 bits d'un Int64 /// public static class BigMath { /// /// Calcule le modulo (reste de la division entière) d'un grand nombre par /// un nombre /// /// Le grand nombre à diviser /// Le diviseur /// le modulo de la division public static ulong Modulo(string number, ulong k) { // Algorithme de calcul du modulo d'un grand nombre // Ai = (10^i) mod k, soit : // A0 = 1; A(i+1) = {Ai * 10} mod k // D = Sum(Di * (10^i), i = 0 to n) // D mod k = Sum(Di*Ai, i = 0 to n) mod k int n = number.Length; // Séquence Ai var A = Enumerable.Range(0, n) .Select(i => (ulong)i) .Scan( (ulong acc, ulong i) => i < 1 ? 1 : (acc * 10) % k ); // Séquence Di var D = number.ToCharArray() .Reverse() .Select(ch => ulong.Parse(ch.ToString())); var sum = EnumerableExtensions.Zip(D, A, (d, a) => d * a) .Aggregate((ulong)0, (s, p) => s + p); return sum % k; } } }