How to get the product of numbers gotten from combinations of datasets - javascript

I have a combinatoric script that's working fine, actually got most of it from the IBM dev website. But I want to be able to not just show the possible combinations, but also extract the numbers on each combination and get the product of the entire numbers. The project am working on mixes numbers (quantity) with strings (codename). So after combining them, i extract the number from each string and get the product of all the numbers in each combination. As shown;
[A2,B4,C5] = 2*4*5 = 40
Here is my javascript code that gets the combination, not to worry, I ran it with a test array of numbers 1-6, without the characters as shown above.
var Util = function() {
};
Util.getCombinations = function(array, size, start, initialStuff, output) {
if (initialStuff.length >= size) {
output.push(initialStuff);
} else {
var i;
for (i = start; i < array.length; ++i) {
Util.getCombinations(array, size, i + 1, initialStuff.concat(array[i]), output);
}
}
}
Util.getAllPossibleCombinations = function(array, size, output) {
Util.getCombinations(array, size, 0, [], output);
}
// Create an array that holds numbers from 1 ... 6.
var array = [];
for (var i = 1; i <= 6; ++i) {
array[i - 1] = i;
}
var output = [];
var resultArray = [];
Util.getAllPossibleCombinations(array, 4, output);
for(var j=0; j<output.length; j++) {
resultArray += output[j] + "=" + "<br />";
}
document.getElementById("test").innerHTML = resultArray;
});
I tried running this code inside the last for loop to get my multiplication, but it's just not executing, i must be doing something wrong. Here is the code;
var inputval = output[j].replace(/[^,.0-9]/g, '');
inputval = inputval.slice(0, -1);
var hoArray = inputval.split(',');
var cunt= hoArray.length;
var ans=1;
for(var m=0; m<cunt; m++)
{
ans *= hoArray[m];
}
Thanks for your assistance in advance.

walk the array then walk the string, then cast and see if it is an integer then tally and sum the product.
let array = ['A20', 'B11', 'C5'];
function getProduct(ar) {
let product = 1;
for (let x of ar) {
let semiProduct = [];
for (let i of x) {
if (Number.isInteger(+i)) {
semiProduct.push(i);
}
}
product *= semiProduct.join('');
}
return product;
}
console.log(getProduct(array))
You could also use a regular expression.
let array = ['A20', 'B11', 'C5'];
function getProduct(ar) {
let product = 1;
for (let x of ar) {
product *= x.match(/\d+/)[0];
}
return product;
}
console.log(getProduct(array))
If you want a way to generate permutations, you can utilize a generator to make things more concise.
let array = ['A20', 'B11', 'C5'];
function* permu(arr, l = arr.length) {
if (l <= 0) yield arr.slice();
else
for (var i = 0; i < l; i++) {
yield* permu(arr, l - 1);
const j = l % 2 ? 0 : i;
[arr[l - 1], arr[j]] = [arr[j], arr[l - 1]];
}
}
console.log(
Array.from(permu(array))
);

When I run that code in the console it throws an error because output[j] is an array [1,2,3,4] and it looks like you're expecting it to be a string. Arrays do not have a replace method in JS.
You should run this:
var count= hoArray.length;
var ans=1;
for(var m=0; m<count; m++)
{
ans *= hoArray[m];
}
And put output[j] instead of hoArray. And don't do any of this:
var inputval = output[j].replace(/[^,.0-9]/g, '');
inputval = inputval.slice(0, -1);
var hoArray = inputval.split(',');

Related

combinational sum- how to write test correctly JavaScript

I need to test Combinational Sum I algorithm using JavaScript. I have done all things in html, but I don't know how to call function (in script.js), which contain Combinational Sum I algorithm, correctly. Does anybody know how to call it? how to calculate? how to write test?
let botun=document.getElementById('botun');
//including variables
botun.onclick=function(){
let niz=document.getElementById('input').value;
let target=document.getElementById('target').value;
//convert string in array
let nizInt=niz.split(' ').map(Number);
//convert element of array in Int
let nizIntNovi=[];
for(var i=0; i<nizInt.length; i++) {
nizInt[i] = parseInt(nizInt[i], 10);
nizIntNovi[i]=nizInt[i];
}
console.log(nizIntNovi);
//calling function
let meduRez=combinationalSum(nizIntNovi,target);
console.log(meduRez);
}
// Javascript program to find all combinations that
// sum to a given value
var combinationalSum=function(candidates,target){
//global result
const result=[];
candidates.sort((a,b)=>a-b);
//dfs recursive helper
const dfs=(i,candidates,target,slate)=>{
//backtracking case
if(target<0) return;
//base case
if(target===0){
result.push(slate.slice());
return;
}
//dfs recursive case
for(let j=i;j<candidates.lenght;j++){
slate.push(candidates[j]);
dfs(j,candidates,target-candidates[j],slate);
slate.pop();
}
}
dfs(0,candidates,target,[]);
return result;
};
You call it like in the snippet below, with some basic HTML.
Or using the console of the browser.
The function is not working right.
You can read about implementation here https://www.geeksforgeeks.org/combinational-sum/
let botun = document.getElementById('botun');
//including variables
botun.onclick = function() {
let niz = document.getElementById('input').value;
let target = document.getElementById('target').value;
//convert string in array
let nizInt = niz.split(' ').map(Number);
//convert element of array in Int
let nizIntNovi = [];
for (var i = 0; i < nizInt.length; i++) {
nizInt[i] = parseInt(nizInt[i], 10);
nizIntNovi[i] = nizInt[i];
}
console.log(nizIntNovi);
//calling function
let meduRez = combinationalSum(nizIntNovi, target);
console.log(meduRez);
}
// Javascript program to find all combinations that
// sum to a given value
var combinationalSum = function(candidates, target) {
//global result
const result = [];
candidates.sort((a, b) => a - b);
//dfs recursive helper
const dfs = (i, candidates, target, slate) => {
//backtracking case
if (target < 0) return;
//base case
if (target === 0) {
result.push(slate.slice());
return;
}
//dfs recursive case
for (let j = i; j < candidates.lenght; j++) {
slate.push(candidates[j]);
dfs(j, candidates, target - candidates[j], slate);
slate.pop();
}
}
dfs(0, candidates, target, []);
return result;
};
input {
height: 30px;
width: 100px;
line-height: 1;
}
.as-console-wrapper {
max-height: 100% !important;
}
Input: <input id="input" value="1 2 3 4"> Target: <input id="target" value="6">
<input type="button" id="botun" value="click">
There is solved problem. Task: input array of integer, input target then calculate Combinational Sum and print the smallest array of Combinational Sum.
For example: Input: [2,4,6] Target:4. Output will be 1, because Combinational Sum prints (2+2),(4). Smaller array is 4 and it contains one element so 1 will be output!
Code:
let botun=document.getElementById('botun');
let nizSplitNew=[];
let targetNew;
let brojac;
let array=[];
let min;
var rezultat=document.getElementById("rezl");
//including variables
botun.onclick=function(){
let niz=document.getElementById('input').value;
let target=document.getElementById('target').value;
//convert string in array
let nizSplit=niz.split(',').map(Number);
//convert element of array in Int
for(var i=0; i<nizSplit.length; i++) {
nizSplitNew[i] = parseInt(nizSplit[i], 10);
}
console.log(nizSplitNew);
targetNew = parseInt(target, 10);
//calling function
let meduRez=combinationSum(nizSplitNew,targetNew);
// Javascript program to find all combinations that
// sum to a given value
function combinationSum(arr, sum) {
let ans = new Array();
let temp = new Array();
// first do hashing since hashset does not always
// sort
// removing the duplicates using HashSet and
// Sorting the arrayList
let set = new Set([...arr]);
arr = [...set];
arr.sort()
findNumbers(ans, arr, sum, 0, temp);
return ans;
}
function findNumbers(ans, arr, sum, index, temp) {
if (sum == 0) {
// pushing deep copy of list to ans
ans.push([...temp]);
return;
}
for (let i = index; i < arr.length; i++) {
// checking that sum does not become negative
if ((sum - arr[i]) >= 0) {
// pushing element which can contribute to
// sum
temp.push(arr[i]);
findNumbers(ans, arr, sum - arr[i], i, temp);
// removing element from list (backtracking)
temp.splice(temp.indexOf(arr[i]), 1);
}
}
}
// Driver Code
// arr.push(5);
// arr.push(4);
// arr.push(8);
//let arr = []
for(let i=0;i<nizSplitNew;i++){
nizSplitNew.push(nizSplitNew[i]);
}
let sum = targetNew;
let ans = combinationSum(nizSplitNew, sum);
// If result is empty, then
// print all combinations stored in ans
for (let i = 0; i < ans.length; i++) {
brojac=0;
for (let j = 0; j < ans[i].length; j++) {
brojac=brojac+1;
}
array.push(brojac);
}
console.log(array);
min = Math.min(...array);
if (array.length == 0) {
rezultat.innerHTML=`<p>-1</p>`
}
else{
rezultat.innerHTML=`<p>${min}</p>`
}
}

how to fix the function to check the same random array value

I am learning javascript, I have been able to create a function that has a parameter, the function has the task of forming an array containing a 2 character (0/1) random string of 1 parameter and the return value must be an array.
example:
console.log (generateString(2));
sample results:
['01', '11']
The problem I face is even though it's a random string, but it still has the possibility to have the same value. Suppose I run the program code
console.log (generateString(4));
and one of the results is like this:
['00', '00', '01', '10']
my question is how can I ensure that the return value of the array has no duplicate value? This is my code so far..
function generateString(num){
let newArray = [];
for(let i = 0; i < num; i++){
let randomChar = generateCharacters();
if(i >= 1 && (newArray[i - 1] === randomChar)){
randomChar = generateCharacters();
newArray.push(randomChar);
} else {
newArray.push(randomChar);
}
}
return newArray;
}
function generateCharacters(){
const chars = '01';
let result = '';
for (let j = 2; j > 0; --j){
result += chars[Math.floor(Math.random() * chars.length)];
}
return result;
}
console.log(generateString(4));
Just check for the duplicate before adding the new string.
function generateString(num){
let newArray = [];
let i =0;
while(i<num){
console.log(newArray)
let randomChar = generateCharacters();
if(newArray.indexOf(randomChar)<=-1){
newArray.push(randomChar);
i+=1;
}
}
return newArray;
}
You can use a do-while inside the for-loop and keep making new random strings until the new strings generated is not included in the previous array.
function generateString(num){
let newArray = [];
let randomChar;
for(let i = 0; i < num; i++){
do{
randomChar = generateCharacters();
}
while(newArray.includes(randomChar));
newArray.push(randomChar)
}
return newArray;
}
function generateCharacters(){
const chars = '01';
let result = '';
for (let j = 2; j > 0; --j){
result += chars[Math.floor(Math.random() * chars.length)];
}
return result;
}
console.log(generateString(4));
You can shuffle the array of all 4 possible pairs of digits:
function shuffle(a) {
for (let i = a.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
let temp = a[i];
a[i] = a[j];
a[j] = temp;
}
return a;
}
function generateString(num){
let all = ["00", "01", "10", "11"];
shuffle(all);
return all.slice(0, num); // Only take the number of elements requested
}
console.log(generateString(4));
Made changes in your generateString function. You can use set for not updating duplicates in the result. I think you need to update generateCharacters function to generate all possible strings properly.
function generateString(num){
let newArraySet = new Set();
for(let i = 0; i < num; i++){
let randomChar = generateCharacters();
while(newArraySet.has(randomChar)) {
randomChar = generateCharacters();
}
newArraySet.add(randomChar);
}
return Array.from(newArraySet);
}
function generateCharacters(){
const chars = '01';
let result = '';
for (let j = 2; j > 0; --j){
result += chars[Math.floor(Math.random() * chars.length)];
}
return result;
}
console.log(generateString(4));
When building the array you need to check to see if the random number is not already in the array before adding it to the array. This function will return true if you feed it the array in question and your "random" item you need to check.
function isInArray(myArray, arrayItemToCheck)
{
var found = myArray.find(function(arrayItem) {
return arrayItem == arrayItemToCheck;
});
return !!found
}
in your function, you change the line let randomChar = generateCharacters(); to:
let randomChar;
// loops forever until condition is met
while (true) {
randomChar = generateCharacters();
if (!isInArray(newArray, randomChar)) {
break;
}
}

Given an array of integers, find the pair of adjacent elements that has the largest product and return that product

Given an array of integers, find the pair of adjacent elements that has the largest product and return that product.
and here is my code
function adjacentElementsProduct(inputArray) {
var arr = inputArray;
var x=0;
var y=0;
var p=0;
for(var i=0;i<arr.length;i++){
x=arr[i];
y=arr[i+1];
if(x*y>p){
p=x*y;
};
};
return p;
};
the problem is all the tests works fine but except the array with the negative product as it shown in the attached photo
can anyone help .. and thanks in advance
You could start with a really large negative value, instead of zero.
var p = -Infinity;
You are initializing the variable p to zero. That means any multiplication values smaller than that are not accepted. Rather set it to the smallest possible integer value:
var p = Number.MIN_SAFE_INTEGER;
function adjacentElementsProduct(inputArray) {
var arr = inputArray;
var x = 0;
var y = 0;
var p = Number.MIN_SAFE_INTEGER;
for (var i = 0; i < arr.length; i++) {
x = arr[i];
y = arr[i + 1];
if (x * y > p) {
p = x * y;
};
};
return p;
};
console.log(adjacentElementsProduct([-23, 4, -3, 8, -12]));
This is quite simple actually
function adjacentElementsProduct(inputArray) {
let max = -Infinity;
for (let i = 1; i < inputArray.length; i++) {
max = Math.max(inputArray[i] * inputArray[i - 1], max);
}
return max;
}
This is quite simple actually
const solution = (inputArray) => Math.max(...inputArray.slice(0, -1).map((n, index) => n * inputArray[index + 1]))
console.log(solution([3, 6, -2, -5, 7, 3]))
function solution(inputArray: number[]): number {
var max = -Infinity;
for(var i=0; i+1<inputArray.length; i++)
{
if(max<(inputArray[i]*inputArray[i+1])){
max=inputArray[i]*inputArray[i+1];
}
}
return max;
}
console.log(solution([2,3,6]))
I had the same problem at first, defining the first max as 0. Then i came up with this:
function solution(inputArray) {
let products = inputArray.map(function(x, index){
return inputArray[index+1] != undefined? x *inputArray[index+1] : -Infinity;
})
return Math.max(...products);
}
Problem:
Given an array of integers, find the pair of adjacent elements that has the largest product and return that product. #javascript #arraymethods
function solution(inputArray) {
let productsArr = []; // to hold the products of adjacent elements
let n = 0;
for (let i = 0; i < inputArray.length; i++) {
if (i < inputArray.length - 1)
{
productsArr[n] = inputArray[i] * inputArray[i + 1];
n++;
}
}
return productsArr.reduce((aggr, val) => Math.max(aggr, val)); // to find out the biggest product
}
Here's a very simple implementation without using any additional variables (actually less), and no special values. Just simple logic.
function adjacentElementsProduct(inputArray) {
var c =inputArray[0]*inputArray[1];
var p = c;
for(var i=1;i<inputArray.length;i++){
console.log(c);
var c=inputArray[i]*inputArray[i+1];
if(c > p){
p=c;
};
};
return p;
};
console.log("minimum product = " + adjacentElementsProduct([-23,4,-3,8,-12]));
What I did was, initialize a variable c (current product) with the product of first two elements of the array. And then I declared the variable p and initialize it to c. This way, all other products are compared to this product. Rest is simple.
Hope it helps. :)
you can try to initialize a integer as negative infinity value -math.inf and then use the python ternary operator var=true if condition else false to find the maximum value
code in python
def adjacentarray(a):
maximum=-math.inf
for i,in range(0,len(a)-1):
maximum=a[i]*a[i+1] if a[i]*a[i+1]>maximum else maximum
return maximum
code in javascript
function adjacentElementsProduct(a) {
var maximum=-Infinity;
for (var i=0;i<a.length-1;i++){
maximum= a[i]*a[i+1]>maximum?a[i]*a[i+1]:maximum;
}
return maximum;
}
function solution(inputArray) {
let first, second, sum = []
inputArray.map((arr,index)=>{
first = arr;
second = inputArray[index+1]
if(second == undefined){
return second
}
return sum.push(first * second)
})
let last = sum.sort().reduce((pre,next)=> {
return pre > next ? pre : next
})
return last;
}
//Kotlin
fun solution(inputArray: MutableList<Int>): Int {
var result: Int = Int.MIN_VALUE
for (i in 0..inputArray.size - 2) {
if (inputArray[i] * inputArray[i + 1] > result)
result = inputArray[i] * inputArray[i + 1]
}
return result
}
import 'dart:math';
int solution(List<int> inputArray) {
//assumption for highest number
int highestNumber = inputArray[0] * inputArray[1] ;
//we'll go through the array to campare the highestNumber
//with next index
for(var i = 1 ; i < inputArray.length ; i++){
highestNumber = max(highestNumber, inputArray[i] * inputArray[i - 1]);
}
return highestNumber;
}
In Javascript, you could use the reduce method from an array to avoid iterating in a for loop, just like this.
function solution(inputArray) {
let maxProd = []
inputArray.reduce((accumulator, currentValue) => {
maxProd.push(accumulator*currentValue)
return currentValue
},
);
return Math.max(...maxProd)
}
Once you have in the maxProd array the products, you use the spread operator to get the numbers and using Math.max() you get the largest
python solution
You can make a loop from 1 to end of your list and do the following arithmetic operations
def solution(inputArray):
list1 =[]
for i in range(1,len(inputArray)):
list1.append(inputArray[i]*inputArray[i-1])
return max(list1)
Here is a solution in PHP that is quite simple.
function solution($inputArray) {
$largest = null;
$pos = null;
for($i = 0; $i < count($inputArray) -1; $i++){
$pos = ($inputArray[$i] * $inputArray[$i+1]);
if($largest < $pos){
$largest = $pos;
}
}
return $largest ?? 0;
}
You can try to create a new array of length (arr.length-1) inside the function and append the products of adjacent numbers to this new array. Then find the largest number in the array and return it. This will solve the problem with negative product.
function adjacentElementsProduct(inputArray) {
var arr = inputArray;
var prodArr[];
var p;
for (var i = 0; i < arr.length-1; i++) {
prodArr[i] = arr[i]*arr[i+1];
};
for (j=prodArr.length; j--){
if (prodArr[j] > p) {
p = prodArr[j];
};
return p;
};
console.log(adjacentElementsProduct([-23, 4, -3, 8, -12]));
The var p which saves the max product should be initialized as small as possible instead of a 0. So that when the product is negative, it will still meet the if condition and save the value.
Here is a C# solution:
static void Main(string[] args)
{
int[] arr = { 1, -4, 3, -6, -7, 0 };
Console.WriteLine(FindMaxProduct(arr));
Console.ReadKey();
}
static int FindMaxProduct(int[] arr) {
int currentProduct = 0;
int maxProduct = int.MinValue;
int a=0, b = 0;
for (int i = 0, j = i + 1; i < arr.Length - 1 && j < arr.Length; i++, j++)
{
currentProduct = arr[i] * arr[j];
if (currentProduct>maxProduct) {
a = arr[i];
b = arr[j];
maxProduct = currentProduct;
}
}
Console.WriteLine("The max product is {0}, the two nums are {1} and {2}.",maxProduct,a,b);
return maxProduct;
}
function solution(inputArray) {
let f, s, arr = []
for(let i=0; i<inputArray.length; i++){
f = inputArray[i]
s = inputArray[i+1]
arr.push(f*s)
}
let max = arr.sort((a, b) => b - a)
return max[0]
}
console.log(solution([3, 6, -2, -5, 7, 3]))
This should help, wrote it in python. Concept: Pass an empty list, for every consecutive product keep storing it in the list. Then just return the max value.
def consecutive_product_max(a):
lst2 = []
for i in range(0, len(a)-1):
x = a[i] * a[i+1]
lst2.append(x)
return max(lst2)

Prime numbers not printing in Javascript

I have the following code to find the prime numbers from 2 to 1000:
#!/usr/bin/env node
var primesarray = function(n) {
var nums = [];
for (var i = 0; i < n; i++) {
nums.push("1");
}
return nums;
};
var primes = function(arr) {
var i = 2;
var primes = [];
for (i = 2; i < arr.length - 1; i++) {
if (arr[i] === "1")
primes.push(i);
for (j = 2; Math.pow(i, j) < arr.length - 1; j++ ) {
arr[Math.pow(i,j)] = "0";
}
}
return primes;
};
// Print to console
var fmt = function(arr) {
return arr.join(",");
};
var k = 1000;
console.log("primes(" + k + ")");
console.log(fmt(primes(k)));
When I run the file, it just prints the first console.log line. I'm not seeing what's wrong here.
The function primes is written to expect an array, but you're passing it an integer.
Did you mean fmt(primes(primesarray(k)))?
(That does at least print a list of numbers, but I'm afraid many of them are not primes!)
You need to prime you array ;)
var arr = primesarray(k)
like this
var k = 1000;
var arr = primesarray(k)
console.log(primes(arr));
console.log(fmt(primes(arr)));
DEMO
Some actual solutions: http://www.codecademy.com/forum_questions/5033d10f77955e0002004142

Take an input single dimensional array [1,2,3,4] and output the product of the integers excluding the current index [24,12,8,6];

Guys I need your opinion; I've encountered this earlier during my interview, I just want to confirm I understood the question right and I got the answer correctly. Thank you. Please check the question and my answer below:
Take an input single dimensional array [1,2,3,4] and output the product of the integers excluding the current index [24,12,8,6];
//My answer
function calculate(values:Array):Array {
var resultArray:Array = new Array();
for(var i:int = 0; i < values.length; i++) {
var getVal1:Number = 1;
for(var k:int = 0; k <= values.length; k++) {
if(i != k) {
var getVal2:Number = values[k];
getVal1 *= getVal2;
}
}
resultArray.push(getVal1);
}
return resultArray;
}
Nested loops seems like a very messy way to go.
Assuming relatively up-to-date browser (IE 8 and below are out) or suitable shim:
var resultArray = sourceArray.map(function(val,ind,arr) {
arr = arr.slice(0); // create copy of array to work on here
arr.splice(ind,1); // remove current item from array
return arr.reduce(function(prev,curr) {return prev*curr;},1);
});
Array.prototype.map
Array.prototype.reduce
EDIT Here's another way that should be more efficient:
var product = sourceArray.reduce(function(prev,curr) {return prev*curr;},1);
var resultArray = sourceArray.map(function(val) {return product/val;});
Your solution gives the correct answer, but there is a much more efficient method to calculate the new array:
function calculate(values:Array):Array {
var resultArray:Array = new Array();
var product:int = 1;
for(var i:int = 0; i < values.length; i++) {
product *= values[i];
}
for(var i:int = 0; i < values.length; i++) {
resultArray.push(product / values[i]);
}
return resultArray;
}
This solution has O(n) execution time, while your code has O(n²) execution time.
That should work. You can do it easier and more efficiently by multiplying all items first:
function calculate(values) {
var prod = 1;
for (var i = 0; i < values.length; i++) prod *= values[i];
var result = [];
for (i = 0; i < values.length; i++) result.push(prod / values[i]);
return result;
}
I believe that my code below is very easy to read. And has no nested loops, but two consecutives. My answer would be:
function calculate(array){
var total = array.reduce(function(a, b){
return a * b;
});
return array.map(function(element){
return total / element;
});
}
Though I like #Kolink's short-and-efficient solution best, here's another way to solve the task - not using division but still being in O(n):
function calculate(values) {
var acc = 1,
l = values.length,
result = new Array(l);
for (var i=0; i<l; i++) {
result[i] = acc;
acc *= values[i];
}
acc = 1;
while(i--) {
result[i] *= acc;
acc *= values[i]
}
return result;
}
Or, the same thing but a little obfuscated*:
function calculate(values) {
var acc = 1,
i = 0,
l = values.length,
result = new Array(l);
if (l)
result[i] = 1;
while( ++i < l)
result[i] = acc *= values[i-1];
i -= acc = 1;
while (i--)
result[i] *= acc *= values[i+1];
return result;
}
*: I like shorthand operators!

Categories