[Question]
  [
![](https://i.stack.imgur.com/ElM9V.jpg)
[Mr. Mackey](https://en.wikipedia.org/wiki/List_of_South_Park_Elementary_staff#Mr._Mackey) is a [South Park](https://en.wikipedia.org/wiki/South_Park) character well-known for adding "m'kay" in everything he says.
Write a program or function that transforms a string of text into something Mr. Mackey would say.
### M'kay placement
* `m'kay` has a **random 50% chance** of being added **after the punctuations `,`, `.`, `?` and `!`**. If that is the case, it will be followed by the exact same punctuation mark that preceeds it and preceeded by a space.
For example, in the sentence `Test, test.`, there are two places where `m'kay` can be added: after the comma, and after the period, with a 50% chance at each place. Possible results would be `Test, m'kay, test`. or `Test, test. M'kay.` or `Test, m'kay, test. M'kay.`.
* There must always be **at least one `m'kay` added**. Moreover, it cannot always be at the same place and each valid place where `m'kay` could be added must occur with equal probability. That is, you can't add `m'kay` always at the end of the string if because of randomness you never added any `m'kay`. If there is only one `m'kay`, it must have the same probability of appearing in each valid position, even though its presence is enforced.
* If `m'kay` is after `?`, `.` or `!`, the `m` must be uppercased.
* The number of `m` in `m'kay` must be uniformely picked between 1 and 3. That is, `m'kay`, `mm'kay` and `mmm'kay` are all possible choices, each with probability 0.33... If it must be uppercased (see above rule), all `m` must be uppercased.
### Inputs, outputs
* Inputs are ASCII strings containing characters from ASCII Dec 32 (Space) to ASCII Dec 126 (Tilde `~`). There are no linebreaks in the input. You may assumed that any input will contain at least one of `, . ? !`.
* You may assume that there are no `m'kay` or any of its variants in the input.
Inputs may be taken from STDIN, function arguments, command line, or anything similar.
* Output may be via STDOUT, a function return, or something similar.
### Test cases
* Input: `Test.`
Possible output: `Test. M'kay.`
* Input: `Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.`
Possible output: `Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. MMM'kay. It's 100% free, mm'kay, no registration required.`
* Input: `Drugs are bad, so, if you do drugs, you're bad, because drugs are bad. They can hurt your body, cause drugs are bad.`
Possible output: `Drugs are bad, m'kay, so, if you do drugs, you're bad, m'kay, because drugs are bad. They can hurt your body, m'kay, cause drugs are bad. M'kay.`
* Input: `Do you understand? Really? Good!`
Possible output: `Do you understand? MM'kay? Really? Good! MMM'kay!`
### Scoring
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest code in bytes wins, m'kay?
  
[Answer]
# APL (66)
```
{∊⍉⍵⍪⍉⍪(¯1+⌈?2×⍵∊',.!?')/¨{' ',⍵,⍨'''kay',⍨'mM'[1+⍵≠',']/⍨?3}¨⍵}⍣≢
```
Result of 10 runs:
```
      ↑ ({∊⍉⍵⍪⍉⍪(¯1+⌈?2×⍵∊',.!?')/¨{' ',⍵,⍨'''kay',⍨'mM'[1+⍵≠',']/⍨?3}¨⍵}⍣≢)¨ 10/⊂'Test, test. Test! Test?'
Test, m'kay, test. Test! Test?                  
Test, test. M'kay. Test! MMM'kay! Test? M'kay?  
Test, mm'kay, test. Test! MM'kay! Test? MM'kay? 
Test, mmm'kay, test. Test! Test? M'kay?         
Test, mm'kay, test. Test! Test? M'kay?          
Test, test. MM'kay. Test! Test? MMM'kay?        
Test, test. MMM'kay. Test! MMM'kay! Test? M'kay?
Test, test. Test! MM'kay! Test?                 
Test, mm'kay, test. M'kay. Test! Test?          
Test, test. MM'kay. Test! MM'kay! Test?   
```
Explanation:
* `{`...`}⍣≢`: apply the function to the input until the value changes
	+ Generate a `M'kay` for each character:
	+ `{`...`}¨⍵`: for each character in the input:
		- `'mM'[1+⍵≠',']/⍨?3`: generate 1 to 3 `m`s or `M`s depending on whether the character was a comma or not.
		- `'''kay',⍨`: append the string `'kay`.
		- `⍵,⍨`: append the character
		- `' ',`: prepend a space.
	+ `(¯1+⌈?2×⍵∊',.!?')/¨`: for each `M'kay`', if its corresponding character is one of `.,!?`, select it with 50% chance, otherwise select it with 0% chance.
	+ `⍉⍵⍪⍉⍪`: match each selection with its character,
	+ `∊`: list all the simple elements (characters) in order.
[Answer]
# CJam, ~~65~~ ~~52~~ 49 bytes
```
l{_{_",.?!"#:IW>)mr{SI'M'm?3mr)*"'kay"3$}&}%_@=}g
```
Try it online in the [CJam interpreter](http://cjam.aditsu.net/#code=l%7B_%7B_%22%2C.%3F!%22%23%3AIW%3E)mr%7BSI'M'm%3F3mr)*%22'kay%223%24%7D%26%7D%25_%40%3D%7Dg&input=Drugs%20are%20bad%2C%20so%2C%20if%20you%20do%20drugs%2C%20you're%20bad%2C%20because%20drugs%20are%20bad.%20They%20can%20hurt%20your%20body%2C%20cause%20drugs%20are%20bad.).
### How it works
```
l            e# Read a line from STDIN.
{            e# Do:
  _          e#   Duplicate the line.
  {          e#   For each of its characters:
    _",.?!"# e#     Find its index in that string.
    :IW>     e#     Save the index in I and check if it's greater than -1.
    )        e#     Add 1 to the resulting Boolean.
     mr      e#     Pseudo-randomly select a non-negative integer below that sum.
             e#     If I == -1 the result will always be 0.
    {        e#     If the result is 1:
      S      e#       Push a space.
      I'M'm? e#       Select 'm' if I == 0 (comma) and 'M' otherwise.
      3mr)   e#       Pseudo-randomly select an integer in [1 2 3].
      *      e#       Repeat the M that many times.
      "'kay" e#       Push that string. MMM'kay.
      3$     e#       Copy the proper punctuation.
    }&       e#
  }%         e#
  _          e#   Copy the resulting array.
  @=         e#   Compare it to the copy from the beginning.
}g           e# Repeat the loop while the arrays are equal.
             e# This makes sure that there's at least one m'kay. M'kay.
```
[Answer]
# K5, ~~99~~ 90 bytes
```
{f::0;{x;~f}{,/{f::f|r:(*1?2)&#&",.?!"=x;x,("";" ",((1+1?3)#"Mm"@x=","),"'kay",x)@r}'x}/x}
```
Well, *someone* needed to kick-start this!
Saved 9 bytes by using a less fancy method of uppercasing the M.
## Explanation
```
{                                                                                        }  Define a function
 f::0;                                                                                      Set `f` (used to determine when to stop) to 0.
      {x;~f}{                                                                         }/x   While `f` is 0 (no "m'kay"s have been inserted), loop over the string argument
               {                                                                   }'x      For each character in the string
                       (*1?2)&#&",.?!"=x                                                    If we are at a punctuation character, generate a random number between 0 and 1
                     r:                                                                     and assign it to `r`
                f::f|                                                                       If the number is one, an "m'kay" will be inserted, so the outer while loop should exit after this
                                                            "Mm"@x=","                      If the punctuation is a comma, then use a lowecase `m`, otherwise use `M`
                                                    (1+1?3)#                                Repeat the `m` between 1 and 3 times
                                               " ",(                  ),"'kay",x            Join the "m'kay" string to the punctuation and prepend a space
                                         x,("";                                 )@r         If the random number is 1, append the "m'kay" string, to the current string
             ,/                                                                             Join the resulting string
```
## 99-byte version
```
{f::0;{x;~f}{,/{f::f|r:(*1?2)&#&",.?!"=x;x,("";" ",((1+1?3)#`c$(-32*~","=x)+"m"),"'kay",x)@r}'x}/x}
```
[Answer]
# Julia, mm'kay, ~~115~~ 114 bytes
```
f(s)=(R=replace(s,r"[,.?!]",r->r*(" "*(r==","?"m":"M")^rand(1:3)*"'kay"*r)^rand(0:1));ismatch(r"m'kay"i,R)?R:f(R))
```
This creates a recursive function that accepts a string and returns a string.
Ungolfed + explanation:
```
function f(s)
    # Replace occurrences of punctuation using random repeats
    R = replace(s, r"[,.?!]", r -> r*(" " * (r == "," ? "m" : "M")^rand(1:3) * "'kay" * r)^rand(0:1))
    # Check whether anything was replaced
    if ismatch(r"m'kay"i, R)
        # If so, return the replaced string
        R
    else
        # Otherwise recurse
        f(R)
    end
end
```
I dislike South Park, but the thrill of the golf was too enticing to pass this up. Thanks to KRyan for simplifying a regex, saving 1 byte.
[Answer]
# JavaScript ES6, ~~79~~ ~~86~~ 108 bytes
Turns out making the `M` repeat takes a lot of bytes.
```
(s,z=Math.random)=>s.replace(/([!?.,])/g,l=>z(t=t+1)>=.5||t?` ${(l==','?'m':'M').repeat(0|z()*3+1)}'kay`+l:l)
```
Old version (doesn't repeat)**(86 bytes)**
```
(s,t=1)=>s.replace(/([!?.,])/g,l=>Math.random()>=.5||--t?` ${l==','?'m':'M'}'kay`+l:l)
```
Older version (doesn't repeat, doesn't require at least one m'kay)**(79 bytes)**:
```
s=>s.replace(/([!?.,])/g,l=>~~(Math.random()*2)?l+` ${l==','?'m':'M'}'kay`+l:l)
```
Oldest version:
```
s=>(r=t=>t.replace(/([!?.])/,"$1 M'kay$1").replace(/,/,", m'kay,"),r(s),[for(i of s)~~(Math.random()*2)?r(i):i].join``)
```
[Answer]
# Pyth, ~~51~~ ~~50~~ 49
*Saved 1 byte thanks to @Maltysen.*
```
 fnzJsm?&O2}dK",.!?"s[d\ *hO3?xKd\M\m"'kay"d)dz0J
```
[Try it online.](https://pyth.herokuapp.com/?code=+fnzJsm%3F%26O2%7DdK%22%2C.!%3F%22s[d%5C+*hO3%3FxKd%5CM%5Cm%22%27kay%22d%29dz0J&input=Drugs+are+bad%2C+so%2C+if+you+do+drugs%2C+you%27re+bad%2C+because+drugs+are+bad.+They+can+hurt+your+body%2C+cause+drugs+are+bad.&debug=0)
Explanation & more golfing coming soon.
[Answer]
# C, 170 bytes
First crack at it:
```
n;main(r,v,p)char**v,*p;{for(srand(time(0)),p=v[1];r=rand(),*p;p++)if(strchr(".,?!",putchar(*p))&&r%2||(!*(p+1)&&!n))n=printf(" %.*s'kay%c",r/2%3+1,*p%4?"MMM":"mmm",*p);}
```
Ungolfed:
```
n;
main(r,v,p)
char**v,*p;
{
    for(srand(time(0)), p=v[1]; r=rand(), *p; p++) /* loop through string */
        if(strchr(".,?!",putchar(*p)) /* print the char, check if punctuation */
            && r % 2 /* should we say it? */
            || (!*(p+1) && !n)) /* If this is the end of the string and we haven't M'kay'd, then do it now */
            n=printf(" %.*s'kay%c", r/2%3+1, *p%4 ? "MMM" : "mmm", *p); /* say it! */
}
```
[Answer]
## Scala, 191 bytes
```
var(r,s,a,o)=(util.Random,readLine,1>2,"")
while(!a){o=""
for(c<-s)o+=(if(",.?!".contains(c)&&r.nextBoolean){a=2>1
s"$c ${(if(c==46)"M"else"m")*(1+r.nextInt(3))}'kay$c"}else s"$c")}
print(o)
```
[Answer]
# Mathematica, 202 bytes
```
i=0;r=Random;x=r[];
h=" "<>If[#==",","m","M"]~Table~{Ceiling[3r[]]}<>"'kay"<>#&;
(ee/.a:>(If[e~Count~a@__==i&&#==Floor[x*i],h@#2,""]&))@
StringReplace[#,x:","|"."|"?"|"!":>x~~RandomChoice@{i++~a~x,h@x}]&
```
Line breaks added for readability. Evaluates to an anonymous function taking the string as an argument. (`` is shorthand for `\[Function]`.)
Ungolfed:
```
h[x_]:=" " <> Table[
    If[x==",", "m", "M"],
    { Ceiling[3 Random[]] }
] <> "'kay" <> x;
```
`h` takes a punctuation char and makes it `" m'kay,"`, `" mm'kay,"`, etc. randomly and capitalized appropriately.
```
f[s_] := (i = 0;
   StringReplace[s, 
    x : "," | "." | "?" | "!" :> 
     x ~~ RandomChoice[{a[i++, x], h[x]}]]);
```
`f` takes a string and looks for any punctuation character `x`; when it finds it, it tacks on with 50% probability the appropriate `h[x]`, and 50% an expression like `a[3, x]`. It also updates `i` to the total number of punctuation replaced (with both cases). So `f["X, x."]` might evaluate to
```
"X," ~~ h[","] ~~ " x." ~~ a[1, "."]           ...which might expand to
"X, mmm'kay, x." ~~ a[1, "."]                  , and i would equal 2
```
Finally, `g` will deal with the `a`'s.
```
g[expr_] := (r = Random[]; 
  expr /. a -> (If[Count[expr, a[__]] == i && # == Floor[r*i], h[#2], ""] &))
```
`Count` will count how many `a`'s we put in there; if it equals `i`, the total number of punctuation, then we didn't add any m'kays. In this case, we will have expressions like `a[0, _] ... a[i-1, _]`, and we define `a` so that it'll return an m'kay for exactly one of `0..i-1`. 
[Answer]
# Python, 173 168 156
```
from random import randint as R
    m,k,s,C="mM","'kay",input(),0
    while C<1:
        S=""
        for c in s:r=R(0,c in",.!?");C+=r;S+=c+(' '+m[c!=","]*R(1,3)+k+c)*r
    print(S)
```
Ungolfed:
```
from random import randint
m, kay = "mM", "'kay"
string = input()
count = 0
while count < 1: #at least one occurrence
    newString= ""
    for char in s:
        rm  = randint(1,3) #number of "m"
        rmk = randint(0, char in ",.!?") #occurrence of "m'kay"
        count += rmk
        newString += char + (' ' + m[c != ","] * rm + kay + char) * rmk
print(newString)
```
[Answer]
## **><>, 150 bytes**
```
i:0(?v
r0&v >
?v~>:0(?v::o1[:::",.?!"{=${=+${=+r=+]
>x~^    >&:0)?;&"."14.
v>&1+&1[:","=&"yak'"&84**"M"+
 >  >84*v
>x::^>22 .
 >: ^]
ol0=?^  >
```
13 wasted bytes, but I've gotten a little bored trying to rearrange it. Also, randomisation in a Funge is hard to golf -.-
[Answer]
# Perl, ~~93~~ ~~89~~ 88 bytes
```
$_=$0=<>;s/[.?!]|(,)/$&.($".($1?"m":M)x(1+rand 3)."'kay$&")[rand 2]/ge while$0eq$_;print
```
Can definitely be golfed some more!
*4 bytes cut off thanks to Dom Hastings*
[Answer]
## C++ 290
**My solution**
```
void M(string x){
srand(rand());
string p(",.?!");
char c=0,m='m',n='M';
int r=0;
size_t z=0;
for(size_t i=0;i<x.size();i++)
{
c=x[i];cout<<c;
z=p.find(c);
r=rand()%2;
if(z!=string::npos&&r)
{
cout<<' ';
c=(z?n:m);
r=rand()%3+1;
while(r--){cout<<c;}
cout<<"\'kay";
}
}
}
```
**Explanation**
variable z determines which punctuation mark and z=0 indicates to use 'm' rather than 'M'.
**Test**
```
int main()
{
int x=5;
while(x--){
string S("Do you understand? Really? Good! Yes, I do.");
M(S);
cout<<endl;
}
return 0;
}
```
[Answer]
# JavaScript ES6, 121 bytes
```
(s,r=Math.random,f=t=>t==s?f(s.replace(/[!?.,]/g,m=>r()<.5?m:m+" "+(m==","?"mmm":"MMM").slice(r()*3)+"'kay"+m)):t)=>f(s)
```
Crashes if the given string contains no suitable punctuation.
[Answer]
# Lua, ~~162~~ 160 bytes
```
r=math.random;s,m=io.read()repeat m=s:gsub("([,.?!])",function(p)return p..(r()>.5 and" "..(p==","and"m"or"M"):rep(r(1)).."'kay"..p or"")end)until s~=m;print(m)
```
> 
> Did you ever hear the tragedy of Darth Plagueis The Wise? MM'kay? I thought not. MMM'kay. It’s not a story the Jedi would tell you. M'kay. It’s a Sith legend. Darth Plagueis was a Dark Lord of the Sith, m'kay, so powerful and so wise he could use the Force to influence the midichlorians to create life… He had such a knowledge of the dark side that he could even keep the ones he cared about from dying. MM'kay. The dark side of the Force is a pathway to many abilities some consider to be unnatural. MM'kay. He became so powerful… the only thing he was afraid of was losing his power, mmm'kay, which eventually, mm'kay, of course, m'kay, he did. M'kay. Unfortunately, he taught his apprentice everything he knew, then his apprentice killed him in his sleep. M'kay. Ironic. He could save others from death, but not himself.
> 
> 
> 
]