Insertar errores tipográficos en el texto

63

Escribí un texto, pero parece demasiado profesional. Quiero que parezca que estaba realmente cansado cuando lo escribí. Necesito que insertes algunos errores tipográficos.

Su desafío es tomar una única línea de texto arbitraria y agregar errores tipográficos. Esto significa que para cada personaje, habrá un 10% de posibilidades de que se tipifique.

La definición de "tipificado" es que debe elegir (al azar) uno de los siguientes:

  • Duplicar el personaje.
  • Eliminar el personaje.
  • Desplaza el carácter un espacio del teclado. El "teclado" se define como:

    qwertyuiop
    asdfghjkl
     zxcvbnm
    

    Para el cambio de personaje, debes ir un espacio arriba, abajo, izquierda o derecha. Esto debe ser elegido al azar. La opción de desplazamiento solo se aplica a los caracteres alfabéticos. El caso debe ser preservado. ¡Tenga cuidado con los casos de borde, como m!

La definición de "aleatorio" es que el resultado no debe ser predecible (al observar los resultados anteriores). Por ejemplo, no puedes tipificar cada décimo personaje. Además, la aleatoriedad debe tener una distribución uniforme. Por ejemplo, no puede hacer 30% de duplicado, 30% de eliminación y 40% de desplazamiento; tiene que tener una probabilidad de 1/3 para cada uno (1/2 para cada uno si es un personaje no alfabético).

Entrada de ejemplo:

This is some correct text. It is too correct. Please un-correctify it.

Salida de ejemplo:

This iissome xorreect tex..  It is too coteect. Please jn-corretify it.

Este es el , por lo que ganará el código más corto en bytes.

Pomo de la puerta
fuente
44
¿Qué hay de golpear accidentalmente la tecla de mayúsculas? Cuando uno escribe una "A" o "Z", debería haber una posibilidad aleatoria de que lleguen a mayúsculas en su lugar, ND TERMINE ASÍ.
AJMansfield
2
@AJMansfield Lol, eso probablemente sería demasiado complicado. Ya es lo suficientemente complicado como es: P
Pomo de la puerta
1
@ user2509848 ¡Oye, deja de hacerlo, o co, plicado de lo que ya es! :-P
Pomo de la puerta
1
@Doorknob Su salida de ejemplo no parece que estuviera cansada , parece que es nuevo en escribir y no sabe cómo corregir errores tipográficos. (O no miraste lo que escribiste ) .
Blacklight Shining
1
"edge-cases" <- Veo lo que hiciste allí. * aplauso lento *
Adam Maras

Respuestas:

15

GolfScript, 120 caracteres

{10{rand}:R~!{[{.}{;}{Z\?[.(.10-@).10+]{Z=}%' '-.,R=}]'QWERTYUIOP ASDFGHJKL  ZXCVBNM'' '22*11/*.{32|}%+:Z 2$?0>2+R=~}*}%

El código se puede probar aquí .

{                      # 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
  }*
}%
Howard
fuente
19

C, 358 bytes

(Solo hay tres líneas de código, pero he dividido la línea 3 por legibilidad)

#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));}}

El conjunto de cadenas al principio enumera las posibles teclas adyacentes para cada letra del alfabeto. Tuve que duplicar la "O" (adyacente a "P") para evitar el cálculo random()%1al seleccionar un personaje desplazado.

Prueba de funcionamiento:

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

Actualizar:

Aquí hay una versión ampliada y comentada del mismo código fuente:

#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. */
  }
}
ossifrage aprensivo
fuente
2
Estoy bastante seguro de que no necesitas poner el 26 char*s[26]. El compilador debería poder resolverlo por sí mismo.
FDinoff
@FDinoff Ah, por supuesto. No tiene mucho sentido editar ahora; el barco ya está hundido :-D
ostensivo ossifrage
También podría reemplazar ambos continues con elses. (Deje el lugar ;donde estaba el primero).
AShelly
1
¿Cuál es el problema con random ()% 1? Cualquier int% 1 debería ser 0.
user253751
18

Rubí, 168

Toma ligeramente más corta usando una estrategia de indexación de matriz:

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)}

Versión original de expresión regular (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)}
Paul Prestidge
fuente
3
Lo siento, no puedo leer a Ruby. Aquí ejecuté este programa 10 veces con STDIN '0123456789'x10, es decir, 100 dígitos (es decir, 1000 dígitos en total en 10 ejecuciones), y nunca hubo dígitos duplicados en la salida. ¿Hay algún problema con ese sitio o mi comprensión de cómo funciona todo?
user2846289
@VadimR buena captura, gracias! Había empezado a usar Kernel#putcpara imprimir la salida ya que eso no requería parens, ahorrándome un carácter. Por supuesto, putcsolo imprime el primer carácter, y la cadena de salida a veces puede tener dos caracteres de longitud. Estúpido error. ¡Prueba esta versión!
Paul Prestidge
Perfecto ahora Gracias.
user2846289
9

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())

Técnica de búsqueda muy simple, por un momento pensé que podría ser más barato codificar el teclado como un gráfico no dirigido, pero la sobrecarga para crear ese tipo en Python resultó prohibitiva. Como las funciones aleatorias de Python tienen nombres demasiado descriptivos, uso choice()exclusivamente, renombrándolo a w. El 10% de posibilidades de error se maneja en el lugar w([z]*9+[...])donde las nueve copias de un carácter sin escribir están en una lista con un error tipográfico.

-16 caracteres - gracias grc, +2 caracteres (y corrección, valen más de 2 caracteres) - gracias Dhara

Kaya
fuente
2
Algunas mejoras menores: use espacios como delimitador d="SQ VNH XVF...".split(), elimine el espacio después printy reemplace el if/ elsecon ([...]+[...])*z.isalpha(). Además, no necesita una variable dya que solo la usa una vez.
grc
1
Puedes hacerlo w=__import__('random').choice(al menos en Python 3 afaik).
SimonT
1
Este código se rompe con varios caracteres de texto:?;: <Etc
Dhara
1
Además, tiene un error off-by-one en la indexación: 'b' en 'bbbbbbbb' se reemplaza por 'x', 'zzzzzzzzzz' da un índice fuera de límites
Dhara
1
Use Python 3 input()y print()para guardar 2 caracteres.
Cees Timmerman
8

C #, 320 bytes (360 bytes con ajuste de programa)

Incluye soporte para letras mayúsculas "desplazadas".

Como una función (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;
}

Como un programa que lee una línea de texto (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);
    }
}

Muestra de entrada y salida:

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!
Hand-E-Food
fuente
Los programas legales de C # deben tener al menos "public class A {static void Main () {}}" para ser válidos. Luego deberá leer desde la consola. Pero parece que su solución seguirá siendo más corta que la mía, así que bien hecho.
Xantix
@ Xantix, lo sé, pero nunca dijeron que tenía que ser un programa. De cualquier manera, mi respuesta ahora incluye envolturas de programas.
Hand-E-Food
Me acabo de dar cuenta de que mi función aceptará caracteres CR y LF en la entrada que podrían duplicarse o descartarse. Eso sería una salida interesante ...
Hand-E-Food
2
Hmm, no hay suficientes llamadas aleatorias para hacer Func<int,int> n=x=>r.Next(x);una buena idea. Si solo el compilador pudiera inferir el tipo para los delegados ...
Magus
8

JS, 303 , 288 , 275 , 273 , 274 (corrección de errores)

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('')}

Algoritmo para el deslizamiento de tecla:

  • encontrar char en cadena (o mayúscula)
  • agregue 11, -11, 1 o -1 al índice.
  • si no es válido (0 o nulo), vuelva a tirar

Versión sin golf por solicitud:

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
}
No es que Charles
fuente
¡Bravo! JS ninja premiado!
Sunny R Gupta
1
@SunnyRGupta ¡Gracias! Ojalá pudiera entenderlo más. Creo que el infierno de paréntesis masivo podría hacerlo más largo de lo necesario.
No es que Charles
¡También intente mostrar la versión no minificada para principiantes!
Sunny R Gupta
Bueno, técnicamente su código tiene 277 bytes en Windows. DEBE reemplazar todas las líneas nuevas con ;. Esa es la única forma de decir que en realidad tiene 274 bytes. Además, solo funciona en las versiones más recientes de Javascript y JScript.
Ismael Miguel
6

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

Ejecutar con -p, luego 148 + 1 = 149 bytes. P.ej:

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.

Sin golf, más o menos:

s#((\pL)|.)#rand>.1
    ? $&
    : ($&x2,'',
        do{
            1until/^.{@{[(2,-10,12)[rand 4]-1
                +index$_=QWERTYUIOP0ASDFGHJKL000ZXCVBNM,uc($,=$&)]}}(\D)/;
            $,&' '|$1
        }
    )[rand@-]
#ge

Al principio pensé que elegir un elemento aleatoriamente en una matriz (de 26 de ellos de diferentes longitudes) es estadísticamente más "limpio" (es decir, aleatorio), pero tal vez estuvo mal. (Ver versión anterior.) Este último intento es, siguiendo a los líderes :-), avanzar a lo largo de una cadena por -1,1, -11,11 (al azar) y repetir hasta el paso válido.

Editar: Gracias a la ayuda de tobyink y otras optimizaciones, logramos reducir considerablemente el tamaño del código.

El último enfoque utiliza algunos trucos con la búsqueda de expresiones regulares para encontrar un paso válido a lo largo de la cadena de sustitución, eliminando las verificaciones manuales.

Otra edición: 5 bytes de descuento porque no necesitamos enteros para los índices de matriz + pequeño truco con índice de matriz ilegal. Intenté el mismo truco con [-4+rand@-](es decir, índices negativos) y eliminé un elemento de la lista, '',pero no guardó nada.

Editar: Volver a la simplicidad - reemplazando la condición ~~rand 10con rand>.1guardar 2 bytes ...

usuario2846289
fuente
1
No hay necesidad de un punto y coma después de la definición de sub i. No está utilizando estricto, por lo que 'QWERTYUIOP0ASDFGHJKL000ZXCVBNM'se puede dar como una palabra simple (guarda dos caracteres de comillas). De manera similar, también puede hacerlo 'Z'(aunque esto significa que necesita agregar un espacio entre ellos y gt, por lo tanto, solo guarda un carácter). Ahorro total: 4 caracteres.
tobyink
1
La construcción ($n=i$&=~/\pL/?3:2)?--$n?do{...}:$&x2:''se puede reescribir como ($&x2,'',do{...})[i$&=~/\pL/?3:2]. Significa que la evaluación no es perezosa (calcula las tres formas en que el personaje podría ser sustituido antes de decidirse por una técnica de sustitución), pero funciona, y mis otros cálculos guardan otros siete caracteres.
tobyink
1
Oh, acabo de notar que también tienes espacios en blanco antes gt'Z', eso se puede eliminar. Con todos estos cambios, debería poder reducirlo a 184 caracteres.
tobyink
@tobyink, muchas gracias, especialmente por su segundo comentario: cómo no vi esta construcción allí, no sé :-(. Sub se ha ido (nos ahorra un par de bytes). El truco de Barewords también es bueno, y en realidad ya lo estaba haciendo cuando leí tu comentario. :-) Gracias de nuevo.
user2846289
1
Tengo un personaje más para ti. Si cambia el nombre $sa $,(esta variable incorporada es el separador de campo para print, pero no está imprimiendo múltiples campos en ningún lado, por lo que su uso incorporado es irrelevante, lo que hace que la variable esté lista para su reutilización), entonces puede eliminar el espacio en blanco en $s x3hacerlo justo $,x3.
tobyink
4

PHP, función con 368 bytes

Aquí está mi intento.

Es un poco de "frankencode", pero es un poco funciona.

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;}

Un código más "legible":

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;
}

La única diferencia entre los 2 códigos es que uno tiene toneladas de pestañas y líneas nuevas.

No produce el mismo tipo exacto de "incorrección", pero elimina o reemplaza un carácter utilizando las condiciones mencionadas.

Puedes probarlo en http://writecodeonline.com/php/ .

Copia y pega este codigo:

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.');

Después de la prueba, por favor, dígame si es una respuesta válida.

Ismael Miguel
fuente
No parece afectar a las letras mayúsculas en absoluto.
aprensivo ossifrage
1
Las letras mayúsculas no se ven afectadas en el ejemplo. Pero sí, no lo hace. Pero también note que dije que KINDA funciona.
Ismael Miguel
3

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+"";}}

y en un formato más legible:

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 + "";
    }
}
Xantix
fuente
3

PHP, 326 320 318 315 caracteres

$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;

Y una versión más legible y comentada:

// $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 */

Todavía podría mejorarse, supongo.

-2, -3 gracias a Ismael Miguel

Aurel Bílý
fuente
1
Donde tiene (!($g=rand(0,($e=($c>-1&&$c<26)or$c>31&&$c<58)?2:1))cambio (!($g=rand(0,($e=($c>-1&&$c<26)or$c>31&&$c<58)+1))?y ahorrará 2 bytes.
Ismael Miguel
1
Donde tenga ($e?0:32), reemplazando con 32*!!$e(observe la falta de paréntesis) guarde 2 bytes. Si $eSIEMPRE es booleano, puede hacerlo 32*!$ey guardar 3 bytes. Esto funcionará porque php tiene precedencia aritmética. Esto significa que las multiplicaciones y divisiones se hacen antes de cualquier suma y resta.
Ismael Miguel
2

Java (475 bytes)

Este es mi intento en el lenguaje detallado que es Java. Obtener números aleatorios es bastante largo en Java, y el mapeo no es realmente eficiente. Probablemente se pueda mejorar.

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);}}

Uso:

java T "This is some correct text. It is too correct. Please un-correctify it."

Sin comprimir, elogios añadidos:

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);
    }
}
Olivier Grégoire
fuente
2

AutoHotkey 441 bytes

La entrada se debe dar como un parámetro de línea de comando, la salida se da como un mensaje de error.

Versión de golf

bucle, analizar, 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 =
si r (10)! = 10 {
h. = a
Hacer continuación
}
para x, y en k
z: = y = a? x: z
si q = 1
h. = aa
si q = 3
{
Lazo{
t: = r (4), w: = z + (t = 1? 20: t = 2? -20: t = 3? 1: -1)
} hasta k.HasKey (w)
h. = k [w]
}
}
tiro% h
r (n) {
Aleatorio, w, 1, n
volver w
}

Versión sin golf y anotada (la diferencia es que esta versión tiene más espacio en blanco y las asignaciones variables están en líneas separadas para facilitar la lectura).

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"}
bucle, analizar, 1
{
    a: = A_LoopField
    ; obtenga un número aleatorio del 1 al 10 y verifique si es 10
    ; si no se salta el resto de esta iteración
    si r (10)! = 10
    {
        h. = a
        Hacer continuación
    }

    ; compruebe si el carácter actual está en la k
    z =
    para x, y en k
        z: = y = a? x: z

    ; elija un número aleatorio para decidir qué error tipográfico hacer
    q: = r (z? 3: 2)
    si q = 1
        h. = aa; duplicar la clave
    si q = 3
    {
        ; la matriz de teclado está configurada de modo que al sumar o restar
        ; 20 del índice te estás moviendo hacia arriba o hacia abajo una fila
        ; y al sumar o restar 1 te mueves hacia la derecha o hacia la izquierda
        ; entonces solo necesita verificar si el índice ajustado
        ; es válida
        Lazo
        {
            t: = r (4)
            w: = z + (t = 1? 20: t = 2? -20: t = 3? 1: -1)
        } hasta si k.HasKey (w)
        h. = k [w]
    }
}
; muestra la cadena como un mensaje de error
tiro% h
r (n)
{
    Aleatorio, w, 1, n
    volver w
}
Persona93
fuente
¿Con qué programas funciona esto?
Ismael Miguel
Lo ejecuta AutoHotkey.exe. autohotkey.com
Person93