Fizzbuzz game with for loop - javascript

I'm trying to do a function that'll print the numbers between 1-27 in my console.log.
When a number can be divided by 3, it should replace the number with "Fizz"
When a number can be divided by 5, replace it with "Buzz".
If the number can be divided by both 3 and 5, replace it with "Fizzbuzz"
Reference: http://en.wikipedia.org/wiki/Fizz_buzz)
This is my code:
var fizzbuzz = function(start,stop) {
for (var x=1;x <= stop; x++)
var string =',';
if (x%3 == 0) {
string += 'Fizz';
}
if (x%5 == 0){
string += 'Buzz';
}
if (x%5 && x%3){
string += 'Fizzbuzz';
}
return string;
};
Console.log is giving me "," and I'm not sure what I've done wrong.
Just to clarify.
I want my answer to print out 1,2,Fizz,4,Buzz,Fizz,7,8,Fizz,Buzz,11,Fizz,13,14,Fizz Buzz,16,17,Fizz,19,Buzz,Fizz,22,23,Fizz,Buzz,26,Fizz and so on depending on 'stop' in the If-statement.

Valentins comment is correct, you do need to add brackets around your loop.
You are however also redefining the string var in every iteration of the loop.
The last if also makes the output a bit wrong as for example 15 would hit all 3 statements and print FizzBuzzFizzBuzz
so go with something like
var fizzbuzz = function(start,stop) {
var string = '';
var addComma = false;
for (var x=1;x <= stop; x++){
addComma = false;
if (x%3 == 0) {
string += 'Fizz';
addComma = true;
}
if (x%5 == 0){
string += 'Buzz';
addComma = true;
}
if(addComma && x!== stop){
string+=','
}
}
return string;
};
This is not the best way to keep track of where to add a comma, but it does the job.

for(let x = 0; x <=30; x++) {
if (x % 15 === 0) {
console.log('Fizzbuzz')
} else if (x % 5 === 0) {
console.log('Buzz')
} else if (x % 3 === 0) {
console.log('Fizz')
} else {
console.log(x)
}
}
this is how i dealt with it

You need to correct your for loop
You have
for (var x=1;x <= stop; x++)
var string =',';
being executed up until x <= stop.
Javascript allows you to avoid using brackets if you want to execute one line statements like so.
if (a===true)
alert(a); // This is executed when a === true
alert(b); // This is always executed no matter what a is
Indentation here was to make a point but the if statement would execute everything until the first semicolon.
On the other hand if you wanted to perform multiple lines of code if a === true you would choose to use curly braces like so
// Alert a and alert b are only executed if a is true
if (a===true) {
alert(a);
alert(b);
}
The if statement would execute everything in the curly braces.
Its important to note that return stops execution and exits the function. Once you reach a return statement the loop will be exited. That is why you should return the whole string after the for loop.
This is a better implementation but you should definitely try implementing it yourself
var fizzbuzz = function(start,stop) {
var string = '';
for (var x=1;x <= stop; x++) {
var status = x.toString(); //Each time the loop executes a new variable `status`is created and set to the value `x` for that loop.
// x is checked as to whether it is divisible by 3 or 5 or both, if it is divisible its status is set to a that value
if (x%3 === 0) {
status = 'Fizz';
}
if (x%5 === 0){
status = 'Buzz';
}
if (x%5 === 0 && x%3 === 0){
status = 'Fizzbuzz';
}
string += status; // Append status to the end
if (x !== stop){ // If x is not equal to the value of stop add a comma
string += ',';
}
}
return string; //This returns the string value which has had statuses and commas appended to it.
};

There are multiple problems with this:
(1) The construct
for (var x=1;x <= 10; x++)
statement;
otherstatement;
will execute statement 10 times before it executes other statement. Without braces, Javascript assumes that the next statement is the contents of the for loop;
(2) The string variable is redefined in every loop which gets rid of the preceding version, so the return statement only prints out the last value of string.
(3) The logic of the fizzBuzz if statements are wrong. If you follow this for a statement that divides by 15, it executes all three statements. The third iff statement is therefore completely redundant.
A solution would look like:
var fizzBuzz = function(x){
if(x%15==0){
return "Fizzbuzz";
}
if(x%3==0){
return "Fizz";
}
if(x%5==0){
return "Buzz";
}
return x;
};
var mainFunction = function(start,stop){
var str="";
for(var i=start; i < stop; i++){
str += fizzBuzz(i) + ", ";
}
return str;
};
Note that the third if statement for %15 is necessary only if this version demands that you print Fizzbuzz, rather than FizzBuzz.

Related

How to check for valid braces in javascript, programming problem?

have been struggling for the last couple of days with the following problem from codewars:
Write a function that takes a string of braces, and determines if the order of the braces is valid. It should return  true  if the string is valid, and  false  if it's invalid.
All input strings will be nonempty, and will only consist of parentheses, brackets and curly braces:  ()[]{} .
What is considered Valid?
A string of braces is considered valid if all braces are matched with the correct brace.
Examples
"(){}[]" => True
"([{}])" => True
"(}" => False
"[(])" => False
"[({})](]" => False
So I'm really stuck with the code for this one, and this is what I have up to this point:
function validBraces(braces){
let opening = [ '(', '[', '{']
let closing = [ ')', ']', '}']
let count = 0
const left = []
const right = []
// I generate left and right arrays, left w/the opening braces from the input, right w/ the closing
for (let i = 0; i < braces.length; i++) {
if (opening.includes(braces[i])) {
left.push(braces[i])
} else if (closing.includes(braces[i])) {
right.push(braces[i])
}
}
if (braces.length % 2 !== 0) {
return false
}
// I know there's no point in doing this but at one point I thought I was finishing the program and thought I would 'optimize it' to exit early, probably this is dumb haha.
if (left.length !== right.length) {
return false
}
// The juicy (not juicy) part where I check if the braces make sense
for (let i = 0; i < left.length; i++) {
// If the list are made up of braces like ()[]{} add one to counter
if (opening.indexOf(left[i]) === closing.indexOf(right[i])) {
count += 1
} else // If left and right are mirrored add one to the counter
if (opening.indexOf(left[i]) === closing.indexOf(right.reverse()[i])) {
count += 1
}
}
//If the counter makes sense return true
if (count === braces.length / 2) {
return true
} else { return false}
}
console.log(validBraces( "()" )) //true
console.log(validBraces("([])")) //true
console.log(validBraces( "[(])" )) //false
console.log(validBraces( "[(})" )) //false
console.log(validBraces( "[([[]])]" )) //true
Some comments: I know I'm still not checking for this example ([])() but I thought of breaking this up into two smaller checks in some way.
Thank you if you read up to this point. I would appreciate guidance in some way, though I don't want the problem solved for me. I'm probably overcomplicating this in some way since its a 6kyu problem, if so a tip on how to approach it more cleverly would be very much appreciated.
Thank you in advance! :pray: :pray:
Hell yeah!! I'm very happy to finally reach to the solution myself using some of the hints given to me here:
function validBraces(braces){
let opening = [ '(', '[', '{']
let closing = [ ')', ']', '}']
let arr = []
//console.log(closing.indexOf(braces[")"]) === opening.indexOf(arr[")"]))
for (let i = 0; i < braces.length; i++) {
if (opening.includes(braces[i])) {
arr.push(braces[i])
} else
if (closing.indexOf(braces[i]) === opening.indexOf(arr[arr.length - 1])) {
arr.pop()
} else return false
} return arr.length === 0;
}
I was clearly overthinking it in the first place haha. Thanks for everyone that helped!
As Dave suggested, using a stack, I've wrote the code for it:
var leftBraces="([{";
var rightBraces=")]}";
function checkBraces(braces) {
var ok=true;
var stack=[];
for(var i=0; i<braces.length && ok; i++) {
var brace=braces[i];
if(leftBraces.includes(brace)) stack.push(brace);
else {
var leftBrace=stack.pop();
if(leftBrace==undefined) ok=false;
else if(leftBraces.indexOf(leftBrace)!=rightBraces.indexOf(brace)) ok=false;
}
}
if(stack.length) ok=false;
return ok;
}
Code assumes only braces (no spaces or other characters).
I'm using string.indexOf() that matches for leftBraces and rightBraces.
Also, within the for loop, notice the termination part (2nd): i<braces.length && ok - doesn't "have to" use the iterator and, if I'm not mistaken, can even be empty...
var validBraces = (s) => {
let objO = {'(': 0, '[': 1, '{': 2};
let objC = {')': 0, ']': 1, '}': 2};
let stack = [];
for (let i=0; i<s.length; i++) {
if (objO.hasOwnProperty(s[i])) {
if (stack.length === 0 || stack[stack.length-1].idx!==objO[s[i]])
stack.push({idx: objO[s[i]], count: 1});
else
stack[stack.length-1].count++;
}
else if (objC.hasOwnProperty(s[i])) {
if (stack.length === 0 || stack[stack.length-1].idx!==objC[s[i]])
return false;
else {
stack[stack.length-1].count--;
if (stack[stack.length-1].count===0)
stack.pop();
}
}
}
return stack.length === 0;
};
console.log(validBraces("(){}[]"));
console.log(validBraces("([{}])"));
console.log(validBraces("(})"));
console.log(validBraces("[(])"));
console.log(validBraces("[({})](]"));
Here is a simplified solution:
let isMatchingBraces = function(str) {
let stack = [];
let symbol = {
'(': ')',
'[': ']',
'{': '}'
};
for (let i = 0; i < str.length; i += 1) {
// If character is an opening brace add it to a stack
if (str[i] === '(' || str[i] === '{' || str[i] === '[') {
stack.push(str[i]);
}
// If that character is a closing brace, pop from the stack, which will also reduce the length of the stack each time a closing bracket is encountered.
else {
let last = stack.pop();
//If the popped element from the stack, which is the last opening brace doesn’t match the corresponding closing brace in the symbol, then return false
if (str[i] !== symbol[last]) {
return false
};
}
}
// After checking all the brackets of the str, at the end, the stack is not
// empty then fail
if (stack.length !== 0) {
return false
};
return true;
}
function validBraces(braces){
let par =0;
let bra =0;
let cur =0;
for(let i =0; i<braces.length; i++){
if(braces[i]==="("){
par++;
}
if(braces[i]===")"){
par--;
}
if(braces[i]==="["){
bra++;
}
if(braces[i]==="]"){
bra--;
}
if(braces[i]==="{"){
cur++;
}
if(braces[i]==="}"){
cur--;
}
}
if(par<0 || bra<0 || cur<0){
return false;
}
return true;
};
Here is my solution:
var isValid = function (s) {
let charMap = new Map();
for (let i = 0; i < s.length; i++) {
charMap.set(s[i], i);
}
return Boolean(
charMap.get("(") < charMap.get(")") &&
charMap.get("(") % 2 != charMap.get(")") % 2 &&
charMap.get("{") < charMap.get("}") &&
charMap.get("{") % 2 != charMap.get("}") % 2 &&
charMap.get("[") < charMap.get("]") &&
charMap.get("[") % 2 != charMap.get("]") % 2
);
};
Explanation:
In order to achieve a quick and short solution, I have identified the common pattern of validity for opening/closing braces.
The common pattern for opening and closing braces' validity is that if say the opening(closing) stands at the even index in the string, the other one should be odd and vice versa. Example {}, {[]}, {()[]}, {[()]}.
Because we want to avoid a double loop for performance reasons, we are using a Hash Table via Map() to store the character and the index.
An alternative for getting the character's index would be using Array's find or another method, but that would end up in a second loop over the values which we want to avoid.
Finally, once the indexes of and the characters are stored in the charMap, we check whether or not the stored closing/opening characters' standing (odd/even) in the string is not equal, e.g. if '(' is odd the ')' should be even and vice versa.
We check this via the remainder (%) operator, i.e. a number's remainder of 2 is 0 if even.
Additionally, we need to check whether the order of braces is correct, e.g. if '(' is before '}';
The Boolean() function coerces the comparisons in the desired result.

checking for palindromes in js [duplicate]

I have the following:
function checkPalindrom(palindrom)
{
for( var i = palindrom.length; i > 0; i-- )
{
if( palindrom[i] = palindrom.charAt(palindrom.length)-1 )
{
document.write('the word is palindrome.');
}else{
document.write('the word is not palindrome!');
}
}
}
checkPalindrom('wordthatwillbechecked');
What is wrong with my code? I want to check if the word is a palindrome.
Maybe I will suggest alternative solution:
function checkPalindrom (str) {
return str == str.split('').reverse().join('');
}
UPD. Keep in mind however that this is pretty much "cheating" approach, a demonstration of smart usage of language features, but not the most practical algorithm (time O(n), space O(n)). For real life application or coding interview you should definitely use loop solution. The one posted by Jason Sebring in this thread is both simple and efficient (time O(n), space O(1)).
25x faster than the standard answer
function isPalindrome(s,i) {
return (i=i||0)<0||i>=s.length>>1||s[i]==s[s.length-1-i]&&isPalindrome(s,++i);
}
use like:
isPalindrome('racecar');
as it defines "i" itself
Fiddle: http://jsfiddle.net/namcx0yf/9/
This is ~25 times faster than the standard answer below.
function checkPalindrome(str) {
return str == str.split('').reverse().join('');
}
Fiddle: http://jsfiddle.net/t0zfjfab/2/
View console for performance results.
Although the solution is difficult to read and maintain, I would recommend understanding it to demonstrate non-branching with recursion and bit shifting to impress your next interviewer.
explained
The || and && are used for control flow like "if" "else". If something left of || is true, it just exits with true. If something is false left of || it must continue. If something left of && is false, it exits as false, if something left of a && is true, it must continue. This is considered "non-branching" as it does not need if-else interupts, rather its just evaluated.
1. Used an initializer not requiring "i" to be defined as an argument. Assigns "i" to itself if defined, otherwise initialize to 0. Always is false so next OR condition is always evaluated.
(i = i || 0) < 0
2. Checks if "i" went half way but skips checking middle odd char. Bit shifted here is like division by 2 but to lowest even neighbor division by 2 result. If true then assumes palindrome since its already done. If false evaluates next OR condition.
i >= s.length >> 1
3. Compares from beginning char and end char according to "i" eventually to meet as neighbors or neighbor to middle char. If false exits and assumes NOT palindrome. If true continues on to next AND condition.
s[i] == s[s.length-1-i]
4. Calls itself again for recursion passing the original string as "s". Since "i" is defined for sure at this point, it is pre-incremented to continue checking the string's position. Returns boolean value indicating if palindrome.
isPalindrome(s,++i)
BUT...
A simple for loop is still about twice as fast as my fancy answer (aka KISS principle)
function fastestIsPalindrome(str) {
var len = Math.floor(str.length / 2);
for (var i = 0; i < len; i++)
if (str[i] !== str[str.length - i - 1])
return false;
return true;
}
http://jsfiddle.net/6L953awz/1/
The logic here is not quite correct, you need to check every letter to determine if the word is a palindrome. Currently, you print multiple times. What about doing something like:
function checkPalindrome(word) {
var l = word.length;
for (var i = 0; i < l / 2; i++) {
if (word.charAt(i) !== word.charAt(l - 1 - i)) {
return false;
}
}
return true;
}
if (checkPalindrome("1122332211")) {
document.write("The word is a palindrome");
} else {
document.write("The word is NOT a palindrome");
}
Which should print that it IS indeed a palindrome.
First problem
= is assign
== is compare
Second problem, Your logic here is wrong
palindrom.charAt(palindrom.length)-1
You are subtracting one from the charAt and not the length.
Third problem, it still will be wrong since you are not reducing the length by i.
It works to me
function palindrome(str) {
/* remove special characters, spaces and make lowercase*/
var removeChar = str.replace(/[^A-Z0-9]/ig, "").toLowerCase();
/* reverse removeChar for comparison*/
var checkPalindrome = removeChar.split('').reverse().join('');
/* Check to see if str is a Palindrome*/
return (removeChar === checkPalindrome);
}
As a much clearer recursive function: http://jsfiddle.net/dmz2x117/
function isPalindrome(letters) {
var characters = letters.split(''),
firstLetter = characters.shift(),
lastLetter = characters.pop();
if (firstLetter !== lastLetter) {
return false;
}
if (characters.length < 2) {
return true;
}
return isPalindrome(characters.join(''));
}
SHORTEST CODE (31 chars)(ES6):
p=s=>s==[...s].reverse().join``
p('racecar'); //true
Keep in mind short code isn't necessarily the best. Readability and efficiency can matter more.
At least three things:
You are trying to test for equality with =, which is used for setting. You need to test with == or ===. (Probably the latter, if you don't have a reason for the former.)
You are reporting results after checking each character. But you don't know the results until you've checked enough characters.
You double-check each character-pair, as you really only need to check if, say first === last and not also if last === first.
function checkPalindrom(palindrom)
{
var flag = true;
var j = 0;
for( var i = palindrom.length-1; i > palindrom.length / 2; i-- )
{
if( palindrom[i] != palindrom[j] )
{
flag = false;
break; // why this? It'll exit the loop at once when there is a mismatch.
}
j++;
}
if( flag ) {
document.write('the word is palindrome.');
}
else {
document.write('the word is not palindrome.');
}
}
checkPalindrom('wordthatwillbechecked');
Why am I printing the result outside the loop? Otherwise, for each match in the word, it'll print "is or is not pallindrome" rather than checking the whole word.
EDIT: Updated with changes and a fix suggested by Basemm.
I've added some more to the above functions, to check strings like, "Go hang a salami, I'm a lasagna hog".
function checkPalindrom(str) {
var str = str.replace(/[^a-zA-Z0-9]+/gi, '').toLowerCase();
return str == str.split('').reverse().join('');
}
Thanks
The most important thing to do when solving a Technical Test is Don't use shortcut methods -- they want to see how you think algorithmically! Not your use of methods.
Here is one that I came up with (45 minutes after I blew the test). There are a couple optimizations to make though. When writing any algorithm, its best to assume false and alter the logic if its looking to be true.
isPalindrome():
Basically, to make this run in O(N) (linear) complexity you want to have 2 iterators whose vectors point towards each other. Meaning, one iterator that starts at the beginning and one that starts at the end, each traveling inward. You could have the iterators traverse the whole array and use a condition to break/return once they meet in the middle, but it may save some work to only give each iterator a half-length by default.
for loops seem to force the use of more checks, so I used while loops - which I'm less comfortable with.
Here's the code:
/**
* TODO: If func counts out, let it return 0
* * Assume !isPalindrome (invert logic)
*/
function isPalindrome(S){
var s = S
, len = s.length
, mid = len/2;
, i = 0, j = len-1;
while(i<mid){
var l = s.charAt(i);
while(j>=mid){
var r = s.charAt(j);
if(l === r){
console.log('#while *', i, l, '...', j, r);
--j;
break;
}
console.log('#while !', i, l, '...', j, r);
return 0;
}
++i;
}
return 1;
}
var nooe = solution('neveroddoreven'); // even char length
var kayak = solution('kayak'); // odd char length
var kayaks = solution('kayaks');
console.log('#isPalindrome', nooe, kayak, kayaks);
Notice that if the loops count out, it returns true. All the logic should be inverted so that it by default returns false. I also used one short cut method String.prototype.charAt(n), but I felt OK with this as every language natively supports this method.
function palindromCheck(str) {
var palinArr, i,
palindrom = [],
palinArr = str.split(/[\s!.?,;:'"-()]/ig);
for (i = 0; i < palinArr.length; i++) {
if (palinArr[i].toLowerCase() === palinArr[i].split('').reverse().join('').toLowerCase() &&
palinArr[i] !== '') {
palindrom.push(palinArr[i]);
}
}
return palindrom.join(', ');
}
console.log(palindromCheck('There is a man, his name! was Bob.')); //a, Bob
Finds and upper to lower case. Split string into array, I don't know why a few white spaces remain, but I wanted to catch and single letters.
= in palindrom[i] = palindrom.charAt(palindrom.length)-1 should be == or ===
palindrom.charAt(palindrom.length)-1 should be palindrom.charAt(palindrom.length - i)
Sharing my fast variant which also support spaces
function isPalindrom(str) {
var ia = 0;
var ib = str.length - 1;
do {
if (str[ia] === str[ib]) continue;
// if spaces skip & retry
if (str[ia] === ' ' && ib++) continue;
if (str[ib] === ' ' && ia--) continue;
return false;
} while (++ia < --ib);
return true;
}
var palindrom="never odd or even";
var res = isPalindrom(palindrom);
document.getElementById('check').innerHTML ='"'+ palindrom + '"'+" checked to be :" +res;
<span id="check" />
Some above short anwsers is good, but it's not easy for understand, I suggest one more way:
function checkPalindrome(inputString) {
if(inputString.length == 1){
return true;
}else{
var i = 0;
var j = inputString.length -1;
while(i < j){
if(inputString[i] != inputString[j]){
return false;
}
i++;
j--;
}
}
return true;
}
I compare each character, i start form left, j start from right, until their index is not valid (i<j).
It's also working in any languages
One more solution with ES6
isPalin = str => [...str].every((c, i) => c === str[str.length-1-i]);
You can try the following
function checkPalindrom (str) {
str = str.toLowerCase();
return str == str.split('').reverse().join('');
}
if(checkPalindrom('Racecar')) {
console.log('Palindrome');
} else {
console.log('Not Palindrome');
}
function checkPalindrom(palindrom)
{
palindrom= palindrom.toLowerCase();
var flag = true;
var j;
j = (palindrom.length) -1 ;
//console.log(j);
var cnt = j / 2;
//console.log(cnt);
for( i = 0; i < cnt+1 ; i++,j-- )
{
console.log("J is => "+j);
console.log(palindrom[i] + "<==>" + palindrom[j]);
if( palindrom[i] != palindrom[j] )
{
flag = false;
break;
}
}
if( flag ) {
console.log('the word is palindrome.');
}
else {
console.log('the word is not palindrome.');
}
}
checkPalindrom('Avid diva');
I'm wondering why nobody suggested this:
ES6:
// "aba" -> true
// "acb" -> false
// "aa" -> true
// "abba" -> true
// "s" -> true
isPalindrom = (str = "") => {
if (str[0] === str[str.length - 1]) {
return str.length <= 1 ? true : isPalindrom(str.slice(1, -1))
}
return false;
}
alert(["aba", "acb", "aa", "abba", "s"].map((e, i) => isPalindrom(e)).join())
ES5:
// "aba" -> true
// "acb" -> false
// "aa" -> true
// "abba" -> true
// "s" -> true
function isPalindrom(str) => {
var str = typeof str !== "string" ? "" : str;
if (str[0] === str[str.length - 1]) {
return str.length <= 1 ? true : isPalindrom(str.slice(1, -1))
}
return false;
}
alert(["aba", "acb", "aa", "abba", "s"].map(function (e, i) {
return isPalindrom(e);
}).join());
Recursive Method:
var low;
var high;
var A = "abcdcba";
function palindrome(A , low, high){
A = A.split('');
if((low > high) || (low == high)){
return true;
}
if(A[low] === A[high]){
A = A.join('');
low = low + 1;
high = high - 1;
return palindrome(A , low, high);
}
else{
return "not a palindrome";
}
}
palindrome(A, 0, A.length-1);
I thought I'd share my own solution:
function palindrome(string){
var reverseString = '';
for(var k in string){
reverseString += string[(string.length - k) - 1];
}
if(string === reverseString){
console.log('Hey there palindrome');
}else{
console.log('You are not a palindrome');
}
}
palindrome('ana');
Hope will help someone.
I found this on an interview site:
Write an efficient function that checks whether any permutation of an
input string is a palindrome. You can ignore punctuation, we only care
about the characters.
Playing around with it I came up with this ugly piece of code :)
function checkIfPalindrome(text) {
var found = {};
var foundOne = 0;
text = text.replace(/[^a-z0-9]/gi, '').toLowerCase();
for (var i = 0; i < text.length; i++) {
if (found[text[i]]) {
found[text[i]]++;
} else {
found[text[i]] = 1;
}
}
for (var x in found) {
if (found[x] === 1) {
foundOne++;
if (foundOne > 1) {
return false;
}
}
}
for (var x in found) {
if (found[x] > 2 && found[x] % 2 && foundOne) {
return false;
}
}
return true;
}
Just leaving it here for posterity.
How about this, using a simple flag
function checkPalindrom(str){
var flag = true;
for( var i = 0; i <= str.length-1; i++){
if( str[i] !== str[str.length - i-1]){
flag = false;
}
}
if(flag == false){
console.log('the word is not a palindrome!');
}
else{
console.log('the word is a palindrome!');
}
}
checkPalindrom('abcdcba');
(JavaScript) Using regexp, this checks for alphanumeric palindrome and disregards space and punctuation.
function palindrome(str) {
str = str.match(/[A-Za-z0-9]/gi).join("").toLowerCase();
// (/[A-Za-z0-9]/gi) above makes str alphanumeric
for(var i = 0; i < Math.floor(str.length/2); i++) { //only need to run for half the string length
if(str.charAt(i) !== str.charAt(str.length-i-1)) { // uses !== to compare characters one-by-one from the beginning and end
return "Try again.";
}
}
return "Palindrome!";
}
palindrome("A man, a plan, a canal. Panama.");
//palindrome("4_2 (: /-\ :) 2-4"); // This solution would also work on something like this.
`
function checkPalindrome (str) {
var str = str.toLowerCase();
var original = str.split(' ').join('');
var reversed = original.split(' ').reverse().join('');
return (original === reversed);
}
`
This avoids regex while also dealing with strings that have spaces and uppercase...
function isPalindrome(str) {
str = str.split("");
var str2 = str.filter(function(x){
if(x !== ' ' && x !== ',') {
return x;
}
});
return console.log(str2.join('').toLowerCase()) == console.log(str2.reverse().join('').toLowerCase());
};
isPalindrome("A car, a man, a maraca"); //true
function myPolidrome(polidrome){
var string=polidrome.split('').join(',');
for(var i=0;i<string.length;i++){
if(string.length==1){
console.log("is polidrome");
}else if(string[i]!=string.charAt(string.length-1)){
console.log("is not polidrome");
break;
}else{
return myPolidrome(polidrome.substring(1,polidrome.length-1));
}
}
}
myPolidrome("asasdsdsa");
Thought I will share my solution using Array.prototype.filter(). filter()
filters the array based on boolean values the function returns.
var inputArray=["","a","ab","aba","abab","ababa"]
var outputArray=inputArray.filter(function isPalindrome(x){
if (x.length<2) return true;
var y=x.split("").reverse().join("");
return x==y;
})
console.log(outputArray);
This worked for me.
var number = 8008
number = number + "";
numberreverse = number.split("").reverse().join('');
console.log ("The number if reversed is: " +numberreverse);
if (number == numberreverse)
console.log("Yes, this is a palindrome");
else
console.log("Nope! It isnt a palindrome");
Here is a solution that works even if the string contains non-alphanumeric characters.
function isPalindrome(str) {
str = str.toLowerCase().replace(/\W+|_/g, '');
return str == str.split('').reverse().join('');
}

Why doesn't my javascript work?

I'm trying to create javascript that will count from 1 to 1000 and push any multiples of 3, 5 into an array called multiples then print that array out using console.log(). For some reason my code isn't working. Does anyone know why?
var n;
var multiples = [];
for(n = 1; n <= 1000; n += 1) {
console.log("Counting");
}
if(n % 3 === 0) {
n.push(multiples);
}
else {
}
if(n % 5 === 0) {
n.push(multiples);
}
else {
}
if(n >= 1000) {
console.log(multiples);
}
else {
}
There are few issues with your code. Using {} in your for block designates the scope of the code executing in each iteration. So in order to access each value for n you need to be placing your conditional statements inside of the {} and not outside of them.
There is a slight syntax error with your multiples array. In order to push a value into an array you would use the arrayname followed by the dot operator and then the push function with the argument being the value pushed. In terms of multiples and n, this means multiples.push(n).
When using an if() block, else is not required.
It is generally best practice to include the variable declaration inside of for loops, and also to use ++ as opposed to += 1.
Overall, your code would need to look more like this
var multiples = [];
console.log("Counting");
for(var n = 1; n <= 1000; n++) {
if(n % 3 === 0) {
multiples.push(n);
}
if(n % 5 === 0) {
multiples.push(n);
}
}
console.log(multiples);

javascript keeps skipping my if statement thats inside two loops

Ok so im talking in some unput from the user, it must be 4 numbers, and the digits must not be the same. so everything is working accept the part where i check the 4 numbers against each other. i put the string into an array and then compare the array, by
checking the first one against the 2nd, 3rd, 4th,
then i check the second one against the 3rd, and 4th
then i check the third number against the 4th
My issue is the if statement will not work no matter what i try it gets bypassed everytime. I add random returns into the code to see where it goes and it always returns 12 no matter what even if the numbers i enter are 1111 it still passes.
Ive spent hours trying different stuff please help me!!
function validate(guess){
var user_guess = guess;
var valid = true;
var counter = 0;
parseFloat(user_guess);
if(user_guess.length == 4){
if((user_guess == null) || (isNaN(user_guess))){
validation_alert();
}else{
var guess_string = toString(user_guess);
var guess_array = guess_string.split('');
var guess_array2 = guess_array;
for(var i = 0; i < 3; i++){
counter = i + 1;
for(c = counter; c < 4; c++){
if(guess_array[i] == guess_array2[c]){
return 11;
valid = false;
validation_alert();
}
}
}
if(valid == true){
return 12;
}else{
return 13;
validation_alert();
}
}//if null
}else{
validation_alert();
}//if 4 end tag
}// function close
Just to prove to you that JavaScript uses function scope and not block scope (if else for ...) which means every var you declare moves automatically to the top of the current function it's running in.
Also note that when you return something you will exit the current function and not execute anything after that.
If you check against length you can be sure it's going to be a number so use === instead which checks against it's type (number, string, bool) as well.
Your 2 first if statements should be reversed I think. In anycase user_guess == null will never validate as the previous if checks on the length === 4.
Normally when you use return every block scope should return something. I haven't edited this but that's expected in strict javascript.
It seems more logical to start with valid=false and you will only set it to true when you are sure it's true. I'll leave that up to you.
function validate(guess){
var user_guess = parseFloat(guess),
guess_string,
guess_array,
guess_array2,
valid = true,
counter = 0,
i = 0,
c;
if (!user_guess || isNaN(user_guess)){
validation_alert();
} else {
if (guess.length === 4){
guess_string = user_guess.toString();
guess_array = guess_string.split('');
guess_array2 = guess_array;
for (i; i < 3; i++){
counter = i + 1;
c = counter;
for (c; c < 4; c++){
if (guess_array[i] == guess_array2[c]){
valid = false;
validation_alert();
return 11;
}
}
}
if (valid){
return 12;
} else {
validation_alert();
return 13;
}
} else {
validation_alert();
}
}
}
If you just need to check if the string has 4 unique number digits its much easier this way:
function isValid(str){
var unique={};
for(var i=0;i<str.length;i++){//for each character in the string
unique[str[i]]=true;//we add the character as a key in unique object(the =true doesnt really matter)
}
var chars=Object.keys(unique);//we get an array with the keys in the object(we get an array with the unique characters)
if(chars.length != 4) return false; //if the unique chracters are different than 4, its not valid so return false
chars.sort();//we order the array in lexicographical order
if(chars[0]>= '0' && chars[0] <='9' && chars[3]>= '0' && chars[3] <='9') return true;//if the first character and the last ones are digits, then the ones in the middle wil be digits as well because of the sort we made. If they are, return true
return false;//if they are not both digits, return false
}
console.log(isValid('1111'))//false
console.log(isValid('9230'))//true
console.log(isValid('1343'))//false
console.log(isValid('a412'))//false
console.log(isValid(''))//false

Palindrome check in Javascript

I have the following:
function checkPalindrom(palindrom)
{
for( var i = palindrom.length; i > 0; i-- )
{
if( palindrom[i] = palindrom.charAt(palindrom.length)-1 )
{
document.write('the word is palindrome.');
}else{
document.write('the word is not palindrome!');
}
}
}
checkPalindrom('wordthatwillbechecked');
What is wrong with my code? I want to check if the word is a palindrome.
Maybe I will suggest alternative solution:
function checkPalindrom (str) {
return str == str.split('').reverse().join('');
}
UPD. Keep in mind however that this is pretty much "cheating" approach, a demonstration of smart usage of language features, but not the most practical algorithm (time O(n), space O(n)). For real life application or coding interview you should definitely use loop solution. The one posted by Jason Sebring in this thread is both simple and efficient (time O(n), space O(1)).
25x faster than the standard answer
function isPalindrome(s,i) {
return (i=i||0)<0||i>=s.length>>1||s[i]==s[s.length-1-i]&&isPalindrome(s,++i);
}
use like:
isPalindrome('racecar');
as it defines "i" itself
Fiddle: http://jsfiddle.net/namcx0yf/9/
This is ~25 times faster than the standard answer below.
function checkPalindrome(str) {
return str == str.split('').reverse().join('');
}
Fiddle: http://jsfiddle.net/t0zfjfab/2/
View console for performance results.
Although the solution is difficult to read and maintain, I would recommend understanding it to demonstrate non-branching with recursion and bit shifting to impress your next interviewer.
explained
The || and && are used for control flow like "if" "else". If something left of || is true, it just exits with true. If something is false left of || it must continue. If something left of && is false, it exits as false, if something left of a && is true, it must continue. This is considered "non-branching" as it does not need if-else interupts, rather its just evaluated.
1. Used an initializer not requiring "i" to be defined as an argument. Assigns "i" to itself if defined, otherwise initialize to 0. Always is false so next OR condition is always evaluated.
(i = i || 0) < 0
2. Checks if "i" went half way but skips checking middle odd char. Bit shifted here is like division by 2 but to lowest even neighbor division by 2 result. If true then assumes palindrome since its already done. If false evaluates next OR condition.
i >= s.length >> 1
3. Compares from beginning char and end char according to "i" eventually to meet as neighbors or neighbor to middle char. If false exits and assumes NOT palindrome. If true continues on to next AND condition.
s[i] == s[s.length-1-i]
4. Calls itself again for recursion passing the original string as "s". Since "i" is defined for sure at this point, it is pre-incremented to continue checking the string's position. Returns boolean value indicating if palindrome.
isPalindrome(s,++i)
BUT...
A simple for loop is still about twice as fast as my fancy answer (aka KISS principle)
function fastestIsPalindrome(str) {
var len = Math.floor(str.length / 2);
for (var i = 0; i < len; i++)
if (str[i] !== str[str.length - i - 1])
return false;
return true;
}
http://jsfiddle.net/6L953awz/1/
The logic here is not quite correct, you need to check every letter to determine if the word is a palindrome. Currently, you print multiple times. What about doing something like:
function checkPalindrome(word) {
var l = word.length;
for (var i = 0; i < l / 2; i++) {
if (word.charAt(i) !== word.charAt(l - 1 - i)) {
return false;
}
}
return true;
}
if (checkPalindrome("1122332211")) {
document.write("The word is a palindrome");
} else {
document.write("The word is NOT a palindrome");
}
Which should print that it IS indeed a palindrome.
First problem
= is assign
== is compare
Second problem, Your logic here is wrong
palindrom.charAt(palindrom.length)-1
You are subtracting one from the charAt and not the length.
Third problem, it still will be wrong since you are not reducing the length by i.
It works to me
function palindrome(str) {
/* remove special characters, spaces and make lowercase*/
var removeChar = str.replace(/[^A-Z0-9]/ig, "").toLowerCase();
/* reverse removeChar for comparison*/
var checkPalindrome = removeChar.split('').reverse().join('');
/* Check to see if str is a Palindrome*/
return (removeChar === checkPalindrome);
}
As a much clearer recursive function: http://jsfiddle.net/dmz2x117/
function isPalindrome(letters) {
var characters = letters.split(''),
firstLetter = characters.shift(),
lastLetter = characters.pop();
if (firstLetter !== lastLetter) {
return false;
}
if (characters.length < 2) {
return true;
}
return isPalindrome(characters.join(''));
}
SHORTEST CODE (31 chars)(ES6):
p=s=>s==[...s].reverse().join``
p('racecar'); //true
Keep in mind short code isn't necessarily the best. Readability and efficiency can matter more.
At least three things:
You are trying to test for equality with =, which is used for setting. You need to test with == or ===. (Probably the latter, if you don't have a reason for the former.)
You are reporting results after checking each character. But you don't know the results until you've checked enough characters.
You double-check each character-pair, as you really only need to check if, say first === last and not also if last === first.
function checkPalindrom(palindrom)
{
var flag = true;
var j = 0;
for( var i = palindrom.length-1; i > palindrom.length / 2; i-- )
{
if( palindrom[i] != palindrom[j] )
{
flag = false;
break; // why this? It'll exit the loop at once when there is a mismatch.
}
j++;
}
if( flag ) {
document.write('the word is palindrome.');
}
else {
document.write('the word is not palindrome.');
}
}
checkPalindrom('wordthatwillbechecked');
Why am I printing the result outside the loop? Otherwise, for each match in the word, it'll print "is or is not pallindrome" rather than checking the whole word.
EDIT: Updated with changes and a fix suggested by Basemm.
I've added some more to the above functions, to check strings like, "Go hang a salami, I'm a lasagna hog".
function checkPalindrom(str) {
var str = str.replace(/[^a-zA-Z0-9]+/gi, '').toLowerCase();
return str == str.split('').reverse().join('');
}
Thanks
The most important thing to do when solving a Technical Test is Don't use shortcut methods -- they want to see how you think algorithmically! Not your use of methods.
Here is one that I came up with (45 minutes after I blew the test). There are a couple optimizations to make though. When writing any algorithm, its best to assume false and alter the logic if its looking to be true.
isPalindrome():
Basically, to make this run in O(N) (linear) complexity you want to have 2 iterators whose vectors point towards each other. Meaning, one iterator that starts at the beginning and one that starts at the end, each traveling inward. You could have the iterators traverse the whole array and use a condition to break/return once they meet in the middle, but it may save some work to only give each iterator a half-length by default.
for loops seem to force the use of more checks, so I used while loops - which I'm less comfortable with.
Here's the code:
/**
* TODO: If func counts out, let it return 0
* * Assume !isPalindrome (invert logic)
*/
function isPalindrome(S){
var s = S
, len = s.length
, mid = len/2;
, i = 0, j = len-1;
while(i<mid){
var l = s.charAt(i);
while(j>=mid){
var r = s.charAt(j);
if(l === r){
console.log('#while *', i, l, '...', j, r);
--j;
break;
}
console.log('#while !', i, l, '...', j, r);
return 0;
}
++i;
}
return 1;
}
var nooe = solution('neveroddoreven'); // even char length
var kayak = solution('kayak'); // odd char length
var kayaks = solution('kayaks');
console.log('#isPalindrome', nooe, kayak, kayaks);
Notice that if the loops count out, it returns true. All the logic should be inverted so that it by default returns false. I also used one short cut method String.prototype.charAt(n), but I felt OK with this as every language natively supports this method.
function palindromCheck(str) {
var palinArr, i,
palindrom = [],
palinArr = str.split(/[\s!.?,;:'"-()]/ig);
for (i = 0; i < palinArr.length; i++) {
if (palinArr[i].toLowerCase() === palinArr[i].split('').reverse().join('').toLowerCase() &&
palinArr[i] !== '') {
palindrom.push(palinArr[i]);
}
}
return palindrom.join(', ');
}
console.log(palindromCheck('There is a man, his name! was Bob.')); //a, Bob
Finds and upper to lower case. Split string into array, I don't know why a few white spaces remain, but I wanted to catch and single letters.
= in palindrom[i] = palindrom.charAt(palindrom.length)-1 should be == or ===
palindrom.charAt(palindrom.length)-1 should be palindrom.charAt(palindrom.length - i)
Sharing my fast variant which also support spaces
function isPalindrom(str) {
var ia = 0;
var ib = str.length - 1;
do {
if (str[ia] === str[ib]) continue;
// if spaces skip & retry
if (str[ia] === ' ' && ib++) continue;
if (str[ib] === ' ' && ia--) continue;
return false;
} while (++ia < --ib);
return true;
}
var palindrom="never odd or even";
var res = isPalindrom(palindrom);
document.getElementById('check').innerHTML ='"'+ palindrom + '"'+" checked to be :" +res;
<span id="check" />
Some above short anwsers is good, but it's not easy for understand, I suggest one more way:
function checkPalindrome(inputString) {
if(inputString.length == 1){
return true;
}else{
var i = 0;
var j = inputString.length -1;
while(i < j){
if(inputString[i] != inputString[j]){
return false;
}
i++;
j--;
}
}
return true;
}
I compare each character, i start form left, j start from right, until their index is not valid (i<j).
It's also working in any languages
One more solution with ES6
isPalin = str => [...str].every((c, i) => c === str[str.length-1-i]);
You can try the following
function checkPalindrom (str) {
str = str.toLowerCase();
return str == str.split('').reverse().join('');
}
if(checkPalindrom('Racecar')) {
console.log('Palindrome');
} else {
console.log('Not Palindrome');
}
function checkPalindrom(palindrom)
{
palindrom= palindrom.toLowerCase();
var flag = true;
var j;
j = (palindrom.length) -1 ;
//console.log(j);
var cnt = j / 2;
//console.log(cnt);
for( i = 0; i < cnt+1 ; i++,j-- )
{
console.log("J is => "+j);
console.log(palindrom[i] + "<==>" + palindrom[j]);
if( palindrom[i] != palindrom[j] )
{
flag = false;
break;
}
}
if( flag ) {
console.log('the word is palindrome.');
}
else {
console.log('the word is not palindrome.');
}
}
checkPalindrom('Avid diva');
I'm wondering why nobody suggested this:
ES6:
// "aba" -> true
// "acb" -> false
// "aa" -> true
// "abba" -> true
// "s" -> true
isPalindrom = (str = "") => {
if (str[0] === str[str.length - 1]) {
return str.length <= 1 ? true : isPalindrom(str.slice(1, -1))
}
return false;
}
alert(["aba", "acb", "aa", "abba", "s"].map((e, i) => isPalindrom(e)).join())
ES5:
// "aba" -> true
// "acb" -> false
// "aa" -> true
// "abba" -> true
// "s" -> true
function isPalindrom(str) => {
var str = typeof str !== "string" ? "" : str;
if (str[0] === str[str.length - 1]) {
return str.length <= 1 ? true : isPalindrom(str.slice(1, -1))
}
return false;
}
alert(["aba", "acb", "aa", "abba", "s"].map(function (e, i) {
return isPalindrom(e);
}).join());
Recursive Method:
var low;
var high;
var A = "abcdcba";
function palindrome(A , low, high){
A = A.split('');
if((low > high) || (low == high)){
return true;
}
if(A[low] === A[high]){
A = A.join('');
low = low + 1;
high = high - 1;
return palindrome(A , low, high);
}
else{
return "not a palindrome";
}
}
palindrome(A, 0, A.length-1);
I thought I'd share my own solution:
function palindrome(string){
var reverseString = '';
for(var k in string){
reverseString += string[(string.length - k) - 1];
}
if(string === reverseString){
console.log('Hey there palindrome');
}else{
console.log('You are not a palindrome');
}
}
palindrome('ana');
Hope will help someone.
I found this on an interview site:
Write an efficient function that checks whether any permutation of an
input string is a palindrome. You can ignore punctuation, we only care
about the characters.
Playing around with it I came up with this ugly piece of code :)
function checkIfPalindrome(text) {
var found = {};
var foundOne = 0;
text = text.replace(/[^a-z0-9]/gi, '').toLowerCase();
for (var i = 0; i < text.length; i++) {
if (found[text[i]]) {
found[text[i]]++;
} else {
found[text[i]] = 1;
}
}
for (var x in found) {
if (found[x] === 1) {
foundOne++;
if (foundOne > 1) {
return false;
}
}
}
for (var x in found) {
if (found[x] > 2 && found[x] % 2 && foundOne) {
return false;
}
}
return true;
}
Just leaving it here for posterity.
How about this, using a simple flag
function checkPalindrom(str){
var flag = true;
for( var i = 0; i <= str.length-1; i++){
if( str[i] !== str[str.length - i-1]){
flag = false;
}
}
if(flag == false){
console.log('the word is not a palindrome!');
}
else{
console.log('the word is a palindrome!');
}
}
checkPalindrom('abcdcba');
(JavaScript) Using regexp, this checks for alphanumeric palindrome and disregards space and punctuation.
function palindrome(str) {
str = str.match(/[A-Za-z0-9]/gi).join("").toLowerCase();
// (/[A-Za-z0-9]/gi) above makes str alphanumeric
for(var i = 0; i < Math.floor(str.length/2); i++) { //only need to run for half the string length
if(str.charAt(i) !== str.charAt(str.length-i-1)) { // uses !== to compare characters one-by-one from the beginning and end
return "Try again.";
}
}
return "Palindrome!";
}
palindrome("A man, a plan, a canal. Panama.");
//palindrome("4_2 (: /-\ :) 2-4"); // This solution would also work on something like this.
`
function checkPalindrome (str) {
var str = str.toLowerCase();
var original = str.split(' ').join('');
var reversed = original.split(' ').reverse().join('');
return (original === reversed);
}
`
This avoids regex while also dealing with strings that have spaces and uppercase...
function isPalindrome(str) {
str = str.split("");
var str2 = str.filter(function(x){
if(x !== ' ' && x !== ',') {
return x;
}
});
return console.log(str2.join('').toLowerCase()) == console.log(str2.reverse().join('').toLowerCase());
};
isPalindrome("A car, a man, a maraca"); //true
function myPolidrome(polidrome){
var string=polidrome.split('').join(',');
for(var i=0;i<string.length;i++){
if(string.length==1){
console.log("is polidrome");
}else if(string[i]!=string.charAt(string.length-1)){
console.log("is not polidrome");
break;
}else{
return myPolidrome(polidrome.substring(1,polidrome.length-1));
}
}
}
myPolidrome("asasdsdsa");
Thought I will share my solution using Array.prototype.filter(). filter()
filters the array based on boolean values the function returns.
var inputArray=["","a","ab","aba","abab","ababa"]
var outputArray=inputArray.filter(function isPalindrome(x){
if (x.length<2) return true;
var y=x.split("").reverse().join("");
return x==y;
})
console.log(outputArray);
This worked for me.
var number = 8008
number = number + "";
numberreverse = number.split("").reverse().join('');
console.log ("The number if reversed is: " +numberreverse);
if (number == numberreverse)
console.log("Yes, this is a palindrome");
else
console.log("Nope! It isnt a palindrome");
Here is a solution that works even if the string contains non-alphanumeric characters.
function isPalindrome(str) {
str = str.toLowerCase().replace(/\W+|_/g, '');
return str == str.split('').reverse().join('');
}

Categories