this maybe is not the biggest challenging problem but I've got curious about it.
I did a simple code just to get the Fibonacci value based on the user input without recursion and works just fine. Very simple code:
function fib(n) {
let fibArray = [0,1];
let count = 0;
while(fibArray.length <= n){
let previous = fibArray[count + 1];
let beforePrevious = fibArray[count];
fibArray.push(beforePrevious + previous);
count++;
}
return fibArray[n];
}
But the moment I tried to make it as a recursive function, the result is undefined, even if the value is not.
function fib(n, count = 0, fibArray = [0,1]){
if(fibArray.length - 1 === n){
return fibArray[n];
}
if (fibArray.length <= n ) {
let previous = fibArray[count + 1];
let beforePrevious = fibArray[count];
fibArray.push(beforePrevious + previous);
count++;
}
fib(n,count, fibArray);
}
Just add a return statement in the last line.
return fib(n,count, fibArray);
The code is ok, you just need to add a return:
function fib(n, count = 0, fibArray = [0,1]){
if(fibArray.length - 1 === n){
return fibArray[n];
}
if (fibArray.length <= n ) {
let previous = fibArray[count + 1];
let beforePrevious = fibArray[count];
fibArray.push(beforePrevious + previous);
count++;
}
return fib(n,count, fibArray);
}
Related
Let's say we have this string:
BBBBAAAABBAAAAAACCCCCBDDDDEEEEEEE,FFF
As you can see, here B is occurring 4 times at first but B is also present before DDDD.
Similarly, A is occurring 4 times at the beginning and later 6 times.
I want the expected output if I am searching B it should 4 times as the max occurrence B is 4. However if I am searching A then it should return 6 because the most occurrence for A is 6.
Here is my code I tried:
function checkRepeatativeString(str) {
let hashMap = {};
let seen = new Set();
let counter = 1;
let maxValue = 1;
let isPreviousValueSame = false;
let isNextValueSame = true;
for (let i = 0; i < str.length; i++) {
/**
* is previous value same
*/
if (str[i] == str[i-1]) {
isPreviousValueSame = true;
}
/**
* is next value same
*/
if (str[i] == str[i+1]) {
isNextValueSame = true;
}
if (seen.has(str[i]) && isPreviousValueSame) {
hashMap[str[i]][0]++;
hashMap[str[i]][1]++;
isPreviousValueSame = false;
} else if(seen.has(str[i]) && !isNextValueSame) {
maxValue = Math.max(hashMap[str[i]][1], maxValue);
counter = 0;
hashMap[str[i]] = [counter, maxValue];
} else {
maxValue = Math.max(maxValue, counter);
seen.add(str[i]);
hashMap[str[i]] = [counter, maxValue];
isPreviousValueSame = false;
}
}
return hashMap;
}
let str = "BBBBAAAABBAAAAAACCCCCBDDDDEEEEEEE,FFF";
console.log(checkRepeatativeString(str));
This code is working but if you look for B, I am getting stuck at the beginning of value.
My program returns out for B:
B: [ 1, 1 ]
^ ^
Inside array, 1 is a counter which scans the string and second 1 in array is a max value which should return the output. However my program is returning 1 for B. I am expecting 4 as max value.
Help would be appreciated~
Quick and dirty.
function maxConsecutiveCharacters(check, haystack) {
if(check.length !== 1) return false;
let result = 0;
let buffer = 0;
for(let i = 0; i < haystack.length; i++) {
if(haystack[i] === check) {
buffer++;
}
else {
if(buffer > result) {
result = buffer;
}
buffer = 0;
}
if(buffer > result) {
result = buffer;
}
}
return result;
}
That looks overly complicated. Consider approaching the problem from a different angle - first split up the string into segments of repeating characters, and group them into an object based on the length of the longest substring for a given character.
const checkRepeatativeString = (str) => {
const longestCounts = {};
for (const consecutive of (str.match(/(.)\1*/g) || [])) {
const char = consecutive[0];
longestCounts[char] = Math.max(
longestCounts[char] || 0, // Use the existing value in the object if it exists and is higher
consecutive.length // Otherwise, use the length of the string iterated over
);
}
return longestCounts;
};
let str = "BBBBAAAABBAAAAAACCCCCBDDDDEEEEEEE,FFF";
console.log(checkRepeatativeString(str));
Simpler code often means less surface area for bugs.
I have to do a binary search for a names directory in typescript, if the name is in the array the code works properly but if the name it's not in the array it became in an infinite loop.
Can somebody help me? Please!
This is the code:
var initialArray = ['Diego', 'David','Mauricio']
var sortedArray = initialArray.sort()
function search(find) {
var leftLimit = initialArray[0]
var leftLimitIndex = initialArray.indexOf(leftLimit)
var rightLimit = initialArray[initialArray.length - 1]
var rightLimitIndex = initialArray.indexOf(rightLimit)
var pivotIndex = 0
var index = -1
while (compare(leftLimit, rightLimit)) {
pivotIndex = Math.floor((leftLimitIndex + rightLimitIndex)/2)
console.log(pivotIndex)
if (initialArray[pivotIndex] == find) {
index = pivotIndex
break
}
else {
if (compare(initialArray[pivotIndex], find)) {
leftLimitIndex = pivotIndex + 1
}
else {
rightLimitIndex = pivotIndex - 1
}
}
console.log(initialArray[pivotIndex])
}
console.log("Result: "+initialArray[index])
return initialArray[index]
}
function compare(leftLimit, rightLimit) {
var r = (leftLimit < rightLimit ? -1 : 1)
if (r < 0) {
return true
}
else {
return false
}
}
Youare not taking in account the limits index which change and at the end you dont know if you have not more options to search or if the findTerm doesnt exits at all.
You only need to change the follow line
while (compare(leftLimit, rightLimit) && leftLimitIndex <= rightLimitIndex) {
Regards,
function numberSum(num) {
var str = num.toString();
var arrNum = str.split('').map(Number);//arrNum = [1, 2, 3];
//For-looping
var result = 0;
for (var i = 0; i < arrNum.length; i++) {
result = result + arrNum[i];
}
return result;
}
console.log(numberSum(22222)); // 2 + 2 + 2 + 2 + 2 = 10
I did this with For-looping and then iterate it. The question is, how do i did the same but with Recursive Function?
You could use only the first element for addition and call the function with the rest of the array again.
In this case, a check is made for the length, this returns either 0 if the array has no items or the item count, then a shift is made which returns the first item of the array. Additionaly the function is called again with the reduced array.
function iter(array) {
return array.length && array.shift() + iter(array);
// ^^^^^^^^^^^^ exit condition,
// if zero, return zero,
// otherwise return the
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^ iteration part
// return the first value and
// call recursion again
}
function numberSum(v) {
function iter(array) {
return array.length && array.shift() + iter(array);
}
return iter(v.toString().split('').map(Number));
}
console.log(numberSum(22222)); // 2 + 2 + 2 + 2 + 2 = 10
For the input you have (22222) your function is a practical solution. If you want a function that takes a number and adds itself together a certain number of times you can simply do this...
function sums(a, b) {
return a * b;
}
sums(2, 5);
//=> 10
But if you really require an example of a recursive function to do this the following will achieve the same result...
var num = 2;
var iterate = 5;
function sums(n, count, total) {
if (count === 0) {
return total;
} else {
return sums(n, --count, total+n);
}
}
console.log(sums(num, iterate, 0));
//=> 10
Hope that helped. :)
(See this blog post on JavaScript recursion by integralist).
I have the following code
var utils = require(`${__dirname}/../../utils/utils.js`);
...
let object = utils.parse(input);
if (object === undefined){
let helper = utils.recognize(input);
msg.channel.sendMessage("\"" + input + "\" not recognized. Did you mean \"" + helper[0] + "\"?");
object = utils.parse(helper[0]);
}
//code related to object
console.log(object.strLength);
where "parse" tries to match the input to an object in a database, and "recognize" tries to find the best match if the input is spelled incorrectly (Levenshtein) (along with additional info such as how close the match was).
Currently the issue is that the code is ran asynchronously; "object.strLength" returns an undefined before utils.recognize() returns a value. If I copy/paste the recognize() and parse() functions into the file, then the code is run synchronously and I do not run into any issues. However I would rather keep those functions in a separate file as I reuse them in other files.
Is there a way to specify that the functions in utils must be synch? I know that there are libraries that convert asynch into synch but I prefer to use as few libraries as I can help it. I tried to have the recognize functions return a Promise but it ended up as a jumbled mess
edit: here's parse. I did not think it was necessary to answer this question so I did not include it initially:
var db = require(`${__dirname}/../data/database.js`);
...
var parse = (input) => {
let output = db[output];
if (output === null) {
Object.keys(db).forEach((item) => {
if (db[item].num === parseInt(input) || (db[item].color + db[item].type === input)){
output = db[item];
return false;
}
});
}
return output;
}
I solved the issue, thanks everyone. Here's what was wrong, it was with recognize(). It was my mistake to not show the code for it initially.
Original recognize:
var recognize = (item) => {
//iterate through our databases and get a best fit
let bestItem = null;
let bestScore = 99999; //arbitrary large number
//let bestType = null;
//found algorithm online by milot-mirdita
var levenshtein = function(a, b) {
if (a.length == 0) { return b.length; }
if (b.length == 0) { return a.length; }
// swap to save some memory O(min(a,b)) instead of O(a)
if(a.length > b.length) {
let tmp = a;
a = b;
b = tmp;
}
let row = [];
for(let i = 0; i <= a.length; i++) {
row[i] = i;
}
for (let i = 1; i <= b.length; i++) {
let prev = i;
for (let j = 1; j <= a.length; j++) {
let val;
if (b.charAt(i-1) == a.charAt(j-1)) {
val = row[j-1]; // match
} else {
val = Math.min(row[j-1] + 1, // substitution
prev + 1, // insertion
row[j] + 1); // deletion
}
row[j - 1] = prev;
prev = val;
}
row[a.length] = prev;
}
return row[a.length];
}
//putting this here would make the code work
//console.log("hi");
Object.keys(db).forEach((key) => {
if (levenshtein(item, key) < bestScore) {
bestItem = key;
bestScore = levenshtein(item, key);
}
});
return [bestItem, bestScore];
}
My solution was to move the levenshtein function outside of the recognize function, so if I wanted to I can call levenshtein from another function
#user949300 and #Robert Moskal, I changed the forEach loop into a let...in loop. There is no functional difference (as far as I can tell) but the code does look cleaner.
#Thomas, I fixed the let output = db[output]; issue, oops.
Again, thanks for all of your help, I appreciate it. And happy New Year too
Can anyone help me to do this? The function is empty below and I am unsure how to proceed. I have the factorized number showing on the webpage now I would like the math to show before it. Something like this;
A user inputs: 3
Our site outputs: "1 x 2 x 3 = 6"
function factorialize(num) {
var total = 1;
if (num > 1) {
for (var i = 1; i <= num; i += 1) {
total *= i;
}
}
return total;
}
function showMath() {
};
$(document).ready(function() {
$("form#new-item").submit(function(event) {
event.preventDefault();
var userInput = parseInt($("input#input1").val());
var result = factorialize(userInput);
var myWork = showMath(userInput);
// var
$("#output").text(myWork + " = " + result);
});
});
You should build up an array of all the factors. Then it is easy to reduce() the array to a single value or join() it into a string.
function toFactorialArray(num){
var n = num,
arr = [n];
while (--n) arr.push(n);
return arr;
}
function getResult(arr){
return arr.reduce(
function( memo, current ) {
return memo * current
}, 1
);
}
function getWork(arr){
return arr.reverse().join(' * ');
}
$(document).ready(function() {
$("form#new-item").submit(function(event) {
event.preventDefault();
var userInput = parseInt($("input#input1").val());
var factors = toFactorialArray(userInput);
var result = getResult(factors);
var myWork = getWork(factors);
$("#output").text(myWork + " = " + result);
});
});