A loose spellchecker

4

1

John Doe used to be one of the fastest QWERTY keyboard typists in the world, but a recent head injury caused by a stampeding herd of downgoats has critically hampered his ability to type accurately. In a desperate effort to retain his reputation as a typing prodigy, he has tasked us with the creation of a spellchecker - well, sort of. This spellchecker's rigged so that John Doe can worry less about accuracy and more about speed.

Challenge

Here's the keyboard you'll be using. NOTE: non-spacebar keys are separated by 2 spaces, with the unshifted key followed by the shifted key.

`~   1!  2@  3#  4$  5%  6^  7&  8*  9(  0)  -_  =+
Tab  qQ  wW  eE  rR  tT  yY  uU  iI  oO  pP  [{  ]}  \|
     aA  sS  dD  fF  gG  hH  jJ  kK  lL  ;:  '"  enter
     zZ  xX  cC  vV  bB  nN  mM  ,<  .>  /?
             [    SPACEBAR    ]

Notice how I have arranged the keys to line up properly. This is crucial for this challenge to work.

Write a full program/function that, given 2 strings of equal length containing only characters from the above keyboard, outputs a truthy/falsy value according to the following:


If all characters' keys are at most 1 away (horizontally, vertically, or diagonally) from the characters' keys at the same index in string 2, then output truthily.

  • Example using a: Any characters in aAqQsSzZwWxX or \t (tab key) would return truthily.

  • Special cases: \n (enter key) would return truthily for any character in [{]}\|'" or \n. Spaces (spacebar key) would return truthily for any character in xXcCvVbBnNmM,< or spaces.

Otherwise, output falsily.

Note: Tabs and newlines will be actual representations instead of their escaped equivalents (\t and \n).


This is ; shortest code wins.

Example test cases

String1     String2        Output
---------------------------------
asdf        QWeR        => true
cat         gsl         => false
12345       qWeRty      => true
John Doe    Jonh Deo    => false

Mama Fun Roll

Posted 2016-01-17T04:39:26.187

Reputation: 7 234

3"a recent head injury caused by a stampeding herd of downgoats" ಠ_______ಠ – Downgoat – 2016-02-02T04:04:31.163

Well, I mean, he did post some pretty badly-golfed answers... – Mama Fun Roll – 2016-02-02T04:09:27.053

@Downgoat I'll get you for what you did to him. – workoverflow – 2018-03-18T10:55:13.653

Answers

1

JavaScript (ES6), 287 bytes

(a,b)=>[...a].map((l,i)=>{p=k[g="indexOf"](l);q=k[g](o=b[i]);r=r?l==s|o==s?~m[g](l)&&~m[g](o):(x=(p%28/2|0)-(q%28/2|0))<2&x>-2&(y=(p/28|0)-(q/28|0))<2&y>-2:0},r=k=`\`~1!2@3#4$5%6^7&8*9(0)-_=+  \t qQwWeErRtTyYuUiIoOpP[{]}\\|  aAsSdDfFgGhHjJkKlL;:'"
     zZ${m="xXcCvVbBnNmM,<"}.>/?`,m+=s=" ")|r

Explanation

Returns 1 for true and 0 for false.

Note that the \t should be a literal tab character.

(a,b)=>
  [...a].map((l,i)=>{               // for each character l at index i in word A
      p=k[g="indexOf"](l);          // p = index of l in k
      q=k[g](o=b[i]);               // o = letter in word B, q = index of o in k
      r=r?                          // if r
        l==s|o==s?                  // if l or o is a space
          ~m[g](l)&&~m[g](o)        // check the space-matching characters for l and o
        :
          (x=(p%28/2|0)-(q%28/2|0)) // X distance between letters A and B
            <2&x>-2&                // if distance is 2 or greater, r = 0
          (y=(p/28|0)-(q/28|0))     // Y distance between letters A and B
            <2&y>-2                 // if distance is 2 or greater, r = 0
      :0                            // do nothing if r == 0
    },
    r=                              // r = result

    // Keyboard string, each row is 28 characters long, using spaces as padding
    k=`\`~1!2@3#4$5%6^7&8*9(0)-_=+  \t qQwWeErRtTyYuUiIoOpP[{]}\\|  aAsSdDfFgGhHjJkKlL;:'"
     zZ${m="xXcCvVbBnNmM,<"}.>/?`,

    m+=                             // m = list of characters that are adjacent to space
    s=" "                           // add space to the list, s = space character
  )
  |r                                // return r

Test

var solution = (a,b)=>[...a].map((l,i)=>{p=k[g="indexOf"](l);q=k[g](o=b[i]);r=r?l==s|o==s?~m[g](l)&&~m[g](o):(x=(p%28/2|0)-(q%28/2|0))<2&x>-2&(y=(p/28|0)-(q/28|0))<2&y>-2:0},r=k=`\`~1!2@3#4$5%6^7&8*9(0)-_=+  \t qQwWeErRtTyYuUiIoOpP[{]}\\|  aAsSdDfFgGhHjJkKlL;:'"
     zZ${m="xXcCvVbBnNmM,<"}.>/?`,m+=s=" ")|r
A = <input type="text" id="A" value="John Doe" /><br />
B = <input type="text" id="B" value="Jonh Deo" /><br />
<button onclick="result.textContent=solution(A.value,B.value)">Go</button>
<pre id="result"></pre>

user81655

Posted 2016-01-17T04:39:26.187

Reputation: 10 181

Wow, nice job! Although you might be able to save some bytes by lowercasing the input before mapping it (I think). Just a tip that might not work... – Mama Fun Roll – 2016-01-18T01:05:47.237

@ՊՓԼՃՐՊՃՈԲՍԼ The problem is that my solution works by putting the characters in a 28x4 grid. If I don't include the upper-case letters I would need to pad it to 28 characters wide anyway. :( It might be possible to generate the upper-case letters in the grid though. I'll check how many bytes that takes... Nope, too many. – user81655 – 2016-01-18T01:07:58.050