Hey so i'm writing a function that checks whether a series of braces is a valid sequence. I have the following code, which mostly does what I want it to do, except it it always returns false. If i enter a valid sequence of braces it ends up in the right if-statement, but never returns true. I don't understand why.
function match(s) {
if (s === '(') {
return ')'
}
else if (s === '[') {
return ']'
}
else if (s === '{') {
return '}'
}
}
function open(b) {
if ( (b === '(' ) || (b === '[' ) || (b === '{') ) {
return true;
}
return false;
}
function checkValid(string, temp, n) {
var current = string.charAt(n)
var currentMatch = temp.charAt(0)
if (!(current) && (n === string.length) && (temp === "")) {
console.log('hey')
return true
}
if (open(current)) {
temp = match(current).concat(temp)
checkValid(string, temp, n+1)
}
else {
if (current === currentMatch) {
temp = temp.substr(1)
checkValid(string, temp, n+1)
}
return false;
}
return false;
}
function validBraces(braces) {
var n = 0
var temp = ''
return checkValid(braces, temp, n)
}
validBraces('()') // should return true
validBraces('[[)}}{') //should return false
The last return false is always being returned from your original checkValid function call.
This is because you aren't returning the recursive checkValid calls.
function match(s) {
if (s === '(') {
return ')'
}
else if (s === '[') {
return ']'
}
else if (s === '{') {
return '}'
}
}
function open(b) {
if ( (b === '(' ) || (b === '[' ) || (b === '{') ) {
return true;
}
return false;
}
function checkValid(string, temp, n) {
var current = string.charAt(n)
var currentMatch = temp.charAt(0)
if (!(current) && (n === string.length) && (temp === "")) {
console.log('hey')
return true
}
if (open(current)) {
temp = match(current).concat(temp)
return checkValid(string, temp, n+1)
}
else {
if (current === currentMatch) {
temp = temp.substr(1)
return checkValid(string, temp, n+1)
}
return false;
}
return false;
}
function validBraces(braces) {
var n = 0
var temp = ''
return checkValid(braces, temp, n)
}
validBraces('()') // should return true
validBraces('[[)}}{') //should return false
Related
This code return "false" for test input "1" only when I submit in leet code. It's working when I do it in my local or leet code editor for the same input
var temp = 0;
var rev = 0;
var palindromeCheck = function (org) {
temp = org % 10;
rev = rev * 10 + temp;
org = parseInt(org / 10);
if (org > 0) {
palindromeCheck(org);
}
return rev;
};
var isPalindrome = function (x) {
if (x == 0) {
return true;
}
else if(x > 0) {
var value = palindromeCheck(x);
if (value === x) {
return true;
}
else {
return false;
}
}
else {
return false;
}
};
your palindromeCheck() function return a number. The problem comes from this part, where you strictly compare a number and a string:
if (value === x) {
return true;
}
else {
return false;
}
try to do :
if (value == x) {
return true;
}
else {
return false;
}
or
return (value == x);
else you can just use parseInt() function.
I'm stuck with one of curriculum in freeCodeCamp.org
https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/arguments-optional
The below code is what I wrote.
In that code, addTogether(2)(3) should be 5.
But instead of that, addTogether(2)(3) is "undefined"
what's the problem?
I read all hints from freecodecamp forum. But I don't get it.
function addTogether() {
var checkNum = function(x) {
if (typeof x === "number") {
return x
} else {
return undefined
}
}
if (arguments.length > 1) {
if (checkNum(arguments[0]) !== undefined && checkNum(arguments[1]) !== undefined) {
return arguments[0] + arguments[1]
} else {
return undefined
}
} else {
var a = arguments[0]
if (checkNum(a) === undefined) {
return undefined
} else {
return function(args2) {
args2 + a
}
}
}
return false;
}
console.log(addTogether(2)(3))
Your returned function doesn't have a return value. You could use
return function(args2) {
return args2 + a
}
Or
return (args2) => args2 + a
function addTogether(a,b) {
if (arguments.length==2){
if (typeof a == "number" && typeof b == "number"){
return a + b;
}
}
if(arguments.length==1){
if (typeof a == "number"){
return function(b){
if (typeof b == "number"){
return a + b;
}
};
}
}
}
Alright Stackoverflow first post here. I am at a loss, and would appreciate any help.
I have a recursive function that seems to be working properly up until I try and return from it. (Just a little maze runner for fun)
When reaching the return statement it seems to loop back to the if(grid[y+1][x] ===2) statement.
Then I don't see the function getting called again, but the values for y and x start changing as it loops around the function before getting to the else at the bottom and returning there.
I also see the "inside return if" in the console, and setting break points in the browser shows the return statement gets called, just doesn't exit the function.
Many thanks in advance!!!
const grid =[0,0,0,0,3,2],
[0,0,0,0,3,0],
[0,0,0,0,3,0],
[3,3,3,3,3,0],
[0,0,0,0,0,0],
[1,3,3,3,3,3]
],
const recursiveSearch = (y, x) => { // init values y=5 x=0
console.log(y + ' ' + x);
if(grid[y-1]){
if(grid[y-1][x] === 0) {
grid[y-1][x] = 4;
recursiveSearch(y-1, x);
}
if(grid[y-1][x] === 2) {
console.log('inside return if');
return 'end point found at';
}
}
if(grid[y][x+1] || grid[y][x+1] === 0) {
if(grid[y][x+1] === 0) {
grid[y][x+1] = 4;
recursiveSearch(y,x+1);
}
if(grid[y][x+1] === 2) {
return "end point found at";
}
}
if(grid[y+1] || grid[y+1] === 0) {
if(grid[y+1][x] === 0) {
grid[y+1][x] = 4;
recursiveSearch(y+1,x);
}
if(grid[y+1][x] === 2) {
return "end point found at";
}
}
if(grid[y][x-1] || grid[y][x-1] === 0 ) {
if(grid[y][x-1] === 0) {
grid[y][x-1] = 4;
recursiveSearch(y,x-1);
};
if(grid[y][x-1] === 2) {
return "end point found at";
}
} else {
return "No solution found"
}
};
you must return value of calling recursive function.
const grid =[0,0,0,0,3,2],
[0,0,0,0,3,0],
[0,0,0,0,3,0],
[3,3,3,3,3,0],
[0,0,0,0,0,0],
[1,3,3,3,3,3]
],
const recursiveSearch = (y, x) => { // init values y=5 x=0
console.log(y + ' ' + x);
if(grid[y-1]){
if(grid[y-1][x] === 0) {
grid[y-1][x] = 4;
return recursiveSearch(y-1, x); // must return value of calling recursiveSearch
}
if(grid[y-1][x] === 2) {
console.log('inside return if');
return 'end point found at';
}
}
if(grid[y][x+1] || grid[y][x+1] === 0) {
if(grid[y][x+1] === 0) {
grid[y][x+1] = 4;
return recursiveSearch(y,x+1); // // must return value of calling recursiveSearch
}
if(grid[y][x+1] === 2) {
return "end point found at";
}
}
if(grid[y+1] || grid[y+1] === 0) {
if(grid[y+1][x] === 0) {
grid[y+1][x] = 4;
return recursiveSearch(y+1,x); // must return value of calling recursiveSearch
}
if(grid[y+1][x] === 2) {
return "end point found at";
}
}
if(grid[y][x-1] || grid[y][x-1] === 0 ) {
if(grid[y][x-1] === 0) {
grid[y][x-1] = 4;
return recursiveSearch(y,x-1); // must return value of calling recursiveSearch
};
if(grid[y][x-1] === 2) {
return "end point found at";
}
} else {
return "No solution found"
}
};
Kindly add return statement for every recursive call.
Working on a Holdem hand evaluator, and part of the yak shaving is writing a "how many combos of 5 do you get from 7 cards" function (pickNofSet()). I've done that, but the way I've done that returns a bunch of duplicates.
So I have to write a removeDuplicates(). Here's the problem... it works with a simple array, but it doesn't work with the "arrays of arrays" that my "pickNofSet" function generates.
-- here's the removeDuplicates code --
var removeDuplicates = function(input){ // takes array
var output = [];
for (i=0; i < input.length; i++){
var unique = true; // all elements are innocent until proven guilty
for(j=i+1; j < input.length; j++){
if(input[j] === input[i]){
unique = false; // guilty!
};// endif
};// end jfor
if(unique){ // if not found guilty,
output.push(input[i]); // you may go free, little element
};// end if
};// end ifor
console.log(output);
return output; };//end function
Here's what I get from the Console:
> removeDuplicates(['a','b','c'],['a','b','c'],['d','e','f'],['g','h','i']);
< undefined
> removeDuplicates([1, 2, 2, 3, 3, 5, 5, 6, 6, 6]);
< [1, 2, 3, 5, 6]
Operator === can't compare array
As you use === to check equality between two elements, this only works with primitive data types, but not array. e.g.
1===1 // true
[1]===[1] // Sorry, you can't
If you want your algorithm to work with both primitive elements and array elements, you may need to upgrade your equality check from === to a customized function.
From this:
if(input[j] === input[i]){
unique = false; // guilty!
};// endif
To this:
if (equals(input[j],input[i]){
unique = false; // guilty!
};// endif
And implement equals function to be capable of comparing both primitive data types and arrays:
function equals(a,b){
if (typeof(a)!=typeof(b))
return false;
else if (typeof(a)=='object'){
if (Object.keys(a).length != Object.keys(b).length)
return false;
else{
for (var keyA of Object.keys(a)){
if (!(keyA in b))
return false;
else if (a[keyA]!==b[keyA])
return false;
else
return true;
}
}
}
else
return a===b;
}
Hint: This solution should, hopefully, also work with JSON element.
Here is an example of a general purpose unique filter that should fill your need. Requires an ES5 compliant environment.
(function () {
'use strict';
function $strictEqual(a, b) {
return a === b;
}
function $isUndefined(inputArg) {
return $strictEqual(typeof inputArg, 'undefined');
}
function $isPrimitive(inputArg) {
var type = typeof inputArg;
return type === 'undefined' || inputArg === null || type === 'boolean' || type === 'string' || type === 'number' || type === 'symbol';
}
function $isFunction(inputArg) {
return typeof inputArg === 'function';
}
function $isDate(inputArg) {
return Object.prototype.toString.call(inputArg) === '[object Date]';
}
function $isRegExp(inputArg) {
return Object.prototype.toString.call(inputArg) === '[object RegExp]';
}
function $isString(inputArg) {
return Object.prototype.toString.call(inputArg) === '[object String]';
}
function $isArguments(inputArg) {
return Object.prototype.toString.call(inputArg) === '[object Arguments]';
}
function $getItem(object, index) {
var item;
if ($isString(object)) {
item = object.charAt(index);
} else {
item = object[index];
}
return item;
}
var de = function (a, b, circ) {
if (a === b) {
return true;
}
var aType,
bType,
aIsArgs,
bIsArgs,
aIsPrim,
bIsPrim,
aCirc,
bCirc,
ka,
kb,
length,
index,
it;
if ($isDate(a) && $isDate(b)) {
return a.getTime() === b.getTime();
}
if ($isRegExp(a) && $isRegExp(b)) {
return a.source === b.source &&
a.global === b.global &&
a.multiline === b.multiline &&
a.lastIndex === b.lastIndex &&
a.ignoreCase === b.ignoreCase &&
a.sticky === b.sticky;
}
aIsPrim = $isPrimitive(a);
bIsPrim = $isPrimitive(b);
if ((aIsPrim || $isFunction(a)) && (bIsPrim || $isFunction(b))) {
/*jslint eqeq: true */
return a == b;
}
if (aIsPrim || bIsPrim) {
return a === b;
}
if (a.prototype !== b.prototype) {
return false;
}
if (circ.a.indexOf(a) === -1) {
circ.a.push(a);
} else {
aCirc = true;
}
if (circ.b.indexOf(b) === -1) {
circ.b.push(b);
} else {
bCirc = true;
}
if (aCirc && bCirc) {
circ.cnt += 1;
} else {
circ.cnt = 0;
}
if (circ.cnt > 200) {
throw new RangeError('Circular reference limit exceeded');
}
aIsArgs = $isArguments(a);
bIsArgs = $isArguments(b);
if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) {
return false;
}
if (aIsArgs) {
return de(Array.prototype.slice.call(a), Array.prototype.slice.call(b), circ);
}
ka = Object.keys(a);
kb = Object.keys(b);
length = ka.length;
if (length !== kb.length) {
if (Array.isArray(a) && Array.isArray(b)) {
if (a.length !== b.length) {
return false;
}
} else {
return false;
}
} else {
ka.sort();
kb.sort();
for (index = 0; index < length; index += 1) {
if (ka[index] !== kb[index]) {
return false;
}
}
}
for (index = 0; index < length; index += 1) {
it = ka[index];
if (!de($getItem(a, it), $getItem(b, it), circ)) {
return false;
}
}
aType = typeof a;
bType = typeof b;
return aType === bType;
};
if (!Object.prototype.deepEqual) {
Object.defineProperty(Object.prototype, 'deepEqual', {
enumerable: false,
configurable: true,
writable: true,
value: function (b) {
var a = this;
return de(a, b, {
a: [],
b: [],
cnt: 0
});
}
});
}
if (!Array.prototype.unique) {
Object.defineProperty(Array.prototype, 'unique', {
enumerable: false,
configurable: true,
writable: true,
value: function (equalFn, thisArg) {
var object = Object(this),
length,
index,
eqFn,
arr,
idx,
val,
it;
if ($isUndefined(equalFn)) {
eqFn = $strictEqual;
} else {
eqFn = equalFn;
}
if (!$isFunction(eqFn)) {
throw new TypeError('Argument is not a function: ' + eqFn);
}
arr = [];
length = object.length >>> 0;
for (index = 0; index < length; index += 1) {
if (index in object) {
it = $getItem(object, index);
val = true;
for (idx = 0; idx < length; idx += 1) {
if (idx < index && idx in object && eqFn.call(thisArg, it, $getItem(object, idx))) {
val = false;
break;
}
}
if (val) {
arr.push(it);
}
}
}
return arr;
}
});
}
}());
var data1 = [1, 2, 2, 3, 3, 5, 5, 6, 6, 6],
data2 = [
['a', 'b', 'c'],
['a', 'b', 'c'],
['d', 'e', 'f'],
['g', 'h', 'i']
],
equals = Function.prototype.call.bind(Object.prototype.deepEqual),
pre = document.getElementById('out');
pre.textContent = JSON.stringify(data1.unique(equals), null, 2);
pre.textContent += '\n\n';
pre.textContent += JSON.stringify(data2.unique(equals), null, 2);
<pre id="out"></pre>
I'm getting a "Maximum call stack size exceeded." while trying to iterate the contents of an array and I can't for the life of me figure out why
Edit: By the way I want to add that this is for Safari
here's the function:
function compareObj(a,b) {
var u = function(c,d) {//Check types
var type = Object.prototype.toString.call(a)
if (type !== Object.prototype.toString.call(b)) return false
return type.slice(8,-1) == 'Array' ? v(a,b) : type.slice(8,-1) == 'Object' ? w(a,b) :
type.slice(8,-1) == 'String' ? x(a,b) : type.slice(8,-1) == 'Number' ? y(a,b) :
type.slice(8,-1) == 'Boolean' ? z(a,b) : false ;
}
var v = function(c,d) {//Array
if (c.length !== d.length) return false
/*for (var i = 0; i < c.length; i++) {
if (!u(c[i],d[i])) {
return false
}
}*/
while (c.length) {
if (!u(c[0],d[0])) {
return false
} else {
c.shift();
d.shift();
}
}
return true
}
var w = function(c,d) {//Object
for (i in c) {
}
return true
}
var x = function(c,d) {//String
return c === d
}
var y = function(c,d) {//Number
return c === d
}
var z = function(c,d) {//Boolean
return c === d
}
return u(a,b)
}
I get the overload in the return statement of the u() function
Your function can be a lot shorter. It's advisable to use meaningfull function names. Some functions are redundant. There is no need for recursion. I took the liberty to rewrite your function, just for demonstration. You can see it in action here.
function compareObj(a,b) {
var doCompare = function(c,d) {
//Check types (IE compatible)
var objRE = /Array|Object|String|Number|Boolean/,
aType = a.constructor.name || String(a.constructor).match(objRE)[0],
bType = b.constructor.name || String(b.constructor).match(objRE)[0];
//Types different? No dice.
if (aType !== bType) {return false;}
switch(aType){
case 'Array' : return arrayCompare(a,b); break;
case 'Object' : return objectCompare(a,b); break;
case 'String' : return valueCompare(a,b); break;
case 'Number' : return valueCompare(a,b); break;
case 'Boolean': return valueCompare(a,b); break;
default: return false
}
}
var arrayCompare = function(c,d) { //Array
if (c.length !== d.length) {return false;}
var i = c.length;
while (--i) {
if ( !valueCompare(c[i],d[i]) ) {
return false;
}
}
return true;
}
var objectCompare = function(c,d) { //Object
//you'll have to consider the number of elements too
var lenb = 0, lena = 0;
for (var label in d){
if (d.hasOwnProperty(label)) { lenb+=1; }
}
for (var label in c) {
if (c.hasOwnProperty(label)){
lena += 1;
if ( !valueCompare(c[label],d[label]) ) {
return false;
}
}
}
return lena === lenb;
}
var valueCompare = function(c,d) {//String
return JSON.stringify(c) === JSON.stringify(d);
}
return doCompare(a,b);
}
Actually, if you use JSON (native in newer browsers, or from library), you can do all this just using:
function compare(a,b){
return JSON.stringify(a) === JSON.stringify(b);
}