Random number in ternary statement - javascript

I borrowed this script (which had 3 pages) and added another 2 pages. The problem is that it only randomizes between the first 3 on the list. I don't quite undertand the ternary if/else either. If n is greater than 3, it's 0. Else if n is greater than 8, it's 1. Else 2? Did I get that right? It seems like a weird way to do it. How would I get it to randomize between 1 and 5?
<script type="text/javascript">
(function(n){
var pages = ['Happy.html', 'Sad.html', 'Pensive.html', 'Eager.html', 'Inquisitive.html'];
n = n < 3? 0 : n < 8? 1 : 2;
window.location.replace(pages[n]);
})(Math.floor(Math.random() * 10));
</script>

you dont need the ternary operator.. you can just do this
function(n){
//everything except the ternary operator
}(Math.floor(Math.random()*10)%5)
The output of this expression is randomly between 0 and 4. not 1 and 5. this is required because the index of the array of 5 elements is between 0 and 4 inclusive.

Do this:
<script type="text/javascript">
(function(n){
var pages = ['Happy.html', 'Sad.html', 'Pensive.html', 'Eager.html', 'Inquisitive.html'];
window.location.replace(pages[n]);
})(Math.floor(Math.random() * 5)); // Gets a random number between 0 and 4
</script>
or call this function borrowed from here:
<script type="text/javascript">
function randomFromInterval(from, to)
{
return Math.floor(Math.random() * (to - from + 1) + from);
}
(function(n){
var pages = ['Happy.html', 'Sad.html', 'Pensive.html', 'Eager.html', 'Inquisitive.html'];
window.location.replace(pages[n - 1]);
})(randomFromInterval(1, 5)); // Gets a random number between 1 and 5
</script>

In order to completely understand the ternary statement you presented, you need to know about Operator Precendence in JavaScript.
Take a look at this document: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence
You got it right about how the ternary statement is going to be executed.
n = n < 3? 0 : n < 8? 1 : 2;
can be translated into
if (n < 3) {
n = 0;
}
else if (n < 8) {
n = 1;
}
else {
n = 2;
}
So it is more clear to understand what is going on.
And, here is how you get random int.
function randInt(n, min) {
return (Math.floor(Math.random() * n)) + (min || 0);
}
var r = randInt(5, 1); // get random number from 1 to 5

Related

How to make a string palindrome?

Create a function which takes a string as parameter. Return the shortest palindrome formed by adding the letter to that string.
"abc" // cbabc
"21234" // 4321234
"321234" // 4321234
"a" // a
What I have tried so far is below.
function isPal(str){
return [...str].reverse().join('') === str;
}
function palindrome(s){
if(isPal(s)) return s;
for(let i = 0;i<s.length;i++){
if(isPal(s)) return s;
s = s.slice(0,i) + s[s.length - 1 - i] + s.slice(i)
}
return s;
}
console.log(palindrome('abc'))
console.log(palindrome('321234'))
console.log(palindrome('21234'))
console.log(palindrome('a'))
The code works fine but its not efficient because its checking for isPal during each iteration.
I would like to know the efficient solution for the problem. I can't calculate the time-complexity of the solution but its clears it not linear. I want to know the solution with linear time-complexity or better than mine.
Make r = reversed string (s)
Find the longest suffix of r equal to prefix of s (checking char by char)
a b c
c b a
for another example
2 1 2 3 4
4 3 2 1 2
but better variant does exist:
2 1 2 3 4
4 3 2 1 2
Note that you really don't need to build reversed string - just use corresponding indexes
Both operations should be linear.
Edit: Modified code exploiting z-function
(thanks #Kalido for pointing to abcdba test case)
It is possible to use z-function mentioned in your earlier theme. I am not familiar with JS (enough to properly make result strings), so just made z-array for comparison of string suffix with prefix of reversed one (note index mangling in the right part here s[z[i]] == s[n - 1 - i - z[i]])
Code looks for the largest value z[maxi] except for the first item. The first item is used only if it is equal to n (string already is palindrome). Result is length of prefix to add.
For example, 21234 gives z[maxi]=3, so function returns 2 (we add prefix of 43212of length 5-3=2), ie 43 = > 43 21234
cabac gives z[0] = 5 = n, result is zero, so we don't need to add anything
abcdba gives z[0] = 2 < n, so we choose maximum among other items
function ex_z_function(s) {
var n = s.length;
var z = Array(n).fill(0);
var i, l, r, maxi = 1;
for (i = 0, l = 0, r = 0; i < n; ++i) {
if (i <= r)
z[i] = Math.min(r - i + 1, z[i - l]);
while (i + z[i] < n && s[z[i]] == s[n - 1 - i - z[i]])
++z[i];
if ((i > 0) && (z[i] > z[maxi]))
maxi = i;
if (i + z[i] - 1 > r)
l = i, r = i + z[i] - 1;
}
if (z[0] == n) {
return 0;
}
return n - z[maxi];
}
console.log(ex_z_function("a"));
console.log(ex_z_function("abc"));
console.log(ex_z_function("abac"));
console.log(ex_z_function("cabac"));
console.log(ex_z_function("21234"));
console.log(ex_z_function("abcdba"));
console.log(ex_z_function("abacaba"));
console.log(ex_z_function("vfvcabgvcvfv"));
You could already gain a lot of time on your isPal function by just checking half the string, or return if the check fails early:
function isPal(str){
for (let i = 0, l = str.length; i < l / 2; i++) {
if (str[i] != str[l-i-1]) {
return false
}
}
return true
}
console.log(isPal('kayak'))
console.log(isPal('toot'))
console.log(isPal('john'))
https://jsperf.com/palindrome-detection
Note: the complexity of isPal remains linear but the best case is far better.

JavaScript - Factorial explanation

I wanted someone to basically help me understand what each line of code is doing and help me comment each line (if applicable) so that it can help explain to another person what it's doing. It'd be awesome if one can just give second eyes and ensure that the code is actually good - I'm trying to get my head around Factorial/Recursion, and did some research and found these solutions for this.
I was given this scenario:
For positive n, factorial is n! = n(n−1)!   (e.g. 5! = 5 * 4
* 3 * 2 * 1)*
Here's what I've found for this scenario:
// Prompt user to enter a number to calculate the factorial
var num = prompt("What number do you want to find the factorial of?");
var factorial = function(n) {
if (n == 0) {
return 1;
} else {
product = 1;
for (i = 1; i < n; i++) {
product *= i;
}
return product;
}
}
console.log(factorial(num));
Recursive
Create a recursive algorithm to calculate the factorial using every second
number as shown in examples below:
5! = 5 * 3 * 1 = 15
6! = 6 * 4 * 2 = 48
As for the cursive part, this is added onto the above code and is written in the following -
//  recursive
var factorial = function(n) {
if (n == 0) {
return 1;
} else {
return n * factorial(n - 1);
}
}
console.log(factorial(num));
Would appreciate your assistance on this - Apologies if this has already been answered, please direct me to another thread if this has been already posted. Thanks!
You don't need recursion for that:
/**
* Calculate factorial, optionally using a difference other than 1 with previous value.
* Example: factorial(6, 2) // 6*4*2 = 48
*/
var factorial = function(n, d) {
if (!d) {d = 1;}
var product = 1;
while (n > 1) {
product *= n;
n -= d;
}
return product;
};
console.log(factorial(6, 2)); // 48
console.log(factorial(6)); // 720
Note: Declare local variables inside the function with keyword 'var'. Otherwise they become globals and the second time you attempt to use a function may produce wrong results.
Usually, writing a function for Factorial is an exercise on writing recursive function. The first example code is not recursive and just an overly complicated way of calculating a factorial by multiplying the numbers iteratively so I'll skip that.
The second code is recursive, and it is following the recursive definition of factorial in your usual mathematics:
f: N => N, f(x) = x! = { x < 1 : 1, else : x (x - 1)! }
Or equivalently in JavaScript:
let fac = n => n < 1 ? 1 : n * fac(n - 1);
An expansion of an example computation would look like:
5!
5(4!)
5(4(3!))
5(4(3(2!)))
5(4(3(2(1))))
5(4(3(2(1(0!)))))
5(4(3(2(1(1)))))
120

How to convert this Pascal Code to JavaScript?

I am trying to make simple JS code to find out the amount a number from 1 to 9 occurs in a given string. I have this Pascal code that works:
Var n,i:longint;
A:array[0..9] of byte;
Begin
write('Введите число: ');readln(n);
While n>0 do
Begin
A[n mod 10]:=A[n mod 10]+1;
n:=n div 10;
End;
For i:=0 to 9 do
writeln('The number ',i,' occurs ',A[i],' amount of times');
readln;
End.
In JS I ended up with this, but that seems to have a never-ending loop:
function plosh(form) {
var list = new Array(9);
var n = form.a.value;
while (n>0) {
a = n % 10;
list[a] = list[a]+1;
n = n % 10;
}
for (var i=0; i<=9; i++)
{
alert("Цифра"+i+"встречается"+A[i]+"раз");
}
}
Would appreicate any help on where I am going wrong with this. Thanks in advance!
n = n % 10 leaves n unchanged as soon as it's lower than 10, so it will usually never reach 0, hence the endless loop.
The div operator in Pascal makes an integral division.
Change
n = n % 10
to
n = Math.floor( n / 10 );
You also have another problem : you're not properly initializing your array so you're adding 1 to undefined. Fix that like this :
function plosh(form) {
var a,
list = [],
n = form.a.value;
while (n>0) {
a = n % 10;
list[a] = (list[a]||0)+1;
n = Math.floor( n / 10 );
}
for (var i=0; i<=9; i++) {
console.log("Цифра"+i+"встречается"+A[i]+"раз"); // <- less painful than alert
}
}
n:=n div 10;
was translated as:
n = n % 10;
but should be:
n = Math.floor(n / 10);
Edit: Also, you define an array [0..9] in Pascal, which means 10 elements. When you call Array(9) you only create 9 elements.

javascript - generate a new random number

I have a variable that has a number between 1-3.
I need to randomly generate a new number between 1-3 but it must not be the same as the last one.
It happens in a loop hundreds of times.
What is the most efficient way of doing this?
May the powers of modular arithmetic help you!!
This function does what you want using the modulo operator:
/**
* generate(1) will produce 2 or 3 with probablity .5
* generate(2) will produce 1 or 3 with probablity .5
* ... you get the idea.
*/
function generate(nb) {
rnd = Math.round(Math.random())
return 1 + (nb + rnd) % 3
}
if you want to avoid a function call, you can inline the code.
Here is a jsFiddle that solves your problem : http://jsfiddle.net/AsMWG/
I've created an array containing 1,2,3 and first I select any number and swap it with the last element. Then I only pick elements from position 0 and 1, and swap them with last element.
var x = 1; // or 2 or 3
// this generates a new x out of [1,2,3] which is != x
x = (Math.floor(2*Math.random())+x) % 3 + 1;
You can randomly generate numbers with the random number generator built in to javascript. You need to use Math.random().
If you're push()-ing into an array, you can always check if the previously inserted one is the same number, thus you regenerate the number. Here is an example:
var randomArr = [];
var count = 100;
var max = 3;
var min = 1;
while (randomArr.length < count) {
var r = Math.floor(Math.random() * (max - min) + min);
if (randomArr.length == 0) {
// start condition
randomArr.push(r);
} else if (randomArr[randomArr.length-1] !== r) {
// if the previous value is not the same
// then push that value into the array
randomArr.push(r);
}
}
As Widor commented generating such a number is equivalent to generating a number with probability 0.5. So you can try something like this (not tested):
var x; /* your starting number: 1,2 or 3 */
var y = Math.round(Math.random()); /* generates 0 or 1 */
var i = 0;
var res = i+1;
while (i < y) {
res = i+1;
i++;
if (i+1 == x) i++;
}
The code is tested and it does for what you are after.
var RandomNumber = {
lastSelected: 0,
generate: function() {
var random = Math.floor(Math.random()*3)+1;
if(random == this.lastSelected) {
generateNumber();
}
else {
this.lastSelected = random;
return random;
}
}
}
RandomNumber.generate();

Round number up to the nearest multiple of 3

How would I go about rounded a number up the nearest multiple of 3?
i.e.
25 would return 27
1 would return 3
0 would return 3
6 would return 6
if(n > 0)
return Math.ceil(n/3.0) * 3;
else if( n < 0)
return Math.floor(n/3.0) * 3;
else
return 3;
Simply:
3.0*Math.ceil(n/3.0)
?
Here you are!
Number.prototype.roundTo = function(num) {
var resto = this%num;
if (resto <= (num/2)) {
return this-resto;
} else {
return this+num-resto;
}
}
Examples:
y = 236.32;
x = y.roundTo(10);
// results in x = 240
y = 236.32;
x = y.roundTo(5);
// results in x = 235
I'm answering this in psuedocode since I program mainly in SystemVerilog and Vera (ASIC HDL). % represents a modulus function.
round_number_up_to_nearest_divisor = number + ((divisor - (number % divisor)) % divisor)
This works in any case.
The modulus of the number calculates the remainder, subtracting that from the divisor results in the number required to get to the next divisor multiple, then the "magic" occurs. You would think that it's good enough to have the single modulus function, but in the case where the number is an exact multiple of the divisor, it calculates an extra multiple. ie, 24 would return 27. The additional modulus protects against this by making the addition 0.
As mentioned in a comment to the accepted answer, you can just use this:
Math.ceil(x/3)*3
(Even though it does not return 3 when x is 0, because that was likely a mistake by the OP.)
Out of the nine answers posted before this one (that have not been deleted or that do not have such a low score that they are not visible to all users), only the ones by Dean Nicholson (excepting the issue with loss of significance) and beauburrier are correct. The accepted answer gives the wrong result for negative numbers and it adds an exception for 0 to account for what was likely a mistake by the OP. Two other answers round a number to the nearest multiple instead of always rounding up, one more gives the wrong result for negative numbers, and three more even give the wrong result for positive numbers.
This function will round up to the nearest multiple of whatever factor you provide.
It will not round up 0 or numbers which are already multiples.
round_up = function(x,factor){ return x - (x%factor) + (x%factor>0 && factor);}
round_up(25,3)
27
round up(1,3)
3
round_up(0,3)
0
round_up(6,3)
6
The behavior for 0 is not what you asked for, but seems more consistent and useful this way. If you did want to round up 0 though, the following function would do that:
round_up = function(x,factor){ return x - (x%factor) + ( (x%factor>0 || x==0) && factor);}
round_up(25,3)
27
round up(1,3)
3
round_up(0,3)
3
round_up(6,3)
6
Building on #Makram's approach, and incorporating #Adam's subsequent comments, I've modified the original Math.prototype example such that it accurately rounds negative numbers in both zero-centric and unbiased systems:
Number.prototype.mround = function(_mult, _zero) {
var bias = _zero || false;
var base = Math.abs(this);
var mult = Math.abs(_mult);
if (bias == true) {
base = Math.round(base / mult) * _mult;
base = (this<0)?-base:base ;
} else {
base = Math.round(this / _mult) * _mult;
}
return parseFloat(base.toFixed(_mult.precision()));
}
Number.prototype.precision = function() {
if (!isFinite(this)) return 0;
var a = this, e = 1, p = 0;
while (Math.round(a * e) / e !== a) { a *= 10; p++; }
return p;
}
Examples:
(-2).mround(3) returns -3;
(0).mround(3) returns 0;
(2).mround(3) returns 3;
(25.4).mround(3) returns 24;
(15.12).mround(.1) returns 15.1
(n - n mod 3)+3
$(document).ready(function() {
var modulus = 3;
for (i=0; i < 21; i++) {
$("#results").append("<li>" + roundUp(i, modulus) + "</li>")
}
});
function roundUp(number, modulus) {
var remainder = number % modulus;
if (remainder == 0) {
return number;
} else {
return number + modulus - remainder;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Round up to nearest multiple of 3:
<ul id="results">
</ul>
A more general answer that might help somebody with a more general problem: if you want to round numbers to multiples of a fraction, consider using a library. This is a valid use case in GUI where decimals are typed into input and for instance you want to coerce them to multiples of 0.25, 0.2, 0.5 etc. Then the naive approach won't get you far:
function roundToStep(value, step) {
return Math.round(value / step) * step;
}
console.log(roundToStep(1.005, 0.01)); // 1, and should be 1.01
After hours of trying to write up my own function and looking up npm packages, I decided that Decimal.js gets the job done right away. It even has a toNearest method that does exactly that, and you can choose whether to round up, down, or to closer value (default).
const Decimal = require("decimal.js")
function roundToStep (value, step) {
return new Decimal(value).toNearest(step).toNumber();
}
console.log(roundToStep(1.005, 0.01)); // 1.01
RunKit example
Using remainder operator (modulus):
(n - 1 - (n - 1) % 3) + 3
By the code given below use can change any numbers and you can find any multiple of any number
let numbers = [8,11,15];
let multiple = 3
let result = numbers.map(myFunction);
function myFunction(n){
let answer = Math.round(n/multiple) * multiple ;
if (answer <= 0)
return multiple
else
return answer
}
console.log("Closest Multiple of " + multiple + " is " + result);
if(x%3==0)
return x
else
return ((x/3|0)+1)*3

Categories

Resources