Some of you might have realised that I am a sloppy typer when using my phone. That's why I want you to write a program which corrects my typos.


Given a misspelled word, output all of the possible words which I meant to write.


The main cause of my typos is down to the fact that I hit the wrong keys and often hit the key next door. The following is my keyboard layout:

q w e r t y u i o p
 a s d f g h j k l
   z x c v b n m
   , [ space ] .

Note that the bottom row, , [ space ] . will never be used in this challenge

For some reason, I only make mistakes horizontally: I would never hit the n instead of the j, but I might hit an f instead of a d.

For example, I could end up spelling the word sloppy as:


Where I've gone left of each key.

However, don't forget that I may not necessarily make a mistake on every letter in the word.


Let's say the input is:


The possibilities that the word could have been are:

vid cid bid
vis cis bis
vif cif bif
vod cod bod
vos cos bos
vof cof bof
vud cud bud
vus cus bus
vuf cuf buf

Out of those, the following are in the dictionary:


So that should be your output.


You should only use the text file found here as your dictionary: http://mieliestronk.com/corncob_lowercase.txt. You do not have to count this file as part of your byte count.

All input will be a single word. You may display your output in any way you wish (as long as there is some kind of separator).

Assume that with all input, you will find a variant which is in the dictionary.


The shortest code in bytes wins.

  • 11
    \$\begingroup\$ When I saw the title, I thought this was gonna be another challenge about Welsh... \$\endgroup\$ Sep 12 '16 at 9:27
  • \$\begingroup\$ I presume that compressing the dictionary is part of the challenge, and that if I choose to read the dictionary from a file I should count its length towards my score, but that should be made explicit for the benefit of people who haven't read the whole of meta. PS If you're going to post something to the sandbox, leave it there long enough to get feedback. \$\endgroup\$ Sep 12 '16 at 9:50
  • \$\begingroup\$ @PeterTaylor Well not really, it's mainly just the parsing of the dictionary which can be done uncompressed. \$\endgroup\$
    – Beta Decay
    Sep 12 '16 at 9:53
  • \$\begingroup\$ So if I inline the file, what do I count? Two bytes for the delimiting ""? \$\endgroup\$ Sep 12 '16 at 11:08
  • \$\begingroup\$ @PeterTaylor Well yes \$\endgroup\$
    – Beta Decay
    Sep 12 '16 at 11:42

Python 2.7, 161 159 bytes

from itertools import*
lambda a,k=' qwertyuiop asdfghjkl zxcvbnm ':set(map(''.join,product(*[k[k.index(l)-1:k.index(l)+2].strip()for l in a])))&set("<dictionary>".split())

readable version

from itertools import *
keyboard=' qwertyuiop asdfghjkl zxcvbnm '
for letter in input():

print words&dictionary
  • Saved 1 byte thanks to @TuukkaX
  • \$\begingroup\$ You have an useless whitespace at .strip() for. \$\endgroup\$
    – Yytsi
    Sep 14 '16 at 10:23

Japt, 50 47 bytes

;D=R+Dv;W=3pUl¹óW ®s3 s1 £DgDbUgY)-X+1}Ãf@~V·bX

Input is the word to fix, and the dictionary as a string. Test it online! (Note: you'll have to manually paste the dictionary into the string.)

How it works

;D=R+Dv;W=3pUl¹óW ®s3 s1 £DgDbUgY)-X+1}Ãf@~V·bX  // Implicit: U = input, V = dictionary, R = newline
;                                                // Re-assign preset variables. D = "QWERTYUIOP\nASDFGHJKL\nZXCVBNM";
 D=R+Dv;                                         // Convert D to lowercase and prepend a newline.
        W=3pUl¹                                  // Set W to 3 to the power of U.length.
               óW                                // Create the range [W, W+W).
                  ®                       Ã      // Map each item Z in the range by this function:
                   s3                            //  Take Z.toString(3).
                      s1                         //  Remove the first character.
                                                 //  If the input is two chars long, e.g. "id", the array is now
                                                 //  ["00", "01", "02", "10", "11", "12", "20", "21", "22"].
                         £            }          //  Map each char X and index Y in the string by this function:
                              UgY                //   Get the char at position Y in U.
                            Db   )               //   Take the index of the char in D.
                                  -X+1           //   Subtract X and add 1.
                          Dg                     //   Get the char at that position in D.
                                                 // This maps our array for "id" to:
                                                 // ["of", "od", "os", "if", "id", "is", "uf", "ud", "us"].
                                        f@       // Filter to only the items X where
                                             bX  //  the index of X in
                                           V·    //  the dictionary, split at newlines,
                                          ~      //  is not -1.
                                                 // This filters our array for "id" to:
                                                 // ["of", "if", "id", "is", "us"].
                                                 // Implicit: output last expression

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.