diff --git a/dist/primality.js b/dist/primality.js index b3fe171..c3fef3d 100644 --- a/dist/primality.js +++ b/dist/primality.js @@ -1,5 +1,5 @@ /*! - * primality v1.5.5 + * primality v1.5.6 * (c) 2012–2013 Kenan Yildirim * * Includes functions from Lo-Dash @@ -93,6 +93,24 @@ var primality; var WILSON_PRIMES = [ 5, 13, 563 ]; var _ = require("./lib/util/"); + function factorial(value) { + return value === 0 ? 1 : value * factorial(value - 1); + } + function mod(x, y) { + if (y > 0) { + if (x > 0) { + return x % y; + } else if (x == 0) { + return 0; + } else { + return x - y * Math.floor(x / y); + } + } else if (y == 0) { + return x; + } else { + throw new Error("Cannot calculate mod for a negative divisor"); + } + } function leastFactor(n) { if (n === 0) return 0; else if (n % 1 || n * n < 2) return 1; else if (n % 2 === 0) return 2; else if (n % 3 === 0) return 3; else if (n % 5 === 0) return 5; var m = Math.sqrt(n); @@ -138,8 +156,8 @@ if (!primality([ a, b ])) return false; return true; } - function isWilsonPrime(a) { - return _.contains(WILSON_PRIMES, a); + function isWilsonPrime(value) { + return _.contains(WILSON_PRIMES, value) ? true : 0 === (mod(factorial(value - 1) + 1, value) === 0); } primality.VERSION = "1.4.0"; primality.areTwinPrimes = areTwinPrimes; diff --git a/dist/primality.min.js b/dist/primality.min.js index 3255967..1b3aba3 100644 --- a/dist/primality.min.js +++ b/dist/primality.min.js @@ -1,5 +1,5 @@ /*! - * primality v1.5.5 + * primality v1.5.6 * (c) 2012–2013 Kenan Yildirim * * Includes functions from Lo-Dash @@ -9,9 +9,10 @@ */ !function(a){function b(a,c,d){var e=b.resolve(a);if(null==e){d=d||a,c=c||"root";var f=Error('Failed to require "'+d+'" from "'+c+'"');throw f.path=d,f.parent=c,f.require=!0,f}var g=b.modules[e];return g.exports||(g.exports={},g.client=g.component=!0,g.call(this,g.exports,b.relative(e),g)),g.exports}b.modules={},b.aliases={},b.resolve=function(a){"/"===a.charAt(0)&&(a=a.slice(1));for(var c=[a,a+".js",a+".json",a+"/index.js",a+"/index.json"],d=0;d-1}Math.max,c.exports=e}),b.register("primality/lib/util/isArray.js",function(a,b,c){var d=RegExp("^"+(Object.prototype.valueOf+"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),e=d.test(e=Array.isArray)&&e,f=e||function(a){return a?"object"==typeof a&&toString.call(a)==arrayClass:!1};c.exports=f -}),b.register("primality/lib/util/isFinite.js",function(b,c,d){function e(a){return h(a)&&!i(parseFloat(a))}var f={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},g=f[typeof global]&&global;!g||g.global!==g&&g.window!==g||(a=g);var h=a.isFinite,i=a.isNaN;d.exports=e}),b.register("primality/lib/util/isNaN.js",function(a,b,c){function d(a){return"number"==typeof a||f.call(a)==g}function e(a){return d(a)&&a!=+a}var f=Object.prototype.toString,g="[object Number]";c.exports=e}),b.alias("primality/primality.js","primality/index.js"); -var c={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},d=c[typeof exports]&&exports,e=c[typeof module]&&module&&module.exports==d&&module,f=c[typeof global]&&global;!f||f.global!==f&&f.window!==f||(a=f),"function"==typeof define&&"object"==typeof define.amd&&define.amd?(a.primality=b("primality"),define(function(){return b("primality")})):d&&!d.nodeType?e?(e.exports=b("primality")).primality=b("primality"):d.primality=b("primality"):a.primality=b("primality")}(this); \ No newline at end of file +return-1}function d(c){var e=d.resolve(c);return b(e,a,c)}var e=b.normalize(a,"..");return d.resolve=function(d){var f=d.charAt(0);if("/"==f)return d.slice(1);if("."==f)return b.normalize(e,d);var g=a.split("/"),h=c(g,"deps")+1;return h||(h=0),d=g.slice(0,h+1).join("/")+"/deps/"+d},d.exists=function(a){return b.modules.hasOwnProperty(d.resolve(a))},d},b.register("primality/primality.js",function(a,b,c){function d(a){return 0===a?1:a*d(a-1)}function e(a,b){if(b>0)return a>0?a%b:0==a?0:a-b*Math.floor(a/b); +if(0==b)return a;throw Error("Cannot calculate mod for a negative divisor")}function f(a){if(0===a)return 0;if(a%1||a*a<2)return 1;if(0===a%2)return 2;if(0===a%3)return 3;if(0===a%5)return 5;for(var b=Math.sqrt(a),c=7;c<=b;c+=30){if(0===a%c)return c;if(0===a%(c+4))return c+4;if(0===a%(c+6))return c+6;if(0===a%(c+10))return c+10;if(0===a%(c+12))return c+12;if(0===a%(c+16))return c+16;if(0===a%(c+22))return c+22;if(0===a%(c+24))return c+24}return a}function g(a){return n.isNaN(a)||!n.isFinite(a)||a%1||a<2?!1:a!==f(a)?!1:!0 +}function h(a,b){return 2!=Math.abs(a-b)?!1:l([a,b])?!0:!1}function i(a,b){return 4!=Math.abs(a-b)?!1:l([a,b])?!0:!1}function j(a,b){return 6!=Math.abs(a-b)?!1:l([a,b])?!0:!1}function k(a){return n.contains(m,a)?!0:0===(0===e(d(a-1)+1,a))}var l,m=[5,13,563],n=b("./lib/util/");l=function(a){if(null===a||""===a)return null;if(n.isArray(a)){for(var b=0,c=a.length;b-1}Math.max,c.exports=e}),b.register("primality/lib/util/isArray.js",function(a,b,c){var d=RegExp("^"+(Object.prototype.valueOf+"").replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/valueOf|for [^\]]+/g,".+?")+"$"),e=d.test(e=Array.isArray)&&e,f=e||function(a){return a?"object"==typeof a&&toString.call(a)==arrayClass:!1 +};c.exports=f}),b.register("primality/lib/util/isFinite.js",function(b,c,d){function e(a){return h(a)&&!i(parseFloat(a))}var f={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},g=f[typeof global]&&global;!g||g.global!==g&&g.window!==g||(a=g);var h=a.isFinite,i=a.isNaN;d.exports=e}),b.register("primality/lib/util/isNaN.js",function(a,b,c){function d(a){return"number"==typeof a||f.call(a)==g}function e(a){return d(a)&&a!=+a}var f=Object.prototype.toString,g="[object Number]";c.exports=e +}),b.alias("primality/primality.js","primality/index.js");var c={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},d=c[typeof exports]&&exports,e=c[typeof module]&&module&&module.exports==d&&module,f=c[typeof global]&&global;!f||f.global!==f&&f.window!==f||(a=f),"function"==typeof define&&"object"==typeof define.amd&&define.amd?(a.primality=b("primality"),define(function(){return b("primality")})):d&&!d.nodeType?e?(e.exports=b("primality")).primality=b("primality"):d.primality=b("primality"):a.primality=b("primality") +}(this); \ No newline at end of file diff --git a/primality.js b/primality.js index 6b74bc6..5255c84 100644 --- a/primality.js +++ b/primality.js @@ -13,6 +13,45 @@ var WILSON_PRIMES = [5, 13, 563]; var _ = require('./lib/util/'); +/** + * Returns the factorial of `value` + * + * @private + * @param {Number} value + * @returns {Number} The factorial of `value`. + */ +function factorial(value) { + return value === 0 ? 1 : value * factorial(value - 1); +} + +/** + * Returns the modulus of two numbers. + * + * @param {Number} x + * @param {Number} y + * @returns {number} res + * @private + */ +function mod(x, y) { + if (y > 0) { + if (x > 0) { + return x % y; + } + else if (x == 0) { + return 0; + } + else { + return x - y * Math.floor(x / y); + } + } + else if (y == 0) { + return x; + } + else { + throw new Error('Cannot calculate mod for a negative divisor'); + } +} + /** * Finds the smallest factor of `n` * @@ -153,21 +192,23 @@ function areSexyPrimes(a, b) { } /** - * Checks if `a` is a Wilson prime. + * Checks if `value` is a Wilson prime. * * * * @static * @memberOf primality - * @param {Number} a - * @returns {Boolean} Returns `true` if `a` is a Wilson prime. + * @param {Number} value + * @returns {Boolean} Returns `true` if `value` is a Wilson prime. * @example * * primality.isWilsonPrime(5); * // => true */ -function isWilsonPrime(a) { - return _.contains(WILSON_PRIMES, a); +function isWilsonPrime(value) { + return _.contains(WILSON_PRIMES, value) + ? true + : 0 === (mod(factorial(value - 1) + 1, value) === 0); } /** diff --git a/test/spec/suite.js b/test/spec/suite.js index f004825..51b80c4 100644 --- a/test/spec/suite.js +++ b/test/spec/suite.js @@ -54,7 +54,7 @@ define(['../../dist/primality'], function(primality) { primality.isWilsonPrime(5).should.equal(true); primality.isWilsonPrime(13).should.equal(true); primality.isWilsonPrime(563).should.equal(true); - primality.isWilsonPrime(564).should.equal(false); + primality.isWilsonPrime(1000).should.equal(false); }); }); });