Javascript: Confused about usage of Infinity - javascript

I'm doing some practice problems to stay fresh and I've never really used Infinity before in my job. The question is:
Find maximum difference between two numbers in the given array. Also, the second number must be larger than the first one.
My solution was:
var maxProfit = function(prices) {
let min = 0;
let max = 0;
for (var x = 0; x < prices.length; x++) {
min = Math.min(min, prices[x]);
max = Math.max(max, prices[x] - min);
}
return max;
};
But it comes back incorrect and I'm not sure why. When looking at the accepted solutions, one of them has the same code as me except the initialized value of min is Infinity, ( let min = Infinity ) rather than 0. I'm not really sure how or why that works.

Because 0 is always smaller than any other positive number. Therefore unless you have negative prices, the minimum will be 0. You can exchange 0 with any other larger number, e.g. 1000, and even then the function might return the wrong minimum because the smallest price in the array might only be 1001. So as an initial value you can either take one of the array values (e.g. the first one), or you take Infinity cause that's greater than any other number, and thus it will never be the result unless the array is empty. And in that case, Infinity is a proper result.

Related

Create array with length n, initialize all values with 0 besides one which index matches a certain condition, in O(1)?

I want to create an array of type number with length n. All values inside the array should be 0 except the one which index matches a condition.
Thats how i currently do it:
const data: number[] = [];
for (let i = 0; i < n; i++) {
if (i === someIndex) {
data.push(someNumber);
} else {
data.push(0);
}
}
So lets say n = 4, someIndex = 2, someNumber = 4 would result in the array [0, 0, 4, 0].
Is there a way to do it in O(1) instead of O(n)?
Creating an array of size n in O(1) time is theoretically possible depending on implementation details - in principle, if an array is implemented as a hashtable then its length property can be set without allocating or initialising space for all of its elements. The ECMAScript specification for the Array(n) constructor doesn't mandate that Array(n) should do anything which necessarily takes more than O(1) time, although it also doesn't mandate that the time complexity is O(1).
In practice, Array(n)'s time complexity depends on the browser, though verifying this is a bit tricky. The performance.now() function can be used to measure the time elapsed between the start and end of a computation, but the precision of this function is artificially reduced in many browsers to protect against CPU-timing attacks like Spectre. To get around this, we can call the constructor repetitions times, and then divide the time elapsed by repetitions to get a more precise measurement per constructor call.
My timing code is below:
function timeArray(n, repetitions=100000) {
var startTime = performance.now();
for(var i = 0; i < repetitions; ++i) {
var arr = Array(n);
arr[n-1] = 'foo';
}
var endTime = performance.now();
return (endTime - startTime) / repetitions;
}
for(var n = 10000; n <= 1000000; n += 10000) {
console.log(n, timeArray(n));
}
Here's my results from Google Chrome (version 74) and Firefox (version 72); on Chrome the performance is clearly O(n) and on Firefox it's clearly O(1) with a quite consistent time of about 0.01ms on my machine.
I measured using repetitions = 1000 on Chrome, and repetitions = 100000 on Firefox, to get accurate enough results within a reasonable time.
Another option proposed by #M.Dietz in the comments is to declare the array like var arr = []; and then assign at some index (e.g. arr[n-1] = 'foo';). This turns out to take O(1) time on both Chrome and Firefox, both consistently under one nanosecond:
That suggests the version using [] is better to use than the version using Array(n), but still the specification doesn't mandate that this should take O(1) time, so there may be other browsers where this version takes O(n) time. If anybody gets different results on another browser (or another version of one of these browsers) then please do add a comment.
You need to assign n values, and so there is that amount of work to do. The work increases linearly with increasing n.
Having said that, you can hope to make your code a bit faster by making use of .fill:
const data: number[] = Array(n).fill(0);
data[someIndex] = someNumber;
But don't be mistaken; this is still O(n): .fill may be faster, but it still requires to fill the whole array with zeroes, which means a corresponding size of memory needs to be initialised, so that operation has linear time complexity.
If however you drop the requirement that zeroes need to be assigned, then you can only store the someNumber:
const data: number[] = Array(n);
data[someIndex] = someNumber;
This way you actually do not allocate the memory for the whole array, so this code snippet runs in constant time. Any access to an index different from someIndex will give you a value of undefined. You may trap that condition and translate that to a zero on-the-fly:
let value = i in data ? data[i] : 0;
Obviously, if you are going to access all indices of the array like that, you'll have again a linear time complexity.

Why -Infinity is like a base for comparing numbers to return max?

In this code i can't seem to understand why -Infinity is behaving like a base so when compared to it returns the biggest number from an array of numbers.
function max(...numbers) {
let result = -Infinity;
for (let number of numbers) {
if (number > result) result = number;
}
return result;
}
It is confusing at first and probably in your mind a solution would sound like this:
let result = 0;
The problem is that when we want to find the MAXIMUM value of an array we need to compare every element with each other. It is more like a "habit" that we set the MAXIMUM to -INFINITY. That simply means that the biggest element so far is the lowest possible number that we can express. Does it make sense? We simply assume that the biggest number we will every find is -Infinity. Then we compare the elements from the array with this base number(in our case -Infinity) and if we were false (and probably we were) then we replace -Infinity with the next number that's bigger than our current value. We do that for the whole range of numbers and that's how we find the Maximum element.
You can pick multiple elements as the starting point, but never pick a number entered by yourself( you should do that ONLY if the exercise asks so).
If you would pick for example:
let result = 0;
then you might have a problem. Maybe the numbers are all negative, for example [-3,-13,-5,13,-99] but you already set the biggest number to 0 so every comparation would be wrong and useless.
So, keep in mind that is a good practice, in this case, to set the base value to -Infinity or if you would like to take another approach then set the base value to the first element in the array.
In using this numbers to find the max of a series of numbers ,you loop through an array of numbers, each number will be compared to -infinity. And since the program is running from left to right the result will update itself each time it finds a bigger number. I tried this comparison method with an actual number.
let edge;
let array1 = [1, 2, 3, 4, 5, 6, 8, 9, 100, 200];
function maxwell(){
for(let checker of array1){
if(checker > 2)edge = checker;
}return edge;
}console.log(maxwell())

What is the Infinity property used for in Javascript?

Why is the Infinity property used as a command (rather than a result)
For example, this code below works, but the result isn't what I expected.
alert(isOdd(Infinity));
function isOdd(num) { return num%2==1; }
MDN REFERENCE
Infinity is a property of the global object, i.e. it is a variable in
global scope.
The initial value of Infinity is Number.POSITIVE_INFINITY. The value
Infinity (positive infinity) is greater than any other number. This
value behaves mathematically like infinity; for example, any positive
number multiplied by Infinity is Infinity, and anything divided by
Infinity is 0.
First what does this mean? In essence infinity is a concept not an actual value. Mathematics is based on concepts not values. For instance a number isn't a value, a numeral is.
The number 7 is the concept of the intended value, Romans wrote it as VII, in standard form (BASE-10) you write it as 7. In binary(BASE-2) you write it as 111. If you want to use a triangle or any other mark that is fine also as long as the concept is applied correctly.
Now that you know that, Infinity is simply the concept of being greater than any other number. It holds no value. The only reason that the basic concept of an infinity loops means to run forever is because in concept it means that whatever numeral iteration of that loop you are in (whether 1 or a million) infinity will always be greater than that number.
There are many methods to applying concepts in coding which is why everyone's code is ran differently but for example:
SAMPLE TAKEN FROM w3schools:
function findMax(x) {
var i;
var max = -Infinity;
for(i = 0; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
document.getElementById("demo").innerHTML = findMax(1, 123, 500, 115, 44, 88);
In the site's example they pass the argument of 6 values to the function findMax
findMax(1, 123, 500, 115, 44, 88);
They are then using a loop to stop at the parameters length. In the loop they are reassigning the max value from the concept of infinity to a value and if greater than that value when looped again the max value is then changed to the new high value.
Why is this important? Because in the example they use the concept of negative infinity which is simply the values of infinity decremented negatively. One could easily argue that 0 could replace -Infinity but they'd be wrong. This is why.
What if your value range is dependent upon negative values also being passed in the formula above? What if all you have is negative values that were dynamically captured from user input or another function?
Consider findMax was findMax(-1, -10, -15, -20);
0 would give a false output that it was the correct max value which wouldn't be what you wanted. You'd want -1 one to be the output. There are other methods to achieving the solution but for the sake of Infinity concept discussion I will end here.
I hope this sheds more light on the process of Infinity concept.
Infinity is a property of the global object that holds a numeric value representing the mathematical concept of infinity. I don't know any normal definition by which it could be called a "command."
With regard to your edit, that should return false (I ran it to confirm this suspicion, and it did on my browser). This is correct, as infinity is not normally considered an odd number.

Javascript Infinity

Division by 0 gives this special value:
3/0 output:Infinity
You can’t play positive and negative infinity against each other:
Infinity - Infinity output:NaN (Why?)
It also turns out that “beyond infinity” is still infinity:
Infinity + Infinity output:Infinity(this is accepted)
5 * Infinity
Infinity(this is also accepted)
so why infinity-infinity evalutes to NaN?It should be infinity isn't it?Also i wanted to know why cant object be converted to primitive values?Sorry for posting two question at a time ,as this is the last question i can post.See here:
var obj = {
valueOf: function () {
console.log("valueOf");
return {}; // not a primitive
},
toString: function () {
console.log("toString");
return {}; // not a primitive
}
}
Number(obj) //TypeError: Cannot convert object to primitive values
That's how ∞ works in mathematics. Infinity itself is not a number, it is a concept. The general idea is that
∞ + x = ∞ ∀ x
∞ is, obviously, infinitely big. If you subtract an infinitely big thing from another infinitely big thing, you can't define what you have left. If the first infinity is bigger, you'll get a negative result, but if it's smaller then the result will be positive (basic rule of subtraction), but since both are infinitely big you have no way of knowing which is bigger (unless more information is given, such as the context leading to these infinities*). Therefore, as far as the computer is concerned, ∞ - ∞ is mathematically undefined, or Not a Number.
* Example: Let x = the sum of all positive integers, and y = the sum of each positive integer doubled. In this case, we can say that y > x, even though both are infinity.
Because it's an indeterminate form, so it's not infinity. NaN reflects this the best way possible.
http://en.wikipedia.org/wiki/Indeterminate_form
Related question:
https://math.stackexchange.com/questions/60766/what-is-the-result-of-infinity-minus-infinity
var A = 1/0
var B = 2 * A
var c = B - A
Note that even though B = 2 * A, still A = B (2 * infinity is still infinity, so they are both infinity), so what do you expect C to be? infinity or 0?
Infinity is not really a number, mathematically speaking. Though IsNaN(1/0) = false.

How can I pick the lowest number from a list of numbers?

I have four numbers that can possible be the same, but or most likely different. Basically I want this function to chose no number of they are equal, but if they aren't, pick the lowest one, and if there are two that are the same, to just pick one of them and go with that.
Like for example I have 3434, 3396, 3414, and 3374. Well I want the function to return to me say 0 if they're all the same, 1 for the first one and so on. So in this situation I would need to be returned 4.
But if the numbers were 321, 576, 812, and 321 it would return to me 1.
I've been at this for a couple of days now and I just can't seem to find any way of doing what I need to do. Anyone know something that could make this work magically? Thanks!
EDIT
My approach had me doing something along the lines of creating an array sorting it and trying to use the last result, but when I sort the array, the keys get messed up so I don't know which value it belonged to
var choices = new Array();
choices[1] = parseInt(value1);
choices[2] = ...
choices = choices.sort();
//and then I ran into the problem that my keys being not starting
//with 0, it added an element which I was able to remove by doing this
choices = choices.splice(0,4);
And then I'm stuck for there
Here's a start on the journey to answering your question. As others have pointed out, this code does not handle all the cases you mention; this is deliberate.
How can I pick the lowest number from a list of numbers?
Hand-rolled way; O(n) and one pass:
var myList = [3434, 3396, 3414, 3374];
var min = Infinity;
var minIndex = -1;
var current;
for (var i=0; i<myList.length; i++)
{
current = myList[i];
if (current < min)
{
min = current;
minIndex = i;
}
}
// the value you want is in minIndex
Far more concise; also O(n) but two passes through the array:
var min = Math.min.apply(null, myList);
var minIndex = myList.indexOf(min);
N.B Array.indexOf requires a shim in older versions of IE.
Basically I want this function to chose no number of they are equal
This exercise, as they say, is left to the reader.

Categories

Resources