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\$ Commented Jul 29, 2015 at 1:37
  • \$\begingroup\$ @JerryJeremiah fixed. \$\endgroup\$
    – Maltysen
    Commented Jul 29, 2015 at 1:38
  • 8
    \$\begingroup\$ I'd thank you to limit remarks like "B*lgium" to something artistic. \$\endgroup\$
    – histocrat
    Commented Jul 29, 2015 at 1:50
  • 3
    \$\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
    Commented Jul 29, 2015 at 2:46
  • 2
    \$\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
    Commented Aug 4, 2015 at 9:31

1 Answer 1


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 and acknowledge you have read our privacy policy.

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