Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I am solving one problem .but getting correct output for small array but my solution fail when array size is large
solution
/**
* #param {number[]} digits
* #return {number[]}
*/
var plusOne = function(digits) {
let str = parseInt(digits.join(''))+1+''
return str.split('')
};
Question
The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit.
You may assume the integer does not contain any leading zero, except the number 0 itself.
Example 1:
Input: [1,2,3]
Output: [1,2,4]
Explanation: The array represents the integer 123.
Example 2:
Input: [4,3,2,1]
Output: [4,3,2,2]
Explanation: The array represents the integer 4321.
above cases are passed
failed cases
Input
[6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3]
Output
[6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,0,0,0]
Expected
[6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,4]
let str = parseInt(digits.join(''))+1+''
With too many array elements, you are simply creating a number that is outside of the integer range here.
An implicit conversion to a float has to happen, and with that you get the inherent loss of precision - which then leads to several zeros in those places at the end, when you reverse the process.
Access the last array element specifically, and add 1 to the value. But if that last element had the value 9 already, you will of course have to repeat that same process for the previous one … basic application of “carry the one”.
var input = [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,9];
var output = [];
// loop over input array in reverse order
for(var i=input.length-1, toadd = 1; i>-1; --i) {
// add value `toadd` to current digit
var incremented = input[i] + toadd;
if(incremented < 10) {
output.unshift(incremented); // add to front of output array
toadd = 0; // reset toadd for all following digits, if we had no overflow
}
else {
output.unshift(0); // overflow occurred, so we add 0 to front of array instead
}
}
console.log(output)
This does take an “overflow” for 9 digits at the end into account; it does not handle the case when all digits are 9 though, if you need to handle that edge case as well, please implement that yourself.
This one recursively checks the last digits:
const test1 = [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3]
const test2 = [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,9]
const plusOne = function(digits) {
if(digits[digits.length - 1] === 9){
digits = [...plusOne(digits.slice(0, -1)), 0]
}else{
digits[digits.length - 1]++
}
return digits;
};
console.log(plusOne(test1));
console.log(plusOne(test2));
You could do something like this :
var arr = [6,1,4,5,3,9,0,1,9,5,1,8,6,7,0,5,5,4,3,9,9]
function plusOne(index){
if( index < 0 ) return ; // Base case
if(arr[index] === 9){
arr[index] = 0;
plusOne(index-1); // For carry ahead
}else{
arr[index] += 1
}
}
plusOne(arr.length-1) // start with last digit
Ultimately I want to take this:
2x + 3 = 5
and solve for x, by first subtract 3 from both sides so 2x = 2, then divide both sides by 2 so x = 1. I was thinking a lot how one should go about making a function like this in JavaScript that can return an array of the steps done in order, including the result. Obviously "eval" wouldn't do anything for this, so seemingly one has to re-create equations.
I initially thought to first of all, ignore X, and just try to make a function that can solve simple equations, without eval or any built-in function.
I figured that the first step is to break up the terms using .split, but I was having some trouble with this, as I need to split for multiple symbols. For example, say I have the simple expression to evaluate: 3 - 6 * 3 / 9 + 5. So before we even get into order of operations, just splitting up each term (and categorizing them) is the hard part, which is the main concrete-question I have at this point.
I started simply splitting one after the other, but I was having some problems, and especially considering the order.
function solve(eq) {
var minuses = eq.split("-"),
pluses = minuses.map(x=> x.split("+")),
timeses = pluses.map(x=>x.map(y=>y.split("*"))),
dividers = timeses.map(x=>x.map(y=>y.map(z=>z.split("/"))));
console.log(minuses, pluses, timeses, dividers);
}
solve("3 - 6 * 3 / 9 + 5");
As you can see, for each successive operator I need to map through each of he elements of the previous one to split it, and then I am left with an array of arrays etc...
So 1) how can I split up these terms more efficiently, without making a new variable for each one, and manually recursively mapping through each one? Seemingly I should just have some kind of dictionary of array keeping track of orders of operations (not considering parenthesis or exponents now): ["*","/","+","-"] -- and given that array, generate something similar to the last array in the above example ("dividers") which contains only constants, and somehow keep track of the which elements each of the stored arrays follows...
and 2) How can I solve the expression given the arrays of values?
I was just a little confused with the logic, I guess I need to work up from the last array and solve the constants one at a time, keeping track of which operator is the current one, but I'm not sure how exactly.
While your problem doesn't require to construct, binary expression tree is a good way to brainstorm the logic to solve a math query.
So for the query 3 - 6 * 3 / 9 + 5, the representative binary expression tree is:
plus
|_minus
| |_3
| |_divide
| |_times
| | |_3
| | |_6
| |_9
|_5
to solve above tree, you recursively solve from the leaf level up to the root.
Again, you don't need to construct a tree. It just helps us to see the logic of parsing here:
Get the last minus or plus expression in query and solve left and right child of that expression.
If no plus/minus, get the last times/division expression and solve left and right child
If meet a number, return that number value.
Given above logic, here is an implementation:
function solve(str) {
var expressionIndex = Math.max(str.lastIndexOf("-"), str.lastIndexOf("+"));
if (expressionIndex === -1) {
expressionIndex = Math.max(str.lastIndexOf("*"), str.lastIndexOf("/"));
}
if (expressionIndex === -1) {
var num = Number.parseInt(str.trim());
if (isNaN(num)) {
throw Exception("not a valid number");
} else {
return num;
}
} else {
var leftVal = solve(str.substring(0, expressionIndex).trim());
var rightVal = solve(str.substring(expressionIndex + 1).trim());
switch (str[expressionIndex]) {
case "+":
return leftVal + rightVal;
case "-":
return leftVal - rightVal;
case "*":
return leftVal * rightVal;
case "/":
return leftVal / rightVal;
}
}
}
function parse(str) {
var expressionIndex = Math.max(str.lastIndexOf("-"), str.lastIndexOf("+"));
if (expressionIndex === -1) {
expressionIndex = Math.max(str.lastIndexOf("*"), str.lastIndexOf("/"));
}
if (expressionIndex === -1) {
var num = Number.parseInt(str.trim());
if (isNaN(num)) {
throw Exception("not a valid number");
} else {
return { type: "number", value: num };
}
} else {
var leftNode = parse(str.substring(0, expressionIndex).trim());
var rightNode = parse(str.substring(expressionIndex + 1).trim());
return {
type: "expression",
value: str[expressionIndex],
left: leftNode,
right: rightNode
};
}
}
console.log(solve("3 - 6 * 3 / 9 + 5"));
console.log(parse("3 - 6 * 3 / 9 + 5"));
Above is a solution for very simple query with only +, -, *, / (no parenthesis, e.g.). For solving a equation like your first example requires a lot more of work.
EDIT: add a parse function to return the tree.
You can do that in following steps:
First of all use split() and split by the + and - which will occur after multiplication and division.
Then use map() on array and split() it again by * and /.
Now we have a function which will which will evaluate an array of numbers with operators to single number.
Pass the nested array to complete multiplication and division.
Then pass that result again to sovleSingle and perform addition and subtraction.
The function works same as eval as long as there are no brackets ().
Note: This doesnot matters the which occurs first among + and - or which occurs first among * and /. But *,/ should occur before +,-
function solveSingle(arr){
arr = arr.slice();
while(arr.length-1){
if(arr[1] === '*') arr[0] = arr[0] * arr[2]
if(arr[1] === '-') arr[0] = arr[0] - arr[2]
if(arr[1] === '+') arr[0] = +arr[0] + (+arr[2])
if(arr[1] === '/') arr[0] = arr[0] / arr[2]
arr.splice(1,1);
arr.splice(1,1);
}
return arr[0];
}
function solve(eq) {
let res = eq.split(/(\+|-)/g).map(x => x.trim().split(/(\*|\/)/g).map(a => a.trim()));
res = res.map(x => solveSingle(x)); //evaluating nested * and / operations.
return solveSingle(res) //at last evaluating + and -
}
console.log(solve("3 - 6 * 3 / 9 + 5")); //6
console.log(eval("3 - 6 * 3 / 9 + 5")) //6
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am trying to write a program to decrypt a encrypted message. The encrypted message is a very long set of numbers ".296.294.255.268.313.278.311.270.290.305.322.252.276.286.301.305.264.301.251.269.274.311.304.
230.280.264.327.301.301.265.287.285.306.265.282.319.235.262.278.249.239.284.237.249.289.250.
282.240.256.287.303.310.314.242.302.289.268.315.264.293.261.298.310.242.253.299.278.272.333.
272.295.306.276.317.286.250.272.272.274.282.308.262.285.326.321.285.270.270.241.283.305.319.
246.263.311.299.295.315.263.304.279.286.286.299.282.285.289.298.277.292.296.282.267.245.....ect".
Each character of the message is transformed into three different numbers (eg.first character of message is '230 .280 .264' second character is '.327.301.265' ect).
so i am trying to use javascript to add the groups of three numbers and then save them as their own variable. thanks
Assuming msg has that string in it, this will split it up and add the triplets together.
const [, triplets] = msg
.split('.')
.slice(1)
.map(v => +v)
.reduce(([count, list], val, i) => {
if ((i + 1) % 3) return [count + val, list];
return [val, list.concat(count)];
}, [0, []]);
It would depend on how the data is transmitted. It looks like you could bring the data in as a string (or parse it into a string) and then use the split method to create an array of all of your numbers.
var numbers = "234.345.456.567"
var arr = numbers.split(".")
You would then loop over the array doing whatever you need for every set of three
var newArray[]
var i
for(i = 0; i < length; i += 3){
//Add values here
//Parse back to int
newArray.push("sum Value")
}
Hope this was along the lines of what you need.
Use a regular expression to match all groups of three, then map each group to the number by splitting the string by .s and adding the 3 together:
const input = '296.294.255.268.313.278.311.270.290.305.322.252.276.286.301.305.264.301.251.269.274.311.304. 230.280.264.327.301.301.265.287.285.306.265.282.319.235.262.278.249.239.284.237.249.289.250. 282.240.256.287.303.310.314.242.302.289.268.315.264.293.261.298.310.242.253.299.278.272.333. 272.295.306.276.317.286.250.272.272.274.282.308.262.285.326.321.285.270.270.241.283.305.319. 246.263.311.299.295.315.263.304.279.286.286.299.282.285.289.298.277.292.296.282.267.245';
const groupsOfThree = input.match(/\d{3}\.\d{3}\.\d{3}\./g);
const sums = groupsOfThree.map((group) => {
const nums = group.split('.').map(Number);
return nums[0] + nums[1] + nums[2];
});
console.log(sums);
My purpose is to punch multiple strings into a single (shortest) string that will contain all the character of each string in a forward direction. The question is not specific to any language, but more into the algorithm part. (probably will implement it in a node server, so tagging nodejs/javascript).
So, to explain the problem:
Let's consider I have few strings
["jack", "apple", "maven", "hold", "solid", "mark", "moon", "poor", "spark", "live"]
The Resultant string should be something like:
"sjmachppoalidveonrk"
jack: sjmachppoalidveonrk
apple: sjmachppoalidveonrk
solid: sjmachppoalidveonrk
====================================>>>> all in the forward direction
These all are manual evaluation and the output may not 100% perfect in the example.
So, the point is all the letters of each string have to exist in the output in
FORWARD DIRECTION (here the actual problem belongs), and possibly the server will send the final strings and numbers like 27594 will be generated and passed to extract the token, in the required end. If I have to punch it in a minimal possible string it would have much easier (That case only unique chars are enough). But in this case there are some points:
Letters can be present multiple time, though I have to reuse any
letter if possible, eg: for solid and hold o > l > d can be
reused as forward direction but for apple (a > p) and spark
(p > a) we have to repeat a as in one case it appears before p
for apple, and after p for sparks so either we need to repeat
a or p. Even, we cannot do p > a > p as it will not cover both the case
because we need two p after a for apple
We directly have no option to place a single p and use the same
index twice in a time of extract, we need multiple p with no option
left as the input string contains that
I am (not) sure, that there is multiple outputs possible for a set of
strings. but the concern is it should be minimal in length,
the combination doesn't matter if its cover all the tokens in a forward direction. all (or one ) outputs of minimal possible length
need to trace.
Adding this point as an EDIT to this post. After reading the comments and knowing that it's already an existing
problem is known as shortest common supersequence problem we can
define that the resultant string will be the shortest possible
string from which we can re generate any input string by simply
removing some (0 to N) chars, this is same as all inputs can be found in a forward direction in the resultant string.
I have tried, by starting with an arbitrary string, and then made an analysis of next string and splitting all the letters, and place them accordingly, but after some times, it seems that current string letters can be placed in a better way, If the last string's (or a previous string's) letters were placed according to the current string. But again that string was analysed and placed based on something (multiple) what was processed, and placing something in the favor of something that is not processed seems difficult because to that we need to process that. Or might me maintaining a tree of all processed/unprocessed tree will help, building the building the final string? Any better way than it, it seems a brute force?
Note: I know there are a lot of other transformation possible, please try not to suggest anything else to use, we are doing a bit research on it.
I came up with a somewhat brute force method. This way finds the optimal way to combine 2 words then does it for each element in the array.
This strategy works by trying finding the best possible way to combine 2 words together. It is considered the best by having the fewest letters. Each word is fed into an ever growing "merged" word. Each time a new word is added the existing word is searched for a matching character which exists in the word to be merged. Once one is found both are split into 2 sets and attempted to be joined (using the rules at hand, no need 2 add if letter already exists ect..). The strategy generally yields good results.
The join_word method takes 2 words you wish to join, the first parameter is considered to be the word you wish to place the other into. It then searches for the best way to split into and word into 2 separate parts to merge together, it does this by looking for any shared common characters. This is where the splits_on_letter method comes in.
The splits_on_letter method takes a word and a letter which you wish to split on, then returns a 2d array of all the possible left and right sides of splitting on that character. For example splits_on_letter('boom', 'o') would return [["b","oom"],["bo","om"],["boo","m"]], this is all the combinations of how we could use the letter o as a split point.
The sort() at the beginning is to attempt to place like elements together. The order in which you merge the elements generally effects the results length. One approach I tried was to sort them based upon how many common letters they used (with their peers), however the results were varying. However in all my tests I had maybe 5 or 6 different word sets to test with, its possible with a larger, more varying word arrays you might find different results.
Output is
spmjhooarckpplivden
var words = ["jack", "apple", "maven", "hold", "solid", "mark", "moon", "poor", "spark", "live"];
var result = minify_words(words);
document.write(result);
function minify_words(words) {
// Theres a good sorting method somewhere which can place this in an optimal order for combining them,
// hoever after quite a few attempts i couldnt get better than just a regular sort... so just use that
words = words.sort();
/*
Joins 2 words together ensuring each word has all its letters in the result left to right
*/
function join_word(into, word) {
var best = null;
// straight brute force each word down. Try to run a split on each letter and
for(var i=0;i<word.length;i++) {
var letter = word[i];
// split our 2 words into 2 segments on that pivot letter
var intoPartsArr = splits_on_letter(into, letter);
var wordPartsArr = splits_on_letter(word, letter);
for(var p1=0;p1<intoPartsArr.length;p1++) {
for(var p2=0;p2<wordPartsArr.length;p2++) {
var intoParts = intoPartsArr[p1], wordParts = wordPartsArr[p2];
// merge left and right and push them together
var result = add_letters(intoParts[0], wordParts[0]) + add_letters(intoParts[1], wordParts[1]);
if(!best || result.length <= best.length) {
best = result;
}
}
}
}
// its possible that there is no best, just tack the words together at that point
return best || (into + word);
}
/*
Splits a word at the index of the provided letter
*/
function splits_on_letter(word, letter) {
var ix, result = [], offset = 0;;
while((ix = word.indexOf(letter, offset)) !== -1) {
result.push([word.substring(0, ix), word.substring(ix, word.length)]);
offset = ix+1;
}
result.push([word.substring(0, offset), word.substring(offset, word.length)]);
return result;
}
/*
Adds letters to the word given our set of rules. Adds them starting left to right, will only add if the letter isnt found
*/
function add_letters(word, addl) {
var rIx = 0;
for (var i = 0; i < addl.length; i++) {
var foundIndex = word.indexOf(addl[i], rIx);
if (foundIndex == -1) {
word = word.substring(0, rIx) + addl[i] + word.substring(rIx, word.length);
rIx += addl[i].length;
} else {
rIx = foundIndex + addl[i].length;
}
}
return word;
}
// For each of our words, merge them together
var joinedWords = words[0];
for (var i = 1; i < words.length; i++) {
joinedWords = join_word(joinedWords, words[i]);
}
return joinedWords;
}
A first try, not really optimized (183% shorter):
function getShort(arr){
var perfect="";
//iterate the array
arr.forEach(function(string){
//iterate over the characters in the array
string.split("").reduce(function(pos,char){
var n=perfect.indexOf(char,pos+1);//check if theres already a possible char
if(n<0){
//if its not existing, simply add it behind the current
perfect=perfect.substr(0,pos+1)+char+perfect.substr(pos+1);
return pos+1;
}
return n;//continue with that char
},-1);
})
return perfect;
}
In action
This can be improved trough simply running the upper code with some variants of the array (200% improvement):
var s=["jack",...];
var perfect=null;
for(var i=0;i<s.length;i++){
//shift
s.push(s.shift());
var result=getShort(s);
if(!perfect || result.length<perfect.length) perfect=result;
}
In action
Thats quite close to the minimum number of characters ive estimated ( 244% minimization might be possible in the best case)
Ive also wrote a function to get the minimal number of chars and one to check if a certain word fails, you can find them here
I have used the idea of Dynamic programming to first generate the shortest possible string in forward direction as stated in OP. Then I have combined the result obtained in the previous step to send as a parameter along with the next String in the list. Below is the working code in java. Hope this would help to reach the most optimal solution, in case my solution is identified to be non optimal. Please feel free to report any countercases for the below code:
public String shortestPossibleString(String a, String b){
int[][] dp = new int[a.length()+1][b.length()+1];
//form the dynamic table consisting of
//length of shortest substring till that points
for(int i=0;i<=a.length();i++){
for(int j=0;j<=b.length();j++){
if(i == 0)
dp[i][j] = j;
else if(j == 0)
dp[i][j] = i;
else if(a.charAt(i-1) == b.charAt(j-1))
dp[i][j] = 1+dp[i-1][j-1];
else
dp[i][j] = 1+Math.min(dp[i-1][j],dp[i][j-1]);
}
}
//Backtrack from here to find the shortest substring
char[] sQ = new char[dp[a.length()][b.length()]];
int s = dp[a.length()][b.length()]-1;
int i=a.length(), j=b.length();
while(i!=0 && j!=0){
// If current character in a and b are same, then
// current character is part of shortest supersequence
if(a.charAt(i-1) == b.charAt(j-1)){
sQ[s] = a.charAt(i-1);
i--;
j--;
s--;
}
else {
// If current character in a and b are different
if(dp[i-1][j] > dp[i][j-1]){
sQ[s] = b.charAt(j-1);
j--;
s--;
}
else{
sQ[s] = a.charAt(i-1);
i--;
s--;
}
}
}
// If b reaches its end, put remaining characters
// of a in the result string
while(i!=0){
sQ[s] = a.charAt(i-1);
i--;
s--;
}
// If a reaches its end, put remaining characters
// of b in the result string
while(j!=0){
sQ[s] = b.charAt(j-1);
j--;
s--;
}
return String.valueOf(sQ);
}
public void getCombinedString(String... values){
String sSQ = shortestPossibleString(values[0],values[1]);
for(int i=2;i<values.length;i++){
sSQ = shortestPossibleString(values[i],sSQ);
}
System.out.println(sSQ);
}
Driver program:
e.getCombinedString("jack", "apple", "maven", "hold",
"solid", "mark", "moon", "poor", "spark", "live");
Output:
jmapphsolivecparkonidr
Worst case time complexity of the above solution would be O(product of length of all input strings) when all strings have all characters distinct and not even a single character matches between any pair of strings.
Here is an optimal solution based on dynamic programming in JavaScript, but it can only get through solid on my computer before it runs out of memory. It differs from #CodeHunter's solution in that it keeps the entire set of optimal solutions after each added string, not just one of them. You can see that the number of optimal solutions grows exponentially; even after solid there are already 518,640 optimal solutions.
const STRINGS = ["jack", "apple", "maven", "hold", "solid", "mark", "moon", "poor", "spark", "live"]
function map(set, f) {
const result = new Set
for (const o of set) result.add(f(o))
return result
}
function addAll(set, other) {
for (const o of other) set.add(o)
return set
}
function shortest(set) { //set is assumed non-empty
let minLength
let minMatching
for (const s of set) {
if (!minLength || s.length < minLength) {
minLength = s.length
minMatching = new Set([s])
}
else if (s.length === minLength) minMatching.add(s)
}
return minMatching
}
class ZipCache {
constructor() {
this.cache = new Map
}
get(str1, str2) {
const cached1 = this.cache.get(str1)
if (!cached1) return undefined
return cached1.get(str2)
}
set(str1, str2, zipped) {
let cached1 = this.cache.get(str1)
if (!cached1) {
cached1 = new Map
this.cache.set(str1, cached1)
}
cached1.set(str2, zipped)
}
}
const zipCache = new ZipCache
function zip(str1, str2) {
const cached = zipCache.get(str1, str2)
if (cached) return cached
if (!str1) { //str1 is empty, so only choice is str2
const result = new Set([str2])
zipCache.set(str1, str2, result)
return result
}
if (!str2) { //str2 is empty, so only choice is str1
const result = new Set([str1])
zipCache.set(str1, str2, result)
return result
}
//Both strings start with same letter
//so optimal solution must start with this letter
if (str1[0] === str2[0]) {
const zipped = zip(str1.substring(1), str2.substring(1))
const result = map(zipped, s => str1[0] + s)
zipCache.set(str1, str2, result)
return result
}
//Either do str1[0] + zip(str1[1:], str2)
//or str2[0] + zip(str1, str2[1:])
const zip1 = zip(str1.substring(1), str2)
const zip2 = zip(str1, str2.substring(1))
const test1 = map(zip1, s => str1[0] + s)
const test2 = map(zip2, s => str2[0] + s)
const result = shortest(addAll(test1, test2))
zipCache.set(str1, str2, result)
return result
}
let cumulative = new Set([''])
for (const string of STRINGS) {
console.log(string)
const newCumulative = new Set
for (const test of cumulative) {
addAll(newCumulative, zip(test, string))
}
cumulative = shortest(newCumulative)
console.log(cumulative.size)
}
console.log(cumulative) //never reached
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
This question will need to be answered in Javascript.
For example, I have an array of phone numbers:
var phoneNumbers = ['123-434-4455', '123-495-8475', '484-728-3456'];
The phone number at index 0 (123-434-4455) would be added as 1+2+3+4+3+4+4+4+5+5, totaling to 35.
I'm guessing this will involve some kind of loop (for loops, or the method .forEach), because I will need to do this for multiple phone numbers in an array that will probably be randomly generated by a computer, so length and amount will vary.
Also, I'm wondering if the hyphen will matter, in which case I have found .replaceAll("-","");.
I've researched some other methods on here that involve .split, .parsInt, .map, .toString, .reduce, .digitSum, and more. They seem pretty complicated, especially since I'm in a beginning course (however I'm totally new to programming - this is my first post btw). Also, I'd rather not post the full question because I really want to figure it out alone, but this is the part I'm most stuck on. Forgive me if this has been answered previously! Like I said...new to programming.
I also need to determine which phone number has the last largest sum of digits, and use a return statement to return the required phone number in its’ original form.
You can use map and reduce array methods:
['123-434-4455', '123-495-8475', '484-728-3456'].map(function(str) {
return str.split('').reduce(function(a,b) {
return a + (+b || 0);
}, 0);
}); // [ 35, 48, 51 ]
Some notes:
split('') splits a string into an array of characters
+b coerces b into a number, e.g. "5" to 5 and "-" to NaN.
+b || 0 will return 0 if +b is falsy (0 or NaN), and +b otherwise
This code will do it:
var phoneNumbers = ["123-434-4455", "123-495-8475", "484-728-3456"];
for (var i=0; i<phoneNumbers.length; i++) {//For every phone number
var total=0; //create a total variable
var indNumbers = phoneNumbers[i].replace(/-/g, ""); //remove all dashes
for (var j=0; j<indNumbers.length; j++) {//loop for all digits
total+=parseFloat(indNumbers[j]);//add each digit to total
}
console.log(total);//do stuff with it here
}
All pretty standard javascript stuff. Only confusing bit I might have used is the .replace method - my parameter is /-/g which might look scary, but it's the equivalent of passing in "-" except it tells the function to replace ALL instances of the dash. If you do pass "-", it only replaces the first instance.
If you're a beginner, the things in this code you'll want to learn about are .replace, parseFloat for loops, and accessing strings using square bracket notation.
var phoneNumbers = ["123-434-4455", "123-495-8475", "484-728-3456"];
function crossSum(arr, pos) {
var sum = 0;
var a = arr[pos].split("-").join("").split("");
a.forEach(function(e, i) {
sum += parseInt(a[i]);
})
return sum;
}
document.write(crossSum(phoneNumbers, 0));
This function will return the cross-sum of
your phone-number.
Just use crossSum(phoneNumers, 0) // 0 is the fist number of phoneNumbers.
This will return the crossSum.
Adding on #millerbr answer. If you don't want to use .replace you can just use parseInt/parseFloat on every char, if it is not a number those functions returns NaN which can be checked with isNaN() function
var phoneNumbers = ["123-434-4455", "123-495-8475", "484-728-3456"];
for (var i=0; i < phoneNumbers.length; i++) { //For every phone number
var total=0; //create a total variable
for (var j=0; j < phoneNumbers.length; j++) { //loop for all digits
var parsedNumber = parseInt(phoneNumbers[j]); // parse string to number or NaN if "-"
if (!isNaN(parsedNumber)) { // Check if result is NaN (Not a Number).
total += parsedNumber; //add each digit to total
}
}
console.log(total);//do stuff with it here
}
Assuming that phoneNumbers is an array of strings, you can indeed loop through the entire array and then in each element in the array you can loop through the string and check if the character is a number. If so, add it to your sum and then when you finish each element in the array you have the total sum for it and you can add it to another array full of your sums.