Palindrome: finding the shortest possible string - javascript

The task is the following: "Write a JavaScript program to find the shortest possible string which can create a string to make it a palindrome by adding characters to the end of it."
This is the code I am looking at:
function build_Palindrome(new_str) {
var flag;
for (var i = new_str.length;; i++) {
flag = true;
for (var j = 0; j < i - j - 1; j++) {
if (i - j - 1 < new_str.length && new_str[j] != new_str[i - j - 1]) {
flag = false;
break;
}
}
if (flag) {
for (var j = new_str.length; j < i; j++) {
new_str += new_str[i - j - 1];
}
return new_str;
}
}
}
Test:
console.log(build_Palindrome("abcddc"))
Output:
abcddcba
My question: At first it starts with j=0. If in the for loop, flag=false, then how does it proceed? Is i=7 (i++?) and is j=0 or j=1?

Yes, you can use console.log or any debugger to debug.
For your situation, you if the flag is false, it will break the loop of j and go to its outer loop (i here)
I made the demo here:
https://repl.it/repls/LoyalProfuseRouter
You can see the demo (it come with my solution), and instead of break you can use simple loop to return your string, it more readable.

Related

The only word that is not passing the test is "almostomla."

I am learning JS on freecodecamp and am stuck on a problem. I am creating a palindrome checker. My code almost works. However, there is only one word that is not passing the test and that is almostomla. It is not a palindrome yet my code returns true. I have tried several things. Even rewrote the code and used the while loop but nothing seems to help. There is a solution at the freeCodecamp web but I have written the code in a different way and am unable to figure my mistake out.
Here is my code.
let reversedStr = [];
function palindrome(str) {
let d = str.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
for (let i = d.length - 1; i >= 0; i--) {
reversedStr.push(d[i]);
}
for (let j = 0; j < str.length; j++) {
if (reversedStr[j] == d[j]) {
return true;
} else {
return false;
}
}
}
console.log(palindrome("almostomla"));
This line if (reversedStr[j] == d[j]) {return true; returns as soon as the character matches at both the index. It does not check rest of the characters.
In fact you can just return as soon as the character in both index does not match.
Also note the reversedStr has to be inside the function. Else it will contain previous values
function palindrome(str) {
let reversedStr = [];
let d = str.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
for (let i = d.length - 1; i >= 0; i--) {
reversedStr.push(d[i]);
}
for (let j = 0; j < str.length; j++) {
if (reversedStr[j] !== d[j]) {
return false;
}
}
return true
}
console.log(palindrome("almostomla"));
console.log(palindrome("1221"));
Your code returns "true" or "false" after first match - it checks that 'a' is equal to 'a' and returns true.
You can return "false" from inside of cycle only if you found duplicated letter else return true after the cycle ends.

Conditional Pop-up Box within a for loop (Sheets)

I got the code below working, but when I try to add a Browser.msgBox() once there is a duplicate in the comparison, the code keeps running until it exceeds its time limit.
The idea is to notify the user that the item he/she is trying to add is duplicated and have the script stop running.
var duplicate = false;
for(var x = 0; x < data.length; x++) {
for(var j = 0; j < dataArquivoItens.length; j++){
if(data[x].join() == dataArquivoItens[j].join()){
duplicate = true;
break;
}
}
}
Thanks a lot!
You are only breaking out from the if statement, this is why your code keeps iterating
If you want to break from all nested loops/ statements - give them a name
Sample:
var duplicate = false;
loop1:
for(var x = 0; x < data.length; x++) {
loop2:
for(var j = 0; j < dataArquivoItens.length; j++){
if(data[x].join() == dataArquivoItens[j].join()){
duplicate = true;
Browser.msgBox("That's a duplicate");
break loop1;
}
}
}

misprinted number in prime function

function primeSieve() {
for(i = 0; i <= 100; i++){
let flag = true
for(let j = 2; j < i/2; j++){
if(i % j === 0){
flag = false
}
}
if(flag){
console.log(i)
}
}
}
primeSieve();
Hi,
I'm studying some algos and ran into a prime sieve problem. I'm trying to print all prime numbers between 0 and 100 and it's working for the most part. However, i realized that 4 slipped in somehow and i can't figure out why for the life of me. Wondering if i can get a few pairs of eyes and see how 4 ended up being logged to the console and why that's the case.
thank you!
Your condition in the inner loop:
for (let j = 2; j < i / 2; j++) {
is
j < i / 2
This means that when i is 4, once j gets to 2 (or, since j is always initialized to 2, before the first iteration), the loop breaks. So, without any iterations, there's never any chance for an i of 4 to get to flag = false.
Change to
for (let j = 2; j <= i / 2; j++) {
Also, per wikipedia:
A prime number (or a prime) is a natural number greater than 1 that cannot be formed by multiplying two smaller natural numbers.
So you should probably start i at 2, not 0.
Also, just like your let j, it would be good to declare i with let as well so as not to implicitly pollute the global scope:
function primeSieve() {
for (let i = 2; i <= 100; i++) {
let flag = true
for (let j = 2; j <= i / 2; j++) {
if (i % j === 0) {
flag = false
}
}
if (flag) {
console.log(i)
}
}
}
primeSieve();
Beside the including the value for j to check with j <= i / 2, you could omit the use of a flag and use continue with a label for the outer loop.
function primeSieve() {
outer: for (var i = 2; i <= 100; i++) {
for (var j = 2; j <= i / 2; j++) {
if (i % j === 0) {
continue outer;
}
}
console.log(i);
}
}
primeSieve();

How to detect the end of the loop in javascript

Using for(var i = 0; i < str.length; i++) I can easily detect if the loop is at the end.
But I how can I know if I'm using for or for each.
for(var i = 0; i < str.length; i++) {
if(End of for) //Do something if the end of the loop
}
how to find the last loop in for in javascript ?
for(var i = 0; i < str.length; i++) {
if(i== str.length-1) {
//Do something if the end of the loop
}
}
using forin
for (var item in str) {
if(str[str.length-1] == item) {
//Do something if the end of the loop
}
}
const str = "I am a 24 letter string!";
for (let i = 0; i < str.length; i++) {
if (i + 1 === str.length) {
console.log('Last loop:', i + 1)
}
}
for (var item in str) {
if(str[parseInt(item)+1] === undefined) {
//Do something if the end of the loop
}
}
for(var i = 0; i < arr.length; i++){
if(i == (arr.length - 1)){
//do you stuff
}
}
Just separate the last thing from the loop. Note the use of str.length - 1 in the condition.
//from the beginning up to but not including the last index
for(var i = 0; i < str.length - 1; i++) {
console.log(i)
}
//from the last index only
console.log(str.length - 1)
In a forEach loop, you must iterate linearly over the array, so some conditional logic and a counter are necessary to detect the last element. I find the below harder to read and less efficient especially if you really use an anonymous function in that way. Moreover because of this need for a counter, it simply makes more sense to use the first approach I shared.
var i = 0;
array.forEach(function(i) {
if(i === str.length - 1) {
//do the last thing
} else {
//do all the other things
}
i++;
});
You could use console.log(). If you put this inside the loop, you will be able to view each result in the console.
console.log(i);

undefined is returned in JavaScript function

When I call this function, sending for example: abc as the parameter,
the function returns: undefinedcba. I can't figure out why it's adding
'undefined' to my returned value. I'm probably overlooking something obvious
but I can't spot it. Thank you.
function FirstReverse(str) {
var str_arr1 = new Array();
var ans = '';
for(i=0; i < str.length; i++) {
str_arr1.push(str.charAt(i));
}
for(j=str.length; j >= 0; j--) {
ans += str_arr1[j];
}
return ans;
}
Strings are 0-indexed. str[str.length] does not exist.
j needs to start at str.length - 1.
Or, just return str_arr1.join();
The index of the string starts at 0, so string.length is always one number bigger than index of the last character in the string.
In the second for loop, use
for(var j=str.length -1; j >= 0; j--) {
The error is in the second for statement. See the solution:
function FirstReverse(str) {
var str_arr1 = new Array();
var ans = '';
for(i=0; i < str.length; i++) {
str_arr1.push(str.charAt(i));
}
for(j=str.length-1; j >= 0; j--) {
ans += str_arr1[j];
}
return ans;
}
Because when you pass 'abc' there are only 3 characters in it.
So arrray str_arr have elements at index 0, 1 and 2.
But you are looping for str.length i.e. for 3 times and str_arr[3] is not defined.
You should do this,
function FirstReverse(str) {
var str_arr1 = new Array();
var ans = '';
for(i=0; i < str.length; i++) {
str_arr1.push(str.charAt(i));
}
for(j=str.length-1; j >= 0; j--) {
ans += str_arr1[j];
}
return ans;
}
Looks like you want to reverse a string, which you can do in this javascript one liner
function reverse(s){
return s.split("").reverse().join("");
}
The reason you are getting an undefined is because your j starts with str.length, whereas it should be str.length-1. str_arr1[str.length] is out of bounds and therefore will be undefined.

Categories