The first two functions produce numbers, and the third should join them, but I'm unsure as to why joinNums() doesn't work.
// random number between specified params
function randInteger() {
let min = 1;
let max = 10;
const randomInteger = Math.floor(Math.random() * (max - min + 1)) + min;
console.log(randomInteger);
}
function randDecimal() {
let decimal = 100;
let integral = 100;
const randomDecimal =
Math.floor(
Math.random() * (integral * decimal - 1 * decimal) + 1 * decimal
) /
(1 * decimal);
console.log(randomDecimal);
}
function joinNums() {
let randomDecimal;
let randomInteger;
randInteger();
randDecimal();
console.log("" + randomDecimal + randomInteger);
}
You're not assigning the function results to the variables.
Your functions should return the result, not console.log it.
You need to call joinNums() (you don't seem to be).
So (see ***):
// random number between specified params
function randInteger() {
let min = 1;
let max = 10;
const randomInteger = Math.floor(Math.random() * (max - min + 1)) + min;
return randomInteger; // ***
}
function randDecimal() {
let decimal = 100;
let integral = 100;
const randomDecimal =
Math.floor(
Math.random() * (integral * decimal - 1 * decimal) + 1 * decimal
) /
(1 * decimal);
return randomDecimal; // ***
}
function joinNums() {
let randomDecimal = randDecimal(); // ***
let randomInteger = randInteger(); // ***
console.log(`${randomDecimal}${randomInteger}`);
}
joinNums(); // ***
Or of course, you can just call them directly rather than writing to variables first:
function joinNums() {
console.log(`${randDecimal()}${randInteger()}`); // ***
}
// random number between specified params
function randInteger() {
let min = 1;
let max = 10;
const randomInteger = Math.floor(Math.random() * (max - min + 1)) + min;
return randomInteger; // ***
}
function randDecimal() {
let decimal = 100;
let integral = 100;
const randomDecimal =
Math.floor(
Math.random() * (integral * decimal - 1 * decimal) + 1 * decimal
) /
(1 * decimal);
return randomDecimal; // ***
}
function joinNums() {
console.log(`${randDecimal()}${randInteger()}`);
}
joinNums(); // ***
Related
I'trying to make a function creates a list of exponentially increasing numbers where the sum of the numbers is equal to some maximum.
For example:
/*
* What do I have to raise N by in order for the sum to be 40
*/
(1**x + 2**x + 3**x + 4**x + 5**x) === 40;
/*
* Wolframalpha tells me: x = 1.76445
* But how can I solve with JS.
*/
function listOfNumbers(n, maxSum) {
// implementation
}
var result = listOfNumbers(5, 40);
/*
* result === [1, 3.397..., 6.947..., 11.542..., 17.111...]
*
*/
result.reduce((acc, n) => acc += n) === 40
try https://en.wikipedia.org/wiki/Bisection_method
TOLERANCE = 1e-5;
let f = x => (1 ** x + 2 ** x + 3 ** x + 4 ** x + 5 ** x - 40);
let
min = 0,
max = 1,
x = 0;
// roughly locate the upper bound
while (f(max) < 0)
max *= 2;
// repeatedly bisect the interval [min, max]
while (1) {
x = (min + max) / 2;
let r = f(x);
if (Math.abs(r) < TOLERANCE)
break;
if (r > 0) {
max = x
} else {
min = x
}
}
// now, x is a "good enough" approximation of the root
console.log(x);
I want to generate a random number between 1 and 10 up to 2 decimal places,
I'm currently using this below to generate my numbers,
var randomnum = Math.floor(Math.random() * (10.00 - 1.00 + 1.00)) + 1.00;
Ultimately, I would like to know how to generate numbers like:
1.66
5.86
8.34
In the format: var randomnum = then the code
sidenote: I don't remember why I previously had generated my numbers like that but remember something about Math.random generating numbers to 8 decimal places.
Thank you for the help! :)
Ps: I've seen a lot of posts about waiting to round down or up generated numbers and haven't found one wanting to generate them straight out.
UPDATE: I want a number value not a string that looks like a number
You were very close, what you need is not to work with decimal numbers as min and max. Let's have max = 1000 and min = 100, so after your Math.floor you will need to divide by 100:
var randomnum = Math.floor(Math.random() * (1000 - 100) + 100) / 100;
Or if you want to work with decimals:
var precision = 100; // 2 decimals
var randomnum = Math.floor(Math.random() * (10 * precision - 1 * precision) + 1 * precision) / (1*precision);
Multiply the original random number by 10^decimalPlaces, floor it, and then divide by 10^decimalPlaces. For instance:
floor(8.885729840652472 * 100) / 100 // 8.88
function genRand(min, max, decimalPlaces) {
var rand = Math.random()*(max-min) + min;
var power = Math.pow(10, decimalPlaces);
return Math.floor(rand*power) / power;
}
for (var i=0; i<20; i++) {
document.write(genRand(0, 10, 2) + "<br>");
}
Edit in response to comments:
For an inclusive floating-point random function (using this answer):
function genRand(min, max, decimalPlaces) {
var rand = Math.random() < 0.5 ? ((1-Math.random()) * (max-min) + min) : (Math.random() * (max-min) + min); // could be min or max or anything in between
var power = Math.pow(10, decimalPlaces);
return Math.floor(rand*power) / power;
}
Just to simplify things visually, mathematically and functionally based on the examples above.
function randomNumberGenerator(min = 0, max = 1, fractionDigits = 0, inclusive = true) {
const precision = Math.pow(10, Math.max(fractionDigits, 0));
const scaledMax = max * precision;
const scaledMin = min * precision;
const offset = inclusive ? 1 : 0;
const num = Math.floor(Math.random() * (scaledMax - scaledMin + offset)) + scaledMin;
return num / precision;
};
The Math.max protects against negative decimal places from fractionDigits
You can use below code.
var randomnum = (Math.random() * (10.00 - 1.00 + 1.00) + 1.00).toFixed(2);
A more way with typescript/angular example:
getRandom(min: number, max: number) {
return Math.random() * (max - min) + min;
}
console.log('inserting min and max values: ', this.getRandom(-10.0, -10.9).toPrecision(4));
getting random values between -10.0 and -10.9
Here is another way not yet mentioned, which will generate a random number between 1 and 9.99...
(Math.random() * 8 + 1 + Math.random()).toFixed(2)
console.log((Math.random() * 8 + 1 + Math.random()).toFixed(2))
Whether this is the most practical approach is another question altogether.
A simple javascript example to generate a random number with precision:
function genRand(min, max, decimalPlaces) {
return (Math.random() * (max - min) + min).toFixed(decimalPlaces) * 1;
}
console.log(genRand(-5, 5, 2));
It doesn't give me a value r in the given range? Why?
function getRandomIntInclusive(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var x = window.prompt("minimo");
var y = window.prompt("maximo");
var r = getRandomIntInclusive(x,y);
console.log(r);
edit: This function has been taken from a link of dev mozilla
Thank you
prompt returns a string, you need to parse those strings into integers:
function getRandomIntInclusive(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var x = parseInt(window.prompt("minimo"), 10);
var y = parseInt(window.prompt("maximo"), 10);
var r = getRandomIntInclusive(x, y);
console.log(r);
window.prompt is returning a string, so when you add min ( + min ), you get string concatenation instead of addition. A simple solution is to convert the result of window.prompt to a number:
function getRandomIntInclusive(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var x = parseInt( prompt("minimo"), 10 );
var y = parseInt( prompt("maximo"), 10 );
var r = getRandomIntInclusive(x,y);
console.log(r);
The issue is that javascript is not treating the values as numbers, and is instead treating them as strings.
The below code should get you started fixing this problem, however note that it can have errors if you pass in bad values:
function getRandomIntInclusive(min, max) {
min = parseFloat(min);
max = parseFloat(max);
return Math.floor(Math.random() * ((max - min) + 1)) + min;
}
Working fiddle: https://jsfiddle.net/a5fng2h6/
use parseInit() to convert string to integer
function getRandomIntInclusive(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var x = window.prompt("minimo");
var y = window.prompt("maximo");
var r = getRandomIntInclusive(parseInt(x),parseInt(y));
alert(r);
Try : min + Math.floor( Math.random()*max)
I want to create a function that generates mathematical expressions like ( 21 + 13 ) * 56 using random numbers from 1 to 100.
The function must take a level parameter. The level determines the length of the generated equation, for example:
// level 2
75 - 54 = 21
62 + 15 = 77
88 / 22 = 4
93 + 22 = 115
90 * 11 = 990
// level 3
( 21 + 13 ) * 56 = 1904
82 - 19 + 16 = 79
51 * ( 68 - 2 ) = 3366
So far I can create equations without brackets but I need help that would give me a reliable solution. This is what I have done so far:
var level = 3;
var x = ['/', '*', '-', '+'];
function randomNumberRange(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
var a = '';
for (var i = 0; i < level; i++) {
if (i !== level - 1) {
var n1 = randomNumberRange(1, 100);
var m = randomNumberRange(0, x.length);
var str = x[m];
a += n1;
a += ' ' + str + ' ';
} else {
a += n1;
}
}
I picked up the idea of #plamut to create a binary tree, where each node represents an operator with a left and a right side.
For instance, the equation 2 * (3 + 4) can be seen as
*
/ \
2 +
/ \
3 4
You can represent this quite straight forward using objects as follows:
var TreeNode = function(left, right, operator) {
this.left = left;
this.right = right;
this.operator = operator;
this.toString = function() {
return '(' + left + ' ' + operator + ' ' + right + ')';
}
}
Then you can create a recursive function to build such trees, where one sub-tree would have half of the desired total number of nodes (= length of equation):
function buildTree(numNodes) {
if (numNodes === 1)
return randomNumberRange(1, 100);
var numLeft = Math.floor(numNodes / 2);
var leftSubTree = buildTree(numLeft);
var numRight = Math.ceil(numNodes / 2);
var rightSubTree = buildTree(numRight);
var m = randomNumberRange(0, x.length);
var str = x[m];
return new TreeNode(leftSubTree, rightSubTree, str);
}
Here's a JSFiddle with a working example.
Maybe you still want to care about special cases, like avoiding brackets at top level, but that shouldn't be too hard from here.
Here an implementation that works for +, -, *, /, %, ^, parentheses and functions (min, max, sin, cos, tan, log). You can also easily add support for more functions like sqrt, asin, acos...
const operatorsKeys = ['+', '-', '*', '/', '%', '^'];
const functions = {
min: { arity: 2 },
max: { arity: 2 },
sin: { arity: 1 },
cos: { arity: 1 },
tan: { arity: 1 },
log: { arity: 1 }
};
const functionsKeys = Object.keys(functions);
// ⚠️ High probability that the expression calculation is NaN because of 'log(-1)', '-1 ^ 0.1', '1 % 0', '1 / 0 * 0'
function getRandomMathExpression(nbNodes: number): string {
assert(nbNodes > 0, 'nbNodes must be > 0');
if (nbNodes === 1) {
//return getRandomInt(-9, 9).toString();
return getRandomFloat(-100, 100, { decimalPlaces: 2 }).toString();
}
const operator = operatorsKeys[getRandomInt(0, operatorsKeys.length - 1)];
const func = functionsKeys[getRandomInt(0, functionsKeys.length - 1)];
const nbNodesLeft = Math.floor(nbNodes / 2);
const nbNodesRight = Math.ceil(nbNodes / 2);
const left = getRandomMathExpression(nbNodesLeft);
const right = getRandomMathExpression(nbNodesRight);
let expr;
if (Math.random() < 0.5) {
// eval("-1 ** 2") => eval("(-1) ** 2")
// Fix "SyntaxError: Unary operator used immediately before exponentiation expression..."
expr = operator === '^' ? `(${left}) ${operator} ${right}` : `${left} ${operator} ${right}`;
expr = Math.random() < 0.5 ? `(${expr})` : expr;
} else {
expr =
functions[func]!.arity === 2
? `${func}(${left}, ${right})`
: `${func}(${left}) ${operator} ${right}`;
}
return expr;
}
// Exported for testing purposes only
// https://stackoverflow.com/a/45736131
export function getNumberWithDecimalPlaces(num: number, decimalPlaces: number) {
const power = 10 ** decimalPlaces;
return Math.floor(num * power) / power;
}
type GetRandomNumberOptions = {
/**
* The number of digits to appear after the decimal point.
* https://ell.stackexchange.com/q/141863
*/
decimalPlaces?: number;
};
// min included, max excluded
export function getRandomFloat(min: number, max: number, options: GetRandomNumberOptions = {}) {
const { decimalPlaces } = options;
const num = Math.random() * (max - min) + min;
if (decimalPlaces === undefined) {
return num;
}
return getNumberWithDecimalPlaces(num, decimalPlaces);
}
// min/max included
export function getRandomInt(min: number, max: number) {
// https://stackoverflow.com/a/7228322
return Math.floor(Math.random() * (max - min + 1)) + min;
}
Examples / unit tests:
function convertMathExpressionToEval(expr: string) {
let evalExpr = expr.replaceAll('^', '**');
functionsKeys.forEach(func => (evalExpr = evalExpr.replaceAll(func, `Math.${func}`)));
return evalExpr;
}
test('getRandomMathExpression()', () => {
const numberRegex = /-?\d+(\.\d+)?/g;
for (let i = 0; i < 100; i++) {
// 13.69
// -97.11
{
const expr = getRandomMathExpression(1);
expect(expr).toMatch(/^-?\d+(\.\d+)?$/);
expect(eval(convertMathExpressionToEval(expr))).toEqual(expect.any(Number));
}
// cos(-20.85) * 65.04
// max(50.44, 66.98)
// (-13.33 / 70.81)
// -51.48 / -83.07
{
const expr = getRandomMathExpression(2);
expect(expr.match(numberRegex)).toHaveLength(2);
expect(eval(convertMathExpressionToEval(expr))).toEqual(expect.any(Number));
}
// min(-91.65, min(99.88, -33.67))
// (-77.28 % sin(-52.18) + -20.19)
// (67.58 % -32.31 * -7.73)
// (28.33) ^ (-32.59) ^ -80.54
{
const expr = getRandomMathExpression(3);
expect(expr.match(numberRegex)).toHaveLength(3);
expect(eval(convertMathExpressionToEval(expr))).toEqual(expect.any(Number));
}
// cos(max(24.57, 84.07)) ^ tan(51.78) - -45.52
// (min(-40.91, -67.48) * sin(-25.99) ^ -29.35)
// cos(1.61 - -22.15) % (-70.39 * 0.98)
// ((30.91) ^ -63.24) + 76.72 / 61.07
{
const expr = getRandomMathExpression(4);
expect(expr.match(numberRegex)).toHaveLength(4);
expect(eval(convertMathExpressionToEval(expr))).toEqual(expect.any(Number));
}
// tan((24.97) ^ 55.61) ^ (-46.74 % -31.38 * 84.34)
// max(tan(-7.78) + -2.43, max(35.48, (6.13 % 25.54)))
// ((5.66 / 23.21) - (-22.93 % 96.56 * 52.12))
// (((-40.93 % 13.72)) ^ (29.48 * 57.34 + 13.26))
{
const expr = getRandomMathExpression(5);
expect(expr.match(numberRegex)).toHaveLength(5);
expect(eval(convertMathExpressionToEval(expr))).toEqual(expect.any(Number));
}
}
// Torture test, should not throw
for (let i = 0; i < 100; i++) {
const expr = getRandomMathExpression(1000);
expect(expr.match(numberRegex)).toHaveLength(1000);
// The longer the expression, the more likely it will result in a NaN
expect(eval(convertMathExpressionToEval(expr))).toEqual(expect.any(Number));
}
});
More here: https://gist.github.com/tkrotoff/b0b1d39da340f5fc6c5e2a79a8b6cec0
How can I generate a random number between 1 - 10 except that the random number can't be 3
Get a random number between 1 and 9 and then add one if it's 3 or greater, or
better, just change any 3s into 10s.
function getNumber() {
return (n = 9 * Math.ceil(Math.random())) === 3? 10: n;
}
Based on this nice answer:
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var rand;
while((rand = getRandomInt(1, 10)) == 3);
// rand is now your random number
function rand(begin, end) {
var result = Math.floor( Math.random() * (end - begin + 1) ) + begin;
return result === 3 ? rand(begin, end) : result;
}
function rand(){
var r = Math.ceil(Math.random() * 10);
if (r==3){
return rand()}
else
return r;
}
Here's a short, quick solution, using a self-executing function, that does what you need exactly but is only useful for the specific circumstance you describe:
var randOneToTenButNotThree = function () {
var result = Math.floor(Math.random() * 10) + 1; // PICK A NUMBER BETWEEN 1 AND 10
return (result !== 3) ? result : randOneToTenButNotThree(); // IF THE NUMBER IS NOT 3 RETURN THE RESULT, OTHERWISE CALL THIS FUNCTION AGAIN TO PICK ANOTHER NUMBER
}
var result = randOneToTenButNotThree(); // RESULT SHOULD BE A NUMBER BETWEEN 1 AND 10 BUT NOT 3
However, you could abstract this out to produce a random number in any given range, excluding any number of your choice:
var randExcl = function (lowest, highest, excluded) {
var result = Math.floor(Math.random() * (highest - lowest)) + lowest;
return (result !== excluded) ? result : randExcl();
}
var result = randExcl();
Just don't forget that if the function is renamed, you should also change the reference to it from within at the end of that return statement so that it can keep calling itself whenever it produces the excluded number.
This should work.
var r = 3;
while(r == 3) r = Math.ceil(Math.random() * 10);
function r(){a = Math.floor(Math.random() * 10) + 1; if (a==3) a++; return a;}