Combinations of numbers in array who sum is equal to n - javascript

Example:
var a = [1,2,3,4,5,6];
I want to display all of the unique 3 number combinations in the array where the sum of those 3 digits is equal to 9 (or n).
So result in this example would be:
[1,2,6]
[2,3,4]
[1,3,5]
Closest thing I could find was permutations of a string...
var alphabet = "abcde"; // shortened to save time
function permute(text) {
if(text.length === 3) { // if length is 3, combination is valid; alert
console.log(text); // or alert
} else {
var newalphabet = alphabet.split("").filter(function(v) {
return text.indexOf(v) === -1;
}); // construct a new alphabet of characters that are not used yet
// because each letter may only occur once in each combination
for(var i = 0; i < newalphabet.length; i++) {
permute(text + newalphabet[i]); // call permute with current text + new
// letter from filtered alphabet
}
}
}
permute("");

This could be a possible solution. Please note it does not take care of unique values and for that you need to add additional logic. However, if the array is sorted and have unique entries then the following will be producing the ideal result.
var a = [1,2,3,4,5,6];
var result = [];
for (var i = 0; i < a.length-2; i++) {
for (var j = i+1; j< a.length-1;j++) {
for (var k = j+1; k < a.length;k++) {
if(a[i]+a[j]+a[k] == 9) {
result.push([a[i],a[j], a[k]]);
}
}
}
}
console.log(result);

Related

expand a string in JavaScript to display letter and how many times that letter appears

Write a function that accepts a string where letters are grouped together and returns new string with each letter followed by a count of the number of times it appears.
example : ('aeebbccd') should produce // 'a1e2b2c2d1'
function strExpand(str) {
let results = ""
for (let i = 0; i < str.length; i++) {
let charAt = str.charAt(i)
let count = 0
results += charAt
for (let j = 0; j < str.length; j++) {
if (str.charAt(j) === charAt) {
count++;
}
}
results += count;
}
return results;
}
with the input 'aeebbccd' I am getting 'a1e2e2b2b2c2c2d1' instead of 'a1e2b2c2d1'
This function is adding a number after each character, which is the number of times this character appears anywhere in the string. You could instead do it like this to get the result you want.
function strExpand(str) {
let output = "";
// Iterate through each character of the string, appending
// to the output string each time
for (let i = 0; i < str.length; i++) {
let count = 1;
// If the next character is the same, increase the count
// and increment the index in the string
while (str[i + 1] == str[i]) {
count++;
i++;
}
// Add the character and the count to the output string
output += str[i] + count;
}
return output;
}
For sake of completeness,
how about a Regex?
const pattern = /(.)\1*/g; // put a char that exists in a capture group, then see if it repeats directly after
const s = 'aeebbccd';
var result = '';
for (match of s.match(pattern)) {
let this_group = match;
let this_len = match.length;
result = result + this_group[0] + this_len; // get only the first letter from the group
}
console.log(result); // a1e2b2c2d1
This would to the job. edit: hah i see im late :D, but still nice functional way to solve that.
/**
* #param string to count
* #return string $characterA$count. ex. abbccc -> a1b2c3
*/
function toCharacterCountString(str) {
return Array.from(new Set(str).values())
.map(char => {
return `${char}${(str.match(new RegExp(char, "g")) || []).length}`;
}).join('');
}
console.log(toCharacterCountString('abbccc')); // a1b2c3
console.log(toCharacterCountString('aeebbccd')); // a1e2b2c2d1

Character with longest consecutive repetition

i think i have wirtten the correct code for the problem only one thing and it that i return the first longest sequence how can i alter that to return the last maximum sequence?
an example from codewars editor :
for input '00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz'
Expected: ['c', 19], instead got: ['0', 19]
here is my code:
function longestRepetition(s) {
var count = 0;
var temp = s.charAt(0);
var arr = [];
for (var i = 0; i < s.length; i++) {
if (temp === s.charAt(i)) {
count++
temp = s.charAt(i)
}
else {
temp = s.charAt(i);
arr.push(count)
count = 1;
}
if(i==s.length-1)
arr.push(count);
}
if(arr.length>0)
{
var Max=arr[0]
for(var i=0;i<arr.length;i++)
{
if(Max<=arr[i])
Max=arr[i];
}
}
else var Max=0;
var mindex=arr.indexOf(Max);
return [s.charAt(mindex),Max]
}
I think this would be easier with a regular expression. Match any character, then backreference that character as many times as you can.
Then, you'll have an array of all the sequential sequences, eg ['000', 'aaaaa']. Map each string to its length and pass into Math.max, and you'll know how long the longest sequence is.
Lastly, filter the sequences by those which have that much length, and return the last item in the filtered array:
function longestRepetition(s) {
const repeatedChars = s.match(/(.)\1*/g);
const longestLength = Math.max(...repeatedChars.map(str => str.length));
const longestChars = repeatedChars.filter(str => str.length === longestLength);
return [longestChars.pop(), longestLength];
}
console.log(longestRepetition('00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz'));
The issue in your code is that minindex is an index in your arr, but that index has nothing to do with s. So s.charAt(minindex) makes no sense. You should maintain for which character you had found the count. For instance you could push in arr both the count and the corresponding character (as a subarray with two values). Then the rest of your code would only need little modification to make it work.
Applying this idea to your code without changing anything else, we get this:
function longestRepetition(s) {
var count = 0;
var temp = s.charAt(0);
var arr = [];
for (var i = 0; i < s.length; i++) {
if (temp === s.charAt(i)) {
count++
temp = s.charAt(i) // Not necessary: was already equal
}
else {
arr.push([temp, count]); // <--- pair, BEFORE changing temp
temp = s.charAt(i);
count = 1;
}
if(i==s.length-1)
arr.push([temp, count]); // <---
}
if(arr.length>0)
{
var Max=arr[0]; // <-- Max is now a pair of char & count
for(var i=0;i<arr.length;i++)
{
if(Max[1]<arr[i][1]) // Comparison changed to just less-than
Max=arr[i];
}
}
else Max=[null, 0]; // Must be a pair here also
return Max; // Just return the pair
}
console.log(longestRepetition('00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz'));
But you can do the same with less code:
function longestRepetition(s) {
let result = [null, 0]; // pair of character and count
for (var i = 0; i < s.length; null) {
let start = i++;
while (i < s.length && s[i] === s[start]) i++; // Find end of series
if (i - start > result[1]) result = [s[start], i - start];
}
return result;
}
console.log(longestRepetition('00000000000000111111111111111112222222222222223333333333333344444444444445555555555555666666666666777777777777888888888888888999999999999999999aaaaaaaaabbbbbbbbbbbbbbbbcccccccccccccccccccdddddddddddddddddddeeeeeeeeeeeeeeefffffffffffffggggggggggggggghhhhhhhhhhhhhiiiiiiiiiijjjjjjjjjjjjjjkkkkkkkkkkkkllllllllllmmmmmmmmmmnnnnnnnnnnnnnnoooooooooooopppppppppppppppppqqqqqqqqqqqqrrrrrrrrrrrrrrrrrrrssssssssssttttttttttttuuuuuuvvvvvvvvvvvvvvvvvwwwwwwwwwwwwwwwwxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyzzzzzzzzzzzzzz'));
The solution below answers the question with O(n) runtime:
function longestRepetition(s) {
let count = s.length > 0 ? 1 : 0
let char = s.length > 0 ? s[0] : ''
for (let string_i = 0; string_i < s.length - 1; string_i += 1) {
// keep track of current_char
let current_char = s[string_i]
let next_char = s[string_i + 1]
// while the next char is same as current_char
let tracker = 1
while (current_char === next_char) {
// add one to tracker
tracker += 1
string_i += 1
next_char = s[string_i + 1]
}
// if tracker greater than count
if (tracker > count) {
// returned char = current char
// count =tracker
count = tracker;
char = current_char;
}
}
return [char, count]
}
console.log(longestRepetition("bbbaaabaaaa"))//, ["a",4]

User Input is not storing correctly in array

Im given the task of storing 10 elements in an Array, then I have to add all of those elements.
My problem comes at the time of storing each individual element in the array.
When I set the length of the for loop as numbers.length it fills the array with the first number that was inputted, and if I set the length to 10, it only places the value in the index[0] and leaves the others as undefined.
var numbers = new Array();
function addnew() {
var un = document.getElementById('userNumber').value;
for (var i = 0; i < 10; i++) {
numbers.push(" " + un[i]);
}
console.log(numbers);
document.getElementById('elements').innerHTML = numbers;
The output that is expected is a list that shows the values entered by the user inputs into the array (length of 10) and the sum of those values.
What it's actually showing is the first number inputted followed by undefined till it reaches the maximum length which is 10.
it's because un string length is 1 as it not saved completely
var numbers = new Array();
function addnew() {
var un = '123';
for (var i = 0; i < Math.min(10,un.length); i++) {
numbers.push(" " + un[i]);
}
console.log(numbers);
document.getElementById('elements').innerHTML = numbers;
}
}
If your user is entering a space inbetween each number, you can just split that one string into an array.
numbers = un.split(" ");
numbers now contains an array of strings.
Then convert the strings to numbers, so you can get the sum.
for (var i = 0; i < numbers.length; i++) {
numbers[i] = Number(numbers[i]);
}
And then this will give you the sum.
sumOfNumbers = numbers.reduce((a, b) => a + b, 0);
console.log(sumOfNumbers);
un = "1 2 3 12";
numbers = un.split(" ");
console.log(numbers);
for (var i = 0; i < numbers.length; i++) {
numbers[i] = Number(numbers[i]);
}
console.log(numbers);
sumOfNumbers = numbers.reduce((a, b) => a + b, 0);
console.log("sum is " + sumOfNumbers);
At beginning your numbers.length is 0. I think you should do un.length
function addnew() {
var numbers = [];
var un = document.getElementById('userNumber').value;
for (var i = 0; i < un.length; i++) {
numbers.push(" " + un[i]);
}
console.log(numbers);
document.getElementById('elements').innerHTML = numbers;
}
<input type="text" id="userNumber" onChange="addnew()"/>
<span id="elements"></span>

Splitting Numbers and adding them all - JavaScript

I have a function that returns the sum of all its digits For both POSITIVE and NEGATIVE numbers.
I used split method and converted it to string first and then used reduce to add them all. If the number is negative, the first digit should count as negative.
function sumDigits(num) {
var output = [],
sNum = num.toString();
for (var i = 0; i < sNum.length; i++) {
output.push(sNum[i]);
}
return output.reduce(function(total, item){
return Number(total) + Number(item);
});
}
var output = sumDigits(1148);
console.log(output); // --> MUST RETURN 14
var output2 = sumDigits(-316);
console.log(output2); // --> MUST RETURN 4
Instead of returning the sum, it returned 4592 -1264
Am I doing it right or do I need to use split function? Or is there any better way to do this?
Sorry newbie here.
I think you'll have to treat it as a string and check iterate over the string checking for a '-' and when you find one grab two characters and convert to an integer to push onto the array. Then loop over the array and sum them. Of course you could do that as you go and not bother pushing them on the array at all.
function sumDigits(num) {
num = num + '';
var output = [];
var tempNum;
var sum = 0;
for (var i = 0; i < num.length; i++) {
if (num[i] === '-') {
tempNum = num[i] + num[i + 1];
i++;
} else {
tempNum = num[i];
}
output.push(parseInt(tempNum, 10));
}
for (var j = 0; j < output.length; j++) {
sum = sum + output[j];
}
return sum;
}
var output = sumDigits(1148);
console.log(output); // --> MUST RETURN 14
var output2 = sumDigits(-316);
console.log(output2); // --> MUST RETURN 4

String with the highest frequency of recurring letters in a word

This is a challenge for coderbyte I thought I'd try to do it using a different method for solving it than loops, objects. It passed but it isn't perfect. The directions for the challenge are:
Have the function LetterCountI(str) take the str parameter being passed and return the first word with the greatest number of repeated letters. For example: "Today, is the greatest day ever!" should return greatest because it has 2 e's (and 2 t's) and it comes before ever which also has 2 e's. If there are no words with repeating letters return -1. Words will be separated by spaces.
function LetterCountI(str){
var wordsAndLetters = {};
var count = 0;
var finalword;
str = str.split(" ");
for(var i = 0; i < str.length; i++){
wordsAndLetters[str[i]] = wordsAndLetters[str[i]] || 0;
}
function countWordLetters(strs){
strs = strs.split("");
var lettercount = {};
for(var i = 0; i <strs.length; i++){
lettercount[strs[i]] = lettercount[strs[i]] || 0;
lettercount[strs[i]]++;
}
return lettercount;
}
for(var words in wordsAndLetters){
wordsAndLetters[words] = countWordLetters(words);
var highestLetterFrequency = wordsAndLetters[words];
for(var values in highestLetterFrequency){
if(highestLetterFrequency[values] > count){
count = highestLetterFrequency[values];
finalword = words;
}
if(count !== 1){
return finalword;
}
}
}
return -1;
}
LetterCountI("today is the greatest day ever!");
Sorry if some of the variable names are confusing I've been up for far too long trying to figure out what I did wrong. If you use the parameters at the bottom of the code it returns 'greatest' like it should however change the parameters to
LetterCountI("toddday is the greatttttest day ever!");
and it logs 'toddday' when it should log 'greatttttest'. Is my code completely wrong? I realize if the parameters were ("caatt dooog") it should log 'caatt' since there are 4 recurring letters but I'm not worried about that I just am concerned about it finding the most recurrence of one letter(but by all means if you have a solution I would like to hear it!). Any changes to the variables if needed to make this code more readable would be appreciated!
The problem with your code is the positioning of the following section of code:
if(count !== 1){
return finalword;
}
Move it from where it currently is to just before the return -1, like so:
for(var words in wordsAndLetters){
wordsAndLetters[words] = countWordLetters(words);
var highestLetterFrequency = wordsAndLetters[words];
for(var values in highestLetterFrequency){
if(highestLetterFrequency[values] > count){
count = highestLetterFrequency[values];
finalword = words;
}
}
}
if(count !== 1){
return finalword;
}
return -1;
The problem with your original code is that your were returning the first word that had repeating characters, which meant your code didn't get far enough to check if any subsequent words had more repeating characters.
Also, just for fun, here is my alternative solution.
Here you go
Array.prototype.getUnique = function(){
var u = {}, a = [];
for(var i = 0, l = this.length; i < l; ++i){
if(u.hasOwnProperty(this[i])) {
continue;
}
a.push(this[i]);
u[this[i]] = 1;
}
return a;
}
function LetterCountI(str){
var temp = str.split(" ");
var final = '', weight = 0;
for(var i = 0; i < temp.length; ++i) {
var word = temp[i].split("");
if(word.getUnique().length < word.length) {
var diff = word.length - word.getUnique().length;
if(diff > weight){
weight = diff;
final = temp[i];
}
}
}
return final;
}
console.log(LetterCountI("Catt dooog"));
console.log(LetterCountI("toddday is the greatttttest day ever!"));
Viva LinQ !!!!!
var resultPerWord = new Dictionary<string, int>();
var S = "toddday is the greatttttest day ever!";
foreach(var s in S.Split(' '))
{
var theArray =
from w in s
group w by w into g
orderby g.Count() descending
select new { Letter = g.Key, Occurrence = g.Count() };
resultPerWord.Add(s, theArray.First().Occurrence);
}
var r = "-1";
if (resultPerWord.Any(x => x.Value >1))
{
r = resultPerWord.OrderByDescending(x => x.Value).First().Key;
}

Categories