[Question]
  [
I wrote some text, but it looks too professional. I want to make it look like I was really tired when I wrote it. I need you to insert some typos.
Your challenge is to take an arbitrary single line of text, and add typos. This means that for each character, there will be a 10% chance for it to be typofied.
The definition of "typofied" is that you must choose (randomly) one of the following:
* Duplicate the character.
* Delete the character.
* Shift the character one keyboard space. The "keyboard" is defined as:
```
qwertyuiop
asdfghjkl
 zxcvbnm
```
For the character shift, you must go one space up, down, left, or right. This must be chosen randomly. The shift option only applies to alphabetic characters. Case must be preserved. Be careful with edge-cases, like `m`!
The definition of "random" is that the result must not be predictable (by looking at previous results). For example, you can't typofy every tenth character. Furthermore, the randomness must have an even distribution. For example, you can't do 30% duplicate, 30% delete, and 40% shift; it has to be a 1/3 chance for each (1/2 for each if it's a nonalphabetic character).
Example input:
```
This is some correct text. It is too correct. Please un-correctify it.
```
Example output:
```
This iissome xorreect tex..  It is too coteect. Please jn-corretify it.
```
This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest code in bytes will win.
  
[Answer]
# C, 358 bytes
(There are only three lines of code, but I've broken up line 3 for legibility)
```
#define x putchar
#define y random()
c,n;main(){char*s[26]={"QS","HNV","FVX","EFSX","DRW","CDGR","FHTV","BGJY","KOU","HKNU",
"IJLM","KO","KN","BJM","ILP","OO","AW","EFT","ADWZ","GRY","IJY","BCG","ESQ","CDZ","HTU",
"SX"};while((c=getchar())>0){if(y%10>0&&x(c))continue;if(isalpha(c)&&y%3<1){n=(c&31)-1;
x(s[n][y%strlen(s[n])]|(c&32));continue;}if (y&1)x(x(c));}}
```
The array of strings at the beginning lists the possible adjacent keys for each letter of the alphabet. I had to double up the "O" (adjacent to "P") to avoid calculating `random()%1` when selecting a shifted character.
Test run:
```
$ echo "This is some correct text. It is too correct. Please un-correctify it." |./a.out
This is some  cofrect teext. It is too correct.. Plleaase un-correctify it..
```
---
**Update:**
Here's an expanded and commented version of the same source code:
```
#include <stdio.h>
#include <string.h>
/* ^^ These should be included, but the code compiles without them */
int c,n;
void main() {
  /* Adjacent keys for each letter of the alphabet (A, B, C, ..., Z): */
  char *s[26] = { "QS","HNV","FVX","EFSX","DRW","CDGR","FHTV","BGJY","KOU","HKNU",
                  "IJLM","KO","KN","BJM","ILP","OO","AW","EFT","ADWZ","GRY","IJY",
                  "BCG","ESQ","CDZ","HTU","SX" };
  
  /* Fetch input until null character or EOF reached */
  while ((c=getchar())>0) {
  
    /* For 90% of the time, just echo the character unchanged */
    if (random()%10>0 && putchar(c)) continue;
    
    /* If it's a letter of the alphabet, shift with 33% probability */
    if (isalpha(c) && random()%3<1) {
      /* Calculate offset to adjacent keys data */
      n=(c&31)-1;
      /* Choose a random adjacent key, and change to lower case if needed */
      putchar(s[n][random()%strlen(s[n])]|(c&32));
      continue;
    }
    
    /* If we reach this point, either we didn't fetch an alphabet character, or   */
    /* we did but chose not to shift it. Either way, we now need to either repeat */
    /* the character or delete it, with 50% probability for each. */
    
    /* This repeats the character by printing the return value from putchar() */
    if (random()&1) putchar(putchar(c));
    
    /* To delete the character, we don't have to do anything. */
  }
}
```
[Answer]
## Ruby, 168
Slightly shorter take using an array indexing strategy:
```
z='qwertyuiop.asdfghjkl...zxcvbnm'+?.*11
gets.chars{|c|$_=z[c]?z:z.upcase
h=[1,-1,11,-11].map{|d|$_[d+~/#{c}/]}-[?.]rescue[]
$><<(rand<0.9?c:[c*2,'',*h.sample].sample)}
```
Original regular expression version (184):
```
s='.qwertyuiop.asdfghjkl...zxcvbnm.'
gets.chars{|c|c=~/\w/&&(s[c]?s: s.upcase)=~/((\w).{9})?((\w)|.)#{c}((\w)|.)(.{9}(\w))?/
$><<(rand<0.9?c:[c*2,'',*[*$2,*$4,*$6,*$8].sample].sample)}
```
[Answer]
### GolfScript, 120 characters
```
{10{rand}:R~!{[{.}{;}{Z\?[.(.10-@).10+]{Z=}%' '-.,R=}]'QWERTYUIOP ASDFGHJKL  ZXCVBNM'' '22*11/*.{32|}%+:Z 2$?0>2+R=~}*}%
```
The code can be tested [here](http://golfscript.apphb.com/?c=IlRoaXMgaXMgc29tZSBjb3JyZWN0IHRleHQuIEl0IGlzIHRvbyBjb3JyZWN0LiBQbGVhc2UgdW4tY29ycmVjdGlmeSBpdC4iCgp7MTB7cmFuZH06Un4he1t7Ln17O317Wlw%2FWy4oLjEwLUApLjEwK117Wj19JScgJy0uLFI9fV0nUVdFUlRZVUlPUCBBU0RGR0hKS0wgIFpYQ1ZCTk0nJyAnMjIqMTEvKi57MzJ8fSUrOlogMiQ%2FMD4yK1I9fn0qfSUK&run=true).
```
{                      # loop over all characters
  10{rand}:R~!         # take random number [0..9] and negate (i.e. 10% chance of true)
  {                    # {...}* is the if-block
    [                  # Three possible operations (code blocks) in the arry
      {.}              # a) duplicate
      {;}              # b) delete
      {                # c) shift
        Z              #      Z is the keyboard layout (see below)
        \?             #      Find the index of the current letter
        [.(.10-@).10+] #      Calculate index of letter left, right, above, below
        {Z=}%          #      Extract the corresponding letters for indices
        ' '-           #      Remove any spaces
        .,R=           #      Take random item
      }
    ]
                       # Z is the keyboard layout (upper and lower case)
                       # with enough spaces around
    'QWERTYUIOP ASDFGHJKL  ZXCVBNM'' '22*11/*.{32|}%+:Z
    2$?0>              # Is the current letter contained in Z and not a space?
    2+                 # Add 2 (i.e. 3 for letters, 2 for any other char)
    R=                 # Take a random code block from above
    ~                  # Execute the block
  }*
}%
```
[Answer]
# Python, 251
```
from random import*
w=choice
o=ord
print"".join(w([z]*9+[w(["",z*2]+[chr(o(w("DGRC FHTV GJYB UOK HKUN JLIM KO NK BMJ IPL O WA ETF ADWZ RYG YIJ CBG QES ZCD TUH XS SQ VNH XVF SFEX WRD".split()[(o(z)&31)-6]))|o(z)&32)]*z.isalpha())])for z in raw_input())
```
Very simple look-up technique, for a moment I thought it might be cheaper to encode the keyboard as a undirected graph but the overhead for creating such a type in Python proved prohibitive. Since Python's random functions have too-descriptive names I use `choice()` exclusively, renaming it to `w`. The 10% chance of error is handled by `w([z]*9+[...])` where the nine copies of an un-typoed character are in a list with one typo.
-16 characters--thanks grc, +2 characters (and
correctness, worth many more than 2 chars)--thanks Dhara
[Answer]
## C#, 320 bytes (360 bytes with program wrapping)
Includes support for "shifted" upper-case letters.
As a function (320 bytes):
```
string T(string s){
    string t="",z="      ",k=z+z+"qwertyuiop asdfghjkl   zxcvbnm";
    k+=k.ToUpper()+z+z;
    int[]m={-11,-1,1,11};
    var r=new System.Random();
    foreach(var c in s){
        if(r.Next(10)>0)
            t+=c;
        else{
            int i=r.Next(k.IndexOf(c)>0?3:2);
            if(i>1){
                while(' '==k[i=k.IndexOf(c)+m[r.Next(4)]]);
                t+=k[i];
            }
            else if(i>0)
                t=(t+c)+c;
        }
    }
    return t;
}
```
As a program that reads a line of text (360 bytes):
```
using System;
class P{
    static void Main(){
        string t="",z="      ",k=z+z+"qwertyuiop asdfghjkl   zxcvbnm";
        k+=k.ToUpper()+z+z;
        int[]m={-11,-1,1,11};
        var r=new Random();
        foreach(var c in Console.ReadLine()){
            if(r.Next(10)>0)
                t+=c;
            else{
                int i=r.Next(k.IndexOf(c)>0?3:2);
                if(i>1){
                    while(' '==k[i=k.IndexOf(c)+m[r.Next(4)]]);
                    t+=k[i];
                }
                else if(i>0)
                    t=(t+c)+c;
            }
        }
        Console.Write(t);
    }
}
```
Input output sample:
```
This is some correct text. It is too correct. Please un-correctify it.
This  is some corrrect texy. Ut is too correct. Pease un-coorrectify it.
TYPO RAGE CAPS TEXT!
TYPPORAGE CAOS TEX!
```
[Answer]
## JS, 303, 288, 275, 273, 274 (bug fix)
```
function z(s){return s.split('').map(function(d){if((r=Math.random)(b='qwertyuiop0asdfghjkl000zxcvbnm')>.1)return d
if((c=r(x=(d>'`'?b:(b=b.toUpperCase())).indexOf(d))*(/[a-z]/i.test(d)+2))<2)return c>1?d+d:''
for(a=0;!a;)a=b[x+[11,-11,1,-1][~~(r()*4)]]
return a}).join('')}
```
Algorithm for the keyslip:
* find char in string (or uppercase)
* add 11, -11, 1 or -1 to the index.
* if it's invalid (0 or null), re-roll
Non-Golfed version per request:
```
function z (s) {
  return s.split('') // split input string into characters.
          .map( // and then for each character...
    function (d) {
      r = Math.random; // set up a shortened form of Math.random
      // declare keyboard here because we have parens and we can save a delimeter.
      b = 'qwertyuiop0asdfghjkl000zxcvbnm';  
      if (r() > .1) {  // normal case
        return d;
      }
      numOptions = /[a-z]/i.test(d) + 2; // if it's a character, 1+2, else 0+2 options
      // test here because we have parens. x might be -1
      if (d > '`') { 
        x = b.search(d);  // x marks the spot
      } else {
        b = b.toUpperCase();
        x = b.search(d);
      }
      c = r() * numOptions; // chars can be 0-3, non-chars: 0-2
      if (c < 2) {                // this case is simple, so it comes first
        return c>1 ? d + d : ''; // double or omit.
      }
      // we must be in keyslip mode.
      // in the golfed code, this while loop become for loops, 
      // but it's really a while.
      a = 0;
      while (!a) { // that is, a != null && a != 0
        v = ~~(r() * 4); // 0, 1, 2, or 3
        newX = x + [11, -11, 1, -1][v]; // choose one
        a = b[newX];  // slip the key
      }
      return a;
    }
  ) // end the map function
  .join('') // and then reassemble the string
}
```
[Answer]
## Perl, ~~278~~ ~~239~~ ~~197~~ ~~169~~ ~~162~~ ~~156~~ ~~151~~ 149
```
s#((\pL)|.)#rand>.1?$&:($&x2,'',do{1until/^.{@{[(2,-10,12)[rand 4]-1+index$_=QWERTYUIOP0ASDFGHJKL000ZXCVBNM,uc($,=$&)]}}(\D)/;$,&' '|$1})[rand@-]#ge
```
Run with `-p`, then 148+1=149 bytes. E.g.:
```
perl -p typos.pl
Your challenge is to take an arbitrary single line of text, and add typos.
You challenge is to tale an  arbitrary singe lind of text, and add yposs.
This is some correct text. It is too correct. Please un-correctify it.
This iis some correct text. It s too coorrect.Pleqse un-correctify it.
```
Un-golfed, more or less:
```
s#((\pL)|.)#rand>.1
    ? $&
    : ($&x2,'',
        do{
            1until/^.{@{[(2,-10,12)[rand 4]-1
                +index$_=QWERTYUIOP0ASDFGHJKL000ZXCVBNM,uc($,=$&)]}}(\D)/;
            $,&' '|$1
        }
    )[rand@-]
#ge
```
At first I thought that choosing element randomly in an array (of 26 of them of different lengths) is more statistically 'clean' (i.e. random), but maybe it was wrong. (See previous version.) This last attempt is, following the leaders:-), stepping along a string by either -1,1,-11,11 (randomly) and repeating until valid step. 
Edit: Thanks to **tobyink** help and other optimizations, we managed to considerably reduce code size. 
The last approach uses some tricks with regexp search to find valid step along substitution string, eliminating manual checks.
Another edit: 5 bytes off because we don't need integers for array indexes + small trick with illegal array index. I tried same trick with `[-4+rand@-]` (i.e. negative indexes) and get rid of one list element, `'',` but it didn't save anything.
Edit: Back to simplicity - replacing condition `~~rand 10` with `rand>.1` saves 2 bytes...
[Answer]
# **PHP, function with 368 bytes**
Here is my attempt.
It's some "frankencode", but it **kinda** works.
```
function _($m){$q=array(array('qwertyuiop','asdfghjkl',' zxcvbnm'),'!.-,;?+/');$r='mt_rand';foreach(str_split($m)as$k=>$c)if(!$r(0,9)&&$c!=' ')foreach($q[0]as$x=>$y)if(($z=strpos($y,$c))!==!1){switch($t=$r(-3,2-($z>>3)-($x>>1))){case 2:++$z;break;case 1:++$x;break;case -1:--$x;break;case -2:--$z;break;case -3:$z=8;break;}$m[$k]=$t?$q[0][$x][$z]:$q[1][$z];}return$m;}
```
A more "readable" code:
```
function _($m)
{
    $q=array(array('qwertyuiop','asdfghjkl',' zxcvbnm'),'!.-,;?+/');
    $r='mt_rand';
    foreach(str_split($m)as$k=>$c)
        if(!$r(0,9)&&$c!=' ')
            foreach($q[0]as$x=>$y)
                if(($z=strpos($y,$c))!==!1)
                {
                    switch($t=$r(-3,2-($z>>3)-($x>>1)))
                    {
                        case 2:
                            ++$z;break;
                        case 1:
                            ++$x;break;
                        case -1:
                            --$x;break;
                        case -2:
                            --$z;break;
                        case -3:
                            $z=8;break;
                    }
                    $m[$k]=$t?$q[0][$x][$z]:$q[1][$z];
                }
    return$m;
}
```
The only difference between the 2 codes is that one has tons of tabs and newlines.
It doesn't produce the same exact type of "incorrectness", but it either deletes or replaces a char using the said conditions.
You can try it at <http://writecodeonline.com/php/>.
Copy and paste this code:
```
function _($m){$q=array(array('qwertyuiop','asdfghjkl',' zxcvbnm'),'!.-,;?+/');$r='mt_rand';foreach(str_split($m)as$k=>$c)if(!$r(0,9)&&$c!=' ')foreach($q[0]as$x=>$y)if(($z=strpos($y,$c))!==!1){switch($t=$r(-3,2-($z>>3)-($x>>1))){case 2:++$z;break;case 1:++$x;break;case -1:--$x;break;case -2:--$z;break;case -3:$z=8;break;}$m[$k]=$t?$q[0][$x][$z]:$q[1][$z];}return$m;}
echo _('This is some correct text. It is too correct. Please un-correctify it.');
```
After testing, please, tell me if it is a valid answer.
[Answer]
# C#, 581 bytes
```
using System;class B{static void Main(){var z=Console.ReadLine();var r=new Random();foreach(char C in z){String o;if(r.Next(10)==0){int w=r.Next(3);o=w==0?C+""+C:w==1?"":f(C,r);}else{o=C+"";}Console.Write(o);}Console.ReadLine();}static string f(char C,Random r){string[]k={"00000000000","0qwertyuiop0","0asdfghjkl0","00zxcvbnm0","000000000"};char L=char.ToLower(C);char h='0';for(int i=1;i<4;i++){var d=k[i].IndexOf(L);if(d!=-1){while(h=='0'){int n=r.Next(4);h=n==0?k[i][d-1]:n==1?k[i][d+1]:n==2?k[i-1][d]:k[i+1][d];}h=char.IsUpper(C)?char.ToUpper(h):h;return h+"";}}return C+"";}}
```
and in a more readable format:
```
using System;
class A
{
    static void Main()
    {
        var z = Console.ReadLine();
        var r = new Random();
        foreach (char C in z)
        {
            String o;
            if (r.Next(10) == 0)
            {
                int w = r.Next(3);
                o = w == 0 ? C + "" + C :
                    w == 1 ? "" :
                             f(C, r);
            }
            else
            {
                o = C + "";
            }
            Console.Write(o);
        }
    }
    static string f(char C, Random r)
    {
        string[] k = {
                            "00000000000", 
                            "0qwertyuiop0", 
                            "0asdfghjkl0", 
                            "00zxcvbnm0", 
                            "000000000"};  
        char L = char.ToLower(C);
        char h = '0';
        for (int i = 1; i < 4; i++)
        {
            var d = k[i].IndexOf(L);
            if (d != -1)
            {
                while (h == '0')
                {
                    int n = r.Next(4);
                    h = n == 0 ? k[i][d - 1] :
                        n == 1 ? k[i][d + 1] :
                        n == 2 ? k[i - 1][d] :
                                 k[i + 1][d];
                }
                h = char.IsUpper(C) ? char.ToUpper(h) : h;
                return h + "";
            }
        }
        return C + "";
    }
}
```
[Answer]
## PHP, ~~326~~ ~~320~~ ~~318~~ 315 chars
```
$h=array(qs,vhn,vxf,sefx,wrd,drgc,fthv,gyjb,uko,hukn,jilm,ok,nk,bjm,ilp,o,aw,etf,awdz,rgy,yji,cgb,qse,zdc,thu,sx);$a=x.$argv[1];for(;$d=$a[++$b];)echo!rand(0,9)&&($c=ord($d)-65)?(!($g=rand(0,($e=($c>-1&&$c<26)or$c>31&&$c<58)+1))?$d.$d:($g<2?"":(($j=$i[rand(0,strlen($i=$h[$c-!$e*32]))])&&$e?strtoupper($j):$j))):$d;
```
And a more readable and commented version:
```
// $a   input
// $b   char iterator
// $c   current char ascii value
// $d   current char
// $e   is uppercase
// $g   rand() output
// $h   char displacement
// $i   current character in $h
// $j   temporary var for uppercasing
// the neighbouring characters of a-z, in alphabetical (and ASCII) order
$h=array(qs,vhn,vxf,sefx,wrd,
    drgc,fthv,gyjb,uko,hukn,
    jilm,ok,nk,bjm,ilp,
    o,aw,etf,awdz,rgy,
    yji,cgb,qse,zdc,thu,
    sx);
// input from argument
$a=x.$argv[1];
for(;$d=$a[++$b];)
    echo!rand(0,9)&&($c=ord($d)-65)? /* 10% chance, read char ASCII value - 65 into $c */
        (!($g=rand(0,($e=($c>-1&&$c<26)or$c>31&&$c<58)+1))?
          /* random number from 0 to 2 (if alphabetic) or 0 to 1 stored in $g */
            $d.$d: /* double char if $g = 0 */
            ($g<2?
                "": /* omit char if $g = 1*/
                (($j=$i[rand(0,strlen($i=$h[$c-!$e*32]))])&&$e?
                  /* $j = random neighbour of the current char */
                    strtoupper($j): /* uppercase $j */
                    $j)))
        :$d; /* keep char */
```
Still could be improved, I suppose.
-2, -3 thanks to Ismael Miguel
[Answer]
# Java (475 bytes)
This is my try in the verbose language that is Java. Getting random numbers is quite long in Java, and the mapping isn't really efficient. It can probably be improved.
```
import static java.lang.Math.*;public class T{public static void main(String[]a){String z="",v;for(char c:a[0].toCharArray()){double g=random()*60;if(g>=6)z+=c;else{boolean u='A'<=c&c<='Z',l='a'<=c&c<='z';if(g<(l|u?2:3))z+=""+c+c;else if((l|u)&g<4){v="qs,hnv,fvx,efsx,drw,cdgr,fhtv,kou,bgjy,hknu,ijlm,ko,kn,bjm,ilp,o,aw,eft,adwz,gry,ijy,bcg,eqs,cdz,htu,sx".split(",")[u?c-'A':c-'a'];c=v.charAt((int)(random()*v.length()));z+=u?(char)(c-'a'+'A'):c;}}}System.out.println(z);}}
```
Usage:
```
java T "This is some correct text. It is too correct. Please un-correctify it."
```
Uncompressed, accolades added:
```
import static java.lang.Math.*; // Need random()
public class T {
    public static void main(String[] a) {
        String z = "", v;
        for (char c : a[0].toCharArray()) {
            double g = random() * 60; // Compute random only once for two cases.
            if (g >= 6) {
                // 90% must be correct (accolades are stripped)
                // so we just copy the character.
                z += c;
            } else {
                // These tests come often.
                boolean u = 'A' <= c & c <= 'Z', l = 'a' <= c & c <= 'z';
                // reuse the random. g is [0,6[.
                if (g < (l | u ? 2 : 3)) { 
                    // If c is an ascii letter (l|u) then g must be [0,2[ ; if not, then g must be [0,3[.
                    // If those conditions are met, we duplicate the character
                    z += "" + c + c;
                } else if ((l | u) & g < 4) {
                    // if c is letter and g [2,4[ then we perform the wrong key event.
                    // I could not compress it using the keyboard mapping shorter in Java than expanding it like it is now.
                    v = "qs,hnv,fvx,efsx,drw,cdgr,fhtv,kou,bgjy,hknu,ijlm,ko,kn,bjm,ilp,o,aw,eft,adwz,gry,ijy,bcg,eqs,cdz,htu,sx".split(",")[u ? c - 'A' : c - 'a'];
                    // get a random character from the string.
                    c = v.charAt((int) (random() * v.length()));
                    // Keep the case of the character.
                    z += u ? (char) (c - 'a' + 'A') : c;
                } else { // if c is not an ascii letter or if g is [4,6[
                    // Do nothing. This else is stripped.
                }
            }
        }
        System.out.println(z);
    }
}
```
[Answer]
# AutoHotkey 441 bytes
The input must be given as a command line parameter, the output is given as an error message.
Golfed version
```
loop, parse, 1
{
k:={1:"q",2:"w",3:"e",4:"r",5:"t",6:"y",7:"u",8:"i",9:"o",10:"p",21:"a",22:"s",23:"d",24:"f",25:"g",26:"h",27:"j",28:"k",29:"l",42:"z",43:"x",44:"c",45:"v",46:"b",47:"n",48:"m"},a:=A_LoopField,q:=r(z?3:2),z=
if r(10)!=10{
h.=a
continue
}
for x,y in k
z:=y=a?x:z
if q=1
h.=a a
if q=3
{
Loop{
t:=r(4),w:=z+(t=1?20:t=2?-20:t=3?1:-1)
} until k.HasKey(w)
h.=k[w]
}
}
throw % h
r(n){
Random,w,1,n
return w
}
```
Un-golfed and annotated version
(difference is that this version has more white space and the variable assignments are on separate lines for readability.)
```
k:={1:"q",2:"w",3:"e",4:"r",5:"t",6:"y",7:"u",8:"i",9:"o",10:"p",21:"a",22:"s",23:"d",24:"f",25:"g",26:"h",27:"j",28:"k",29:"l",42:"z",43:"x",44:"c",45:"v",46:"b",47:"n",48:"m"}
loop, parse, 1
{
    a:=A_LoopField
    ;get a random number from 1-10 and check if it is 10
    ;  if it isn't skip the rest of this iteration
    if r(10)!=10
    {
        h.=a
        continue
    }
    ;check if the current character is in the k
    z=
    for x,y in k
        z:=y=a?x:z
    ;choose a random number to decide what typo to do
    q:=r(z?3:2)
    if q=1
        h.=a a ;duplicate the key
    if q=3
    {
        ;the keyboard array is set up so that by adding or subtracting
        ;  20 from the index you are moving up or down a row
        ;  and by adding or subtracting 1 you move right or left
        ;  then you just need to check if the adjusted index
        ;  is valid
        Loop
        {
            t:=r(4)
            w:=z+(t=1?20:t=2?-20:t=3?1:-1)
        } until if k.HasKey(w)
        h.=k[w]
    }
}
;display the string as an error message
throw % h
r(n)
{
    Random,w,1,n
    return w
}
```
]