Adding up all combinations of number in an array - javascript

I am trying to write a program in javascript that gets an unspecified number of numbers out of a html textarea and tries all combinations (adding all numbers with eachother) to see if it mathches a number you specified.
Now I can make an array out of the string in the textarea and using for loops I add these up (see below code). The problem how can you do this for an unspecified number of numbers that are to be added up (e.g. adding up 7 different number if you enter 7 numbers in textarea)? I was thinking of using a second array and, which gets the numbers to add up out of the first loop. And then make te lenght of the loop variable by using a for loop with the lenght of the array containing all numbers (lines in my example) as endvalue.
How can I fill in the values of this 2nd array, making sure all combinations are used?
By the way, I wanted this code because I am a auditor. Sometimes a client reverses a couple of amounts in one booking, without any comment. This code will make it a lot easier to check what bookings have been reversed
edit: The awnser of cheeken seems to be working I only have one remark. What if multiple sub sets of your power set added up result in the number you are looking for? e.g.:findSum([1,2,3,4,5],6) can result [1,2,3] but also [2,4] or [1,5]. is it possible to let the function return multiple sub sets?
Found the answer my self :)
I replaced code
return numberSet;
By
document.getElementById("outp").value=document.getElementById("outp").value+ numberSet +"\n";
Thank you very much Cheeken
One more additional question. How do i format the input for parsing that function? The code below doesn't seem to work. inp is the ID of the textarea where the input is (the numbers are seperated with a semicolumn. The variable ge works so there is no problem there (tested it with [1,2,3,4] and it worked. What is wrong with this code?
re edit:
found the solution. The array needed to be parsed as a floating number added this code.`
for (var i=0; i < lines.length; i++) {
lines[i]= parseFloat(lines[i]);
}
findSum(document.getElementById("inp").value.split(";"), ge);
Code:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function powerset(arr) {
var ps = [[]];
for (var i=0; i < arr.length; i++) {
for (var j = 0, len = ps.length; j < len; j++) {
ps.push(ps[j].concat(arr[i]));
}
}
return ps;
}
function sum(arr) {
var total = 0;
for (var i = 0; i < arr.length; i++)
total += arr[i];
return total
}
function findSum(numbers, targetSum) {
var numberSets = powerset(numbers);
for (var i=0; i < numberSets.length; i++) {
var numberSet = numberSets[i];
if (sum(numberSet) == targetSum)
document.getElementById("outp").value=document.getElementById("outp").value+ numberSet +"\n";
}
}
function main()
{
ge= document.getElementById("getal").value;
findSum([1,1,0.5,0.1,0.2,0.2], ge);
}
</script>
</head>
<body>
<input type="button" onclick="main()" value="tel" /><input type="text" id="getal" /><br>
input<br><textarea id="inp" ></textarea><br>
output<br><textarea id="outp" ></textarea><br>
document.getElementById("inp").value.split(";")
</body>
</html>

More concretely, you're looking for a particular sum of each set in the power set of your collection of numbers.
You can accomplish this with the following bit of code.
function powerset(arr) {
var ps = [[]];
for (var i=0; i < arr.length; i++) {
for (var j = 0, len = ps.length; j < len; j++) {
ps.push(ps[j].concat(arr[i]));
}
}
return ps;
}
function sum(arr) {
var total = 0;
for (var i = 0; i < arr.length; i++)
total += arr[i];
return total
}
function findSum(numbers, targetSum) {
var numberSets = powerset(numbers);
for (var i=0; i < numberSets.length; i++) {
var numberSet = numberSets[i];
if (sum(numberSet) == targetSum)
return numberSet;
}
}
Example invocation:
>> findSum([1,2,3,4,5],6)
[1, 2, 3]
>> findSum([1,2,3,4,5],0)
[]
>> findSum([1,2,3,4,5],11)
[1, 2, 3, 5]
If you'd like to collect all of the subsets whose sum is the value (rather than the first one, as implemented above) you can use the following method.
function findSums(numbers, targetSum) {
var sumSets = [];
var numberSets = powerset(numbers);
for (var i=0; i < numberSets.length; i++) {
var numberSet = numberSets[i];
if (sum(numberSet) == targetSum)
sumSets.push(numberSet);
}
return sumSets;
}
Example invocation:
>> findSums([1,2,3,4,5],5);
[[2,3],[1,4],[5]]
>> findSums([1,2,3,4,5],0);
[[]]

Related

Comparing values in an array (app script)

first I'm new to Apps Script respectively Javascript. However in Google Sheets with Apps Script I have filled an array with the contents of one column. Now I would like to find matching values in this array. I tried the following code with a simple array like [2,5,3,6,2,7] and the code works. It doesn't work though with the values from the column (e. g. something like '110rt' or '38tzu0'):
let z = sheet.getRange("D2:D" + sheet.getLastRow())
let a = z.getValues()
for (let i = 0; i < a.length; i++) {
for (let k = i + 1; k < a.length; k++) {
if (a[i] == a[k]) {
console.log("hit")
}
}
}
So in the above code the if clause never becomes true and I don't understand why.
When you use getRange with multiple rows, it returns each row in a seperate sub-array.
The end result is a 2D array, where each sub-array represent a row.
For example:
[
[A1,B1,C1,...],
[A2,B2,C2,...],
[A3,B3,C3,...]
]
In your case, where you have only one column, it looks like that:
[[2 ],[5 ],[3 ],[6 ],[2 ],[7]]
[[D2],[D3],[D4],[D5],[D6],[D7]] // the matching cells
The buttom line is that you need to iterate a[k][0] and a[i][0]
let z = sheet.getRange("D2:D" + sheet.getLastRow())
let a = z.getValues()
for (let i = 0; i < a.length; i++) {
for (let k = i + 1; k < a.length; k++) {
if (a[i][0] == a[k][0]) {
console.log("hit")
}
}

What is the problem in this simple js code?

I am wondering what`s the problem with this simple code. I am making a function where I need to get the length of the shortest word in a string. I know that I can find this function anywhere but,
why mine isn't working?
function findShort(s){
var arr = s.split(" ");
var out = 1000;
for (var i = 0; i < arr.length-1; i++){
if (arr[i] <= out){
out = arr[i].length;
}
}
return out;
}
The above function returns 1000 instead.
You need to compare the length of each word (arr[i].length), not each word itself (arr[i]) to the shortest length so far.
function findShort(s){
var arr = s.split(" ");
var out = 1000;
for (var i = 0; i < arr.length-1; i++){
if (arr[i].length <= out){ // <-- here!
out = arr[i].length;
}
}
return out;
}
Your problem is that when you compare strings in javascript, it doesn't use it's length. You have to use the "length" attribute of a String, like in the fixed code below. Also you have to save the result to give an output
function findShort(s){
var arr = s.split(" ");
var comp = 1000;
var out = "";
for (var i = 0; i < arr.length-1; i++){
if (arr[i].length <= comp){
comp = arr[i].length;
out = arr[i];
}
}
return out;
}
There still is a problem, if you want to have an array returned with all the shortest words (same length). You could add another if statement and make it add the word to an array when it's the same length, and clear it when there was found a shorter one.

Having problems with for loop and arrays

(I know there is easier way to convert to binary but I didn't know that before I was almost finished with this. So I am just gonna try to finish this. I coded this just to learn) :)
I am trying to create a function that converts binary to ASCII code. Here is how I am converting from binary to number:
function fromBinaryToNumber(num) {
let numbers = num.split('') //turns the binary into an array
let firstIndexWith1;
let numbersToAdd = [];
let result;
//Delete 0's at start of array
for (i = 0; i < numbers.length; i++) {
numbers[i] = parseInt(numbers[i], 10);
}
firstIndexWith1 = numbers.indexOf(1);
numbers.splice(0, firstIndexWith1);
//Convert
let checkAgainstThese = [128, 64, 32, 16, 8, 4, 2, 1];
checkAgainstThese = checkAgainstThese.slice(checkAgainstThese.length - numbers.length, checkAgainstThese.length);
//put numbers to add in array
for (i = 0; i < numbers.length; i++) {
if (numbers[i] === 1) {
numbersToAdd.push(checkAgainstThese[i]);
}
}
//add numbers
result = numbersToAdd.reduce((a, b) => a + b, 0);
return result;
}
It works. But I want to be able to convert more than one byte at a time. This is how I am trying to do that:
function fromBinaryToASCII(sentence) {
let convertThis = sentence.split(' ');
let result = [];
for (i = 0; i < convertThis.length; i++) {
result.push(fromBinaryToNumber(convertThis[i]));
}
return result;
}
I have already made a function that successfully converts from a sentence to binary and for some reason that one works but not this one, even though they both look very similar.
So I was trying to find out what the problem was and I tried putting a console.log inside the for loop and printing out the i. Like this:
for (i = 0; i < convertThis.length; i++) {
result.push(fromBinaryToNumber(convertThis[i]));
console.log(i);
}
And for some reason it outputted only the number 6. When I remove the result.push code it outputs correctly. I am very confused. Can someone help me?
-Thanks
(sorry for bad title or if i explained badly)
for(i=0; i<convertThis.length; i++) { <-- global i
for(i=0; i<numbers.length; i++) { <-- global i
When the one runs, it will change the number for the other.... This is why var is not optional. So either use let or var
for(let i=0; i<convertThis.length; i++) {
for(let i=0; i<numbers.length; i++) {

I Want To Print 1 to 100 Numbers Using Arrays In Javascript Only

<!DOCTYPE html>
<html>
<head>
<title>100-Numbers</title>
</head>
<body>
<script>
var points = new Array(100);
var label = points.length;
for (var i = 0; i < label; i++) {
console.log(points[i]);
}
</script>
</body>
</html>
This is my First question in Stackoverflow. As i am an beginner, Please bare me and i need alot of support from you people. I m trying to print 1 to 100 numbers using arrays in javascript only. I'm Facing some errors in the above code. Please correct my mistakes to get the output..Thankyou in advance.
This will print 1-100 without any loops
Array.from({length: 100},(_,x) => console.log(x+1))
he said he wants to print 1-100 from an ARRAY...So the array needs to be populated, first. THEN, you can loop through the array.
var points = new Array(100);
for (var i = 0; i < 100; i++) {
points[i] = i + 1; //This populates the array. +1 is necessary because arrays are 0 index based and you want to store 1-100 in it, NOT 0-99.
}
for (var i = 0; i < points.length; i++) {
console.log(points[i]); //This prints the values that you stored in the array
}
The array values are uninitialized. I'm assuming that you want to print the values 1 to 100 using arrays where the values 1 to 100 are inside the array.
First initialize the array.
var oneToHundredArray = [];
Now populate it with values 1 to 100.
for(var value = 1; value <= 100; value++) {
oneToHundredArray.push(value);
}
Now the contains the values you want. Just loop and print over it now.
for(var index = 0; index < oneToHundredArray.length; index++) {
console.log(oneToHundredArray[index]);
}
Done :)
Array.from(Array(100), (_,i) => console.log(i+1));
The second parameter acts as mapping callback, so you also do this...
const arr = Array.from(Array(100), (_,i) => i+1);
for(num of arr) {
console.log(num);
}
Reference: Array.from
You should start off with an empty array, then run a loop for 1-101, I logged the iterator so you can see the values populate, you then need a binding agent to hold the value of the iteration, then you would need to push those values to your empty array.
var numbersArray = [];
for( var i = 1; i <101; i++){
console.log(i);
var numbers = i;
numbersArray.push(numbers);
}
After that, you then need to run a loop for the length of the numbersArray to output the individual results.
for(var m=0; m<= numbersArray.length -1; m++){
console.log(numbersArray[m]);
}
output console.log logs numbers 1-100 respectively.
var label = new Array(100);
for (var i = 0; i < 100; i++) {
label[i] = i + 1;
}
for (var i = 0; i < label.length; i++) {
console.log(label[i]);
}
It's much more easier with "while"
var i = 1;
while (i < 100) {
document.write(i + "<br/>");
i++;
}
Using a for loop:
function get_array() {
var arr = [];
for(var i=1; i<=100; i++) {
arr.push(i);
}
console.log(arr);
}
get_array()

Why is this incrementer returning NAN when if I hard code the index it works as expected?

I am trying to do a simple factorial code challenge, but with Javascript, when I try to get the index position by looping of the indexes, I get NAN. I understand that NAN is of the typeOf number, just that Javascript doesn't know which number. I don't see why that is happening in this case. Also how can I use get the index of an array by looping over them in Javascript? Thanks!
// Input = 4 Output = 24
// Input = 8 Output = 40320
var total = 0;
var factor_Array = [];
function FirstFactorial(num) {
for (var i = 1; i <= num; i++){
factor_Array.unshift(i);
// console.log(factor_Array);
}
for (var j = 0; j < factor_Array.length; j++){
// Why does this work??? But not when I use 'j' to grab the index position? Seems like BOTH ways should work
total = factor_Array[0] * factor_Array[0+1];
total = factor_Array[j] * factor_Array[j+1];
}
console.log(total);
//return num;
}
FirstFactorial(4);
Because when j = (factor_Array.length-1) it tries to access the j+1 element, which doesn't exist.
The following would work as you expect
for (var j = 0; j < (factor_Array.length-1); j++){
total = factor_Array[j] * factor_Array[j+1];
}
When you loop
for (var j = 0; j < factor_Array.length; j++){
total = factor_Array[j] * factor_Array[j+1];
}
Then then on the last iteration you will be out of the array bounds since
j = factor_Array.length - 1
and you're accessing j + 1.

Categories