Get stuck on Hidden Anagram

I am working to solve this hard challenge in www.edabit.com.
My code is messing to complete the challenge and I tried too much on my code but until know I do not know how to pass this hard challenge. This challenge is called Hidden Anagram.

My Code So Far:

function hiddenAnagram(text, phrase) {
	 text = text.replace(/[^\w]/g, "").toLowerCase();
	  phrase = phrase.replace(/[^\w]/g, "").toLowerCase();
  let sortText = text.split("").sort();
  let sortPhrase = phrase.split("").sort()
  return "noutfond";
}
console.log(hiddenAnagram("D  e b90it->?$ (c)a r...d,,#~", "bad credit"));

Link to challenge: https://edabit.com/challenge/7hnsWYJGc6yPqEMjc

So at what point in your code do you compare text and phrase?

Okay, maybe i can be a bit more helpful. I’m going to spoiler tag each of these individually, as they’ll get more spoilery.

How is “An old west action hero actor” an anagram of “Clint Eastwood”?

What do you need to do to find any possible starting point for an anagram of the target?

What do we know about the length of the anagram, and how can that narrow our search

How do we check all of the possible substrings of the original text for an anagram of the target?

Follow-on: What do we know about when we can stop looking for points in the string where the anagram could start?

Check every valid starting point to see if the substring, once sorted, matches the target. If it does, return the original substring. If it doesn’t, continue. If you get to the end of your possibilities, return noutfond.

Bonus hint that i’ll give out in the open: \w matches more than just letters. \w is [a-zA-Z0-9_]

I mean what to do next with the code above to pass the challenge!!

Have you read some of the spoilers in my above post?

@m_hutley
I have read your post and I try again with my code but I have two problems:

  1. The output in the console are not sorted as the challenge said. for example:
    when you pass to the console :

the output returns: badcredit. But the challenge said should return: debitcard. But as you see, both are the same length and the same letters but in different order.

  1. I used filter method and not for..loop because it did not work with me and I tried too much with it. so I do not know where to put return "noutfond".
  1. You’re returning the phrase instead of the substring.
  2. either way can work. return "noutfond" should be the last line of the function; the function should return the matched string if it finds one at any point - and return the default if it tries everything, and has no match.

I forgot to put my new code in the previous post so you can help more :slight_smile:

function hiddenAnagram(text, phrase) {
  text = text.replace(/[^\w]/g, "").toLowerCase();
  phrase = phrase.replace(/[^\w]/g, "").toLowerCase();
  let sortText = text.split("");
  let sortPhrase = phrase.split("");
  let filter = sortPhrase.filter((i) => sortPhrase[i] == sortText[i]);
  
  return filter.join("");
}
console.log(hiddenAnagram("D  e b90it->?$ (c)a r...d,,#~", "bad credit"));

#1: Please read post #4.
#2: You’re not looking to see if an anagram can be made from the letters of the string. That’s not what the puzzle is asking you to do. Go back to the instructions, look at the example for hiddenAnagram("Bright is the moon", "Bongo mirth"), and their explanation for why that one should return noutfond.
Before trying to code the answer, you need to understand what the question is asking you to do.

1 Like

yes Thank you
I was using Arrays instead of string.
I will try again solving this challenge.
I’m sorry not understanding correctly the challenge. English is not my first language!

What the challenge is asking you to do is to take the letters of a string, in order, and determine if any subset of consecutive characters in the string (case insensitively) constitute an anagram of the target phrase. If so, return the substring of those characters as they were in the original string. Otherwise, return “noutfond”.

Did anyone else have a go at this?

I guess it is safe to post a solution, given the OP hasn’t responded in 8 days.

My attempt and an excuse to play with generators

Possible solution (click)
const hiddenAnagram = (text, phrase) => {
  
  const textLetters = toLowerCaseLetters(text)
  const phraseLetters = toLowerCaseLetters(phrase)
  const chunks = chunker(textLetters, phraseLetters)

  let value

  while ((value = chunks.next().value)) {
    if (match(value, phraseLetters)) return value
  }

  return 'noutfond'
}

const toLowerCaseLetters = text => text.toLowerCase().replace(/[^a-z]/g, '')

// Example 'sirpatrickmoorewasafamousmoonstarer' and 'astronomer'
// each iterative call will yield "sirpatrick", "irpatrickm", "rpatrickmo" ... 'moonstarer'
const chunker = function* (sentence, phrase) {
  let i = 0

  while ((sentence.length - i) >= phrase.length) {
    yield sentence.substr(i++, phrase.length)
  }
}

const match = ([letter, ...word], phrase) => (
  (phrase.indexOf(letter) === -1)
    ? (phrase.length) 
      ? false 
      : true
    : match(word, phrase.replace(letter, ''))
)

console.log(hiddenAnagram(
  'A building, built to stay free of defects, is uncommon!',
  'Statue of Liberty'
)) // builttostayfree

console.log(hiddenAnagram(
  "Bright is the moon", 
  "Bongo mirth"
)) // noutfond

I did, in fact.
I stuck closer to the OP’s work (and based on the suggestions in the challenge, probably what they were expecting), because… well it was going to go in here.

function hiddenAnagram(text, phrase) {
	text = text.toLowerCase().replace(/[^a-z]/g, "");
	phrase = phrase.toLowerCase().replace(/[^a-z]/g, "").split("").sort().join("");
    for(i = 0; i <= text.length - phrase.length; i++) {
		const ss = text.substr(i,phrase.length);
		if(ss.split("").sort().join("") == phrase) { return ss; }		
	}
  return "noutfond";
}

Mine still passed the test and was an accepted answer m_hutley. It’s only calling the hidden anagram function.

I did not say yours was bad or not working. It’s absolutely fine.

1 Like