Javascript math.floor and math.random question - javascript

var letters = ["A", "B", "C", "D"];
var rnd = Math.random();
var rndK = letters[Math.floor(rnd*letters.length)];
return rndK;
My question to this is, I've run it a couple of times and it prints D sometimes, but I don't really understand why, since to my knowledge,
math.random() returns a pseudorandom number between 0 and 1 but not 1,
math.floor() returns the highest integer that's less or equal to the value, rounding down essentially.
shouldn't D only be printed out when the rnd gives a 1, but since math.floor() rounds down, this shouldn't be possible?
I'm probably missing something really obvious here, thanks if anyone can explain it for a complete beginner to javascript.

You're right, math.random() only returns a value between 0 and 1. Multiplying it by letters.length, which is 4, and flooring it will only return a value between 0 and 3, never 4. That will still return D sometimes, because the index of D is 3. Remember, the index of the element is the element's place minus 1. So the index of A is 0, the index of B is 1, the index of C is 2, and the index of D is 3. If you don't want D returned, multiply math.random() by letters.length - 1.

Math.floor(rnd*letters.length)
Returns a number between 0 and 3 in your case. Because letters.length === 4
letters[0] === "A"
letters[3] === "D"
So everything works as expected :)

Related

Find The Smallest - Codewars Challenge - Javascript

Trying to solve this Codewars challenge.
You have a positive number n consisting of digits. You can do at most one operation: Choosing the index of a digit in the number, remove this digit at that index and insert it back to another or at the same place in the number in order to find the smallest number you can get.
Task: Return an array or a tuple or a string depending on the language (see "Sample Tests") with:
1) the smallest number you got
2) the index i of the digit d you took, i as small as possible
3) the index j (as small as possible) where you insert this digit d to have the smallest number.
Example:
smallest(261235) --> [126235, 2, 0] or (126235, 2, 0) or "126235, 2, 0"
Other examples:
209917, [29917, 0, 1]
285365, [238565, 3, 1]
269045, [26945, 3, 0]
296837, [239687, 4, 1]
So, in order to get the smallest number possible, we will want to remove the smallest digit from the number and place it at the front of the number, correct?
function smallest (n) {
//turn n into an array
let array = String(n).split("").map(Number);
let smallest = Math.min(...array);
//find index of smallest in original array
let index = array.indexOf(smallest);
//remove smallest from original array, move it to front
array.splice(index, 1);
array.unshift(smallest);
let newNumber = Number(array.join(""));
//return array of new number, index of where the smallest was,
//and index of where the smallest is now
return ([newNumber, index, 0]);
}
console.log(smallest(239687));
My answer is returning the correct number, but, about half the time, it is not returning the correct index i and index j.
EDIT: Latest attempt:
function smallest (n) {
let array = Array.from(String(n)).map(Number);
let original = Array.from(String(n)).map(Number);
let sorted = Array.from(String(n)).map(Number).sort((a, b) => a - b);
let swapValueOne = [];
let swapValueTwo = [];
for (let i = 0; i < array.length; i++) {
if (array[i] !== sorted[i]) {
swapValueOne.push(sorted[i]);
swapValueTwo.push(original[i]);
break;
}
}
swapValueOne = Number(swapValueOne);
swapValueTwo = Number(swapValueTwo);
let indexOne = original.indexOf(swapValueOne);
let indexTwo = original.indexOf(swapValueTwo);
//remove swapValue
array.splice(indexOne, 1);
//insert swapValue
array.splice(indexTwo, 0, swapValueOne);
return ([Number(array.join("")), indexOne, array.indexOf(swapValueOne)]);
}
console.log(smallest(296837));
^ Sometimes it gives the correct number with the correct swap indices, and sometimes both the number and the swap indices are wrong.
Putting the smallest element in the front (let's call it a "greedy" solution) is non-optimal. Consider the case where n = 296837, as in your last test case. Your code returns [296837, 0, 0] because it finds that 2 is the smallest digit and it moves it to the front (does nothing, essentially). As your example illustrates, there's a better approach: [239687, 4, 1], that is, move 3 to the first index in the array.
You'll need to reformulate your strategy to be non-greedy to find a global optimum.
If you're still stuck, you can try the following:
Numbers can't contain that many digits--why not try every possible swap?
Here's a small idea that might help.
If you have a number like:
239687
The smallest number you can make with this is the sorted digits:
236789
In the original number, the 2 and the 3 are already in the correct position. If you start from the left of the number and the sorted number, the first difference you find is the number that needs to be swapped. It needs to be swapped with the corresponding number in the sorted list:
orig 2 3 9 6 8 7 -- 6 needs to go before 9
| | x
sorted 2 3 6 7 8 9
Above the next sorted digit is 6, but the original has 9. You need to insert 6 before 9.
For an algorithm you can sort your digits and find the index of the first difference (starting from the left). This is one of your return values (2 in the example). Now find the index of sorted[2] (ie. 6) in the original (index 3). Insert the value in you original array and you're done.
The approach of finding the first not sorted element doesnt solve correctly all the cases for example if the number is 300200, the first not sorted number is the 3 and if you put a 0 in that place, depending what 0 you move you got:
(0)30020
(0)30020
(0)30200
(0)30200
All of the answers are wrong because what you have to do is to put the 3 at the end of the number to get
(000)2003

Counting zeros in a recursive manner

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/

Round number down to nearest power of ten

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("");

JavaScript biased results?

Let's say I have two items in an array, e.g:
["a", "b"]
Now let's say I have a function called random that chooses a random item from this array, e.g:
function random() {
// do awesome random stuff here...
return random_choice;
}
How can I get the random function to return "a" 80% of the time and "b" 20% of the time?
I'm not really sure as to what this is called but for example if I ran the console.log(random()); 10 times the result should look a little something like this:
>>> "a"
>>> "a"
>>> "a"
>>> "a"
>>> "a"
>>> "a"
>>> "a"
>>> "a"
>>> "b"
>>> "b"
"a" get's returned 8/10 times and "b" gets returned 2/10 times.
NOTE: the "results" above are just an example, I understand that they won't always be that perfect and they don't have to be.
Quickest answer would be:
var result = Math.random() >= 0.2 ? "a" : "b";
Generalized solution for any number of values
function biasedRandomSelection(values, probabilities) {
// generate random number (zero to one).
var rand = Math.random();
// cumulative probability, starting at 0
var cumulativeProb = 0;
// loop through the raw `probabilities` array
for(var i=0; i<probabilities.length; i++) {
// increment cumulative probability
cumulativeProb += probabilities[i];
// test for `rand` being less than the cumulative probaility;
// when true, return return the corresponding value.
if(rand < cumulativeProb) return values[i];
}
}
The knack here is to test against a rolling "cumulative probability", derived from the raw probabilities.
Sample calls :
biasedRandomSelection(['a', 'b'], [0.8, 0.2]); // as per the question
biasedRandomSelection(['a', 'b'], [0.2, 0.8]); // reversed probailities
biasedRandomSelection(['a', 'b', 'c', 'd', 'e'], [0.4, 0.1, 0.2, 0.2, 0.1]); // larger range of values/probailities
Demo
As written, biasedRandomSelection() performs no range checking.
A safer version would check that :
values and probabilities were congruant
the sum of the probabilities was 1.
Math.random() returns a number in [0;1). Just use p < 0.2 / p < 0.8 to have a biased result instead of the the unbiased p < 0.5.
If you want the first N outcomes to be deterministic, then you can use a simple counter i++ < N.
A bit extended:
var array="a".repeat(8)+"b".repeat(2);
var random=()=>array[Math.floor(Math.random()*array.length)];
alert(random());
This also works for more than two results and all different kinds of probability.
Note that array is not really an array but rather a lookupstring
..
http://jsbin.com/besapetidi/edit?console

Decomposing a value into results of powers of two

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));

Categories