24
\$\begingroup\$

Monday Mini-Golf: A series of short questions, posted (hopefully!) every Monday.

Sometimes folks get tired of life's rules: "don't do this", "you can't do that", "we won't let you do this". It can seem really restricting at times! But every now and then, it's good to have a little fun, so let's write some code to modify these rules. And while we're at it, might as well modify other negativity as well. (Of course, these modifications won't WILL be only temporary, so we'll leave the original wording too.)

Challenge

Your challenge is to write a program or function that puts HTML <s>strikethroughs</s> around restrictive words—that is, words ending in n't or followed by not—and after each of these, inserts its positive equivalent in ALL CAPS. At the end, after a space, the number of replacements made should be included. For example:

Please don't jump into the pool.

becomes

Please <s>don't</s> DO jump into the pool. 1

For words ending in n't or followed by not (as well as cannot), the positive equivalent is everything up to the aforementioned not (excluding spaces). Here's what I mean:

  • do not speak becomes <s>do not</s> DO speak
  • it doesn't work becomes it <s>doesn't</s> DOES work
  • we cannot becomes we <s>cannot</s> CAN

However, there are a few exceptions. Make sure these are handled properly.

can't -> <s>can't</s> CAN
won't -> <s>won't</s> WILL
ain't -> <s>ain't</s> AM
shan't -> <s>shan't</s> SHALL
I'm not -> <s>I'm not</s> I AM
you're not -> <s>you're not</s> YOU ARE

Details

  • The input will never contain any whitespace except normal spaces (no tabs, newlines, etc.).
  • The input will never contain any double negatives (e.g. we can't not do this).
  • If a not appears immediately after a punctuation mark, or as part of another word, leave it be.
  • Be sure to preserve the original text, including upper/lowercase, between the <s></s> tags.
  • If you wish, you may use <strike></strike> in place of <s></s>.

Test-cases

Inputs:

I'm sorry, but you can't do that.
Driving on the beach isn't allowed.
Driving on the beach is not allowed.
Please don't jump in; I cannot imagine what might come of that.
Don't worry; we won't get into trouble.
I'm not perfect, but you're not either.
You shan't do it 'cause I ain't doin' it!
Can't we capitalize special cases?
I don't like the words can't, shan't, won't, don't, ain't, or ppcgn't.
Oh, this? It's nothing.
Tie a slipknot in the rope.
Would you like Pinot Noir?
This sentence contains none of the replacement words. Not even knot or ca't.
This sentence doesn't contain one of the replacement words.

Outputs:

I'm sorry, but you <s>can't</s> CAN do that. 1
Driving on the beach <s>isn't</s> IS allowed. 1
Driving on the beach <s>is not</s> IS allowed. 1
Please <s>don't</s> DO jump in; I <s>cannot</s> CAN imagine what might come of that. 2
<s>Don't</s> DO worry; we <s>won't</s> WILL get into trouble. 2
<s>I'm not</s> I AM perfect, but <s>you're not</s> YOU ARE either. 2
You <s>shan't</s> SHALL do it 'cause I <s>ain't</s> AM doin' it! 2
<s>Can't</s> CAN we capitalize special cases? 1
I <s>don't</s> DO like the words <s>can't</s> CAN, <s>shan't</s> SHALL, <s>won't</s> WILL, <s>don't</s> DO, <s>ain't</s> AM, or <s>ppcgn't</s> PPCG. 7
Oh, this? It's nothing. 0
Tie a slipknot in the rope. 0
Would you like Pinot Noir? 0
This sentence contains none of the replacement words. Not even knot or ca't. 0
This sentence <s>doesn't</s> DOES contain one of the replacement words. 1

Scoring

This is , so shortest valid code in bytes wins. Tiebreaker goes to submission that reached its final byte count first. The winner will not WILL be chosen next Monday, Oct 26. Good luck!

\$\endgroup\$
  • \$\begingroup\$ @FryAmTheEggman Yes, unless there are some others worth adding to the list. I'd rather keep it short, but do you have any suggestions? \$\endgroup\$ – ETHproductions Oct 20 '15 at 3:31
  • \$\begingroup\$ Nope, just didn't want this to suffer from the "you changed the spec now it sucks" challenge syndrome :P \$\endgroup\$ – FryAmTheEggman Oct 20 '15 at 3:42
  • 1
    \$\begingroup\$ Suggested test case: Can't we capitalize special cases? \$\endgroup\$ – DLosc Oct 20 '15 at 5:57
  • \$\begingroup\$ Do we need to be careful with strings like: Oh this? It's nothing... or I wonder if we'll notice any words like this?? \$\endgroup\$ – Dom Hastings Oct 20 '15 at 11:09
  • 2
    \$\begingroup\$ One <strike>does not</strike> DOES simply convert memes into contests! \$\endgroup\$ – Jan Oct 22 '15 at 16:32
7
\$\begingroup\$

Pip, 138 140 bytes

Yeesh, that cannot/knot distinction is tricky.

x:"ca wo ai sha i'm you're"^sY"CAN0WILL0AM0SHALL0I AM0YOU ARE"^0OqR-`([\w']+)( no|n'|(?<=can)no)t\b`{++i"<s>".a."</s>".s.((yx@?LCb)|UCb)}s.i

Reads a line from stdin, outputs to stdout. The regex:

`([\w']+)( no|n'|(?<=can)no)t\b`

matches a word (including apostrophes) followed by one of three things:

  • not
  • n't
  • not without a space, provided the first half of the word was can

The - operator on a regex makes it case-insensitive.

Matches are replaced with the result of the following function. (Note: within the function, a is the whole match and b is capture group 1.)

{++i"<s>".a."</s>".s.((yx@?LCb)|UCb)}
 ++i                                   Increment counter
    "<s>".a."</s>"                     Return entire match wrapped in HTML tags...
                  .s.(             )   plus space, plus the following:
                           LCb         Lowercase first capture group
                        x@?            Find its index in list x of special cases (nil if
                                         not in list)
                      (y      )        Use that as index into list y of replacements
                               |UCb    If it wasn't a special case, this is nil, and we
                                         instead use uppercase(b)

Once the modified string is done, we also output a space and the number of replacements i.

\$\endgroup\$
3
\$\begingroup\$

GNU Sed, 321 bytes

(including +1 for -r)

:
s!(can('|no)t)([^<])!<s>\1</s> CAN\3!i
s!(won't)([^<])!<s>\1</s> WILL\2!i
s!(ain't)([^<])!<s>\1</s> AM\2!i
s!(shan't)([^<])!<s>\1</s> SHALL\2!i
s!(I'm not)([^<])!<s>\1</s> I AM\2!i
s!(you're not)([^<])!<s>\1</s> YOU ARE\2!i
t
s!(([^ .!?]+)(n't| not))([^<])!<s>\1</s> \U\2\4!i
t
h
s/1//g
s/<s>/1/g
s/[^1]//g
x
G
s/\n/ /

"String replacement - a job for sed!" I thought. But this was surprisingly hard, and I kept inflooping with the substitution of the original text. And the counting! At least there's no prohibition on unary in the question...

\$\endgroup\$
2
\$\begingroup\$

Perl, 153 bytes

150 script + 3 for -p

$c=0|s!\b((ca)nnot|([\w']+)(?: not|n't))\b!"<s>$&</s> ".uc({ai,AM,ca,CAN,wo,WILL,sha,SHALL,"i'm","I AM","you're","YOU ARE"}->{lc$+}||$+)!egi;s/
/ $c
/

So whilst I match all the test cases now but that regex has cost me dearly... I'll think on it!

Example output:

$perl -p can.pl <<< "I'm sorry, but you can't do that.
Driving on the beach isn't allowed.
Driving on the beach is not allowed.
Please don't jump in; I cannot imagine what might come of that.
Don't worry; we won't get into trouble.
I'm not perfect, but you're not either.
You shan't do it 'cause I ain't doin' it!
Can't we capitalize special cases?
I don't like the words can't, shan't, won't, don't, ain't, or ppcgn't.
Oh, this? It's nothing.
This sentence contains none of the replacement words. Not even knot or ca't.
This sentence doesn't contain one of the replacement words.
Tie a slipknot in the rope.
Would you like Pinot Noir?
You cannot be serious\!"
I'm sorry, but you <s>can't</s> CAN do that. 1
Driving on the beach <s>isn't</s> IS allowed. 1
Driving on the beach <s>is not</s> IS allowed. 1
Please <s>don't</s> DO jump in; I <s>cannot</s> CAN imagine what might come of that. 2
<s>Don't</s> DO worry; we <s>won't</s> WILL get into trouble. 2
<s>I'm not</s> I AM perfect, but <s>you're not</s> YOU ARE either. 2
You <s>shan't</s> SHALL do it 'cause I <s>ain't</s> AM doin' it! 2
<s>Can't</s> CAN we capitalize special cases? 1
I <s>don't</s> DO like the words <s>can't</s> CAN, <s>shan't</s> SHALL, <s>won't</s> WILL, <s>don't</s> DO, <s>ain't</s> AM, or <s>ppcgn't</s> PPCG. 7
Oh, this? It's nothing. 0
This sentence contains none of the replacement words. Not even knot or ca't. 0
This sentence <s>doesn't</s> DOES contain one of the replacement words. 1
Tie a slipknot in the rope. 0
Would you like Pinot Noir? 0
You <s>cannot</s> CAN be serious\! 1
\$\endgroup\$
  • \$\begingroup\$ Wow, this is compact! One issue: I'm not isn't working properly--it should be I AM instead of I'M. But I think you just need to change I'm to i'm in the code to fix it. \$\endgroup\$ – DLosc Oct 20 '15 at 14:42
  • \$\begingroup\$ Oh--also, try it on sentences like Tie a slipknot in the rope. or Would you like Pinot Noir?. They're not in the test cases yet, but the OP's intention was to exclude any word ending in not except cannot. \$\endgroup\$ – DLosc Oct 20 '15 at 15:01
  • \$\begingroup\$ @DLosc Excellent test cases! I couldn't think of any longer words ending in not! The I'm was a bad miss, thanks for the spot! \$\endgroup\$ – Dom Hastings Oct 20 '15 at 15:30

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.