How to calculate certain chars from a string - javascript

i'm looking for this since yesterday, already searched a lot but didn't find any answer for exactly what I need. If you find any, just tell me, i'll appreciate and close this question :)
What I want is:
-> If there are an even number of digits, double every other digit starting with the first
-> If there are an odd number of digits, double every other digit starting with the second.
This is what I did so far:
function validate(n){
var num = n.toString(); // THIS COULD BE AN ARRAY OR WHATEVER
if (eval(num%2==0)) { // IF HAS EVEN NUMBER OF DIGITS
for (var i=0; i<num.length; i++) {
if (num.charAt(i) === num.charAt(0)) {
eval(num.charAt(i)*=2);
}
}
console.log(num);
} else { // IF HAS ODD NUMBER OF DIGITS
for (var i=0; i<num.length; i++) {
if (num.charAt(i) === num.charAt(1)) {
eval(num.charAt(i)*=2);
}
}
console.log(num);
}
}
validate(1234516178);
Examples:
1714 => [1*, 7, 1*, 4] => [2, 7, 2, 4]
891 => [8, 9*, 1] => [8, 18, 1]
Hope I was clear. Can someone help on this? Appreciate!

Maybe this works for you. It utilizes an array with the values and iterates over the values to change.
function validate(n) {
var array = n.toString().split('').map(Number),
number = n % 2 ? array[1] : array[0];
return array.map(function (a) {
return a === number ? 2 * a : a;
});
}
function print(o) {
document.write('<pre>' + JSON.stringify(o, 0, 4) + '</pre>');
}
print(validate(1234516178));
print(validate(1714)); // => [1*, 7, 1*, 4] => [2, 7, 2, 4]
print(validate(891)); // => [8, 9*, 1] => [8, 18, 1]

You could try something like this:
function validate(n) {
n = n.toString();
var isEven = (parseInt(n, 10) % 2 === 0);
var digits = n.split("");
// Strings to numbers
digits.forEach(function(digit, index) {
digits[index] = parseInt(digit, 10);
});
if(isEven) {
var firstDigit = digits[0];
digits.forEach(function(digit, index) {
console.log(digit);
if(digit === firstDigit) {
digits[index] *= 2;
}
});
} else {
var secondDigit = digits[1];
digits.forEach(function(digit, index) {
if(digit === secondDigit) {
digits[index] *= 2;
}
});
}
return JSON.stringify(digits);
}
This can be of course be made better with including more conditions and leaving just a single forEach

You dont need strings to do that
function validate(s){
var a = parseInt(s);
var b = 0;
var odd = (a+'').length %2//true;
//var summ = 0;
while(a>=1){
var b = Math.floor(a%10);
var c = odd?b: b*2//<10? b*2 : b*2-9;
//summ += c;
odd = !odd;
a = a/10;
//output
$('input').after('+'+c)
}
//output
$('input').after('<br>')//.after(summ).after('<br> summ: ')
//return summ%10
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="validate($('input').val())">validate</button>
<input>

Related

Finding closest sum of numbers to a given number

Say I have a list [1,2,3,4,5,6,7]
and I would like to find the closest sum of numbers to a given number. Sorry for the crappy explanation but here's an example:
Say I have a list [1,2,3,4,5,6,7] I want to find the closest numbers to, say, 10.
Then the method should return 6 and 4 or 7 and 3 because its the closest he can get to 10. So 5 + 4 would be wrong because thats 9 and he can make a 10.
another example : you want the closest to 14 , so then he should return 7 and 6
If you got any questions plz ask because its difficult to explain what I want :P
Functions for combine, locationOf, are taken from different answers, written by different authors.
printClosest([0.5,2,4] , 5);
printClosest([1, 2, 3, 4, 5, 6, 7], 28);
printClosest([1, 2, 3, 4, 5, 6, 7], 10.9);
printClosest([1, 2, 3, 4, 5, 6, 7], 10, 2);
printClosest([1, 2, 3, 4, 5, 6, 7], 10, 3);
printClosest([1, 2, 3, 4, 5, 6, 7], 14, 2);
function printClosest(array, value, limit) {
var checkLength = function(array) {
return array.length === limit;
};
var combinations = combine(array); //get all combinations
combinations = limit ? combinations.filter(checkLength) : combinations;//limit length if required
var sum = combinations.map(function(c) { //create an array with sum of combinations
return c.reduce(function(p, c) {
return p + c;
}, 0)
});
var sumSorted = sum.slice(0).sort(function(a, b) {//sort sum array
return a - b;
});
index = locationOf(value, sumSorted);//find where the value fits in
//index = (Math.abs(value - sum[index]) <= Math.abs(value - sum[index + 1])) ? index : index + 1;
index = index >= sum.length ? sum.length - 1 : index;
index = sum.indexOf(sumSorted[index]);//get the respective combination
console.log(sum, combinations, index);
document.getElementById("result").innerHTML += "value : " + value + " combi: " + combinations[index].toString() + " (limit : " + (limit || "none") + ")<br>";
}
function combine(a) {
var fn = function(n, src, got, all) {
if (n == 0) {
if (got.length > 0) {
all[all.length] = got;
}
return;
}
for (var j = 0; j < src.length; j++) {
fn(n - 1, src.slice(j + 1), got.concat([src[j]]), all);
}
return;
}
var all = [];
for (var i = 0; i < a.length; i++) {
fn(i, a, [], all);
}
all.push(a);
return all;
}
function locationOf(element, array, start, end) {
start = start || 0;
end = end || array.length;
var pivot = parseInt(start + (end - start) / 2, 10);
if (end - start <= 1 || array[pivot] === element) return pivot;
if (array[pivot] < element) {
return locationOf(element, array, pivot, end);
} else {
return locationOf(element, array, start, pivot);
}
}
<pre id="result"><pre>
var data= [1, 2, 3,4,5,6,7];
var closest = 14;
for (var x = 0; x < data.length; x++) {
for (var y = x+1; y < data.length; y++) {
if(data[x] + data[y] == closet){
alert(data[x].toString() + " " + data[y].toString());
}
}
}
From what I understood from your question, I made this snippet. I assumed you did not wanted to have the same digit twice (e.g 14 => 7 + 7).
It is working with your examples.
var arr = [1, 2, 3, 4, 5, 6, 7];
var a = 0, b = 0;
var nb = 14;
for(var i in arr) {
for(var j in arr) {
if(i != j) {
var tmp = arr[i] + arr[j];
if(tmp <= nb && tmp > a + b) {
a = arr[i];
b = arr[j];
}
}
}
}
document.write("Closest to " + nb + " => " + a + " + " + b);
I have a little bit long winded solution to the problem just so it is easier to see what is done.
The main benefits with solution below:
The second loop will not start from beginning of the array again. What I mean that instead of having loop_boundary for second loop as 0 as you normally would, here it starts from next index. This helps if your numbers array is long. However, if it as short as in example, the impact in performance is minimal. Decreasing first loop's boundary by one will prevent errors from happening.
Works even when the wanted number is 1 or negative numbers.
Fiddle:
JSFiddle
The code:
var numbers = [1,2,3,4,5,6,7];
var wanted_number = 1;
var closest_range, closest1, closest2 = null;
var loop1_boundary = numbers.length-1;
for(var i=0; i<loop1_boundary; i++) {
var start_index = i+1;
var loop2_boundary = numbers.length;
for(var k=start_index; k<loop2_boundary; k++) {
var number1 = parseInt(numbers[i]);
var number2 = parseInt(numbers[k]);
var sum = number1 + number2;
var range = wanted_number - sum;
document.write( number1+' + '+number2 +' < '+closest_range+'<br/>' );
if(Math.abs(range) < Math.abs(closest_range) || closest_range == null ) {
closest_range = range;
closest1 = number1;
closest2 = number2;
}
}
if(range==0){
break;
}
}
document.write( 'closest to given number was '+closest1+' and '+closest2+'. The range from wanted number is '+closest_range );
This proposal generates all possible combinations, collects them in an object which takes the sum as key and filters then the closest sum to the given value.
function getSum(array, sum) {
function add(a, b) { return a + b; }
function c(left, right) {
var s = right.reduce(add, 0);
if (s > sum) {
return;
}
if (!result.length || s === result[0].reduce(add, 0)) {
result.push(right);
} else if (s > result[0].reduce(add, 0)) {
result = [right];
}
left.forEach(function (a, i) {
var x = left.slice();
x.splice(i);
c(left.slice(0, i), [a].concat(right));
});
}
var result = [];
c(array, [], 0);
return result;
}
function print(o) {
document.write('<pre>' + JSON.stringify(o, 0, 4) + '</pre>');
}
print(getSum([1, 2, 3, 4, 5, 6, 7], 10));
print(getSum([1, 2, 3, 4, 5, 6, 7], 14));
print(getSum([1, 2, 3, 4, 5, 6, 7], 19));

How to output the number of occurrences in array using JavaScript [duplicate]

This question already has answers here:
How to find the indexes of all occurrences of an element in array?
(16 answers)
Closed 7 years ago.
The goal here is to is count the number of occurrences in the following array:
[2, 3, 7, 9, 7, 3, 2]
For example if the user enters 7, the output should be [2, 4] because 7 occurs at both these indices. What I have so far looks like this
var arr1 = [2,3,7,9,7,3,2];
printArray(arr1);
var indexOfNum = findValueInArray(arr1, num);
if (indexOfNum === -1) {
console.log('%d was not found in the array of random integers.', num);
}
else {
console.log('%d was found in the array of random integers at index %d',num, indexOfNum);
}
My results are:
arr[0] = 2
arr[1] = 3
arr[2] = 7
arr[3] = 9
arr[4] = 7
arr[5] = 3
arr[6] = 2
7 was found in the array of random integers at index 2
I know I'm close but I'm not sure exactly what I'm overlooking. Thank you guys!
try this,
var arr1 = [2,3,7,9,7,3,2];
function occurance(array,element){
var counts = [];
for (i = 0; i < array.length; i++){
if (array[i] === element) {
counts.push(i);
}
}
return counts;
}
occurance(arr1, 2); //returns [0,6]
occurance(arr1, 7); //returns [2,4]
function findValueInArray(arr, num) {
var r = [];
for(i = 0; i < arr.length; i++) (arr[i] == num) ? r.push(i) : '';
return r;
}
function printArray(num, indexOfNum) {
console.log('%d was found ... index %s', num, indexOfNum.join(', '));
}
var arr = [2,3,7,9,7,3,2];
var num = 7;
var indexOfNum = findValueInArray(arr, num);
printArray(num, indexOfNum);
You can do it like this:
var arr = [2, 3, 7, 9, 7, 3, 2];
function occurrences(x, a) {
var pos = [];
a.forEach(function(val, i) {
if (x === a[i]) {
pos.push(i);
}
});
return pos;
}
console.log(occurrences(7, arr)); // [2, 4]
console.log(occurrences(5, arr)); // []
console.log(occurrences(2, arr)); // [0, 6]

Moving several elements within array to a certain index in array

I have an array of elements.
0,1,2,3,4,5,6,7,8,9
user can pick any number of elements and ask to move them after any 1 particular element.
example: ask for 4,5,7 to be moved after 1 for example, thus resulting in
0,1,4,5,7,2,3,6,8,9
or ask for 0,5 to be moved after 9
1,2,3,4,6,7,8,9,0,5
any pseudo code is greatly appreciated.
move_after= function(after, move_array) {
//remove elements from the array
move_array.forEach(function(element) {
var index = operations.indexOf(element);
operations.splice(index, 1);
});
var after_index = operations.indexOf(after) + 1;
//insert each move_array element to array
move_array.forEach(function(element) {
operations.splice(after_index++, 0, element);
});
}
move_after(2, [0,1]);
doesn't exactly give me what i want
Here a prototype is used, which inserts an array into an array after a specific digit:
Array.prototype.insertIntoArr = function(insert, digit) {
var i = this.indexOf(digit) + 1;
return this.slice(0, i).concat(insert).concat(this.slice(i));
}
The function moveAfter( ... ) first cleans the array from the values of toMove. Second toMove is inserted after the specific digit:
function moveAfter(arr, toMove, after) {
toMove.forEach(function (value) {
arr.splice(arr.indexOf(value), 1);
});
var res = arr.insertIntoArr(toMove, after);
return res;
}
Example
What about something like this: http://plnkr.co/edit/k2h6BWTUCFj5BS4oFF8C
(function(){
var arr = [0,1,2,3,4,5,6,7,8,9];
var userArr = [4,5,7];
var temp = [];
var pos = 1;
for(var i = arr.length; i >= 0; i--){
if(userArr.indexOf(arr[i]) !== -1){
temp.push(arr[i]);
arr.splice(i, 1);
}
}
for(var i = 0; i < temp.length; i++){
arr.splice(arr.indexOf(pos) + 1, 0, temp[i]);
}
console.log(arr);
//outputs [0, 1, 4, 5, 7, 2, 3, 6, 8, 9]
})();
Using your idea
function move_after(orig_array, after, move_array) {
//remove elements from the array
move_array.forEach(function(element) {
var index = operations.indexOf(element);
orig_array.splice(index, 1);
});
var after_index = orig_array.indexOf(after) + 1;
//insert each move_array element to array
move_array.forEach(function(element) {
orig_array.splice(after_index++, 0, element);
});
return orig_array;
}
Then you use
var result = move_after([0, 1, 2] , 2, [0,1]);
Hope it works,
Dan
Try this:
move_after = function (after, move_array) {
var i, s;
s = [];
for (i = 0; i < 10; i++)
{
// only append "i" it if is NOT in move_array
if (move_array.indexOf(i) === -1) s.push(i);
if (i == after) s.push(move_array);
}
return s;
};
Something like this?
var a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
var b = move_after(1, [4, 5, 7]);
var c = move_after(9, [0, 5]);
console.log(a);
console.log(b);
console.log(c);
function move_after(moveAfter, toMove) {
var arr = a.reduce(function (c, e, i) {
if (toMove.indexOf(e) === -1) {
c.push(e);
}
return c;
}, []);
var toMoveAfterIndex = arr.indexOf(moveAfter) + 1;
Array.prototype.splice.apply(
arr, [toMoveAfterIndex, 0].concat(toMove)
);
return arr;
}

Get the sum of array items that are equal to the target (Subset sum)

I need to get the sum of array items that are equal to the target. If the sum of array item will not equal to the target I would like to get the highest sum that is less than the target.
Here is an example:
Input: [4, 6, 8, 12, 4, 6, 6, 12, 4, 4,4]
Results:
[12]
[12]
[8, 4]
[6, 6]
[4,4,4]
[6,4]
Note: The array item can only be used once.
Currently here is what I have right now:
var subset_sum = function (items, target) {
var results = [];
items.sort(function (a, b) { return b - a });
ss = function (items) {
var item = items.shift();
if (item < target) {
var perms = [];
perms.push(item);
var isItemPush = false;
var counter = 0
var innerSubset = function () {
if (item + items[counter] === target) {
perms.push(items[counter])
items.splice(counter, 1);
results.push(perms);
isItemPush = true;
} else {
if (counter < items.length) {
counter += 1;
innerSubset();
}
}
}
innerSubset();
} else {
results.push(item);
}
if (items.length === 0) {
return results;
}
return ss(items);
}
return ss(items)
}
window.onload = function () {
var items = [4, 6, 8, 12, 4, 6, 6, 12, 4, 4];
target = 12;
result = subset_sum(items, target);
console.log(result);
}
The problem with this approach is that it is only one or two dimensional. From the example above, it does not return the result [4,4,4] and 6.
Very similar solution to yours, a bit unclear if it's helpful:
numbers = [4, 6, 8, 12, 4, 6, 6, 12, 4, 4];
var result = createSubsets(numbers, 12);
console.log('Result', JSON.stringify(result));
function createSubsets(numbers, target) {
// filter out all items larger than target
numbers = numbers.filter(function (value) {
return value <= target;
});
// sort from largest to smallest
numbers.sort(function (a, b) {
return b - a;
});
// array with all the subsets
var result = [];
while (numbers.length > 0) {
var i;
var sum = 0;
var addedIndices = [];
// go from the largest to the smallest number and
// add as many of them as long as the sum isn't above target
for (i = 0; i < numbers.length; i++) {
if (sum + numbers[i] <= target) {
sum += numbers[i];
addedIndices.push(i);
}
}
// remove the items we summed up from the numbers array, and store the items to result
// since we're going to splice the numbers array several times we start with the largest index
// and go to the smallest to not affect index position with splice.
var subset = [];
for (i = addedIndices.length - 1; i >= 0; i--) {
subset.unshift(numbers[addedIndices[i]]);
numbers.splice(addedIndices[i], 1);
}
result.push(subset);
}
return result;
}
Produces array:
[12],[12],[8,4],[6,6],[6,4],[4,4]
There's no limit regarding the subset length. If you add one more 4 to the numbers array you will get result:
[12],[12],[8,4],[6,6],[6,4],[4,4,4]
JSFiddle: http://jsfiddle.net/kUELD/

Extracting the most duplicate value from an array in JavaScript (with jQuery)

I have several array to deal with. I need to extract the most duplicate value from each array.
From [3, 7, 7, 7], I need to find the value 7. Each array size is 4. For now, I don't have to think about when the most duplicate values are more than one such as [3, 7, 7, 7]. All the values are a number.
I looked around the web. I found several ways to make an array to become uniq(). But I haven't found a way to get the duplicate value. I am using jQuery, but raw JavaScript is fine for this task.
Not perfect in terms of efficiency, but does the job:
var nums = [3, 7, 7, 7];
var freqs = {};
var max_index;
var max_value = -1/0; // Negative infinity.
$.each(nums, function(i, v) {
if (freqs[v] != undefined) {
freqs[v]++;
} else {
freqs[v] = 1;
}
});
$.each(freqs, function(num, freq) {
if (freq > max_value) {
max_value = freq;
max_index = num;
}
});
if (max_index != undefined) {
alert("Most common element is " + max_index + " with " + max_value + " repetition(s).");
}
​
Here's a simpler and faster version using only JavaScript:
var arr = [3, 7, 7, 7, 10, 10, 8, 5, 5, 5, 5, 20, 20, 1];
var counts = {}, max = 0, res;
for (var v in arr) {
counts[arr[v]] = (counts[arr[v]] || 0) + 1;
if (counts[arr[v]] > max) {
max = counts[arr[v]];
res = arr[v];
}
}
alert(res + " occurs " + counts[res] + " times");
Note that this is a much more efficient since you're looping over the data once, if you're sorting very large arrays this will start to matter.
Here's a quick example using javascript:
function mostFrequent(arr) {
var uniqs = {};
for(var i = 0; i < arr.length; i++) {
uniqs[arr[i]] = (uniqs[arr[i]] || 0) + 1;
}
var max = { val: arr[0], count: 1 };
for(var u in uniqs) {
if(max.count < uniqs[u]) { max = { val: u, count: uniqs[u] }; }
}
return max.val;
}
A quick note on algorithmic complexity -- because you have to look at each value in the array at least once, you cannot do better than O(n). This is assuming that you have no knowledge of the contents of the array. If you do have prior knowledge (e.g. the array is sorted and only contains 1s and 0s), then you can devise an algorithm with a run time that is some fraction of n; though technically speaking, it's complexity is still O(n).
Array.prototype.mostFreq=function(){
var what, a= this.concat(), ax, freq,
count, max=0, limit= a.length/2;
while(a.length){
what= a.shift();
count=1;
while((ax= a.indexOf(what))!= -1){
a.splice(ax,1); // remove counted items
++count;
}
// if any item has more than half the array, quit counting
if(count> limit) return what;
if(count> max){
freq= what;
max= count;
}
}
return freq;
}
var a=[1,1,2,5,4,2,7,7,1,1,1,3,7,7,3,4,3,7,3,5,6,2,3,1,1,7,7,2,4,3,6,7,6,6]
alert(a.mostFreq())
Another solution can be based on Array.reduce():
var arr = [1,1,2,5,4,2,10,10,1,1,1,3,10,10,3,4,3,10,3,5,6,2,3,1,1,10,10,2,4,3,6,10,6,6];
var result = arr.reduce(function(acc, e) {
acc[e] = (acc[e] || 0) + 1;
if (acc[e] > acc.mostFreq.freq) {
acc.mostFreq.value = e;
acc.mostFreq.freq = acc[e];
}
return acc;
}, {"mostFreq": {"value": 0, "freq": 0}}).mostFreq;
console.log('The most duplicated elements is: ' + JSON.stringify(result));

Categories