4
\$\begingroup\$

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
\$\endgroup\$
  • 3
    \$\begingroup\$ "a recent head injury caused by a stampeding herd of downgoats" ಠ_______ಠ \$\endgroup\$ – Downgoat Feb 2 '16 at 4:04
  • \$\begingroup\$ Well, I mean, he did post some pretty badly-golfed answers... \$\endgroup\$ – Mama Fun Roll Feb 2 '16 at 4:09
  • \$\begingroup\$ @Downgoat I'll get you for what you did to him. \$\endgroup\$ – workoverflow Mar 18 '18 at 10:55
1
\$\begingroup\$

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>

\$\endgroup\$
  • \$\begingroup\$ 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... \$\endgroup\$ – Mama Fun Roll Jan 18 '16 at 1:05
  • \$\begingroup\$ @ՊՓԼՃՐՊՃՈԲՍԼ 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. \$\endgroup\$ – user81655 Jan 18 '16 at 1:07

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.