Write a D*mn Unambiguous Censor

16

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******.

Clarifications

  • 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

Maltysen

Posted 2015-07-29T01:17:17.877

Reputation: 25 023

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? – Jerry Jeremiah – 2015-07-29T01:37:55.147

@JerryJeremiah fixed. – Maltysen – 2015-07-29T01:38:46.087

@DLosc you are right, fixing. – Maltysen – 2015-07-29T01:46:28.557

5I'd thank you to limit remarks like "B*lgium" to something artistic. – histocrat – 2015-07-29T01:50:28.737

"If unambiguous censoring is impossible, censor a single letter that causes the least collisions." What are collisions? – xnor – 2015-07-29T02:07:36.480

@Maltysen Yes, that makes sense. – xnor – 2015-07-29T02:09:56.253

There's still a problem in the example. If I see *******, I still know it's Belgium, unambiguously, because it's the only 7 letter word that might get censored. – orlp – 2015-07-29T02:36:20.920

2@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. – Maltysen – 2015-07-29T02:46:05.187

For the third example wouldn't ha* be invalid because it three interpretations unlike the other two which have just two? – Beta Decay – 2015-07-29T08:15:50.447

@Maltysen Oh, I see, sorry I misread the list :o – Beta Decay – 2015-07-29T08:26:00.623

1@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! – Alchymist – 2015-08-04T09:31:24.260

Answers

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.

Downgoat

Posted 2015-07-29T01:17:17.877

Reputation: 27 116