I try to implement the Lucas–Lehmer test (LLT) primality test for Mersenne numbers (https://en.wikipedia.org/wiki/Lucas%E2%80%93Lehmer_primality_test). It should be polynomial and hence fast. Here is my code:
function countPrimeNumberWithDigits(numberOfDigits)
{
if(numberOfDigits < 1)
{return "Please give a valid input!";}
var shouldBeMoreThanThis = Math.pow(10, numberOfDigits-1), n = 3, M = countMWithIndex(n);
while(M < shouldBeMoreThanThis)
{
n += 2;
M = countMWithIndex(n);
}
console.log(n);
while(true)
{
var S = 4, k = 1;
M = countMWithIndex(n);
while(k != n - 1)
{
S = (S*S - 2)%M;
k +=1;
}
if(S!=0)
{n+=2;}
else
{break;}
}
return "Prime number: " + countMWithIndex(n);
}
function countMWithIndex(n)
{return Math.pow(2, n) - 1;}
Here is attempt to use the algorithm implemented above:
https://oobarbazanoo.github.io/findPrimeNumberWithSpecifiedQuantumOfDigits/
When I try number of digits which is less than 7 everything is okay, but when I try to ask for prime number with at least 7 digits the program just stumbles and doesn`t give an answer.
Please, help me. What is wrong with my algorithm implementation or what is wrong with my program itself?
If I run the code on https://repl.it/languages/javascript with this change:
S = (S*S - 2 + M)%M;
Then it finishes for (seemingly) any number of digits. However, the results seem incorrect: it outputs non-primes with more digits than requested.
The problem is that javascript can evaluate modulo to negative results. For example, -2 % 5 will be -2. This is mathematically correct, but most computer science algorithms require positive values, so 3 in this case.
Adding M in that formula will ensure that the result is positive regardless of language quirks.
The problem with incorrect results is likely due to the fact that you do not follow this requirement:
The Lucas–Lehmer test works as follows. Let Mp = 2**p − 1 be the Mersenne number to test with p an odd prime.
The p there is the n in your code. Nowhere do you ensure that n is prime.
Then there is also that javascript's integer type might not be big enough. With n larger than 23, it starts to reach its limits. For example, there is no Mersenne prime with 7 digits. The next is with 10 digits, which is 2**31 - 1.
You won't be able to find it in (pure) javascript however, because the computation involves squaring 2**31 - 1, which exceeds the bounds of javascript's integers.
Related
I am trying to count TRAILING zeros from a recursive manner. Basically I split the final recursive result and then created a var counter that will count all the zeros.
function countingZeros(n) {
if (n < 0) {
// Termination condition to prevent infinite recursion
return;
}
// Base case
if (n === 0) {
return 1;
}
// Recursive case
let final = n * countingZeros(n -1);
let counter = 0;
String(final).split('').forEach(function(item){
item === 0 ? counter++ : counter;
});
return counter;
}
countingZeros(12) // => suppose to output 2 since there are 2 trailing zeros from 479001600 but got 0
countingZeros(6) // => suppose to get 1 since 720 is the final result.
I am expecting to get 2 in return as the counter must return but instead I got 0. Any idea what am I missing on my function? How should I fix it?
I think you're working too hard. First of all, in response to a comment, you don't actually need to calculate the factorial, since all you really need is to count factors of 5 and of 2. And since there are many more factors of 2, your real answer is just counting factors of 5. But each factor of 5 must be a factor of one of {1, 2, 3, ... n}, so we just have to add up the highest powers of five that evenly divide into each of {1, 2, 3, ... n}.
We can do that with some simple recursion:
const fiveFactors = (n, acc = 0) => (n % 5 == 0)
? fiveFactors(n / 5, acc + 1)
: acc
const factZeros = (n, acc = 0) => (n > 0)
? factZeros(n - 1, acc + fiveFactors(n))
: acc
factZeros(1000) //=> 249
Note that both functions are eligible for tail-call optimization.
Also, although this does involve a double recursion, it's not really ill-performant. Four out of five times, the internal recursion stops on the first call, and of the remainder, four out of five stop on the second call, and so on.
You are trying to count the number of zeroes using string functions(i will assume, you forgot to include the factorial method. Correct flow could have been- you first pass the input to a factorial method and pass output from factorial method to countingZeros method). Anyways as stated already in other answer, you don't really need to calculate the factorial product to count the trailing zeroes.
Here a sample to count the number of trailing zeroes in n!
temp = 5;
zeroes = 0;
//counting the sum of multiples of 5,5^2,5^3....present in n!
while(n>=temp){
fives = n/temp;
zeroes = zeroes + fives;
temp = temp*5;
}
printf("%d",zeroes);
Note that each multiple of 5 in the factorial product will contribute 1 to the number of trailing zeros. On top of this, each multiple of 25 will contribute an additional 1 to the number of trailing zeros. Then, each multiple of 125 will contribute another 1 to the number of trailing zeros, and so on.
Here's a great link to understand the concept behind this:
https://brilliant.org/wiki/trailing-number-of-zeros/
I have a number and I need to round it down to the nearest power of ten. It seems like this should be possible without a whole bunch of if statements or using recursion or looping, but I don't know the most elegant way to do it. In case it's unclear what I mean, here are some examples:
f(1) === 1
f(5) === 1
f(15) === 10
f(43) === 10
f(456) === 100
f(999) === 100
To clarify: I do not need nearest multiple of 10 (not: 10, 20, 30...), but nearest power of ten (10, 100, 1000...).
Edit: To my knowledge this is not a duplicate question. Please stop closing as a duplicate of a question asking about rounding to the nearest multiple of ten. This question is unrelated to the linked question, because it asks about rounding to the nearest power of ten. If you would like to close this question as a duplicate, please find and link a duplicate question. The question which is currently linked was commented about 30 seconds after I posted the question, by someone who did not read the entire question and merely commented complaining about it being a duplicate. That person has since deleted his comments (after realizing he was wrong), although you can see comments by myself and someone else both pointing out that this is not a duplicate.
You could take the logarithm of 10 and take the integer value for the power of 10.
function f(v) {
return Math.pow(10, Math.floor(Math.log10(v)));
}
console.log(f(1)); // 1
console.log(f(5)); // 1
console.log(f(15)); // 10
console.log(f(43)); // 10
console.log(f(456)); // 100
console.log(f(999)); // 100
Simply get the length of the number(by converting Number into a string) and then generate the result by taking the power of 10(where the exponent is length - 1).
function generateNum(v) {
return Math.pow(10, v.toString().length - 1);
}
var data = [1, 5, 15, 43, 456, 456, 999];
data.forEach(function(v) {
console.log(generateNum(v));
})
function generateNum(v) {
return Math.pow(10, v.toString().length - 1);
}
FYI : In case number includes decimal part then you need to avoid decimal part by taking the floor value.
function generateNum(v) {
return Math.pow(10, Math.floor(v).toString().length - 1);
}
Here's a variant that works for negative numbers:
let round10 = v => Math.pow(10, Math.floor(Math.log10(Math.abs(v)))) * Math.pow(-1, v < 0);
You can do it in the following way
function f(num){
let count = 0;
while(num > 1){
count ++;
num/= 10;
}
return Math.pow(10, count-1) * (Math.round(num) ? 10: 1);
}
console.log(f(453));
f = n => +("1"+"0".repeat((""+n).length-1));
or:
f = n => +(""+n).split("").map((_,i)=>i?"0": "1").join("");
I have a factorial code but when it will find the result of the factorial it will get the result of the whole factorial.
Im looking for a code that finds the factorial of the last 5 factorials of a number? For example, 10! ? I need only the result of 10 x 9 x 8 x 7 x 6 = 30240? How do I do that?
<html>
<body>
<script type = "text/javascript">
var n = parseInt(window.prompt("Enter the Number:"));
var result = fact(n);
window.alert("Factorial of the given number " + result);
function fact(n)
{
if(n == 0)
return 1;
else
return (n*fact(n-1));
}
</script>
</body>
As MinusFour already noted: you want 10!/5!. You can do it that way and compute both values and divide. They divide exactly, no worry about fractions (proof omitted). But it is size-restricted, you cannot do e.g. 100!95! in JavaScript without a big-integer library and even with a big-integer library things like 1000000!/999998! will need a lot of computation time (both are numbers with over 5 million decimal digits).
My suggestion: no tricks, just compute it linearly like you would do it by hand:
function fact(n,k){
var t = 1;
for(var i = n;i>k;i--){
t *= i;
}
return t;
}
console.log(fact(10,5));
The first one must be the bigger one, both must be positive, all other checks and balances are omitted, too.
Is it possible to get the integers that, being results of powers of two, forms a value?
Example:
129 resolves [1, 128]
77 resolves [1, 4, 8, 64]
I already thought about using Math.log and doing also a foreach with a bitwise comparator. Is any other more beautiful solution?
The easiest way is to use a single bit value, starting with 1 and shift that bit 'left' until its value is greater than the value to check, comparing each bit step bitwise with the value. The bits that are set can be stored in an array.
function GetBits(value) {
var b = 1;
var res = [];
while (b <= value) {
if (b & value) res.push(b);
b <<= 1;
}
return res;
}
console.log(GetBits(129));
console.log(GetBits(77));
console.log(GetBits(255));
Since shifting the bit can be seen as a power of 2, you can push the current bit value directly into the result array.
Example
You can adapt solutions from other languages to javascript. In this SO question you'll find some ways of solving the problem using Java (you can choose the one you find more elegant).
decomposing a value into powers of two
I adapted one of those answers to javascript and come up with this code:
var powers = [], power = 0, n = 129;// Gives [1,128] as output.
while (n != 0) {
if ((n & 1) != 0) {
powers.push(1 << power);
}
++power;
n >>>= 1;
}
console.log(powers);
Fiddle
Find the largest power of two contained in the number.
Subtract from the original number and Add it to list.
Decrement the exponent and check if new 2's power is less than the number.
If less then subtract it from the original number and add it to list.
Otherwise go to step 3.
Exit when your number comes to 0.
I am thinking of creating a list of all power of 2 numbers <= your number, then use an addition- subtraction algorithm to find out the group of correct numbers.
For example number 77:
the group of factors is { 1,2,4,8,16,32,64} [ 64 is the greatest power of 2 less than or equal 77]
An algorithm that continuously subtract the greatest number less than or equal to your number from the group you just created, until you get zero.
77-64 = 13 ==> [64]
13-8 = 7 ==> [8]
7-4 = 3 ==> [4]
3-2 = 1 ==> [2]
1-1 = 0 ==> [1]
Hope you understand my algorithm, pardo my bad english.
function getBits(val, factor) {
factor = factor || 1;
if(val) {
return (val % 2 ? [factor] : []).concat(getBits(val>>1, factor*2))
}
return [];
}
alert(getBits(77));
When I try to do 8067 % 80.67 I get 80.66999999999983, instead of 0 beacuse of known floating point javascript behaviour.
So I went and made a function for this, to avoid floating point javascript errors.
function math(a, b) {
var left = Math.abs(a),
times = 1,
abs = a >= 0 ? 1 : -1;
while (Math.abs(a) >= b * times) {
left -= b;
times++;
}
return (a - (b * (times - 1))) * abs;
}
http://jsfiddle.net/s5w3C/
So my question is: is this usefull, ie a good tool to use instead of %? is there cases where this will also give falsy results like the modulus % oprator.
I am looking for a tools to calculate % consistently.
I didn't really inspect the algorithm for correctness, but if you care about efficiency, this is a bad idea. Basically, the larger the input, the slower your code will execute.
I think any fix will only work to a certain level of accuracy and for certain sized numbers. Perhaps something like the following will be sufficient:
function nearlyMod(a, b) {
var precision = ('' + b).split('.').length;
var estimate = (a % b).toFixed(precision);
return estimate == b ? 0 : +estimate;
}
console.log(nearlyMod(8067, 80.66)); // 1
console.log(nearlyMod(8067, 80.67)); // 0
console.log(nearlyMod(8067, 80.68)); // 79.68
It tests if the result is an even divisor within the precision of the original number. If so, it returns 0, otherwise it returns a number to the same precision (which may or may not be what you want).
The result is always a number (the value returned from toFixed is a string, hence +estimate).
A better name might be "roundedMod" or similar.