I need to decrement var "left" by 1 and only once instead of having it go through a loop and decrement if conditions pass true. But conditions are valid only if they are in a loop. How would I do this?
let key = e.key.toLowerCase()
for (i = 0; i < word.length; i++) {
if (word[i] == key) {
if (guessed[i] != key) {
console.log(e.key)
guessed[i] = key
} else {
console.log('This is where i want left--')
}
}
}
left--; //Need this to decrement only once
Store whether left has been decremented in a variable:
let key = e.key.toLowerCase()
let decrementedLeft = false;
for (i = 0; i < word.length; i++) {
if (word[i] == key) {
if (guessed[i] != key) {
console.log(e.key)
guessed[i] = key
} else {
if(!decrementedLeft){
decrementedLeft = true;
left--;
}
}
}
}
if(!decrementedLeft){
left--;
}
You can use this method:
key = e.key.toLowerCase()
Let decrement=false;
for (i = 0; i < word.length; i++) {
if(decrement==false)
if (word[i] == key) { if (guessed[i] != key) { console.log(e.key) guessed[i] = key } else { left--;
decrement=true;} } }
Or you can just break out from the loop using break
Due to more conditions I decided so. Thank you for your answers!
As a standard, got myself a few additional problems. Like first if{}else{} in the loop is executing both if and else instead of one or the other... So confusing.
let correct = 0;
let key = e.key.toLowerCase()
for (i = 0; i < word.length; i++) {
if (word[i] == key) {
if (guessed[i] != key) {
guessed[i] = key
correct = 1;
console.log(e.key)
} else {
console.log('Guessing same key')
correct = 1;
}
}
}
if (correct != 1) {
left--;
console.log('Decrementing')
tries.innerHTML += `<span>${key} </span>`
correct = 0
}
Related
Here I have an async function in javascript that is used to fill up the sudoku board with numbers (basically its solution). I used a sleeper function between each number insertion so that the user can get a better feel of the recursion and backtracking algorithm, however after the fifteenth number gets inserted, the function stops by itself... What is going on here exactly ?
var finalInd;
function sleep() {
console.log("happy")
return new Promise(resolve => setTimeout(resolve, 100));
}
async function solve () {
allowed = false;
var empty = findEmptySpace();
if(!empty) {
return true;
}
for(let i=1; i<10; i++) {
if(checkDuplicates(board, i, empty)) {
board[empty[0]][empty[1]] = i;
finalInd = (empty[0]*9) + empty[1];
await sleep()
funcId("board").children[finalInd].innerHTML = i;
if(solve(board)) {
return true;
}
board[empty[0]][empty[1]] = 0;
funcId("board").children[finalInd].innerHTML = 0;
}
}
funcId("board").children[0].innerHTML = board[0][0];
return false;
}
function checkDuplicates (board, num, empty) {
for(let i=0; i<9; i++) {
if(board[empty[0]][i] == num && empty[1] != i) {
return false;
}
}
for(let i=0; i<9; i++) {
if(board[i][empty[1]] == num && empty[0] != i) {
return false;
}
}
var x = Math.floor(empty[1]/3);
var y = Math.floor(empty[0]/3);
for(let i=(y*3); i<(y*3)+3; i++) {
for(let j=(x*3); j<(x*3)+3; j++) {
if(board[i][j] == num && i != empty[0] && j != empty[1]) {
return false;
}
}
}
return true;
}
function findEmptySpace () {
for(let i=0; i<9; i++) {
for(let j=0; j<9; j++) {
if(board[i][j] == 0) {
return [i, j];
}
}
}
}
I think you forgot to await the recursive call to solve, so it will always return a promise, which it's truthy, and your function will terminate.
function solution(string, searchValue) {
let answer;
for (let i = 0; i < string.length; i++) {
var count_no_string = 0;
//case 1
if (searchValue[0] == string[i]) {
let save = i;
let count = 0;
for (let j = 0; j < searchValue.length; j++) {
if (searchValue[j] == string[save + j]) {
count = count + 1;
if (searchValue.length == count) {
answer = save;
return answer;
} else{
console.log('f'+ count +' '+ searchValue.length);
}
} else {
console.log('일치하는 문서가 없습니다' );
return -1;
}
}
}
//case2
else if(searchValue[0] != string[i]){
count_no_string = count_no_string+1;
console.log('test ' + count_no_string);
if(count_no_string == string.length){
//retrun -1;
return -1;
}
}
}
}
i don't know why count_no_string variable is always '1'
why?..
i found let, var, const js variable concept, but i can't solve it
thanks you so much
.........
.........
.......
.........
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;
}
var i;
function f_arrsmatch (array1,array2) {
var error = 0;
if(!array1 || !array2) { error++; }
if(array1.length != array2.length) { error++; }
for (i = 0; i < array1.length; i++) {
if(array1[i] instanceof Array && array2[i] instanceof Array) {
if(!f_arrsmatch(array1[i], array2[i])) { error++; }
} else {
if(array1[i] != array2[i]) { error++; }
}
}
return (error == 0);
}
var arr1 = [1,2,3];
var arr2 = [[3,1,2],[1,3,2],[3,2,1]];
for(i = 0; i < arr2.length; i++) {
if(f_arrsmatch(arr1, arr2[i])) {
alert('true');
} else {
alert('false');
}
}
It shows alert with 'false' text only 1 time, but if I run this:
var i;
function f_arrsmatch (array1,array2) {
var error = 0;
if(!array1 || !array2) { error++; }
if(array1.length != array2.length) { error++; }
for (i = 0; i < array1.length; i++) {
if(array1[i] instanceof Array && array2[i] instanceof Array) {
if(!f_arrsmatch(array1[i], array2[i])) { error++; }
} else {
if(array1[i] != array2[i]) { error++; }
}
}
return (error == 0);
}
var arr1 = [1,2,3];
var arr2 = [[3,1,2],[1,3,2],[3,2,1]];
for(i = 0; i < arr2.length; i++) {
alert('something');
}
then browser alerts 3 times with text 'something'. Is it okay for js to be so weird or am i doing something wrong?
In function f_arrsmatch, the global variable i is re-evaluated. After the call of f_arrsmatch, the i is assigned as 3. Then to the next step of loop, the condition i < arr2.length is false, so the loop finish, thus the alert will be called only one time.
I am making a custom registration page with only 2 values Email and Password, later I will add confirm password as well, for my password field I have some restrictions and I am using some regex and also some custom made code to make the validation.
this is my validateField:
validateField(fieldName, value) {
let fieldValidationErrors = this.state.formErrors;
let emailValid = this.state.emailValid;
let passwordValid = this.state.passwordValid;
//let passwordValidConfirm = this.state.passwordConfirmValid;
switch(fieldName) {
case 'email':
emailValid = value.match(/^([\w.%+-]+)#([\w-]+\.)+([\w]{2,})$/i);
fieldValidationErrors.email = emailValid ? '' : ' is invalid';
break;
case 'password':
passwordValid = (value.length >= 5 && value.length <= 32) && (value.match(/[i,o,l]/) === null) && /^[a-z]+$/.test(value) && this.check4pairs(value) && this.check3InRow(value);
fieldValidationErrors.password = passwordValid ? '': ' is not valid';
break;
default:
break;
}
this.setState({formErrors: fieldValidationErrors,
emailValid: emailValid,
passwordValid: passwordValid,
//passwordValidConfirm: passwordValidConfirm
}, this.validateForm);
}
as you can see for
passwordValid
I have made some methods, this one
check3InRow
doesnt work the way I want it to work, this one makes sure, you have at least 3 letters in your string that are in a row so like "abc" or "bce" or "xyz".
check3InRow(value){
var counter3 = 0;
var lastC = 0;
for (var i = 0; i < value.length; i++) {
if((lastC + 1) === value.charCodeAt(i)){
counter3++;
if(counter3 >= 3){
alert(value);
return true;
}
}
else{
counter3 = 0;
}
lastC = value.charCodeAt(i);
}
return false;
}
this doesnt work correctly so it should accept this:
aabcc
as a password but not:
aabbc
You are starting your counter from 0 and looking for greater than equal to 3 which will never be 3 for 3 consecutive characters. Rest everything is fine with your code.
check3InRow(value) {
var counter3 = 1;
var lastC = 0;
for (var i = 0; i < value.length; i++) {
if ((lastC + 1) === value.charCodeAt(i)) {
counter3++;
if (counter3 >= 3) {
alert(value);
return true;
}
} else {
counter3 = 1;
}
lastC = value.charCodeAt(i);
}
return false;
}
Can we not do a simple version of that function? Like
function check3InRow2(value){
for (var i = 0; i < value.length-2; i++) {
const first = value.charCodeAt(i);
const second = value.charCodeAt(i+1);
const third = value.charCodeAt(i+2);
if(Math.abs(second - first) === 1 && Math.abs(third-second) === 1){
return true;
}
}
return false;
}
I mean complexity wise it is O(N) so maybe we can give this a try
Also adding the your function. When you are AT a char then you should consider counter with 1. Because if another one matches it will be 2 consecutive values.
function check3InRow(value) {
var counter3 = 1;
var lastC = value.charCodeAt(0);
for (var i = 1; i < value.length; i++) {
if ((lastC + 1) === value.charCodeAt(i)) {
counter3++;
if (counter3 >= 3) {
return true;
}
} else {
counter3 = 1;
}
lastC = value.charCodeAt(i);
}
return false;
}