4
\$\begingroup\$

We are doing a PCG challenge at work, and I'm submitting answers in C#. This is a modification of the "M'Kay" challenge. My solution has been deemed correct by the requirements, I'm just trying to shrink it further if possible.

A filler word is an apparently meaningless word, phrase, or sound that marks a pause or hesitation in speech.

Your task is to create a function that has a 30%-50% chance of adding a random filler word to a block of text after the punctuation marks , ; . ? and !; and when added is followed by the same punctuation. The same filler word must be used for each replacement within a single execution of the function.

If the filler word occurs after a sentence completing punctuation mark such as . ? or ! the filler word must have the first letter capitalized. If the filler word occurs after a sentence pausing punctuation mark such as , or ; the filler word must be in lowercase.

Fillers: um, literally, you know, er, okay, right, ah, like

My submitted code:

string p(string i,int z=-1){string w="Um|Literally|You know|Er|Okay|Right|Ah|Like".Split('|')[i.Length %8],s="?,!;.",o="";foreach(var c in i){var x=s.IndexOf(c);o+=(z>0&&i[z]>'9'&&x>-1&&(1&z)<1?c+" "+(x%2>0?" "+w.ToLower():w):"")+c;z++;}return o;}

Original input text: We heard tales of Americans like Coast Guard Petty Officer Ashlee Leppert, who is here tonight in the gallery with Melania. Ashlee was aboard one of the first helicopters on the scene in Houston during Hurricane Harvey. Through 18 hours of wind and rain, Ashlee braved live power lines and deep water, to help save more than 40 lives. Thank you, Ashlee.

With fillers added: We heard tales of Americans like Coast Guard Petty Officer Ashlee Leppert, okay, who is here tonight in the gallery with Melania. Ashlee was aboard one of the first helicopters on the scene in Houston during Hurricane Harvey. Okay. Through 18 hours of wind and rain, Ashlee braved live power lines and deep water, okay, to help save more than 40 lives. Thank you, Ashlee.

Clarification comments welcome, I don't know what else I need to include.

\$\endgroup\$
  • \$\begingroup\$ You have a redundant space in [i.Length %8], no? \$\endgroup\$ – Mr. Xcoder Feb 2 '18 at 18:57
  • \$\begingroup\$ @Mr.Xcoder dang, yes. I had problems before with compilation errors in LINQPad and adding the space fixed them. It runs now without it though. \$\endgroup\$ – Bryan Boettcher Feb 2 '18 at 19:01
  • \$\begingroup\$ Also, I wonder if you could use lambdas (=>-functions). I don’t know C# so I cannot tell for sure. \$\endgroup\$ – Mr. Xcoder Feb 2 '18 at 19:05
  • 1
    \$\begingroup\$ "Your task is to create a function that has a 30%-50% chance of adding a random filler word to a block of text after the punctuation marks" would imply to me that 30-50% of runs add the filler after every punctuation mark. \$\endgroup\$ – Jonathan Allan Feb 2 '18 at 19:20
  • 1
    \$\begingroup\$ There does not seem to be any requirement for any additional spaces, just the filler and trailing punctuation, so you can drop both " "+ (and I believe the one before w.ToLower() is excess to requirements even if adding spaces is required). \$\endgroup\$ – Jonathan Allan Feb 2 '18 at 19:39
5
\$\begingroup\$
string ... s="?,!;." ... var x=s.IndexOf(c);

s is used only once, so could be inlined.


var x=s.IndexOf(c); ... &&x>-1&& ... c+" "+(x%2>0?" "+w.ToLower():w):"")+c;

Change "?,!;." to ",;?!." and the test x%2>0 can be simplified to x<2.

Where in the spec does it require double-space after sentence-terminating punctuation? IMO you could lose the " "+ inside the parentheses.


Given the IMO ridiculous interpretation which they're allowing of "random", I don't see why you do such complicated stuff with z. Just use the character index modulo 3. A direct change to

string p(string i){int n=i.Length,j,x;string w="Um|Literally|You know|Er|Okay|Right|Ah|Like".Split('|')[n%8],o="";for(j=0;j<n;j++){var c=i[j];x=",;.?!".IndexOf(c);o+=(x>-1&&j%3<1?c+" "+(x<2?" "+w.ToLower():w):"")+c;}return o;}

gives a further nice saving. An alternative using Linq also saves a lot by exploiting fat arrow syntax, and would be cheaper if they give you free using statements:

using System.Linq;string p(string s)=>string.Join("",s.Select((c,i)=>{var w="Um|Literally|You know|Er|Okay|Right|Ah|Like".Split('|')[s.Length%8];var x=",;.?!".IndexOf(c);return(x>=0&&i%3<1?c+" "+(x<2?" "+w.ToLower():w):"")+c;}));
\$\endgroup\$

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.