Censors are a common tool used on the interwebs. But they often censor too much of the word, and thus make the cursing ambiguous to the reader. And sometimes they don't censor enough, so the words still remain offending. Your task is to fix that.

Your task

Write a program/function/whatever that takes two lists and a string. The first list will be the dictionary of all words in your language like: ["hello", "goodbye", "belgium", "offensive", "jumping", "hypercool"]. The next will be subset of the first list containing all of the offensive words in the language: ["belgium", "offensive"]. The words in these lists are guaranteed to contain only lowercase letters of the alphabet.

The string is the phrase you will have to censor. It will be made of words from the dictionary, separated by spaces: "Goodbye offensive belgium"

The return value will be that phrase censored. However, you have to censor in a certain way. Specifically, for each word in the offensive list, you have to censor as many letters as possible while remaining completely unambiguous in the main dictionary. So here it would be: Goodbye o******** b******.


  • Your code has to interpret the words case-insensitively, but return with the initial capitalization.
  • If there are multiple optimal answers, pick any of them.
  • If unambiguous censoring is impossible, censor a single letter that has the least number of other possible interpretations (If multiple are possible, again, its your choice).

Test Cases

["hello", "goodbye", "belgium", "offensive", "jumping", "hypercool"] ["belgium", "offensive"] "Goodbye offensive belgium" -> "Goodbye o******** b******"
["word"] ["word"] "word" -> "****"
["hot", "hat", "bat", "had"] ["hat"] "hat" -> "*at" or "h*t" or "ha*"
https://gist.github.com/deekayen/4148741 ["quart"] "I am a quart" -> "I am a q**r*"

This is so shortest d*mn code in bytes wins!

P.S. Anyone caught the reference with belgium? ;P

  • \$\begingroup\$ In your explanation you say ["hello", "goodbye", "belgium", "offensive"] ["belgium", "offensive"] "Goodbye offensive belgium" -> "Goodbye o******** b******" but the test cases say ["hello", "goodbye", "belgium", "offensive"] ["belgium", "offensive"] "Goodbye offensive belgium" -> "Goodbye offensive b******" The test case is wrong, correct? \$\endgroup\$ Jul 29 '15 at 1:37
  • \$\begingroup\$ @JerryJeremiah fixed. \$\endgroup\$
    – Maltysen
    Jul 29 '15 at 1:38
  • 6
    \$\begingroup\$ I'd thank you to limit remarks like "B*lgium" to something artistic. \$\endgroup\$
    – histocrat
    Jul 29 '15 at 1:50
  • 2
    \$\begingroup\$ @orlp I guess my question isn't clear enough. The "reader" of these censored messages isn't aware of the presence of the censor lists. They just know the main dict. \$\endgroup\$
    – Maltysen
    Jul 29 '15 at 2:46
  • 1
    \$\begingroup\$ @Maltysen - only Zaphod himself would be brazen enough to use a word like b****** in plain text, even when explaining the issue. I'm shocked. You are definitely not a hoopy frood! \$\endgroup\$
    – Alchymist
    Aug 4 '15 at 9:31

JavaScript ES7, 194 bytes

(d,c,s,g=(a,b)=>[...b].reduce((z,l,i)=>z+(a[i]==l?1:0),0))=>[for(s of s.split` `)~d.indexOf(s)?[...c[(x=[for(i of c)g(i,s)]).indexOf(Math.max(...x))]].map((l,i)=>l!=s[i]?`*`:l).join``:s].join` `

A very large function. I'm guessing a few bytes can be golfed off but not much unless I completely change the way it works.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.