Javascript Math.random() and conditional expressions - javascript

I would like to share with you my thoughts about this code:
for (var i = 1, max = 5; i < max; i++) {
let random = Math.random();
let expression = (random < 1 / (i + 1));
if (expression){
console.log('random is: ' + random + ' and the expression is: ' + expression + ', i is: ' + i);
}else{
console.log('random was: ' + random + ' and the expression was: ' + expression + ', i was: ' + i);
}
}
I was studying this example taken from GitHub: https://github.com/chuckha/ColorFlood
And I had trouble trying to know what was the meaning of the expression inside the if().
I used the JS repl: https://jscomplete.com/repl/
The context of this example is that this function would take a random index from 0 to 5, to map a random color to a Node.
Here we have a sample output from the repl:
"random was: 0.7118559117992413 and the expression was: false, i was: 1"
"random was: 0.478919411809795 and the expression was: false, i was: 2"
"random was: 0.4610390397998597 and the expression was: false, i was: 3"
"random was: 0.7051121468181564 and the expression was: false, i was: 4"

The syntax:
let expression = (random < 1 / (i + 1));
Means:
(i + 1) first add 1 to var i
Next, 1 / (i + 1) divide 1 by the sum (i + 1)
Let say result = 1 / (i + 1)
random < result, if the random value less than above division result than return true, else false.
So, something simple like:
for (var i = 1, max = 5; i < max; i++) {
let random = Math.random();
let expression = (random < 1 / (i + 1));
console.log(
i,
random.toFixed(2),
(1 / (i + 1)).toFixed(2),
expression
)
}

I first thought that it would be evaluated random < 1 so then as random uses Math.random() which gets a number between 0 and 1, excluding the one; I thought that part of the expression would be alway true.
But in fact after putting it into the repl I discovered that the 1 / (i+1) part is done first, and then it is done all together: random / result.
I have also read:
https://www.w3schools.com/js/js_comparisons.asp
https://www.w3schools.com/js/js_arithmetic.asp
https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Math/random
Please note that in the original post I simplified the code, the original code is:
var randomIndexFromCollection = function randomIndexFromCollection(collection) {
var index = 0;
for (var i = 1, max = collection.length; i < max; i++) {
if (Math.random() < 1 / (i + 1)) {
index = i;
debugger;
}
}
return index;
};

Related

How to make triangle with '&' and '+' symbol in JavaScript?

How to make a pyramid like this one in javascript?
👇
&
+++
&&&&&
+++++++
I've tried this one but didn't get the exact output.
function pyramid(n) {
for (let i = 1; i <= n; i++) {
let str = ' '.repeat(n - i);
let symb1 = '&'.repeat(i * 2 - 1);
let symb2 = '+'.repeat(i * 2 - 1);
console.log(str + symb1 + str);
console.log(str + symb2 + str);
}
}
pyramid(4)
You could do something like this:
Declare a variable res which gonna store in it, lines.
loop over number of lines and in each one switch between two symbols by using modulo %
function pyramid(n) {
let res = '';
for (let i = 1; i <= n; i++) {
let str = ' '.repeat(n - i);
let line = ['+', '&'][i % 2].repeat(i * 2 - 1);
res += str + line + "\n";
}
return res;
}
console.log(pyramid(4));
Note: \n character for a line break to add a new line into result string.
You're outputting both lines on every iteration of the loop:
let symb1 = '&'.repeat(i * 2 - 1);
let symb2 = '+'.repeat(i * 2 - 1);
console.log(str + symb1 + str);
console.log(str + symb2 + str);
Instead, conditionally output one or the other. You can check whether i is even or odd for the condition:
if (i % 2 == 1) {
let symb1 = '&'.repeat(i * 2 - 1);
console.log(str + symb1 + str);
} else {
let symb2 = '+'.repeat(i * 2 - 1);
console.log(str + symb2 + str);
}
(You can of course refactor this into something shorter, reduce repetition, etc. The point here is to demonstrate the goal of outputting one or the other instead of both.)
Use a ternary and test for even using remainder
You can push into an array and join with newlines
function pyramid(n) {
const lines = [];
for (let i = 1; i <= n; i++) {
let str = ' '.repeat(n - i);
let symb = (i%2===0 ? '+' : '&').repeat(i * 2 - 1);
lines.push(str + symb + str);
}
console.log(lines.join("\n"));
}
pyramid(4)

How do I make my JavaScript loop run slower [duplicate]

This question already has answers here:
How do I add a delay in a JavaScript loop?
(32 answers)
Closed 10 months ago.
I am trying a little bit of coding and I would like for the 30 character strings to appear in the 1 second intervals one after another when the code is started. I tried setInterval & setTimeout and I couldn't get it to work. If someone could please help that would be much appreciated.
count = 0
while (count < 200) {
console.log(create_random_string(30))
function create_random_string(string_length){
var random_string = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz'
for(var i, i = 0; i < characters.length; i++){
random_string += characters.charAt(Math.floor(Math.random() * characters.length))
}
return "|BTC| " + random_string + " | " + " PRIVATNI KLJUČ NIJE ISPRAVAN" + " | " + " STANJE: 0.00"
}
count = count + 1
}
setInterval(code, time);
this function will allow you to wait X miliseconds before running the code defined.
here, the correct code, and i fixed your formatting a bit.
let count = 0;
while (count < 200) {
setTimeout(
function() { console.log(create_random_string(30)); }
, 500);
count++;
}
function create_random_string(string_length){
var random_string = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz'
for(var i, i = 0; i < characters.length; i++){
random_string += characters.charAt(Math.floor(Math.random() * characters.length))
}
return "|BTC| " + random_string + " | " + " PRIVATNI KLJUČ NIJE ISPRAVAN" + " | " + " STANJE: 0.00"
}
by the way, you probably wanted to replace characters.length inside your for loop for : string_length to use the fuction's parameter (which you never actually used)

Determine how many integers, starting from the number 1, need to be added so that the sum will equal more than 100? Using JavaScript

I am trying to find a solution to this task "Determine how many integers, starting from the number 1, need to be added so that the sum will equal more than 100."using JavaScript.
I have my solution but I tend to feel that it is wrong.
Could you please help me?
I do not even realize if I understand the task in the right way.
Please see my solution below:
<script>
let result = 0;
for ( i = 1; i<20; i++){
result+=i;
if( result>100) {
break
}
}
console.log(i)
</script>
Output is 14, It is right , but I am not sure in the way I solving it.
If it works, there is nothing wrong about it.
You could simplify it, for example use a while rather than a for loop :
let total = 0
let count = 1;
// we loop until total is greater or equals to 100.
while(total < 100) {
// add the current count to the total
total += count;
// increment the count.
count++;
}
// we need to account for the last ++;
console.log(count - 1);
Here the while loop will run until the condition is broken.
1 + 2 + 3 + 4 + ... + k is a triangular number.
It can be solved using and then .
There, n is 100 and x is the base of the triangle (k in the above example, i in your loop).
This is a quadratic equation, solved using :
if we replace a b c by their respective values, we get :
x = 13.6509716981 or x = -14.6509716981 depending of the sign we use
If you round up 13.6509716981 you get 14, the expected result
This is written Math.ceil((-1 + Math.sqrt(1 - 4 * 1 * (-2 * num))) / 2) in JS, num being the value to reach (100 in your example)
This can be shortened to Math.ceil((-1 + Math.sqrt(1 + 8 * num)) / 2)
// Your original code, as reference
function FindNumberUsingLoops(num)
{
let result = 0;
// I modified the loop exit condition to make sure every case will run
for ( i = 1; i < num; i++){
result+=i;
if( result>=num) {
return i;
}
}
}
function FindNumber(num)
{
return Math.ceil((-1 + Math.sqrt(1 + 8 * num)) / 2);
}
console.log("using equation : " + FindNumber(100));
console.log("using loops : " + FindNumberUsingLoops(100));
console.log("using equation : " + FindNumber(500));
console.log("using loops : " + FindNumberUsingLoops(500));
console.log("using equation : " + FindNumber(42));
console.log("using loops : " + FindNumberUsingLoops(42));
console.log("using equation : " + FindNumber(1000));
console.log("using loops : " + FindNumberUsingLoops(1000));
console.log("using equation : " + FindNumber(1000000000000000000));
// uncomment below, this takes few seconds to solve
// console.log("using loops : " + FindNumberUsingLoops(1000000000000000000));
You can use this code:
let cheker = 0;
for (i = 1; i; i++) {
cheker += i;
if (cheker <= 100) {
console.log(i, cheker); // sum before 100 (94) and integers before 100 (13)
} else {
console.log(i, cheker); // sum after 100 (105) and integers before 100 (14 - answer)
break;
}
}

Looping through a string of numbers in Javascript

Hey guys working on a problem from CoderBytes. The directions of the following:
Using the JavaScript language, have the function DashInsert(num) insert dashes ('-') between each two odd numbers in num. For example: if num is 454793 the output should be 4547-9-3. Don't count zero as an odd number.
Use the Parameter Testing feature in the box below to test your code with different arguments.
So I didn't create a function but here is my road map.
num = 3333333333
arr = num.toString().split("")
for(var i = 0; i < arr.length; i++){
if(arr[i] % 2 === 1 && arr[i + 1] % 2 === 1){
num.toString().replace(arr[i].toString() + arr[i+1].toString(),
arr[i].toString() + "-" + arr[i+1].toString())
}
}
The thing is when I run this it only puts a dash between the first two threes. I really can't figure out why this is happening. Anyone know where I am going wrong?
Here, this simple solution should do well:
var num = 3434333333
var arr = num.toString().split("");
var finalStr = "";
for(var i = 0; i < arr.length; i++){
if(arr[i] % 2 === 1 && arr[i + 1] % 2 === 1){
finalStr += arr[i] + "-";
}
else {
finalStr += arr[i];
}
}
simply keep a string for the result, if two consecutive numbers are odd append an extra "-" after the number in the string, otherwise simply append the number and your final string will contain the desired result.
See the DEMO here

less than 10 add 0 to number [duplicate]

This question already has answers here:
How can I pad a value with leading zeros?
(76 answers)
Closed 4 years ago.
How can I modify this code to add a 0 before any digits lower than 10
$('#detect').html( toGeo(apX, screenX) + latT +', '+ toGeo(apY, screenY) + lonT );
function toGeo(d, max) {
var c = '';
var r = d/max * 180;
var deg = Math.floor(r);
c += deg + "° ";
r = (r - deg) * 60;
var min = Math.floor(r);
c += min + "′ ";
r = (r - min) * 60;
var sec = Math.floor(r);
c += sec + "″";
return c;
}
So the outpout would change from
4° 7′ 34″W, 168° 1′ 23″N
to
04° 07′ 34″W, 168° 01′ 23″N
Thanks for your time
You can always do
('0' + deg).slice(-2)
See slice():
You can also use negative numbers to select from the end of an array
Hence
('0' + 11).slice(-2) // '11'
('0' + 4).slice(-2) // '04'
For ease of access, you could of course extract it to a function, or even extend Number with it:
Number.prototype.pad = function(n) {
return new Array(n).join('0').slice((n || 2) * -1) + this;
}
Which will allow you to write:
c += deg.pad() + '° '; // "04° "
The above function pad accepts an argument specifying the length of the desired string. If no such argument is used, it defaults to 2. You could write:
deg.pad(4) // "0045"
Note the obvious drawback that the value of n cannot be higher than 11, as the string of 0's is currently just 10 characters long. This could of course be given a technical solution, but I did not want to introduce complexity in such a simple function. (Should you elect to, see alex's answer for an excellent approach to that).
Note also that you would not be able to write 2.pad(). It only works with variables. But then, if it's not a variable, you'll always know beforehand how many digits the number consists of.
Make a function that you can reuse:
function minTwoDigits(n) {
return (n < 10 ? '0' : '') + n;
}
Then use it in each part of the coordinates:
c += minTwoDigits(deg) + "° ";
and so on.
if(myNumber.toString().length < 2)
myNumber= "0"+myNumber;
or:
return (myNumber.toString().length < 2) ? "0"+myNumber : myNumber;
You can always do
('0' + deg).slice(-2)
If you use it very often, you may extend the object Number
Number.prototype.pad = function(n) {
if (n==undefined)
n = 2;
return (new Array(n).join('0') + this).slice(-n);
}
deg.pad(4) // "0045"
where you can set any pad size or leave the default 2.
You can write a generic function to do this...
var numberFormat = function(number, width) {
return new Array(+width + 1 - (number + '').length).join('0') + number;
}
jsFiddle.
That way, it's not a problem to deal with any arbitrarily width.
Hope, this help:
Number.prototype.zeroFill= function (n) {
var isNegative = this < 0;
var number = isNegative ? -1 * this : this;
for (var i = number.toString().length; i < n; i++) {
number = '0' + number;
}
return (isNegative ? '-' : '') + number;
}
Here is Genaric function for add any number of leading zeros for making any size of numeric string.
function add_zero(your_number, length) {
var num = '' + your_number;
while (num.length < length) {
num = '0' + num;
}
return num;
}
I was bored and playing around JSPerf trying to beat the currently selected answer prepending a zero no matter what and using slice(-2). It's a clever approach but the performance gets a lot worse as the string gets longer.
For numbers zero to ten (one and two character strings) I was able to beat by about ten percent, and the fastest approach was much better when dealing with longer strings by using charAt so it doesn't have to traverse the whole string.
This follow is not quit as simple as slice(-2) but is 86%-89% faster when used across mostly 3 digit numbers (3 character strings).
var prepended = ( 1 === string.length && string.charAt( 0 ) !== "0" ) ? '0' + string : string;
$('#detect').html( toGeo(apX, screenX) + latT +', '+ toGeo(apY, screenY) + lonT );
function toGeo(d, max) {
var c = '';
var r = d/max * 180;
var deg = Math.floor(r);
if(deg < 10) deg = '0' + deg;
c += deg + "° ";
r = (r - deg) * 60;
var min = Math.floor(r);
if(min < 10) min = '0' + min;
c += min + "′ ";
r = (r - min) * 60;
var sec = Math.floor(r);
if(sec < 10) sec = '0' + sec;
c += sec + "″";
return c;
}
A single regular expression replace should do it:
var stringWithSmallIntegers = "4° 7′ 34″W, 168° 1′ 23″N";
var paddedString = stringWithSmallIntegers.replace(
/\d+/g,
function pad(digits) {
return digits.length === 1 ? '0' + digits : digits;
});
alert(paddedString);
shows the expected output.

Categories

Resources