Number of combinations in a given number array in javascript - javascript

var ans = (49*48*47*46*45*44)/(6*5*4*3*2*1)
alert(ans.toLocaleString())
This will output 13,983,816 and it's the correct number of possible combinations from a number array of 1 to 49.
How do I implement this with numbers that I can get from 2 variables?
For example if I want to calculate the number of combinations possible for 5 numbers out of 40 I need to have (40*39*38*37*36)/(5*4*3*2*1) and I need this to be replaced like: 40*39*38*37*36 with var n and (5*4*3*2*1) with var t but output the correct order of numbers.
Just to be clear, I don't want to write these operations manually in the variables, I want the number specified in the variables to generate the operations based on their value. If I specify 6 selections I need to generate 6*5*4*3*2*1, if I specify 5 selections it needs to generate 5*4*3*2*1 and so on.
Thanks for the help!

Updated, (with loops):
Number.prototype.to = function(to){
var result = 1;
while(this >= to) result *= to++;
return result
};
var n = 49..to(44); //49*48*47*46*45*44
var t = 6..to(1); //6*5*4*3*2*1
document.writeln((n/t).toLocaleString())

You can try for loops:
function binom(a,b) {
if(a < 2*b) b = a-b;
var n = 1;
for(var i=a-b+1; i<=a; ++i) n *= i;
for(var i=2; i<=b; ++i) n /= i;
return n;
}

Nevermind, I managed to figure it out after some good hours:
function getChance(numbers, out_of) {
return numbers>0?out_of/numbers*getChance(numbers-1,out_of-1):1;
}
var np = 6; //numbers picked
var tn = 49; //total numbers
var ntm = 6; //numbers to match
var picks = getChance(np-ntm, tn-ntm);
var combs = getChance(np, tn);
var probs = combs/picks;
document.getElementById('chance').innerHTML = (probs | 0).toLocaleString();

Related

Seperate Digits of Positive Integer in JS using while loop without string/array

I am trying to run a program that, upon receiving a positive integer, splits it into its separate digits like so. Number is 652, output is 2, 5, 6. There is supposed to no arrays and I can't make the number a string. I've written most of the code but it's missing something that I can't figure out. The issue is really that I don't know how to store the numbers to be output during iterations. Would appreciate any help. I am using a while loop but for loop could be used as well.
function problem_09() {
var outputObj=document.getElementById("output");
var a = parseInt(prompt("Please enter a number: ", ""));
var i = 0;
var digits = ;
outputObj.innerHTML="number: "+a+"<br><br>its digits: ";
while (a>0) {
digits[i]= a%10;
a = Math.floor(a/10);
i++;
}
outputObj.innerHTML=digits;
outputObj.innerHTML=outputObj.innerHTML+"<br><br>"+"program ended";
document.getElementsByTagName("button")[0].setAttribute("disabled","true");
}
I know the issue lies with the digits and the i but I don't know how to fix it.
You could take a place value and multiply by 10 for each iteration.
function getDigits(value) {
var place = 1;
while (value >= place) {
console.log(Math.floor(value / place) % 10);
place *= 10;
}
}
getDigits(652);
getDigits(100);
A solution without using Math.floor(...)
function getDigits(n) {
var res = [];
while (n > 0) {
var r = n % 10,
d = n - r,
curr = d / 10;
n = curr;
res.push(r);
}
return res;
}
var n = prompt("Enter a number: "),
output = document.getElementById("output");
output.textContent = getDigits(+n);
<div id="output"></div>
then just to replace
var i = 0;
var digits = [];
while (a > 0) {
digits.push(a % 10);
a = Math.floor(a/10);
i++;
}
the question does not make really sense.. without arrays, but he is actually expecting the result to be an array...

javascript string algorithm

Let's say I have a string variable called myString, and another string variable called myChar.
var myString = "batuhan"; // it's user input.
var myChar = "0"; // will be one character, always
What I need is, a function that returns all the combinations of myString and myChar.
Like:
"batuhan","batuha0n","batuh0an","batuh0a0n","batu0han","batu0ha0n","batu0h0an","batu0h0a0n","bat0uhan","bat0uha0n","bat0uh0an","bat0uh0a0n","bat0u0han","bat0u0ha0n","bat0u0h0an","bat0u0h0a0n","ba0tuhan","ba0tuha0n","ba0tuh0an","ba0tuh0a0n","ba0tu0han","ba0tu0ha0n","ba0tu0h0an","ba0tu0h0a0n","ba0t0uhan","ba0t0uha0n","ba0t0uh0an","ba0t0uh0a0n","ba0t0u0han","ba0t0u0ha0n","ba0t0u0h0an","ba0t0u0h0a0n","b0atuhan","b0atuha0n","b0atuh0an","b0atuh0a0n","b0atu0han","b0atu0ha0n","b0atu0h0an","b0atu0h0a0n","b0at0uhan","b0at0uha0n","b0at0uh0an","b0at0uh0a0n","b0at0u0han","b0at0u0ha0n","b0at0u0h0an","b0at0u0h0a0n","b0a0tuhan","b0a0tuha0n","b0a0tuh0an","b0a0tuh0a0n","b0a0tu0han","b0a0tu0ha0n","b0a0tu0h0an","b0a0tu0h0a0n","b0a0t0uhan","b0a0t0uha0n","b0a0t0uh0an","b0a0t0uh0a0n","b0a0t0u0han","b0a0t0u0ha0n","b0a0t0u0h0an","b0a0t0u0h0a0n"
Rules: myChar shouldn't follow myChar
How can I do that? Really my brain dead right now :/
It's possible to implement what you want using recursion.
// Example: allCombinations("abcd", "0") returns the array
// ["abcd", "abc0d", "ab0cd", "ab0c0d", "a0bcd", "a0bc0d", "a0b0cd", "a0b0c0d"]
function allCombinations(str, chr) {
if (str.length == 1)
return [str];
var arr = allCombinations(str.substring(1), chr);
var result = [];
var c = str.charAt(0);
for (var i = 0; i < arr.length; i++)
result.push(c + arr[i]);
for (var i = 0; i < arr.length; i++)
result.push(c + chr + arr[i]);
return result;
}
You may or may not have noticed this but this is basically counting in binary. If we define bit 0 to be the absence of myChar and bit 1 to be the presence of myChar, then the following sequence:
var myString = ".....";
var myChar = "1";
var sequence = [
".....1",
"....1.",
"....1.1",
"...1.."
];
is basically counting from 1 to 4 in binary:
var sequence = [
0b0000001,
0b0000010,
0b0000011,
0b0000100
];
Therefore, all you need is a for loop to count up to the bit amount of the length of the string plus 1 (because the position at the end of the string is also legal):
var len = Math.pow(2,myString.length+1);
for (var x = 0; x < len; x++) {
// x in binary is all the possible combinations
// now use the "1" bits in x to modify the string:
// Convert myString to array for easy processing:
var arr = myString.split('');
arr.push(""); // last position;
for (var i = myString.length; i >= 0; i--) {
if ((x >> i) & 0x01) { // check if bit at position i is 1
arr[i] = myChar + arr[i];
}
}
console.log(arr.join('')); // print out one combination
}
Of course, this works only for small strings of up to 31 characters. For larger strings you'd need to do the binary counting using things other than numbers. Doing it in a string form is one option. Another option is to use a bigint library such as BigInteger.js to do the counting.

Finding Products within large Digits

I have been working on a way to find products of 5 digits within a large number. For example, I have the number 158293846502992387489496092739449602783 And I want to take the first 5 digits (1,5,8,2,9) and multiply them, then the second, (5,8,2,9,3), multiply then, then the third... And so on. Then I want to find the largest of all of them I find, now I came up with the following code to solve this problem:
// I put the digit into a string so I can modify certain parts.
var digit = "158293846502992387489496092739449602783";
var digitLength = digit.length;
var max = 0;
var tempHolder;
var tempDigit = 0;
var tempArray = [];
for(var i = 0; i<=digitLength; i++){
tempHolder = digit.substring(i, i+5);
tempArray = tempHolder.split("");
for(var j = 0; j < 5; j++){
tempDigit += tempArray[j];
}
if(tempDigit > max){
max = tempDigit;
}
}
console.log(max);
It logs to the console A longer number than what I put into it, along with 10 undefined, no spaces. Can anyone figure out the problem here?

Javascript generate random unique number every time

Ok so i need to create four randomly generated numbers between 1-10 and they cannot be the same. so my thought is to add each number to an array but how can I check to see if the number is in the array, and if it is, re-generate the number and if it isnt add the new number to the array?
so basically it will go,
1.create new number and add to array
2.create second new number, check to see if it exist already, if it doesn't exist, add to array. If it does exist, re-create new number, check again etc...
3.same as above and so on.
You want what is called a 'random grab bag'. Consider you have a 'bag' of numbers, each number is only represented once in this bag. You take the numbers out, at random, for as many as you need.
The problem with some of the other solutions presented here is that they randomly generate the number, and check to see if it was already used. This will take longer and longer to complete (theoretically up to an infinite amount of time) because you are waiting for the random() function to return a value you don't already have (and it doesn't have to do that, it could give you 1-9 forever, but never return 10).
There are a lot of ways to implement a grab-bag type solution, each with varying degrees of cost (though, if done correctly, won't ever be infinite).
The most basic solution to your problem would be the following:
var grabBag = [1,2,3,4,5,6,7,8,9,10];
// randomize order of elements with a sort function that randomly returns -1/0/1
grabBag.sort(function(xx,yy){ return Math.floor(Math.random() * 3) - 1; })
function getNextRandom(){
return grabBag.shift();
};
var originalLength = grabBag.length;
for(var i = 0; i < originalLength; i++){
console.log(getNextRandom());
}
This is of course destructive to the original grabBag array. And I'm not sure how 'truly random' that sort is, but for many applications it could be 'good enough'.
An slightly different approach would be to store all the unused elements in an array, randomly select an index, and then remove the element at that index. The cost here is how frequently you are creating/destroying arrays each time you remove an element.
Here are a couple versions using Matt's grabBag technique:
function getRandoms(numPicks) {
var nums = [1,2,3,4,5,6,7,8,9,10];
var selections = [];
// randomly pick one from the array
for (var i = 0; i < numPicks; i++) {
var index = Math.floor(Math.random() * nums.length);
selections.push(nums[index]);
nums.splice(index, 1);
}
return(selections);
}
You can see it work here: http://jsfiddle.net/jfriend00/b3MF3/.
And, here's a version that lets you pass in the range you want to cover:
function getRandoms(numPicks, low, high) {
var len = high - low + 1;
var nums = new Array(len);
var selections = [], i;
// initialize the array
for (i = 0; i < len; i++) {
nums[i] = i + low;
}
// randomly pick one from the array
for (var i = 0; i < numPicks; i++) {
var index = Math.floor(Math.random() * nums.length);
selections.push(nums[index]);
nums.splice(index, 1);
}
return(selections);
}
And a fiddle for that one: http://jsfiddle.net/jfriend00/UXnGB/
Use an array to see if the number has already been generated.
var randomArr = [], trackingArr = [],
targetCount = 4, currentCount = 0,
min = 1, max = 10,
rnd;
while (currentCount < targetCount) {
rnd = Math.floor(Math.random() * (max - min + 1)) + min;
if (!trackingArr[rnd]) {
trackingArr[rnd] = rnd;
randomArr[currentCount] = rnd;
currentCount += 1;
}
}
alert(randomArr); // Will contain four unique, random numbers between 1 and 10.
Working example: http://jsfiddle.net/FishBasketGordo/J4Ly7/
var a = [];
for (var i = 0; i < 5; i++) {
var r = Math.floor(Math.random()*10) + 1;
if(!(r in a))
a.push(r);
else
i--;
}
That'll do it for you. But be careful. If you make the number of random numbers generated greater than the may number (10) you'll hit an infinite loop.
I'm using a recursive function. The test function pick 6 unique value between 1 and 9.
//test(1, 9, 6);
function test(min, max, nbValue){
var result = recursValue(min, max, nbValue, []);
alert(result);
}
function recursValue(min, max, nbValue, result){
var randomNum = Math.random() * (max-min);
randomNum = Math.round(randomNum) + min;
if(!in_array(randomNum, result)){
result.push(randomNum);
nbValue--;
}
if(nbValue>0){
recursValue(min, max, nbValue, result);
}
return result;
}
function in_array(value, my_array){
for(var i=0;i< my_array.length; i++){
if(my_array[i] == value){
console.log(my_array+" val "+value);
return true;
}
}
return false;
}
Here is a recursive function what are you looking for.
"howMany" parameter is count of how many unique numbers you want to generate.
"randomize" parameter is biggest number that function can generate.
for example : rand(4,8) function returns an array that has 4 number in it, and the numbers are between 0 and 7 ( because as you know, Math.random() function generates numbers starting from zero to [given number - 1])
var array = [];
var isMatch= false;
function rand(howMany, randomize){
if( array.length < howMany){
var r = Math.floor( Math.random() * randomize );
for( var i = 0; i < howMany; i++ ){
if( array[i] !== r ){
isMatch= false;
continue;
} else {
isMatch= true;
break;
}
}
if( isMatch == false ){
array.push(r);
ran(howMany, randomize);
}
ran(howMany, randomize);
return array;
}
}
In your answer earlier, you do have a small bug. Instead of
var originalLength = grabBag.length;
for(var i = 0; i < originalLength .length; i++){
console.log(getNextRandom());
}
I believe you meant:
var originalLength = grabBag.length;
for(var i = 0; i < originalLength; i++){
console.log(getNextRandom());
}
Thanks.

javascript: generate 2 random but distinct numbers from range

quick question:
What is the best way for implementing this line of python code (generates two random but distinct numbers from a given range)...
random.sample(xrange(10), 2)
...in Javascript?
Thanks in advance!
Martin
Here is my attempt using splice:
var a = [1,2,3,4,5,6,7,8,9,10];var sample = [];
sample.push(a.splice(Math.random()*a.length,1));
sample.push(a.splice(Math.random()*a.length,1));
Wrapped in a function:
function sample_range(range, n) {
var sample = [];
for(var i=0; i<n; i++) {
sample.push(range.splice(Math.random()*range.length,1));
}
return sample;
}
var sample = sample_range([1,2,3,4,5,6,7,8,9,10], 2);
We could also stick the function into Array.prototype to have something like dot notation syntax:
Array.prototype.sample_range = function(n) {
var sample = [];
for(var i=0;i<n;i++) {
sample.push(this.splice(Math.random()*this.length,1));
}
return sample;
};
var sample = [1,2,3,4,5,6,7,8,9,10].sample_range(2);
If you want to generate random numbers between 0 and n, one way is to randomly pick number r1 in 0..n then pick r2 from 0..n-1 and add 1 to r2 if r2 >= r1.
function sample(range,tot){
if(tot > range){
alert('infinite loop?');
return [];
}
var myRandomNumbers = [];
for(var i = 0; i<tot; i++){
var randN = Math.floor(Math.random()*range);
while(myRandomNumbers.contains(randN)){
randN = Math.floor(Math.random()*range);
}
myRandomNumbers.push(randN);
}
return myRandomNumbers
}
var nums = sample(10,2); //array containing 2 distinct random numbers
Generate one, then repeatedly generate the second until it's not the same as the first. Tiny chance it will have to run longer, but you won't see any performance hit unless you need to generate billions of numbers.

Categories

Resources