Reputation: 73
I'm attempting a challenge on a JavaScript learning website.
The instructions are:
It was decided to attribute a "weight" to numbers. The weight of a number will be from now on the sum of its digits For example 99 will have "weight" 18, 100 will have "weight" 1 so in the list 100 will come before 99. Given a string with the weights of FFC members in normal order can you give this string ordered by "weights" of these numbers?
Example: a = "56 65 74 100 99 68 86 180 90"ordered by numbers weights becomes: "100 180 90 56 65 74 68 86 99" When two numbers have the same "weight", let us class them as if they were strings and not numbers: 100 is before 180 because its "weight" (1) is less than the one of 180 (9) and 180 is before 90 since, having the same "weight" (9) it comes before as a string. All numbers in the list are positive numbers and the list can be empty.
My attempt is below:
function orderWeight(strng) {
console.log(strng);
if (strng === "") {
return strng;
} else {
var arr = strng.split(" ").sort();
console.log(arr);
var keys = [];
for (var i = 0; i < arr.length; i++) {
var weight = 0;
var current = arr[i];
//loop through the array adding the digits of each number
for (var j = 0; j < arr[i].length; j++) {
var sNum = parseInt(arr[i].charAt[j]);
weight += sNum;
console.log(weight);
}
keys.push({
weight: weight,
number: current
});
console.log(keys);
}
}
};
The output from my code is:
input string "103 123 4444 99 2000"
console.log(arr); = [ '103', '123', '2000', '4444', '99' ]
console.log(weight); = NaN
I realise I will need to do more after I get this portion of code working but if someone could just point me in the direction of getting this part to do what I want I would much appreciate it.
Upvotes: 0
Views: 1668
Reputation: 7119
It can be done as follow:
function getWeight(string){
return eval(string.split('').join('+'))
}
function orderWeight(string){
return string.split(' ').sort(function(a,b){
var wA = getWeight(a), wB = getWeight(b);
if(wA>wB) return 1;
if(wA<wB) return -1;
if(a>b) return 1;
if(a<b) return -1;
return 0;
}).join(' ');
}
Upvotes: 0
Reputation: 10924
I'd make a function to calculate the weights then use a custom sort function to sort your array.
Here's a running example.
var input = "56 65 74 100 99 68 86 180 90";
var a = input.split(" ");
a.sort(function(x, y) {
var xWeight = getWeight(x);
var yWeight = getWeight(y);
if (xWeight === yWeight)
return x > y;
else
return xWeight > yWeight;
});
function getWeight(x) {
var weight = 0;
var arr = x.split("");
arr.forEach(function(i) {
weight += parseInt(i, 10);
});
}
console.log(a);
Upvotes: 1
Reputation: 12239
Compute the weight of each string by converting it to an integer and taking the sum of the digits:
var weight = 0,
x = parseInt(parts[i], 10);
while (x != 0) {
var digit = x % 10;
weight += digit;
x = (x - digit) / 10;
}
Then make objects that contain each value and the string it came from:
sorted[i] = { weight: weight, string: parts[i] };
Now you can sort the objects with a comparison function that uses the weights if they differ, and the standard string comparison otherwise:
sorted.sort(function (a, b) {
if (a.weight != b.weight) {
return a.weight - b.weight;
}
return a.string.localeCompare(b.string);
});
Finally, extract the strings and print them to show the result.
Demonstration:
function print(s) {
document.write(s + '<br />');
}
function solve(s) {
print('input: ' + s);
var parts = s.split(' '),
n = parts.length,
sorted = new Array(n);
for (var i = 0; i < n; ++i) {
var weight = 0,
x = parseInt(parts[i], 10);
while (x != 0) {
var digit = x % 10;
weight += digit;
x = (x - digit) / 10;
}
sorted[i] = { weight: weight, string: parts[i] };
}
sorted.sort(function (a, b) {
if (a.weight != b.weight) {
return a.weight - b.weight;
}
return a.string.localeCompare(b.string);
});
var newParts = new Array(n);
for (var i = 0; i < n; ++i) {
newParts[i] = sorted[i].string;
}
print('output: ' + newParts.join(' '));
}
solve("56 65 74 100 99 68 86 180 90");
Upvotes: 2
Reputation: 700322
You are using brackets instead of parentheses when calling charAt
.
Change this:
var sNum = parseInt(arr[i].charAt[j]);
to:
var sNum = parseInt(arr[i].charAt(j));
Upvotes: 5