I need a function to calculate the number of possible addition equations for a given sum n.
The operands must always be in descending order, cannot be equal, and must be greater than 0.
So, 5+4 is valid but 4+5 5+5 3+3+3 or 9+0 are not. Only integers are used.
For instance:
n = 2. Result is 0
n = 3. Result is 1. 2+1
n = 5. Result is 2. 4+1 and 3+2
n = 10. Result is 8. 9+1, 8+2, 7+3, 6+4, 7+2+1, 6+3+1, 5+4+1, 5+3+2
Just divide the number by 2 and floor the result:
function calc(num){
return Math.floor(num/2);
}
console.log(calc(5)) //4+1, 2+3
console.log(calc(6)) //1+5, 2+4, 3+3
console.log(calc(7)) //1+6, 2+5, 3+4
Related
This question already has an answer here:
Limit the length of number by rounding it
(1 answer)
Closed 8 months ago.
I want to limit the number to max 5 digits by rounding the decimal. If we have less than 5 digits the number should stay untouched.
Could anyone help me to write that function?
function limitAndRoundNumber(number) {
...
}
Exemplary inputs and outputs:
limitAndRoundNumber(1.234) should return 1.234 (unchanged because number has less than 5 digits)
limitAndRoundNumber(1.234567) should return 1.2346
limitAndRoundNumber(12.34567) should return 12.346
limitAndRoundNumber(123.4567) should return 123.46
limitAndRoundNumber(1234.567) should return 1234.6
limitAndRoundNumber(12345) should return 12345
Input number can be grater than 0 and less than 100000
I tend to use the following to cut a number to a set number of decimals
Math.round(number * multiplier) / multiplier
Where 'multiplier' is 10 to the power of the number of decimals. Now you only need to figure out what the multiplier needs to be, and you can do that by rounding to a whole value and getting the string length of the number. So something like:
function limitAndRoundNumber(number) {
const wholeDigits = Math.round(number).toString().length;
const power = wholeDigits <= 5 ? 5 - wholeDigits : 0;
const multiplier = 10**power;
return Math.round(number * multiplier) / multiplier;
}
console.log(limitAndRoundNumber(1.23));
console.log(limitAndRoundNumber(1.234567));
console.log(limitAndRoundNumber(12.34567));
console.log(limitAndRoundNumber(123.4567));
console.log(limitAndRoundNumber(1234.567));
console.log(limitAndRoundNumber(12345));
console.log(limitAndRoundNumber(123456));
One solution is to convert the number to a string and use String.slice(0,requiredLength) to adjust the length before returning a number version of the string.
The length would depend on whether the number contained a decimal separator, which could be determined by a conditional within the function.
Working snippet:
function limitAndRoundNumber(number) {
const length = (number.toString().indexOf('.')) ? 6 : 5;
return parseFloat(number.toString().slice(0,length));
}
console.log(limitAndRoundNumber(1.234567));
console.log(limitAndRoundNumber(12.34567));
console.log(limitAndRoundNumber(123.4567));
console.log(limitAndRoundNumber(1234.567));
console.log(limitAndRoundNumber(12345));
console.log(limitAndRoundNumber(12));
console.log(limitAndRoundNumber(12.3));
The function could be modified to allow for any length, by including a length argument and referencing it in the ternary operator test for the decimal separator:
length = (number.toString().indexOf('.')) ? length+1 : length;
I saw a code like this. I looked up MDN but there's no mention about toString having parameters. What does 3 do inside n.toString(3)?
function solution(n) {
n = n.toString(3).split('').reverse().join('')
return parseInt(n, 3)
}
This is Number.prototype.toString(), not Array.prototype.toString(). It takes radix as an optional parameter.
An integer in the range 2 through 36 specifying the base to use for representing numeric values.
Your code converts n to base-3. If you want to convert a number to binary, you'd do n.toString(2)
const n = 16,
bases = [2, 3, 4, 10, 16]
console.log(
bases.map(radix => n.toString(radix))
)
It is an optional parameter when converting number to string:
Optional. Which base to use for representing a numeric value. Must be
an integer between 2 and 36. 2 - The number will show as a binary
value 8 - The number will show as an octal value 16 - The number will
show as an hexadecimal value
This is the Radix (a number represent base-3 numeral system or any other numeral systems). For example if you put 2 instead of 3 this function convert the result into the binary system.
you can put from 2 - 36 in it as the parameter.And the default value is 10 and this parameter is completely optional.
test this one:
var x = 10;
x.toString(2); // output: "1010"
I am really curious how these functions actually work? I know there are a lot of questions about how to use these, I already know how to use them, but I couldn't find anywhere how to actually go about implementing this functionality on an array, for example, if there were no such functions? How would you code such a function if there were no helpers?
Here is the Math.max code in Chrome V8 engine.
function MathMax(arg1, arg2) { // length == 2
var length = %_ArgumentsLength();
if (length == 2) {
arg1 = TO_NUMBER(arg1);
arg2 = TO_NUMBER(arg2);
if (arg2 > arg1) return arg2;
if (arg1 > arg2) return arg1;
if (arg1 == arg2) {
// Make sure -0 is considered less than +0.
return (arg1 === 0 && %_IsMinusZero(arg1)) ? arg2 : arg1;
}
// All comparisons failed, one of the arguments must be NaN.
return NaN;
}
var r = -INFINITY;
for (var i = 0; i < length; i++) {
var n = %_Arguments(i);
n = TO_NUMBER(n);
// Make sure +0 is considered greater than -0.
if (NUMBER_IS_NAN(n) || n > r || (r === 0 && n === 0 && %_IsMinusZero(r))) {
r = n;
}
}
return r;
}
Here is the repository.
Below is how to implement the functions if Math.min() and Math.max() did not exist.
Functions have an arguments object, which you can iterate through to get its values.
It's important to note that Math.min() with no arguments returns Infinity, and Math.max() with no arguments returns -Infinity.
function min() {
var result= Infinity;
for(var i in arguments) {
if(arguments[i] < result) {
result = arguments[i];
}
}
return result;
}
function max() {
var result= -Infinity;
for(var i in arguments) {
if(arguments[i] > result) {
result = arguments[i];
}
}
return result;
}
//Tests
console.log(min(5,3,-2,4,14)); //-2
console.log(Math.min(5,3,-2,4,14)); //-2
console.log(max(5,3,-2,4,14)); //14
console.log(Math.max(5,3,-2,4,14)); //14
console.log(min()); //Infinity
console.log(Math.min()); //Infinity
console.log(max()); //-Infinity
console.log(Math.max()); //-Infinity
Let's take a look at the specifications (which could/should help you in implementation!)
In ECMAScript 1st Edition (ECMA-262) (the initial definitions for both Math.max/min), we see the following:
15.8.2.11 max(x, y)
Returns the larger of the two arguments.
• If either argument is NaN, the result is NaN.
• If x>y, the result is x.
• If y>x, the result is y.
• If x is +0 and y is +0, the result is +0.
• If x is +0 and y is −0, the result is +0.
• If x is −0 and y is +0, the result is +0.
• If x is −0 and y is −0, the result is −0.
15.8.2.12 min(x, y)
Returns the smaller of the two arguments.
• If either argument is NaN, the result is NaN.
• If x<y, the result is x.
• If y<x, the result is y.
• If x is +0 and y is +0, the result is +0.
• If x is +0 and y is −0, the result is −0.
• If x is −0 and y is +0, the result is −0.
• If x is −0 and y is −0, the result is −0.
Later versions of the specification give us:
ECMAScript 5.1
15.8.2.11 max ( [ value1 [ , value2 [ , … ] ] ] )
Given zero or more arguments, calls ToNumber on each of the arguments and returns the largest of the resulting values.
• If no arguments are given, the result is −∞.
• If any value is NaN, the result is NaN.
• The comparison of values to determine the largest value is done as in 11.8.5 except that +0 is considered to be larger than −0.
The length property of the max method is 2.
15.8.2.12 min ( [ value1 [ , value2 [ , … ] ] ] )
Given zero or more arguments, calls ToNumber on each of the arguments and returns the smallest of the resulting values.
• If no arguments are given, the result is +∞.
• If any value is NaN, the result is NaN.
• The comparison of values to determine the smallest value is done as in 11.8.5 except that +0 is considered to be larger than −0.
The length property of the min method is 2.
The reference to 11.8.5 can be found here: The Abstract Relational Comparison Algorithm
ECMAScript 2015
20.2.2.24 Math.max ( value1, value2 , …values )
Given zero or more arguments, calls ToNumber on each of the arguments and returns the largest of the resulting values.
• If no arguments are given, the result is −∞.
• If any value is NaN, the result is NaN.
• The comparison of values to determine the largest value is done using the Abstract Relational Comparison algorithm (7.2.11) except that +0 is considered to be larger than −0.
The length property of the max method is 2.
20.2.2.25 Math.min ( value1, value2 , …values )
Given zero or more arguments, calls ToNumber on each of the arguments and returns the smallest of the resulting values.
• If no arguments are given, the result is +∞.
• If any value is NaN, the result is NaN.
• The comparison of values to determine the smallest value is done using the Abstract Relational Comparison algorithm (7.2.11) except that +0 is considered to be larger than −0.
The length property of the min method is 2.
And again, 7.2.11 can be found here: Abstract Relational Comparison
Basic functionality:
Math.max() and Math.min() are used on numbers (or what they can coerce into numbers) you cannot directly pass an array as a parameter.
Ex:
Math.max(1,52,28)
You can have an number of comma delimited numbers.
Arrays:
This example shows how one could apply them to arrays:
JavaScript: min & max Array values?
Basically the following works:
Math.max.apply(null, [1,5,2,3]);
Why that works?
This works because apply is a function that all functions have which applies a function with the arguments of an array.
Math.max.apply(null, [1,5,2,3]) is the same as Math.max(1,5,2,3)
Well, here's min without Math.min (code is in ES6).
function min() {
return Array.from(arguments).reduce(
(minSoFar, next) => minSoFar < next ? minSoFar : next
, Infinity)
}
The same logic could be implemented with a simple loop. You would just need to keep track of one of variable through your iteration, which is the lowest value you've seen so far. The initial value of minSoFar would be Infinity. The reason is that any Number except Infinity is less than Infinity, but in the case of no arguments sent, we want to return Infinity itself, because that's what Math.min() with no arguments evaluates to.
function min() {
let minSoFar = Infinity
for(let i = 0, l = arguments.length; i < l; i++) {
const next = arguments[i]
minSoFar = minSoFar < next ? minSoFar : next
}
return minSoFar
}
Max can be implemented with pretty much the same logic, only you're keeping track of the highest value you've seen so far, and the initial value is -Infinity.
This is easy to implement with Array.prototype.reduce:
function min() {
var args = Array.prototype.slice.call(arguments);
var minValue = args.reduce(function(currentMin, nextNum) {
if (nextNum < currentMin) {
// nextNum is less than currentMin, so we return num
// which will replace currentMin with nextNum
return nextNum;
}
else {
return currentMin;
}
}, Infinity);
return minValue;
}
Here is the implementation of Math.min and Math.max from a real Javascript engine
Math.max : https://github.com/v8/v8/blob/cd81dd6d740ff82a1abbc68615e8769bd467f91e/src/js/math.js#L78-L102
Math.min : https://github.com/v8/v8/blob/cd81dd6d740ff82a1abbc68615e8769bd467f91e/src/js/math.js#L105-L129
I am confused about how arrays work in tandem with functions like Math.random(). Since the Math.random() function selects a number greater than or equal to 0 and less than 1, what specific number is assigned to each variable in an array? For example, in the code below, what number would have to be selected to print out 1? What number would have to be selected to print out jaguar?
var examples= [1, 2, 3, 56, "foxy", 9999, "jaguar", 5.4, "caveman"];
var example= examples[Math.round(Math.random() * (examples.length-1))];
console.log(example);
Is each element in an array assigned a position number equal to x/n (x being the position number relative to the first element and n being the number of elements)? Since examples has 9 elements, would 1 be at position 1/9 and would 9999 be at position 6/9?
Math.round() vs. Math.floor()
The first thing to note: Math.round() is never the right function to use when you're dealing with a value returned by Math.random(). It should be Math.floor() instead, and then you don't need that -1 correction on the length. This is because Math.random() returns a value that is >= 0 and < 1.
This is a bit tricky, so let's take a specific example: an array with three elements. As vihan1086's excellent answer explains, the elements of this array are numbered 0, 1, and 2. To select a random element from this array, you want an equal chance of getting any one of those three values.
Let's see how that works out with Math.round( Math.random() * array.length - 1 ). The array length is 3, so we will multiply Math.random() by 2. Now we have a value n that is >= 0 and < 2. We round that number to the nearest integer:
If n is >= 0 and < .5, it rounds to 0.
If n is >= .5 and < 1.5, it rounds to 1.
If n is >= 1.5 and < 2, it rounds to 2.
So far so good. We have a chance of getting any of the three values we need, 0, 1, or 2. But what are the chances?
Look closely at those ranges. The middle range (.5 up to 1.5) is twice as long as the other two ranges (0 up to .5, and 1.5 up to 2). Instead of an equal chance for any of the three index values, we have a 25% chance of getting 0, a 50% chance of getting 1, and a 25% chance of 2. Oops.
Instead, we need to multiply the Math.random() result by the entire array length of 3, so n is >= 0 and < 3, and then floor that result: Math.floor( Math.random() * array.length ) It works like this:
If n is >= 0 and < 1, it floors to 0.
If n is >= 1 and < 2, it floors to 1.
If n is >= 2 and < 3, it floors to 2.
Now we clearly have an equal chance of hitting any of the three values 0, 1, or 2, because each of those ranges is the same length.
Keeping it simple
Here is a recommendation: don't write all this code in one expression. Break it up into simple functions that are self-explanatory and make sense. Here's how I like to do this particular task (picking a random element from an array):
// Return a random integer in the range 0 through n - 1
function randomInt( n ) {
return Math.floor( Math.random() * n );
}
// Return a random element from an array
function randomElement( array ) {
return array[ randomInt(array.length) ];
}
Then the rest of the code is straightforward:
var examples = [ 1, 2, 3, 56, "foxy", 9999, "jaguar", 5.4, "caveman" ];
var example = randomElement( examples );
console.log( example );
See how much simpler it is this way? Now you don't have to do that math calculation every time you want to get a random element from an array, you can simply call randomElement(array).
They're is quite a bit happening so I'll break it up:
Math.random
You got the first part right. Math.random will generate a number >= 0 and < 1. Math.random can return 0 but chances are almost 0 I think it's like 10^{-16} (you are 10 billion times more likely to get struck by lightning). This will make a number such as:
0.6687583869788796
Let's stop there for a second
Arrays and their indexes
Each item in an array has an index or position. This ranges from 0 - infinity. In JavaScript, arrays start at zero, not one. Here's a chart:
[ 'foo', 'bar', 'baz' ]
Now the indexes are as following:
name | index
-----|------
foo | 0
bar | 1
baz | 2
To get an item from it's index, use []:
fooBarBazArray[0]; // foo
fooBarBazArray[2]; // baz
Array length
Now the array length won't be the same as the largest index. It will be the length as if we counted it. So the above array will return 3. Each array has a length property which contains it's length:
['foo', 'bar', 'baz'].length; // Is 3
More Random Math
Now let's take a look at this randomizing thing:
Math.round(Math.random() * (mathematics.length-1))
They're is a lot going on. Let's break it down:
Math.random()
So first we generate a random number.
* mathematics.length - 1
The goal of this random is to generate a random array index. We need to subtract 1 from the length to get the highest index.
First Part conclusions
This now gives us a number ranging from 0 - max array index. On the sample array I showed earlier:
Math.random() * (['foo', 'bar', 'baz'].length - 1)
Now they're is a little problem:
This code makes a random number between 0 and the length. That means the -1 shouldn't be there. Let's fix this code:
Math.random() * ['foo', 'bar', 'baz'].length
Running this code, I get:
2.1972009977325797
1.0244733088184148
0.1671080442611128
2.0442249791231006
1.8239217158406973
Finally
To get out random index, we have to make this from an ugly decimal to a nice integer: Math.floor will basically truncate the decimal off.
Math.floor results:
2
0
2
1
2
We can put this code in the [] to select an item in the array at the random index.
More Information / Sources
Random Numbers
More solutions
You're looking at simple multiplication, and a bug in your code. It should reference the array 'examples' that you are selecting from, instead of some thing you haven't mentioned called 'mathematics':
var example = examples[Math.round(Math.random() * (examples.length-1))];
^^
Then you're just multiplying a random number by the number of things in the array. So the maximum random number is 1 and if there are 50 things in your array you multiply the random number by 50, and now the maximum random number is 50.
And all the smaller random numbers (0 to 1) are also scaled 50x and now spread from (0 to 50) with roughly the same randomness to them. Then you round it to the nearest whole number, which is a random index into your array from 1 to n, and you can do element[thatnumber] to pick it out.
Full examples:
Math.random() returns numbers between 0 and 1 (it can return 0 but chances of that are incredibly small):
Math.random()
0.11506261994225964
Math.random()
0.5607304393516861
Math.random()
0.5050221864582
Math.random()
0.4070177578793308
Math.random()
0.6352060229006462
Multiply those numbers by something to scale them up; 1 x 10 = 10 and so Math.random() * 10 = random numbers between 0 and 10.
Math.random() *n returns numbers between 0 and n:
Math.random() * 10
2.6186012867183326
Math.random() * 10
5.616868671026196
Math.random() * 10
0.7765205189156167
Math.random() * 10
6.299650241067698
Then Math.round(number) knocks the decimals off and leaves the nearest whole number between 1 and 10:
Math.round(Math.random() * 10)
5
Then you select that numbered element:
examples[ Math.round(Math.random() * 10) ];
And you use .length-1 because indexing counts from 0 and finishes at length-1, (see #vihan1086's explanation which has lots about array indexing).
This approach is not very good at being random - particularly it's much less likely to pick the first and last elements. I didn't realise when I wrote this, but #Michael Geary's answer is much better - avoiding Math.round() and not using length-1.
This is an old question but I will provide a new and shorter solution to get a random item from an array.
Math.random
It returns a number between 0 and 1 (1 not included).
Bitwise not ~
This operator behaves returning the oposite value that you are providing, so:
a = 5
~a // -5
It also forgets about decimals, so for instance:
a = 5.95
~a // -5
It is skipping the decimals, so somehow it behaves like Math.floor (without returning a negative value, of course).
Doubled operators
Negative logical operator !, used to coerce to a boolean type is !!null // false and we are forcing it by double negation.
If we use the same idea but for numbers, we are forcing a number to floor if we do: ~~5.999 // 5
Therefore,
TLDR;
getRandom = (arr, len = arr.length) => arr[~~(Math.random() * len)]
example:
getRandom([1,2,3,4,5]) // random item between 1 and 5
In the code below, if result is set to one, the code returns a number 1024 (2 to the power of 10). If result is set to 2, the code returns the number 2048 (or 2 to the power of 11), BUT if result is set to 3, the code doesn`t return the number 4096 (as I would expect, because 2 to the power of 12) but rather 3072. Why does it return 3072 if "result" is set to 3, but otherwise if set to 1 and 2 it followers the pattern of power to the 10th and 11th
function power(base, exponent) {
var result = 1;
for (var count = 0; count < exponent; count++)
result *= base;
return result;
}
show(power(2, 10));
In this code, result is used as an accumulator. The code computes result * base**exponent; result is not part of the exponent.
I think you're confusing yourself. The thing being raised to some power is your first parameter (in your example 2). The exponent is the 2nd parameter (10). Your example works correctly. Pass in 12 as your exponent and you will see your expected result.
The result parameter is just a place holder in which you accumulate your results (2x2x2x2....)
The numbers doing all the work are the ones you pass in as parameters to the function.
So, in your example, you're going to take 2 and multiply it by itself 10 times, each time storing the cumulative result in the variable "result". The thing that's throwing you off is that result is initially set to 1. This is never meant to be altered. It's built that way so that if you set your exponent to 0 you will end up with a result of 1 (because any number raised to the zeroth power = 1).
Anyway... don't worry about what result is set to. Focus on how the loop works with the interchangeable variable values that are being passed in, in the function call.
Do out the multiplication:
3 * 2 = 6
6 * 2 = 16
12 * 2 = 24
24 * 2 = 48
48 * 2 = 96
96 * 2 = 192
192 * 2 = 384
384 * 2 = 768
768 * 2 = 1536
1536 * 2 = 3072
Multiplication table perhaps? Also, what's wrong with Math.pow, just trying to accomplish it yourself?