Bug in palindrome checker certification test?

I know there’s an easier way to do this, and I did successfully achieve it by stripping out non-word (and underscore) characters. However, I thought I’d get silly with it and really make it a palindrome checker – that even checks (some) reversed symbols.

const doc = document;
doc.getElementById('check-btn').addEventListener('click',function(){
  let theInput = doc.getElementById('text-input');
  let result = doc.getElementById('result');
  if( !theInput.value.length ) {
    alert('Please input a value');
    return;
  }
  result.innerHTML = theInput.value + ' ' + checkPalindrome(theInput.value) + ' a palindrome';

});

function checkPalindrome(val) {
  if ( val.length === 1 ) {
    return 'is';
  }

  val = val.replace(/(\s|,|\.)/g, '');
  val = val.replace(/(^[^0-9A-Za-z])/g, '');
  val = val.replace(/([^0-9A-Za-z]$)/g, '');
  // val = val.replace(/(\W|_)/g, '');
  val = val.toLowerCase();
  
  const isOdd = val.length % 2 == 1 ? true : false;
  const splitLen = isOdd ? (val.length - 1) / 2 : val.length / 2;
  const halfStart = isOdd ? (val.length + 1) / 2 : val.length / 2;
  const half1 = val.substr(0,splitLen);
  let half2 = val.substr(halfStart,splitLen);
  half2 = half2.replace(/\//g, ' ');
  half2 = half2.replace(/\\/g, '/');
  half2 = half2.replace(/\s/g, '\\');
  half2 = half2.replace(/\(/g, ' ');
  half2 = half2.replace(/\)/g, '(');
  half2 = half2.replace(/\s/g, ')');
  half2 = half2.replace(/\[/g, ' ');
  half2 = half2.replace(/\]/g, '[');
  half2 = half2.replace(/\s/g, ']');
  half2 = half2.replace(/-/g, '_');
  half2 = half2.split("").reverse().join("");
  // console.log(half1);
  // console.log(half2);
  if ( half1 == half2 ){
    return 'is';
  }

  return 'is not';
}

function safeText(val){
  this.textContent = text;
  return this.innerHTML;
}

Here’s the trouble: all of FCC’s tests pass except for one. The one for
0_0 (: /-\ :) 0-0
fails, but the code DOES correctly determine that it is a palindrome and displays it appropriately in the #result div!

If the result is arrived at legitimately and is displayed as required, I don’t think it should fail. Seems like a bug in the test.

can you give us the rest of your code (html) so we can investigate your concern?

1 Like

The output looks correct, until I run innerText on it.

result.innerText
'0_0 (: /-\\ :) 0-0 is a palindrome'

Edit: Actually, I guess that is how it is supposed to be.

If I check using my own passing code, if I manually add 0_0 (: /-\ :) 0-0 and log the input value I get the same string back, but if I set the .value property on the input element I get 0_0 (: /- :) 0-0 which is what the test does.

$0.value = "0_0 (: /-\ :) 0-0"
'0_0 (: /- :) 0-0'

HTML is simple, and CSS is essentially nothing. HTML:

<html>
  <head>
    <link href="styles.css">
  <body>

    <div id="inputs">
      <label for="text-input">word</label>
      <input id="text-input" type="text" />
      <button id="check-btn">check</button>
    </div>
    <div id="result">
    </div>
    <script src="script.js"></script>
  </body>
</html>

Inspecting the page to make sure there isn’t some trick happening, I see
<div id="result">0_0 (: /-\ :) 0-0 is a palindrome</div>

The funny thing here is that in my case, I’m re-displaying the string taken straight from the textbox (with theInput.value), so there should be no circumstance where the part before “is a palindrome” shouldn’t match. I can make the test pass by changing my checkPalindrome function to just use .replace(/(\W|_)/g, ''); on the string – but the only thing checkPalindrome returns is “is” or “is not”!

@lasjorg 's reply is interesting, and maybe there’s something behind the scenes with that where that’s what is causing this to fail? But as far as the result div is concerned, the output does indeed match what the test says it requires.

1 Like

i think i know or guessed the issue.
Please try to remove the type=“text” from this field.

Edit: that will fix the .value issue but the test still doesn’t pass. More investigations needed.

Well, your checkPalindrome is returning “is not” for that test. Your code is kind of hard to read and reason about with all those replace happening and the splitting.

All you have to do is remove non-alphanumeric characters and lowercase it, save that in a variable. Then split/reverse/join that variable and save that to a different variable. Now compare the two variables.


@torgborg I guess if you just remove the $ from your replace it should pass.

val = val.replace(/([^0-9A-Za-z]$)/g, '');

Oh yeah, the code is definitely goofy and unnecessary. I did successfully pass the test, but then I was just messing around to try to flip symbols (like \ and /) so they’d be actual mirror image-style palindromic. That’s when I noticed that for whatever reason, code that produces the required result is marked as non-passing.

I don’t think this is a huge deal, since it’s unlikely others will try to do this same thing I did, but I just wanted to report it in case it helps refine the testing mechanism! :slight_smile:

I think it’s cool that you tried to go beyond the instructions. I would try cleaning up the code a bit now.

Am I the only one confused? Does the output match or not match the desired result?
When I tried your code it matched.

In my checking, the value of the input from the test is weird, missing a slash
image


I added this:

function test() {
  document.querySelector("#text-input").value="0_0 (: /-\ :) 0-0";
  document.querySelector("#check-btn").click()
}

test()

and here the test is replicated

image

you are not removing non-alphanumeric characters, so this fails.
Why it happens like that, I think it is some issue with escape characters

does it count as a bug with the tests? probably. if you want you can open an issue for it, but considering that the issue is with characters that should be removed anyway, I would consider it really low priority. Unless we find that the output text has issues and is making the tests fail.

I commented on that.

For that specific test all you should be doing is comparing 0000 to 0000 because after you have removed all non-alphanumeric characters that is what is left. I’m not sure if it really matters what the exact input is.

I was trying to figure out why pasting the string in the input field showed is passing, while the test failed, it looks like it’s one of those weird string behaviours

Like you and I said, it happens when setting the .value property. I assume you have to escape \.

If you try to set a \ directly it is a syntax error, but if it is part of a larger string it is just removed.

document.querySelector('input').value = "\"; // SyntaxError: Invalid or unexpected token 
document.querySelector('input').value = "0_0 (: /-\ :) 0-0";
console.log(document.querySelector('input').value); // "0_0 (: /- :) 0-0"

But I might even consider it a feature and not a bug.

The requirement is to remove all non-alphanumeric characters, the reason why we have tests for hardcoding is that you shouldn’t be relying on knowing the input.

1 Like