Watson gives Sherlock an array A of length N. Then he asks him to
determine if there exists an element in the array such that the sum of
the elements on its left is equal to the sum of the elements on its
right. If there are no elements to the left/right, then the sum is
considered to be zero. Formally, find an i, such that,
Input Format
The first line contains T, the number of test cases. For each test
case, the first line contains N, the number of elements in the array
A. The second line for each test case contains N space-separated
integers, denoting the array A.
Constraints
1<=T<=10
1<=N<=10^5
1<=Ai<=2*10^4
1<=i<=N
Output Format
For each test case print YES if there exists an element in the array,
such that the sum of the elements on its left is equal to the sum of
the elements on its right; otherwise print NO.
Sample Input
2
3
1 2 3
4
1 2 3 3
Sample Output
NO
YES
Explanation
For the first test case, no such index exists. For the second test
case,
therefore index 3 satisfies the given conditions.
I'm having timeout issues on 3 of the test cases
function check(input) {
var result = "NO";
var sum=0;
input.map(function(data){
sum=sum+(+data);
})
sumLeft=0;
sumRight=sum-(+input[0]);
for(var i=1;i<input.length;i++){
sumLeft=sumLeft+(+input[i-1]);
sumRight=sumRight-(+input[i])
if(sumLeft==sumRight)
{
console.log("YES");
return;
}
}
console.log("NO");
}
function processData(input) {
//Enter your code here
var lines = input.split("\r\n");
for (var m = 2; m < lines.length; m = m + 2) {
check(lines[m].split(" "));
}
}
process.stdin.resume();
process.stdin.setEncoding("ascii");
_input = "";
process.stdin.on("data", function(input) {
_input += input;
});
process.stdin.on("end", function() {
processData(_input);
});
Loop over the array once to find the sum. Declare two variables: sumLeft and sumRight. sumLeft should have an initial value of 0 and sumRight should be totalSum-arr[0].
Iterate over the array again and increment sumLeft by the (n-1) element and decrement sumRight by the nth element. Keep comparing the two variables to check if they equal each other. You cut your time complexity down to O(n)
The below code passed the test on https://www.hackerrank.com/challenges/sherlock-and-array . The tricky part was setting up default responses for when the array length was 1. I will admit that #trincot 's answer was more efficient (n as opposed to 2n) for arrays containing only positive integers.
function check(input) {
var result = "NO";
var sum=0;
if(input.length == 1){
console.log("YES");
return;
}
input.map(function(data){
sum=sum+(+data);
})
sumLeft=0;
sumRight=sum-(+input[0]);
for(var i=1;i<input.length-1;i++){
sumLeft=sumLeft+(+input[i-1]);
sumRight=sumRight-(+input[i])
if(sumLeft==sumRight)
{
console.log("YES");
return;
}else if (sumLeft>sumRight) { ///worked both with and without this optimization
console.log("NO");
return;
}
}
console.log("NO");
}
function processData(input) {
//var lines = input.split("\r\n");
var lines = input.split(/\r|\n/)
for (var m = 2; m < lines.length; m = m + 2) {
check(lines[m].split(" "));
}
}
process.stdin.resume();
process.stdin.setEncoding("ascii");
_input = "";
process.stdin.on("data", function(input) {
_input += input;
});
process.stdin.on("end", function() {
processData(_input);
});
You could go through the array from both ends in inwards direction using two pointers (indices). Keep a balance, starting with 0, as follows:
When the balance is negative move the left pointer one step to the right while increasing the balance with the value you leave behind. When the balance is positive, move the right pointer one step to the left while decreasing the balance with the value you leave behind.
When the two pointers meet each other, check the balance. If it is zero, you have success.
Here is the algorithm in ES6 code, together with a text area where you can adapt the input according to the required input format:
function hasMiddle(a) {
var balance = 0, i = 0, j = a.length-1;
while (i < j) balance += balance > 0 ? -a[j--] : a[i++];
return !balance;
}
// I/O: event handling, parsing input, formatting output
var input = document.querySelector('textarea');
var output = document.querySelector('pre');
input.oninput = function() {
var lines = this.value.trim().split(/[\r\n]+/).filter(s => s.trim().length);
// Strip the case count and array element counts:
lines = lines.slice(1).filter( (s, i) => i % 2 );
// Call function for each test case, returning array of booleans:
var results = lines.map( line => hasMiddle(line.match(/\d+/g).map(Number)) );
// Output results
output.textContent = results.map( pos => pos ? 'YES' : 'NO' ).join('\n');
}
// Evaluate input immediately
input.oninput();
Input:<br>
<textarea style="width:100%; height:120px">2
3
1 2 3
4
1 2 3 3
</textarea>
<pre></pre>
This algorithm requires your input array to consist of non-negative numbers.
If you need to support negative numbers in your array, then the algorithm needs to go through the array first to calculate the sum, and then go through the array again to find the point where the balance reaches 0:
function hasMiddle(a) {
var balance = a.reduce( (sum, v) => sum + v );
return !a.every ( (v, i) => balance -= v + (i ? a[i-1] : 0) );
}
// I/O for snippet
var input = document.querySelector('textarea');
var output = document.querySelector('pre');
input.oninput = function() {
var lines = this.value.trim().split(/[\r\n]+/).filter(s => s.trim().length);
// Strip the case count and array element counts:
lines = lines.slice(1).filter( (s, i) => i % 2 );
// Call function for each test case, returning array of booleans:
var results = lines.map( line => hasMiddle(line.match(/[\d-]+/g).map(Number)));
// Output results
output.textContent = results.map( pos => pos ? 'YES' : 'NO' ).join('\n');
}
// Evaluate input immediately
input.oninput();
Input:<br>
<textarea style="width:100%; height:120px">2
3
1 2 3
4
1 2 3 3
</textarea>
<pre></pre>
Given that we have a proper array one might do as follows
var arr = [...Array(35)].map(_ => ~~(Math.random()*10)+1),
sum = arr.reduce((p,c) => p+c),
half = Math.floor(sum/2),
ix;
console.log(JSON.stringify(arr));
midix = arr.reduce((p,c,i,a) => { (p+=c) < half ? p : !ix && (ix = i);
return i < a.length - 1 ? p : ix;
},0);
console.log("best possible item in the middle # index", midix,": with value:",arr[midix]);
console.log("sums around midix:",
arr.slice(0,midix)
.reduce((p,c) => p+c),
":",
arr.slice(midix+1)
.reduce((p,c) => p+c));
Of course for randomly populated arrays as above, we can not always get a perfect middle index.
Related
So I'm making this ReactJS application.
Part of a filtering system I have the following problem:
Simplified...
I have an array, let's say its simple one like let arr = [1,7,4,3,4,7];
and I also input an N variable from the user that is a simple integer input.
I need to return or console.log() the integers from the array that is repeated N times. If there is nonsuch repeating number log err msg or return -1;
For instance,
let arr = [1,7,4,3,4,7]; and let n = 2; i get 7- cos 7 repeats 2 times
let arr = [7,4,5,3,5,5,3,4,3,2,1]; and let n = 3; i get 5 - cos 5 repeats 3 times
let arr = [1,6,4,6,4,6]; and let n = 4; i get -1 or cl("err") - cos nothing repeats 4 times
Code from comments:
const getRepeatingNumber = (arr, n) => {
for (unit of arr) {
if (unit === maj_unit) count++;
else {
count--;
if (count === 0) {
maj_unit = unit;
count = 1;
}
}
}
return maj_unit;
}
You can use array#every, create an accumulator and place the number as key and its frequency as value, once the value reaches the specified number of occurrence, break from the loop using return false, then return the result.
const getRepeatingNumber = (arr, count) => {
let result = -1, hash = {};
arr.every(n => {
hash[n] = (hash[n] || 0) + 1;
if(hash[n] === count) {
result = n;
return false;
}
return true;
});
return result;
}
console.log(getRepeatingNumber([1,7,4,3,4,7],2));
console.log(getRepeatingNumber([7,4,5,3,5,5,3,4,3,2,1], 3));
console.log(getRepeatingNumber([1,6,4,6,4,6], 4));
Below is the code which will fix your problem I hope.
You need to loop over all array values and find how many time each value occurred and save number of occurrence in a result array because there may be multiple values occurred n number of times. i.e. in your provided array let arr = [1,7,4,3,4,7]; 7 and 4 occurred twice but i am returning result[0] since you might only need first occurred value for n times.
let arr = [1,7,4,3,4,7];
let getRepeatingNumber = function (arr, n) {
let result = [];
arr.forEach((value) => {
if (arr.filter(val => val === value).length === n && !result.includes(value)) {
result.push(value);
}
});
return result.length ? result[0] : -1
}
console.log(getRepeatingNumber(arr, 2)); // 7
I want to create simple addition of array with carryover. Also need carryover and result value for display.
Something like this:-
e.g var input = [[0,0,9],[0,9,9]];
var carryover = [];
var result = [];
Thanks...
The two parts you might have been struggling with, I assume would be how you get the carry, and how you get the result..
result [diget] = t % 10;
The % 10 part is what is called modulus, here I'm doing a modulus by 10, so that gets you the 10's unit value.
carryover [diget] = Math.trunc(t / 10);
For the carryover, you just then divide by 10, and then we strip the decimals,. That's what Math.trunc does.
var input = [[0,0,0,9],[0,9,9]];
var carryover = [];
var result = [];
var digetlength = Math.max(input[0].length, input[1].length);
//lets padd inputs to be same size
input[0].unshift(
...new Array(digetlength - input[0].length).fill(0));
input[1].unshift(
...new Array(digetlength - input[1].length).fill(0));
for (var diget = digetlength - 1; diget >= 0; diget -= 1) {
var t = input[0][diget] + input[1][diget];
if (diget < digetlength - 1)
t += carryover[diget + 1];
result [diget] = t % 10;
carryover [diget] = Math.trunc(t / 10);
}
result.unshift(carryover[0]);
console.log('result: ' + result.join(', '));
console.log('carry: ' + carryover.join(', '));
1.turn both numbers into array of digits, reverse them.
2.determine the end index of the for-loop with max length of above 2 arrays.
3.create the 3rd carryover digits array of zeros (don't forget the extra digit).
4.Add the respective digits from step1 and step3,
as you iterate through each of digits from right to left,
4.1 if the sum is greater than 9 then add 1 into next carryover slot.
5. you should have array of carried over digits when the for-loop is done
count the number of 1s you have in them.
function numberOfCarryOperations(num1, num2) {
const dd1 = [...num1.toString()].reverse()
const dd2 = [...num2.toString()].reverse()
const end = Math.max(dd1.length, dd2.length)
const carry = Array(end+1).fill(0)
for (let i = 0; i < end; i++) {
//console.log(i,(Number(dd1[i]?dd1[i]:0)),Number(dd2[i]?dd2[i]:0),carry)
if (((Number(dd1[i]?dd1[i]:0)) + Number(dd2[i]?dd2[i]:0) + carry[i]) > 9) {
carry[i+1] = 1
}
//console.log('-----',carry)
}
//console.log(num1, num2,carry)
return carry.reduce((sum,curr)=>sum+curr)
}
Here is my attempt. It will accept the following as input:
Any number of input arrays
The input arrays don't all need to have the same number of items
I've added code comments to explain what goes on, I hope they're informative enough to explain the answer.
const
input = [
[0,0,9],
[0,9,9],
[1,0,9,9]
];
function getMaxArrayLength(values) {
// Determine the number of items in the longest array. Initialize the reduce with 0.
return values.reduce((maxLength, array) => {
// Return the largets number between the last largest number and the
// length of the current array.
return Math.max(maxLength, array.length);
}, 0);
}
function sumValues(values) {
const
// Determine the number of items in the longest array.
maxLength = getMaxArrayLength(values),
result = [],
carry = [];
// Loop over the length of the longest array. The value of index will be substracted from
// the length of the input arrays. Therefore it is easier to start at 1 as this will
// return a proper array index without needing to correct it.
for (let index = 1; index <= maxLength; index++) {
const
// Get the carryover value from the last sum or 0 in case there is no previous value.
carryValue = (carry.length === 0) ? 0 : carry[carry.length-1],
// Sum up all the values at the current index of all the input arrays. After summing up
// all the values, also add the carry over from the last sum.
sum = values.reduce((sum, array) => {
// Determine the index for the current array. Start at the end and substract the
// current index. This way the values in the array are processed last to first.
const
arrayIndex = array.length - index;
// It could be the current array doesn't have as many items as the longest array,
// when the arrayIndex is less than 0 just return the current result.
if (arrayIndex < 0) {
return sum;
}
// Return the accumulated value plus the value at the current index of the
// current source array.
return sum + array[arrayIndex];
}, 0) + carryValue;
// The carry over value is the number of times 10 fits into the sum. This should be rounded
// down so for instance 5/10=.5 becomes 0.
carry.push(Math.floor(sum / 10));
// Push the remainder of the sum divided by 10 into the result so 15 % 10 = 5.
result.push(sum % 10);
}
// Return the carry over and the result, reverse the arrays before returning them.
return {
carryOver: carry.reverse(),
result: result.reverse()
};
}
const
result = sumValues(input);
console.log(`Carry over: ${result.carryOver}`);
console.log(`Result: ${result.result}`);
I was given the challenge of converting a string of digits into 'fake binary' on Codewars.com, and I am to convert each individual digit into a 0 or a 1, if the number is less than 5 it should become a 0, and if it's 5 or over it should become a 1. I know how to analyze the whole string's value like so:
function fakeBin(x){
if (x < 5)
return 0;
else return 1;
}
This however, analyzes the value of the whole string, how would I go about analyzing each individual digit within the string rather than the whole thing?
Note: I have already looked at the solutions on the website and don't understand them, I'm not cheating.
You can do it in one line with two simple global string replacement operations:
function fakeBin(x){
return ("" + x).replace(/[0-4]/g,'0').replace(/[5-9]/g,'1');
}
console.log(fakeBin(1259))
console.log(fakeBin(7815))
console.log(fakeBin("1234567890"))
The ("" + x) part is just to ensure you have a string to work with, so the function can take numbers or strings as input (as in my example calls above).
Simple javascript solution to achieve expected solution
function fakeBin(x){
x = x+'' ;
var z =[];
for(var i=0;i< x.length;i++){
if((x[i]*1)<5){
z[i] =0;
}else{
z[i]=1;
}
}
return z
}
console.log(fakeBin(357))
The snippet below will take a string and return a new string comprised of zeros and/or ones based on what you described.
We use a for ...of loop to traverse the input string and will add a 0 or 1 to our return array based on whether the parsed int if greater or less than 5.
Also note that we are checking and throwing an error if the character is not a number.
const word = "1639";
const stringToBinary = function(str) {
let ret = [];
for (const char of word) {
if (Number.isNaN(parseInt(char, 10))) {
throw new Error(`${char} is not a digit!`);
} else {
const intVal = parseInt(char, 10);
ret.push(intVal > 5 ? 1 : 0);
}
}
return ret.join('');
};
console.log(stringToBinary(word));
if you are in java you can use
charAt()
and you make a for with the word length and you can check one by one
for(int i = 0; i < text.length(); i++){
yourfunction(texto.charAt(i));
}
Split the string and apply the current function you have to each element of the string. You can accomplish this with map or with reduce:
function fakeBin(x) {
x = x.split('');
let toBin = x => {
if (x < 5)
return 0;
else return 1
}
return x.map(toBin).join('');
}
console.log(fakeBin("2351"));
refactored
function fakeBin(x) {
x = [...x];
let toBin = x => x < 5 ? 0 : 1;
return x.map(toBin).join('');
}
console.log(fakeBin("2351"));
reduce
function fakeBin(x) {
let toBin = x => x < 5 ? 0 : 1;
return [...x].reduce((acc,val) => acc + toBin(val), "");
}
console.log(fakeBin("23519"));
You can use String.prototype.replace() with RegExp /([0-4])|([5-9])/g to match 0-4, 5-9, replace with 0, 1 respectively
let str = "8539734222673566";
let res = str.replace(/([0-4])|([5-9])/g, (_, p1, p2) => p1 ? 0 : 1);
console.log(res);
I have an array based on selected values from multiple select boxes:
Term 03 (-1000),1 (+1000),Price (+3000),1 (+1500),--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--
Comma-separated. As you can see, some values have text in parentheses. I need to take these values in parentheses and sum them, therefore the + and - characters should remain.
Values (+1000), (+3000), (-1000) represent changes of price: + indicates the product will be more expensive, - represents the product will be cheaper. The result of this should be a number that indicates change of the price - e.g. 1500 - the product will cost more than basic price, or e.g. -3000 - the product will be cheaper.
Thanks in advance.
Tom
You have comma-separated values, with numbers in them to extract. Start by splitting the input to an array, then for each item, extract the value using regexp for example:
/\(([+-])(\d+)\)/ //will search for a sign (+/-) and a number between parenthesis
applied to an item will result in an array having the sign in second position and the number in 3rd position
/\(([+-])(\d+)\)/.exec('Term 03 (-1000)') //--> ['Term 03 (-1000)', '-', '1000']
Use reduce to sum the all with consideration to the sign:
var changes = str.split(',').reduce(function(sum, item){
var matches = /\(([+-])(\d+)\)/.exec(item);
if(matches) {
return sum + (matches[1] === '-' ? -1 : 1) * parseInt(matches[2]);
} else {
return sum;
}
}, 0));
P.S.: If you have already an array, you can remove the .split(',') part.
If you are not great with regular expressions I've made a version that does not "use" them, this way it's more readable and easier to see what's going on and how it goes about doing it. Not to say you should not use regular expressions.
For this algorithm we are basically looking through each item, checking if they have valid parentheses, then if we have + we add the value inside the parentheses, otherwise if we have - we subtract (assuming those are the only two you can have):
for(items in array) {
var firstPar = array[items].indexOf("(");
var secondPar = array[items].indexOf(")");
// Check of the item has parentheses and are like this (...)
if( (firstPar > 0 && secondPar > 0) && (secondPar > firstPar) ) {
// Get the number from the string
var value = array[items].substring(firstPar+2, secondPar);
value = parseInt(value); // To Number
if( array[items].charAt(firstPar+1) == '+')
ProductPrice += value; // If "+" add
else
ProductPrice -= value;// If "-" subtract
}
}
Example Here
Maybe something like this:
var sum = 0;
csv.replace(/\([^)]+\)/gi, function (str) { sum += parseInt(str,10); return str; }
Didn't test code. Anyway idea is to use regex to loop all parenthesis and then inside replace function, convert matched string to integer and add it to sum.
I managed to get this to work with the rather cumbersome code below. It does work with both positive and negative integers.
var result = arr.map(function (el) {
if (el.indexOf('(') > -1 && el.indexOf(')') > -1) {
return Number(el.match(/\(([\+\- 0-9]*)\)/g)[0].replace(/[\(\) ]/g , ''));
}
}).filter(function (el) {
if (typeof el !== undefined) {
return el;
}
}).reduce(function (p, c) {
return p + c;
});
DEMO
Try
var arr = "Term 03 (-1000),1 (+1000),Price (+3000),1 (+1500),--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--".split(",")
, sum = 0;
arr.map(function(v, k) {
// cast `v` value as `Number` , e.g., `[-1000, 1000, 3000, 1500]`
var n = Number(v.replace(/\w+[^\(+\d+\)]|[\(|\)]/g, "")) || null;
// add `n` Number's at `sum` , e.g., `-1000 + 1000 + 3000 + 1500` = `4500`
sum += n
});
// console.log(sum); // `4500`
var arr = "Term 03 (-1000),1 (+1000),Price (+3000),1 (+1500),--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--,--".split(",")
, sum = 0;
arr.map(function(v, k) {
// cast `v` value as `Number` , e.g., `[-1000, 1000, 3000, 1500]`
var n = Number(v.replace(/\w+[^\(+\d+\)]|[\(|\)]/g, "")) || null;
// add `n` Number's at `sum` , e.g., `-1000 + 1000 + 3000 + 1500` = `4500`
sum += n
});
document.write(sum) // `4500`
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
"A positive number of whatever length is represented as an array of numerical characters, ergo between '0's and '9's. We know that the most significant cypher is in position of index 0 of the array.
Example:
- Number is 10282
- Array will be number = [1,0,2,8,2]
This considered, create a function of 2 arrays representing two positive numbers that calculates the SUM\ADDITION\SUMMATION of both of them and set it in a third array, containing the sum of the first 2."
This is how the exercise is translated from my own language, italian.
This is my solution but it doesnt entirely work. I have tried with basic stuff like
A=[1,4] and B=[4,7]. The results should be C=[6,1] but it gives me [5,1] as it considers the line where I use the modular but not the one where I say that the -1 index position should take a ++.
Help <3
alert('Insert A length');
var k=asknum();
alert('Insert B length');
var h=asknum();
var A = new Array(k);
var B = new Array(h);
// asknum() is only defined in this particular environment we are
// using at the university. I guess the turnaround would be -prompt-
function readVet(vet){//inserts values in index positions
for(i=0;i<vet.length;i++)
vet[i]=asknum();
}
readVet(A);//fills array
readVet(B);//fills array
function sumArray(vet1,vet2){
var C = new Array();
for(i=vet1.length-1;i>(-1);i--){
for(n=vet2.length-1;n>(-1);n--){
C[i]=vet1[i]+vet2[i];
if(C[i]>9){
C[i]=C[i]%10;
C[i-1]=C[i-1]++;
}
}
}
return C;
}
print(sumArray(A,B));
I'm not sure what you're doing with a nested for loop here. You just need one. Also, to make said loop really simple, normalize the arrays first so that both are the length of the larger array + 1 element (in case of carry). Then correct the result on the way out of the function.
function normalizeArray(array, digits) {
var zeroCnt = digits - array.length,
zeroes = [];
while (zeroCnt--) {
zeroes.push(0);
}
return zeroes.concat(array);
}
function sumArrays(a1, a2) {
var maxResultLength = Math.max(a1.length, a2.length) + 1;
a1 = normalizeArray(a1, maxResultLength);
a2 = normalizeArray(a2, maxResultLength);
var result = normalizeArray([], maxResultLength);
var i = maxResultLength - 1, // working index
digit = 0, // working result digit
c = 0; // carry (0 or 1)
while (i >= 0) {
digit = a1[i] + a2[i] + c;
if (digit > 9) {
c = 1;
digit -= 10;
} else {
c = 0;
}
result[i--] = digit;
}
/* If there was no carry into the most significant digit, chop off the extra 0 */
/* If the caller gave us arrays with a bunch of leading zeroes, chop those off */
/* but don't be an idiot and slice for every digit like sqykly =D */
for (i = 0 ; i < result.length && result[i] === 0 ; i++) {
/* result = result.slice(1); don't do that, or anything */
}
return result.slice(i);
}
That gives the expected output.
I may be missing something because the other answers look much more complicated, but here's my attempt at providing an answer based on the question:
// Takes an array and generates the sum of the elements
function addArrayNumbers(arr) {
return arr.reduce(function (p, c) {
return String(p) + String(c);
});
}
// Sums two numbers and returns an array based on that sum
function addCombinedNumbers(a, b) {
return String(Number(a) + Number(b)).split('');
}
var arrone = [1, 4];
var arrtwo = [4, 7];
var one = addArrayNumbers(arrone);
var two = addArrayNumbers(arrtwo);
var c = addCombinedNumbers(one, two); // [6,1]
Fiddle
I followed a different approach that may very well be less efficient than yours, but i consider it to be much clearer. One important thing is that i reverse the arrays so the least significant bit is first. Comments are in the code.
function sum(a,b){
// ensure a is the largest of the two arrays
if (a.length < b.length)
return sum(b,a);
// flip the arrays so the least significant digit is first
a = a.reverse();
b = b.reverse();
// c will hold the result (reversed at first)
var c = [];
// add each number individually
var carry = a.reduce(function(carry,digitA,index){
// digitA is guaranteed to be a number, digit from b is not!
var sum = digitA + (b[index] || 0) + carry;
c.push(sum%10);
return Math.floor(sum/10); // this is carried to the next step of the addition
},0); // initial carry is 0
if (carry) c.push(1); // resolve if carry exists after all digits have been added
return c.reverse();
}
// Usage:
console.log(sum([1,0,8,3],[1,3,5])); // [1, 2, 1, 8]
console.log(sum([8,3],[7,9])); // [1, 6, 2]
PS: There are many problems with your code. For one, you cannot use two nested loops:
var a = [0,1];
var b = [2,3];
for (var i=0; i<a.length; i++) {
for (var j=0; j<b.length; j++) {
console.log(a[i] + ' ' + b[i]);
}
}
// will output: 0 2, 0 3, 1 2, 1 3
// you want something along the lines of: 0 2, 1 3
What you want is a single loop that iterates over both arrays simultaneously.
My attempt at an efficient solution:
function efficientSum(a,b){
var i = a.length, j = b.length;
if (i<j) return efficientSum(j,i);
var q = 0, c = [];
c.length = i;
while (i) {
c[--i] = a[i] + (b[--j] || 0) + q;
q = c[i] > 9 ? ((c[i]-=10),1) : 0; // comma operator, ugly!
}
if (q) c.unshift(1);
return c;
}