diff options
| author | Chris Boesch <48591413+chrboesch@users.noreply.github.com> | 2022-09-29 20:42:56 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-09-29 21:42:56 +0300 |
| commit | 9c99a88796cb00a220b4d093f5f1a84339167ace (patch) | |
| tree | e256397b2db511b755892cf0463112d29bb0f47e /lib/std/math/gcd.zig | |
| parent | 36d2a5503705b4da03dab9dbf724653895d2b641 (diff) | |
| download | zig-9c99a88796cb00a220b4d093f5f1a84339167ace.tar.gz zig-9c99a88796cb00a220b4d093f5f1a84339167ace.zip | |
std.math: add "Greatest common divisor" (gcd)
Diffstat (limited to 'lib/std/math/gcd.zig')
| -rw-r--r-- | lib/std/math/gcd.zig | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/lib/std/math/gcd.zig b/lib/std/math/gcd.zig new file mode 100644 index 0000000000..298bf5fc2b --- /dev/null +++ b/lib/std/math/gcd.zig @@ -0,0 +1,48 @@ +//! Greatest common divisor (https://mathworld.wolfram.com/GreatestCommonDivisor.html) +const std = @import("std"); +const expectEqual = std.testing.expectEqual; + +/// Returns the greatest common divisor (GCD) of two unsigned integers (a and b) which are not both zero. +/// For example, the GCD of 8 and 12 is 4, that is, gcd(8, 12) == 4. +pub fn gcd(a: anytype, b: anytype) @TypeOf(a, b) { + + // only unsigned integers are allowed and not both must be zero + comptime switch (@typeInfo(@TypeOf(a, b))) { + .Int => |int| std.debug.assert(int.signedness == .unsigned), + .ComptimeInt => { + std.debug.assert(a >= 0); + std.debug.assert(b >= 0); + }, + else => unreachable, + }; + std.debug.assert(a != 0 or b != 0); + + // if one of them is zero, the other is returned + if (a == 0) return b; + if (b == 0) return a; + + // init vars + var x: @TypeOf(a, b) = a; + var y: @TypeOf(a, b) = b; + var m: @TypeOf(a, b) = a; + + // using the Euclidean algorithm (https://mathworld.wolfram.com/EuclideanAlgorithm.html) + while (y != 0) { + m = x % y; + x = y; + y = m; + } + return x; +} + +test "gcd" { + try expectEqual(gcd(0, 5), 5); + try expectEqual(gcd(5, 0), 5); + try expectEqual(gcd(8, 12), 4); + try expectEqual(gcd(12, 8), 4); + try expectEqual(gcd(33, 77), 11); + try expectEqual(gcd(77, 33), 11); + try expectEqual(gcd(49865, 69811), 9973); + try expectEqual(gcd(300_000, 2_300_000), 100_000); + try expectEqual(gcd(90000000_000_000_000_000_000, 2), 2); +} |
