There's an existing question / answer that deals with implementing probability in JavaScript, but I've read and re-read that answer and don't understand how it works (for my purpose) or how a simpler version of probability would look.
My goal is to do:
function probability(n){
// return true / false based on probability of n / 100
}
if(probability(70)){ // -> ~70% likely to be true
//do something
}
What's the simple way to achieve this?
You could do something like...
var probability = function(n) {
return !!n && Math.random() <= n;
};
Then call it with probability(.7). It works because Math.random() returns a number between and inclusive of 0 and 1 (see comment).
If you must use 70, simply divide it over 100 in the body of your function.
Function Probability:
probability(n){
return Math.random() < n;
}
// Example, for a 75% probability
if(probability(0.75)){
// Code to run if success
}
If we read about Math.random(), it will return a number in the [0;1) interval, which includes 0 but exclude 1, so to keep an even distribution, we need to exclude the top limit, that to say, using < and not <=.
Checking the upper and the lower bound probability (which are 0% or 100%):
We know that 0 ≤ Math.random() < 1 so, for a:
Probability of 0% (when n === 0, it should always returning false):
Math.random() < 0 // That actually will always return always false => Ok
Probability of 100% (when n === 1, it should always returning true):
Math.random() < 1 // That actually will always return always true => Ok
Running test of the probability function
// Function Probability
function probability(n){
return Math.random() < n;
}
// Running test with a probability of 86% (for 10 000 000 iterations)
var x = 0;
var prob = 0.86;
for(let i = 0; i < 10000000; i++){
if(probability(prob)){
x += 1;
}
}
console.log(`${x} of 10000000 given results by "Math.random()" were under ${prob}`);
console.log(`Hence so, a probability of ${x / 100000} %`);
This is even more simple :
function probability(n) {
return Math.random() <= n;
}
Related
Based on mdn Math.random() can return 0 but can not return 1
The Math.random() static method returns a floating-point, pseudo-random number that's greater than or equal to 0 and less than 1
I tried to loop Math.random() to get 10 number below e-10 and it takes 15 minutes to complete it with my 4 cores 8 threads cpu and from that 10 numbers 0 never get returned. Is my test case just too small or latest javascript Math.random() can never return 0?
note: I run the code using node.js v18.12.1 and the smallest number ever returned is 5.2724491439448684e-12 (yes its small, but it isn't 0)
let countSmallNumber = 0;
let temp = 0;
console.time("loopTime");
while (countSmallNumber < 10) {
temp = Math.random();
if (temp < 0.0000000001) {
countSmallNumber++;
console.log(`almost 0 => ${temp}`);
}
}
console.timeEnd("loopTime");
The problem is: Print out how much odd numbers there are in a given number.
function oddCount(n) {
var odd = [];
for (i = 0; i < n; i++) {
if (i % 2 == 1) {
odd.push([i]);
}
}
return odd.length;
}
console.log(oddCount(8));
As we can see, it works properly, however, on codewars, it wants me to optimize it to run faster. Can someone show me how so I can learn it quickly please.
function oddCount(n) {
var odd = [];
for (i = 0; i < n; i++) {
if (i & 0x1 == 1) {
odd.push([i]);
}
}
return odd.length;
}
console.log(oddCount(8));
or
function oddCount(n) {
return (n - (n & 0x01)) / 2;
}
console.log(oddCount(8));
Neither "ceil" or "floor" is a correct answer as a one liner. "ceil" will make the division Base 1, "floor" will make the division Base 0. So both could be used in an implementation, but the "polarity" of n matters.
It's necessary to check whether the input number is odd or even.
function oddCount(n) {
// odd / even check
if (n % 2 == 0) {
// its even, we can divide by 2
return n / 2
}
else {
// n is odd, so we must include n as a count+1 itself
return ((n - 1) / 2) + 1
}
}
// Disclaimer: Are negative numbers odd or even? In this code they
// apparently aren't handled. So the set of numbers are integers from
// 0 to +Infinity
// Test cases:
console.log( oddCount(8) ); // 4
console.log( oddCount(9) ); // 5
But this code "breaks" if n itself is 0 or less. So we need to fix it:
Right after we say function oddCount(n) {, put:
if (n < 1) return 0;
All worries solved. But still debate on whether 0 is odd or even, and whether -1 is odd and -2 is even.
I believe this should work.
function oddCount(n) {
return Math.ceil(n/2);
}
console.log(oddCount(8));
If the number is an even number, there's n/2 odd numbers
Eg if n is 6
*1*,2,*3*,4,*5*,6
If it is an odd number, there's n/2+1 odd numbers. Because n-1 would be even
Eg if n is 5
*1*,2,*3*,4, + *5*
So basically
if (n%2==0) return n/2
else return (n-1)/2+1
The for loops aren't needed
Also like the others pointed out, ceiling is a more concise way to do it
return Math.ceil(n/2)
I have written the function which finds largest prime factor of some number. This function works but the problem is that it is too slow. e.g when I enter 600851475143 as a parameter, the process of finding largest prime factor lasts too long. How can I modify it so that it works faster?
Here is my code:
class test {
static addArray(someArray, member) {
for (var i = 0; i <= someArray.length; i++) {
if (i == someArray.length) {
someArray[i] = member;
return someArray;
}
}
}
static someLength(someArray) {
var i = 0;
while (someArray[i] !== undefined) {
var lastItem = i;
i++;
}
return i;
}
static testPrime(i) {
for (var k=2; k < i; k++) {
if (i % k == 0) {
return false;
}
}
return true;
}
}
var primeArray = [];
function largestPrime(n) {
for (var i=2; i < n; i++) {
//var k = n / i;
if (n % i == 0 && test.testPrime(i) == true) {
test.addArray(primeArray, i);
n == n / i;
}
}
return primeArray[test.someLength(primeArray) - 1];
}
document.write(largestPrime(600851475143));
Alright, before we go into that, let's get a little bit of theory sorted. The way you measure the time a particular piece of code takes to run is, mathematically, denoted by the O(n) notation (big-o notation) where n is the size of the input.
Your test prime function is of something called linear complexity meaning that it'll become linearly slow as the size of n (in this case, your number input) gets large.
For the number 15, the execution context is as follows:
15 % 2 == 0 (FALSE)
15 % 3 == 0 (TRUE)
...
15 % 14 == 0 (FALSE)
This means that for the number 100, there will be 98 (2 - 99) steps. And this will grow with time. Let's take your number into consideration: 600851475143. The program will execute 600851475143; the for-loop will get triggered 600,851,475,141 times.
Now, let's consider a clock cycle. Say each instruction takes 1 clock cycle, and a dumbed down version of your loop takes 2, the number 600851475143 will execute 1,201,702,950,286 times. Consider each clock cycle takes 0.0000000625 seconds (for a 16-MHz platform such as the Arduino), the time taken by that code alone is:
0.0000000625 * 1201702950286 = ~75,106 seconds
Or around 20 hours.
You see where I am going with this.
Your best best to get this program to work faster is to use a probabilistic test and confirm your findings using this number (or a BigInteger variant thereof).
Your approach is more linear, in the sense that the number of iterations for the for-loop to check for primality increases with an increasing number. You can plot the CPU cycle time along with the number and you'll realize that this is a rather inefficient way to do this.
I have discrete mathematics at my Uni, so just a word of warning - primality tests and their variants get really messy as you get into the utopia of faster and faster tests. It's a path filled with thorns of mathematics and you should have a seat belt while riding through the jungle! ;)
If you need more information on this, I would be glad to assist! I hope this helped! :)
I'm trying to solve all the lessons on codility but I failed to do so on the following problem: Ladder by codility
I've searched all over the internet and I'm not finding a answer that satisfies me because no one answers why the max variable impacts so much the result.
So, before posting the code, I'll explain the thinking.
By looking at it I didn't need much time to understand that the total number of combinations it's a Fibonacci number, and removing the 0 from the Fibonacci array, I'd find the answer really fast.
Now, afterwards, they told that we should return the number of combinations modulus 2^B[i].
So far so good, and I decided to submit it without the var max, then I got a score of 37%.. I searched all over the internet and the 100% result was similar to mine but they added that max = Math.pow(2,30).
Can anyone explain to me how and why that max influences so much the score?
My Code:
// Powers 2 to num
function pow(num){
return Math.pow(2,num);
}
// Returns a array with all fibonacci numbers except for 0
function fibArray(num){
// const max = pow(30); -> Adding this max to the fibonaccy array makes the answer be 100%
const arr = [0,1,1];
let current = 2;
while(current<=num){
current++;
// next = arr[current-1]+arr[current-2] % max;
next = arr[current-1]+arr[current-2]; // Without this max it's 30 %
arr.push(next);
}
arr.shift(); // remove 0
return arr;
}
function solution(A, B) {
let f = fibArray(A.length + 1);
let res = new Array(A.length);
for (let i = 0; i < A.length; ++i) {
res[i] = f[A[i]] % (pow(B[i]));
}
return res;
}
console.log(solution([4,4,5,5,1],[3,2,4,3,1])); //5,1,8,0,1
// Note that the console.log wont differ in this solution having max set or not.
// Running the exercise on Codility shows the full log with all details
// of where it passed and where it failed.
The limits for input parameters are:
Assume that:
L is an integer within the range [1..50,000];
each element of array A is an integer within the range [1..L];
each element of array B is an integer within the range [1..30].
So the array f in fibArray can be 50,001 long.
Fibonacci numbers grow exponentially; according to this page, the 50,000th Fib number has over 10,000 digits.
Javascript does not have built-in support for arbitrary precision integers, and even doubles only offer ~14 s.f. of precision. So with your modified code, you will get "garbage" values for any significant value of L. This is why you only got 30%.
But why is max necessary? Modulo math tells us that:
(a + b) % c = ([a % c] + [b % c]) % c
So by applying % max to the iterative calculation step arr[current-1] + arr[current-2], every element in fibArray becomes its corresponding Fib number mod max, without any variable exceeding the value of max (or built-in integer types) at any time:
fibArray[2] = (fibArray[1] + fibArray[0]) % max = (F1 + F0) % max = F2 % max
fibArray[3] = (F2 % max + F1) % max = (F2 + F1) % max = F3 % max
fibArray[4] = (F3 % max + F2 % max) = (F3 + F2) % max = F4 % max
and so on ...
(Fn is the n-th Fib number)
Note that as B[i] will never exceed 30, pow(2, B[i]) <= max; therefore, since max is always divisible by pow(2, B[i]), applying % max does not affect the final result.
Here is a python 100% answer that I hope offers an explanation :-)
In a nutshell; modulus % is similar to 'bitwise and' & for certain numbers.
eg any number % 10 is equivalent to the right most digit.
284%10 = 4
1994%10 = 4
FACTS OF LIFE:
for multiples of 2 -> X % Y is equivalent to X & ( Y - 1 )
precomputing (2**i)-1 for i in range(1, 31) is faster than computing everything in B when super large arrays are given as args for this particular lesson.
Thus fib(A[i]) & pb[B[i]] will be faster to compute than an X % Y style thingy.
https://app.codility.com/demo/results/trainingEXWWGY-UUR/
And for completeness the code is here.
https://github.com/niall-oc/things/blob/master/codility/ladder.py
Here is my explanation and solution in C++:
Compute the first L fibonacci numbers. Each calculation needs modulo 2^30 because the 50000th fibonacci number cannot be stored even in long double, it is so big. Since INT_MAX is 2^31, the summary of previously modulo'd numbers by 2^30 cannot exceed that. Therefore, we do not need to have bigger store and/or casting.
Go through the arrays executing the lookup and modulos. We can be sure this gives the correct result since modulo 2^30 does not take any information away. E.g. modulo 100 does not take away any information for subsequent modulo 10.
vector<int> solution(vector<int> &A, vector<int> &B)
{
const int L = A.size();
vector<int> fibonacci_numbers(L, 1);
fibonacci_numbers[1] = 2;
static const int pow_2_30 = pow(2, 30);
for (int i = 2; i < L; ++i) {
fibonacci_numbers[i] = (fibonacci_numbers[i - 1] + fibonacci_numbers[i - 2]) % pow_2_30;
}
vector<int> consecutive_answers(L, 0);
for (int i = 0; i < L; ++i) {
consecutive_answers[i] = fibonacci_numbers[A[i] - 1] % static_cast<int>(pow(2, B[i]));
}
return consecutive_answers;
}
I've been trying to write code that multiplies even indexed elements of an array by 2 and odd indexed elements by 3.
I have the following numbers stored in the variable number, which represents an array of numbers
numbers = [1,7,9,21,32,77];
Even Indexed Numbers - 1,9,32
Odd Indexed Numbers - 7, 21, 77
Please keep in mind that arrays are Zero Indexed, which means the numbering starts at 0. In which case, the 0-Indexed element is actually 1, and the 1-Indexed element is 7.
This is what I expected the output to be
[2,21,18,63,64,231]
Unfortunately, I got this output
[2,14,17,42,64,154]
Here is the code for my method
numbers = numbers.map(function(x) {
n = 0;
while (n < numbers.length) {
if (n % 2 == 0) {
return x * 2;
}
else {
return x * 3;
}
n++;
}});
return numbers;
Here I created a while loop, that executes code for every iteration of the variable n. For every value of the variable n, I'm checking if n is even, which is used by the code n % 2 == 0. While it's true that 0 % 2 == 0 it's not true that 1 % 2 == 0. I'm incrementing n at the end of the while loop, so I don't understand why I received the output I did.
Any help will be appreciated.
You created a global property called n, by doing
n = 0;
and then,
while (n < numbers.length) {
if (n % 2 == 0) {
return x * 2;
} else {
return x * 3;
}
}
n++; // Unreachable
you always return immediately. So the, n++ is never incremented. So, n remains 0 always and so all the elements are multiplied by 2 always.
The Array.prototype.map's callback function's, second parameter is the index itself. So, the correct way to use map is, like this
numbers.map(function(currentNumber, index) {
if (index % 2 === 0) {
return currentNumber * 2;
} else {
return currentNumber * 3;
}
});
The same can be written succinctly, with the ternary operator, like this
numbers.map(function(currentNumber, index) {
return currentNumber * (index % 2 === 0 ? 2 : 3);
});
To complement the other answer, the source of OP's confusion is on how "map" works. The map function is already called for each element - yet, OP attempted to use a while loop inside it, which is another way to iterate through each element. That is a double interaction, so, in essence, if OP's code worked, it would still be modifying each number n times! Usually, you just chose between a loop or map:
Using a loop:
var numbers = [1,7,9,21,32,77];
for (var i=0; i<numbers.length; ++i)
numbers[i] = i % 2 === 0 ? numbers[i] * 2 : numbers[i] * 3;
Using map:
var numbers = [1,7,9,21,32,77];
numbers.map(function(number, index){
return number * (index % 2 === 0 ? 2 : 3);
});
Or, very briefly:
[1,7,9,21,32,77].map(function(n,i){ return n * [2,3][i%2]; });
Basically you want to return a modified array that if the elements of the initial one is:
in even position, then multiply the element by 2.
in odd position, then multiply the element by 3.
You can use map with arrow functions and the conditional (ternary) operator to get this one-liner
console.log([1,7,9,21,32,77].map((num,ind) => num * (ind % 2 === 0 ? 2 : 3)));
This will output the desired
[2, 21, 18, 63, 64, 231]