Stacks with Javascript - javascript

I am working with stacks on the infamous 'Braces' problem and I got to a halt. This should be an easy fix but my eyes are not much of a help at the moment.
The first call to the function is working like a charm but the second one is running an extra time and I can't see why.
The first call returns 01110 which is correct but the second returns 011110 which is not...
If you can't read the code here, got to the fiddle
//constructor function for our Stack class
function Stack() {
this.dataStore = [];
this.top = 0;
this.push = push;
this.pop = pop;
this.peek = peek;
this.length = length;
this.clear = clear;
}
function push(element) {
this.dataStore[this.top++] = element;
}
function pop() {
return this.dataStore[--this.top];
}
function peek() {
return this.dataStore[this.top - 1];
}
function length() {
return this.top;
}
function clear() {
this.top = 0;
}
function braces(expression) {
for (var i = 0; i < expression.length; i++) {
//if the number of elements in the expression is odd, it is guaranteed not to have a matching expression
//therefore we print 0
if (expression[i].length%2 !== 0) {
console.log(0);
} else {
var s = new Stack();
var startPoint = expression[i].charAt(0);
//if the expression starts with an open brace it means we will not have a matching expression so we print 0
if (startPoint == '(' || startPoint == '{' || startPoint == '[') {
for (var j = 0; j < expression[i].length; j++) {
var char = expression[i].charAt(j);
var h = '';
if (char == '(' || char == '{' || char == '[') {
s.push(char);
} else {
h = s.peek();
if (h == "(" && char == ")") {
s.pop();
} else if (h == "{" && char == "}") {
s.pop();
} else if (h == "[" && char == "]") {
s.pop();
}
}
}
} else {
console.log(0);
}
if (s.length() == 0) {
console.log(1)
} else {
console.log(0);
}
}
}
}
var expr = [ "}()()", "[]({})", "([])", "{()[]}", "([)]" ]; //working
var expr2 = [ "}()(){", "[]({})", "([])", "{()[]}", "([)]" ]; //running an extra time
braces(expr);

Change this:
else {
console.log(0);
continue; //this is new
}
if (s.length() == 0) {
Your function would log both 0 and 1/0 if the startpoint is not { or ( or [ and the length of s was 0

Your stack functions are all outside of the scope of Stack() and therefore the data probably won't be what you expect. You can start fixing this by putting functions inside the Stack() function:
function Stack() {
this.dataStore = [];
this.top = 0;
this.push = push;
this.pop = pop;
this.peek = peek;
this.length = length;
this.clear = clear;
this.pop = function () {
// pop
}
this.push = function () {
// code
}
this.peek = function () {
// code
}
}
That way, the methods all have access to the same data.

Related

No response from recursive function

I want to create a function that is able to determine if a number is same or palindrome. if a given number is palindrome or same then return 2 otherwise if it is not palindrome or same then i need check it twice by increment the given number by 1. after that if it palindrome or same then return 1. if no palindrome or same number found then return 0. i write the function which is giving me the exact result when i give the number as 11211 but the function don't show any response if i enter 1122 or other random value. please help me to find where the error of my function.
function sameOrPalindrome(num) {
var c = 0;
var al = 0;
var normalArray = num.toString().split("");
var revArray = num.toString().split("").reverse();
for (var i = 0; i < normalArray.length; i++) {
if (normalArray[i] != revArray[i]) {
c++;
}
}
if (c == 0) {
return 2;
} else {
num++;
al = sameOrPalindrome(num);
if (al == 2) {
return 1;
} else {
num++;
al = sameOrPalindrome(num);
if (al == 2) {
return 1;
}
}
}
return 0;
}
console.log("1233",sameOrPalindrome(1233))
here is my solution to this problem:
function reversedNum(num) {
return (
parseFloat(
num
.toString()
.split('')
.reverse()
.join('')
) * Math.sign(num)
)
}
function sameOrPalindrome(num) {
if (num === reversedNum(num)) {
return 2;
} else {
num++;
if (num === reversedNum(num)) {
return 1;
} else {
num++;
if (num === reversedNum(num)) {
return 1;
}
}
}
return 0;
}
console.log("1233",sameOrPalindrome(1233))
Perhaps not using recurse - I think your function loops
const allEqual = arr => arr.every( v => v === arr[0] )
const sameOrPalin = num => {
const str = String(num);
let arr = str.split("")
if (allEqual(arr)) return 2
arr.reverse();
if (arr.join("") === str) return 1;
return 0
};
console.log("1111",sameOrPalin(1111));
console.log("2111",sameOrPalin(2111));
console.log("2112",sameOrPalin(2112));
console.log("1234",sameOrPalin(1234));
for (let i = 2111; i<=2113; i++) console.log(i,sameOrPalin(i));
Question: I assumed if palindrome test is true at first time then return 2. if not try incrementing by one and test the palindrome again . if true return 1 else try incrementing for last time and check the palindrome if true return 1 else 0.
Store string into array first and do arr.reverse().join("") to compare
let arr=num.toString().split("");
if(num.toString() == arr.reverse().join(""))
function sameOrPalindrome(num, times) {
let arr = num.toString().split("");
if (num.toString() == arr.reverse().join("")) {
if (times == 3) return 2
else return 1;
} else if (times > 0) {
num++; times--;
return sameOrPalindrome(num, times);
} else return 0
}
console.log(sameOrPalindrome(123321, 3));
console.log(sameOrPalindrome(223321, 3));
console.log(sameOrPalindrome(323321, 3));
Your function needs to know if it should not call itself any more, e.g. when it's doing the second and third checks:
function sameOrPalindrome(num,stop) { // <-- added "stop"
var c = 0;
var al = 0;
var normalArray = num.toString().split("");
var revArray = num.toString().split("").reverse();
for (var i = 0; i < normalArray.length; i++) {
if (normalArray[i] != revArray[i]) {
c++;
}
}
if (c == 0) {
return 2;
} else if(!stop) { // <-- check of "stop"
num++;
al = sameOrPalindrome(num,true); // <-- passing true here
if (al == 2) {
return 1;
} else {
num++;
al = sameOrPalindrome(num,true); // <-- and also here
if (al == 2) {
return 1;
}
}
}
return 0;
}
for(let i=8225;i<8230;i++)
console.log(i,sameOrPalindrome(i));
function check_palindrom(num){
var c1 = 0;
var normalArray = num.toString().split("");
var revArray = num.toString().split("").reverse();
for (var i = 0; i < normalArray.length; i++) {
if (normalArray[i] == revArray[i]) {
c1++;
}
}
if(c1==0){
return 2;
}else{
return 1;
}
}//check_palindrom
function my_fun_check_palindrome(mynum){
//console.log(mynum);
var num = mynum;
var c2 = 0;
var al = 0;
var normalArray = mynum.toString().split("");
var revArray = mynum.toString().split("").reverse();
for (var j = 0; j < normalArray.length; j++) {
if (normalArray[j] == revArray[j]) {
c2++;
}
}
if(c2==0){
console.log('Number is palindrome. Return Value :'+ 2);
}
if(1){
console.log('checking again with incremeting value my one');
num = parseInt(num)+1;
al = check_palindrom(num);
if(al==2){
console.log('Number is palindrome. Return Value :'+ 1);
}else{
console.log('Number is not palindrome. Return Value :'+ 0);
}
}
}//my_fun_check_palindrome
console.log(my_fun_check_palindrome(1122));
console.log(my_fun_check_palindrome(11221));
We should always strive to make function more effiecient... you dont need to run full loop. plus actual checking of palindrome can me modularized
function isSameOrPalindrome(num) {
var normalArray = num.toString().split("");
var revArray = num.toString().split("").reverse(),
i;
for (i = 0; i < normalArray.length / 2; i++) {
if (normalArray[i] !== revArray[i]) {
break;
}
}
if (i >= normalArray.length/2) {
return "Palindrome";
} else {
return "Not Palindrome";
}
}
function doCheck(num) {
var isPalindrome = isSameOrPalindrome(num);
console.log(isPalindrome);
if(isPalindrome === "Palindrome") {
return 2;
} else {
num++;
isPalindrome = isSameOrPalindrome(num);
if(isPalindrome === "Palindrome") {
return 1;
} else {
return 0
}
}
}
console.log("100",doCheck(100));

JavaScript Recursive function return undefined instead of an array

I have the next function:
function solveSudoku(prev_tab, fila, columna) {
let tab = _.cloneDeep(prev_tab);
let sig_fila = fila;
let sig_col = columna;
if (fila === 8 && columna === 8) {
//console.log(tab);
return tab;
}
if (columna === 8) {
sig_col = 0;
sig_fila = sig_fila + 1
} else {
sig_col = sig_col + 1;
}
if ((tab[fila][columna]) !== '') {
solveSudoku(tab, sig_fila, sig_col)
} else {
for (let num = 1; num <= 9; num++) {
if (numeroValido(tab, num, fila, columna)) {
tab[fila][columna] = num;
//tab.toString();
solveSudoku(tab, sig_fila, sig_col)
}
}
}
}
it returns undefined instead of a 2D array, i already try to add return in every recursive call =>
return solveSudoku( tab, sig_fila, sig_col )
but now that doesn't work either
I'm not really familiar with algorithms for solving sudoku, so I don't know if the algorithm below is correct.
But you need to ensure that the result of the recursion is returned. In my update below, I return the first recursive call. In the loop, I only return it if the recursion successfully found a solution, otherwise the loop continues trying other numbers in the column.
function solveSudoku(prev_tab, fila, columna) {
let tab = _.cloneDeep(prev_tab);
let sig_fila = fila;
let sig_col = columna;
if (fila === 8 && columna === 8) {
//console.log(tab);
return tab;
}
if (columna === 8) {
sig_col = 0;
sig_fila = sig_fila + 1
} else {
sig_col = sig_col + 1;
}
if ((tab[fila][columna]) !== '') {
return solveSudoku(tab, sig_fila, sig_col)
} else {
for (let num = 1; num <= 9; num++) {
if (numeroValido(tab, num, fila, columna)) {
tab[fila][columna] = num;
//tab.toString();
let result = solveSudoku(tab, sig_fila, sig_col);
if (result) { // continue searching if the recursion failed
return result;
}
}
}
}
}

What the meaning of return [''] in JavaScript?

Please see this leetcode solution. In the function it returns [''] which actually return an array of answer. Could someone tell me what's going on there?
[The problem is solved. Actually it will return in the middle of the code.]
https://leetcode.com/problems/remove-invalid-parentheses/discuss/154272/JavaScript-BFS-solution
function removeInvalidParentheses(s) {
let queue = new Set([s]);
while (queue.size) {
const next = new Set();
for (let v of queue) {
if (isValid(v)) {
return [...queue].filter(isValid);
}
for (let i = 0; i < v.length; i++) {
next.add(v.slice(0, i) + v.slice(i+1));
}
}
queue = next;
}
return [''];
}
function isValid(str) {
let bal = 0;
for (let ch of str) {
if (ch === '(') {
bal++;
} else if (ch === ')') {
bal--;
}
if (bal < 0) {
return false;
}
}
return bal === 0;
}
The function returns an array with a single empty string if the prior code (line 7) does not return a result. It is simply a default value so that calling code sees some result from the method.
function removeInvalidParentheses(s) {
let queue = new Set([s]);
while (queue.size) {
const next = new Set();
for (let v of queue) {
if (isValid(v)) {
return [...queue].filter(isValid);
}
for (let i = 0; i < v.length; i++) {
next.add(v.slice(0, i) + v.slice(i+1));
}
}
queue = next;
}
return [''];
}
function isValid(str) {
let bal = 0;
for (let ch of str) {
if (ch === '(') {
bal++;
} else if (ch === ')') {
bal--;
}
if (bal < 0) {
return false;
}
}
return bal === 0;
}

Will a for loop inside of a while loop fully complete its iterations before the while loop loops once?

I'm trying to use a for loop in a while loop, but the for loop only executes once. My goal is to make an array with the for loop, then check that array for repeating values using the while loop. I'm not too sure if this is just how javascript does loops, but I can't wrap my head around why that would be. When I run this code, I get an error stating that slotarr[1].value is undefined.
If it isn't possible to run a for loop in its entirety in a while loop, are there any workarounds?
var slotobj = {
sloticon1 : {
icon : ":bread:",
value : 1
},
sloticon2 : {
icon : ":custard:",
value : 2
}
}
var slotarr = [];
var done;
var j = 0;
var k = 8;
while (done == false) {
for (i = j; i <= k; i++) {
slotarr[i] = Math.ceil(Math.random()*100);
if (slotarr[i] <= 50) {
slotarr[i] = slotobj.sloticon1;
}
else if (slotarr[i] > 50 && slotarr[i] <= 100) {
slotarr[i] = slotobj.sloticon2;
}
else {
i--;
}
}
if ((slotarr[0].value == slotarr[1].value) || (slotarr[0].value == slotarr[2].value) || (slotarr[1].value == slotarr[2].value)) {
j = 0;
k = 2;
}
else if ((slotarr[3].value == slotarr[4].value) || (slotarr[3].value == slotarr[5].value) || (slotarr[4].value == slotarr[5].value)) {
j = 3;
k = 5;
}
else if ((slotarr[6].value == slotarr[7].value) || (slotarr[6].value == slotarr[8].value) || (slotarr[7].value == slotarr[8].value)) {
j = 6;
k = 8;
}
else {
done = true;
}
}

Infinite recursion - Javascript minimax

I am trying to create a chess AI using the chess.js library. I am using the minimax solution with Alpha-Beta pruning, but for some reason, when the program runs it continues even after the depth reaches 0. Can anyone tell me why?
var Buddha = function() {
this.movehistory = 0;
this.color = "b";
this.opp = "w";
this.minimax = function(board, depth, alpha, beta) {
console.log(depth);
if(depth === 0 || board.game_over() === true) {
console.log("Depth == 0");
return [this.eval_board(board), null]
} else {
if(board.turn() === this.color) {
var bestmove = null
var possible_moves = board.moves()
for (index = 0; index < possible_moves.length; ++index) {
var new_board = new Chess(board.fen());
new_board.move(possible_moves[index])
var mini = this.minimax(new_board, --depth, alpha, beta)
var score = mini[0];
var move = mini[1];
if(score > alpha) {
alpha = score;
bestmove = possible_moves[index];
if(alpha >= beta) {
break;
}
}
}
return [alpha, bestmove]
} else if(board.turn() === this.opp) {
var bestmove = null
var possible_moves = board.moves()
for (index = 0; index < possible_moves.length; ++index) {
var new_board = new Chess(board.fen());
new_board.move(possible_moves[index])
var mini = this.minimax(new_board, --depth, alpha, beta)
var score = mini[0];
var move = mini[1];
if(score < beta) {
beta = score;
bestmove = possible_moves[index];
if(alpha >= beta) {
break;
}
}
}
return [beta, bestmove]
}
}
}
this.eval_board = function(board) {
if(board.in_check()) {
if(board.turn() == this.opp) {
return Number.POSITIVE_INFINITY;
} else {
return Number.NEGATIVE_INFINITY;
}
} else if(board.in_checkmate()) {
if(board.turn() == this.opp) {
return Number.POSITIVE_INFINITY;
} else {
return Number.NEGATIVE_INFINITY;
}
} else if(board.in_stalemate()) {
if(board.turn() == this.opp) {
return Number.POSITIVE_INFINITY;
} else {
return Number.NEGATIVE_INFINITY;
}
}
}
this.move = function(board) {
var bestmove = this.minimax(board, 1, Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY)
}
}
function minimax(board, depth, alpha, beta) {
if(depth === 0 …) { …
return …
} else {
…
for (index = 0; index < possible_moves.length; ++index) {
… minimax(new_board, --depth, alpha, beta)
// ^^
…
}
}
}
Here you're decrementing the depth in a loop. Use depth <= 0 for the base case, and/or pass depth - 1 as an argument or put the decrement statement before the loop.

Categories

Resources