Get minimum number without a Math function - javascript

I need to get a minimum number without using Math.Min function.
The function I've written is quite voluminous, how can I shortened the code and make it more compact?
Feel free to offer other solutions!
Here is my code:
function getMin(a,b,c) {
if (a > b) {
if (b > c) {
return c;
} else {
return b;
}
} else {
if (a > c) {
return c;
} else {
return a;
}
}
}

You could take a nested conditional structure.
function getMin(a, b, c) {
return a > b
? b > c ? c : b
: a > c ? c : a;
}
console.log(getMin(1, 2, 3));
console.log(getMin(1, 3, 2));
console.log(getMin(2, 1, 3));
console.log(getMin(2, 3, 1));
console.log(getMin(3, 1, 2));
console.log(getMin(3, 2, 1));

You might use reduce method with any number of arguments:
function getMin(...args) {
return args.reduce((r, a) => r < a ? r : a, Number.MAX_SAFE_INTEGER)
}
console.log(getMin(-12, 45, 765))
console.log(getMin(-12, 45, 76, 5, 13, -123))
Or do the same using the oldschool for loop:
function getMin() {
var min = Number.MAX_SAFE_INTEGER;
for (var i in arguments)
if (min > arguments[i]) min = arguments[i];
return min;
}
console.log(getMin(-12, 45, 765))
console.log(getMin(-12, 45, 76, 5, 13, -123))

Similar to yours but more compact, you can merge that if statements:
function(a,b,c){
if (a>b && a>c) return a;
if (b>a && b>a) return b;
if (c>a && c>b) return c;
return a; // if they are equal
}
This doesn't scale well with more numbers. As I said, it is just compact version of yours.

Very Easy
function getMin(a,b,c) {
var min = arguments[0];
for (var i = 0, j = arguments.length; i < j; i++){
if (arguments[i] < min) {
min = arguments[i];
}
}
return min;
}
getMin(12,3,5,0,-8)
Demo

There are multiple ways to do so (I have just shared two example)
Here is the working example:
https://codebrace.com/editor/b0884a856
i. Using reduce
function getmin(numarray){
return numarray.reduce((a, b) => ((a > b)?b:a));
}
ii. using sort
function getmin(numarray){
return numarray.sort()[0];
}

Related

How to find the common prime factors of two numbers? javascript

I know how to find the prime factors of a number (my code is below), but I am wondering how I can find the common prime factors between two numbers? Thanks in advance!
function isPrime(number){
if(number<= 1) return false;
if(number===2) return true;
else{
for(let i=2; i<number; i++){
if(number%i===0){
return false;
}
}
return true;
}
}
console.log(isPrime(5)); //5
const findPrimeFactors = num => {
const result = num % 2 === 0 ? [2] : [];
let start = 0;
while(start <= num){
if(num % start === 0){
if(isPrime(start)){
result.push(start);
}
}
start++;
}
return result;
}
console.log(findPrimeFactors(18)); //[2, 2, 3]
console.log(findPrimeFactors(5)); //[5]
You can do as following:
Find the greatest common divisor of 2 numbers.
Factorization of the GCD is the result you want.
Note: It looks like your prime factors function is working wrong
const gcd = function(a, b) {
if (!b) {
return a;
}
return gcd(b, a % b);
}
function isPrime(number){
if(number<= 1) return false;
if(number===2) return true;
else{
for(let i=2; i<number; i++){
if(number%i===0){
return false;
}
}
return true;
}
}
function findPrimeFactors(n) {
const factors = [];
let divisor = 2;
while (n >= 2) {
if (n % divisor == 0) {
factors.push(divisor);
n = n / divisor;
} else {
divisor++;
}
}
return factors;
}
console.log(findPrimeFactors(gcd(6,12)))
Efficient way of doing this, using prime-lib library:
import {primeFactors} from 'prime-lib';
const arr1 = primeFactors(6); // [2, 3]
const arr2 = primeFactors(12); // [2, 2, 3]
const commonFactors = arr1.filter(value => arr2.includes(value));
console.log(commonFactors); //=> [2, 3]
We simply find all factors for both arrays, and get values intersection.
And primeFactors in that library performs much faster than earlier implementations shown here.

New Method for Finding Min Value in Named Array [duplicate]

I have an object that looks like this:
var obj = {
thingA: 5,
thingB: 10,
thingC: 15
}
I would like to be able to select the key/value pair thingA: 5 based on the fact that 5 is the smallest value compared to the other key/value pairs.
Nothing built-in does that, but:
var minPair = Object.keys(obj).map(function(k) {
return [k, obj[k]];
}).reduce(function(a, b) {
return b[1] < a[1] ? b : a;
});
minPair // ['thingA', 5]
Or, sans ECMAScript 5 extensions:
var minKey, minValue;
for(var x in obj) {
if(obj.hasOwnProperty(x)) {
if(!minKey || obj[x] < minValue) {
minValue = obj[x];
minKey = x;
}
}
}
[minKey, minValue] // ['thingA', 5]
here is a simple function that can do exactly what you wanted -
function getSmallest(obj)
{
var min,key;
for(var k in obj)
{
if(typeof(min)=='undefined')
{
min=obj[k];
key=k;
continue;
}
if(obj[k]<min)
{
min=obj[k];
key=k;
}
}
return key+':'+min;
}
//test run
var obj={thingA:5,thingB:10,thingC:15};
var smallest=getSmallest(obj)//thingA:5

GCD of more than 2 numbers

function gcd (a, b) {
if(b == 0){
return a;
}
return gcd(b, a%b);
}
function gcd_more_than_two_numbers (a) {
var last = Math.max.apply(null, a);
var first = Math.min.apply(null, a);
return gcd(first, last);
}
console.log(gcd_more_than_two_numbers([9999,213123,9,15,27]));
console.log(gcd_more_than_two_numbers([5,10,15,25]));
Is it right to take the lowest and the highest values in an array and find a gcd for all the numbers between them ? Is it mathematically right ?
Is it right to take the lowest and the highest values in an array and find a gcd for all the numbers between them ? Is it mathematically right ?
NO.
You need to take the gcd of the first pair and then recalculate against all the other elements of the array, you can do that easily with reduce:
function gcd (a, b) {
if(b == 0){
return a;
}
return gcd(b, a%b);
}
function gcd_more_than_two_numbers (a) {
return a.reduce(gcd)
}
console.log(gcd_more_than_two_numbers([9999,213123,9,15,27]))
No it isn't.
The identity you're after is gcd(a, b, c) = gcd(gcd(a, b), c).
I suggest you unpick the recursion using a loop.
function gcd() {
var arr = Array.prototype.slice.call(arguments);
return arr.reduce(function(a, b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
});
}
console.log(gcd(7,14));
console.log(gcd(9999,213123,9,15,27));
console.log(gcd(5,10,15,25));
You can use array.every as well to check validity:
Sample
function getGCD(arr) {
var min = Math.min.apply(null, arr);
var gcd = 1;
for (var i = gcd + 1; i <= min; i++) {
if (arr.every(x => x % i === 0))
gcd = i;
}
return gcd;
}
var arr = [100, 13000, 1110];
var arr2 = [9999, 213123, 9, 15, 27]
console.log(getGCD(arr))
console.log(getGCD(arr2))

javascript fibonacci memoization

To calculate the nth term of the fibonacci sequence, I have the familiar recursive function:
var fibonacci = function(index){
if(index<=0){ return 0; }
if(index===1){ return 1; }
if(index===2){ return 2; }
return fibonacci(index-2) + fibonacci(index-1);
}
This works as expected. Now, I am trying to store calculated indices in an object:
var results = {
0: 0,
1: 1,
2: 2
};
var fibonacci = function(index){
if(index<=0){ return 0; }
if(index===1){ return 1; }
if(index===2){ return 2; }
if(!results[index]){
results[index] = fibonacci(index-2) + fibonacci(index-1);
}
}
I know this isn't actually increasing performance since I'm not accessing the results object, but I wanted to check first if my results object was being populated correctly before memoizing. Unfortunately, it isn't. For fibonacci(9), I get:
Object {0: 0, 1: 1, 2: 2, 3: 3, 4: NaN, 5: NaN, 6: NaN, 7: NaN, 8: NaN, 9: NaN}
Why am I getting NaN for indices past 3?
Here's a solution using "Helper Method Recursion":
function fib(n) {
const memorize = {};
function helper(n) {
if (n in memorize) return memorize[n];
if (n < 3) return 1;
return memorize[n] = helper(n - 1) + helper(n - 2);
}
return helper(n);
}
Here is my solution:
function fib(n, res = [0, 1, 1]) {
if (res[n]) {
return res[n];
}
res[n] = fib(n - 1, res) + fib(n - 2, res);
return res[n];
}
console.log(fib(155));
The recursive Fibonacci consume too much processing power which is not good for application. to improve this we use Memoization. which keeps the computed result store in Array. so next when the same value comes it will simply return the Stored value from the computed Array.
function memoizeFabonaci(index, cache = []) {
// console.log('index :', index, ' cache:', cache)
if (cache[index]) {
return cache[index]
}
else {
if (index < 3) return 1
else {
cache[index] = memoizeFabonaci(index - 1, cache) + memoizeFabonaci(index - 2, cache)
}
}
return cache[index];
}
let a = 15
console.log('Memoize febonaci', memoizeFabonaci(a))
const f = (n, memo = [0, 1, 1]) => memo[n] ? memo[n] : (memo[n] = f(n - 1, memo) + f(n - 2, memo)) && memo[n]
console.log(f(70))
Going to close the loop on this answer by posting #Juhana's comment:
"Because your function doesn't return anything when index > 2"
Here're my solutions
With Memoization (Dynamic Programming) (Time complexity approximately O(n))
const results = {}
function fib(n) {
if (n <= 1) return n
if (n in results) {
return results[n]
}
else {
results[n] = fib(n - 2) + fib(n - 1)
}
return results[n]
}
console.log(fib(100))
Without Memoization (Time complexity approximately O(2^n))
function fib(n) {
if (n <= 1) return n
return fib(n - 1) + fib(n - 2)
}
console.log(fib(10))
Here is my object orientated attempt.
var memofib = {
memo : {},
fib : function(n) {
if (n === 0) {
return 0;
} else if (n === 1) {
return 1;
} else {
if(this.memo[n]) return this.memo[n];
return this.memo[n] = this.fib(n - 1) + this.fib(n - 2);
}
}
};
console.log(memofib.fib(10));
Here's my solution achieving memoization using a non-recursive approach.
// The Fibonacci numbers.
// 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ……..
function fibonacci(n) {
const map = new Map(); // Objects can also be used
map.set(0,1); // seed value for f(0)
map.set(1,1); // seed value for f(1)
for(let i=2; i < n - 1; i++) {
const result = map.get(i - 1) + map.get(i - 2);
map.set(i,result);
}
return map.get(n - 2);
}
console.log(fibonacci(20)); // 4181
I have added some additions.
var results = {};
var fibonacci = function (index) {
if (index <= 0) return 0;
if (index == 1 || index == 2) return 1;
return fibonacci(index - 2) + fibonacci(index - 1);
};
for (var i = 1; i <= 10; i++) {
results[i] = fibonacci(i);
}
console.log(results);

Javascript sort function. Sort by First then by Second

I have an array of objects to sort. Each object has two parameters: Strength and Name
objects = []
object[0] = {strength: 3, name: "Leo"}
object[1] = {strength: 3, name: "Mike"}
I want to sort first by Strength and then by name alphabetically. I am using the following code to sort by the first parameter. How do I sort then by the second?
function sortF(ob1,ob2) {
if (ob1.strength > ob2.strength) {return 1}
else if (ob1.strength < ob2.strength){return -1}
return 0;
};
Thanks for your help.
(I am using Array.sort() with the aforementioned sortF as the sort comparison function passed into it.)
Expand your sort function to be like this;
function sortF(ob1,ob2) {
if (ob1.strength > ob2.strength) {
return 1;
} else if (ob1.strength < ob2.strength) {
return -1;
}
// Else go to the 2nd item
if (ob1.name < ob2.name) {
return -1;
} else if (ob1.name > ob2.name) {
return 1
} else { // nothing to split them
return 0;
}
}
A < and > comparison on strings is an alphabetic comparison.
This little function is often handy when sorting by multiple keys:
cmp = function(a, b) {
if (a > b) return +1;
if (a < b) return -1;
return 0;
}
or, more concisely,
cmp = (a, b) => (a > b) - (a < b)
Which works because in javascript:
true - true // gives 0
false - false // gives 0
true - false // gives 1
false - true // gives -1
Apply it like this:
array.sort(function(a, b) {
return cmp(a.strength,b.strength) || cmp(a.name,b.name)
})
Javascript is really missing Ruby's spaceship operator, which makes such comparisons extremely elegant.
You could chain the sort order with logical OR.
objects.sort(function (a, b) {
return a.strength - b.strength || a.name.localeCompare(b.name);
});
When I was looking for an answer to this very question, the answers I found on StackOverflow weren't really what I hoped for. So I created a simple, reusable function that does exactly this. It allows you to use the standard Array.sort, but with firstBy().thenBy().thenBy() style.
https://github.com/Teun/thenBy.js
PS. This is the second time I post this. The first time was removed by a moderator saying "Please don't make promotional posts for your own work". I'm not sure what the rules are here, but I was trying to answer this question. I'm very sorry that it is my own work. Feel free to remove again, but please point me to the rule involved then.
steve's answer, but prettier.
objects.sort(function(a,b)
{
if(a.strength > b.strength) {return 1;}
if(a.strength < b.strength) {return -1;}
if(a.name > b.name ) {return 1;}
if(a.name < b.name ) {return -1;}
return 0;
}
function sortF(ob1,ob2) {
if (ob1.strength > ob2.strength) {return 1}
else if (ob1.strength < ob2.strength) {return -1}
else if (ob1.name > ob2.name) {return 1}
return -1;
};
EDIT: Sort by strength, then if strength is equal, sort by name.
The case where strength and name are equal in both objects doesn't need to be accounted for seperately, since the final return of -1 indicates a less-than-or-equal-to relationship. The outcome of the sort will be correct. It might make it run faster or slower, I don't know. If you want to be explicit, just replace
return -1;
with
else if (ob1.name < ob2.name) {return -1}
return 0;
Find 'sortFn' function below. This function sorts by unlimited number of parameters(such as in c#: SortBy(...).ThenBy(...).ThenByDesc(...)).
function sortFn() {
var sortByProps = Array.prototype.slice.call(arguments),
cmpFn = function(left, right, sortOrder) {
var sortMultiplier = sortOrder === "asc" ? 1 : -1;
if (left > right) {
return +1 * sortMultiplier;
}
if (left < right) {
return -1 * sortMultiplier;
}
return 0;
};
return function(sortLeft, sortRight) {
// get value from object by complex key
var getValueByStr = function(obj, path) {
var i, len;
//prepare keys
path = path.replace('[', '.');
path = path.replace(']', '');
path = path.split('.');
len = path.length;
for (i = 0; i < len; i++) {
if (!obj || typeof obj !== 'object') {
return obj;
}
obj = obj[path[i]];
}
return obj;
};
return sortByProps.map(function(property) {
return cmpFn(getValueByStr(sortLeft, property.prop), getValueByStr(sortRight, property.prop), property.sortOrder);
}).reduceRight(function(left, right) {
return right || left;
});
};
}
var arr = [{
name: 'marry',
LocalizedData: {
'en-US': {
Value: 10000
}
}
}, {
name: 'larry',
LocalizedData: {
'en-US': {
Value: 2
}
}
}, {
name: 'marry',
LocalizedData: {
'en-US': {
Value: 100
}
}
}, {
name: 'larry',
LocalizedData: {
'en-US': {
Value: 1
}
}
}];
document.getElementsByTagName('pre')[0].innerText = JSON.stringify(arr)
arr.sort(sortFn({
prop: "name",
sortOrder: "asc"
}, {
prop: "LocalizedData[en-US].Value",
sortOrder: "desc"
}));
document.getElementsByTagName('pre')[1].innerText = JSON.stringify(arr)
pre {
font-family: "Courier New" Courier monospace;
white-space: pre-wrap;
}
Before:
<pre></pre>
Result:
<pre></pre>
With ES6 you can do
array.sort(function(a, b) {
return SortFn(a.strength,b.strength) || SortFn(a.name,b.name)
})
private sortFn(a, b): number {
return a === b ? 0 : a < b ? -1 : 1;
}
Here is the function I use. It will do an arbitrary number.
function Sorter(){
var self = this;
this.sortDefs = [];
for (let i = 0; i < arguments.length; i++) {
// Runs 5 times, with values of step 0 through 4.
this.sortDefs.push(arguments[i]);
}
this.sort = function(a, b){
for (let i = 0; i < self.sortDefs.length; i++) {
if (a[self.sortDefs[i]] < b[self.sortDefs[i]]) {
return -1;
} else if (a[self.sortDefs[i]] > b[self.sortDefs[i]]) {
return 1
}
}
return 0;
}
}
data.sort(new Sorter('category','name').sort);
In 2018 you can use just sort() ES6 function, that do exactly, what you want.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

Categories