# Is the word typeable with keys adjacent to each other?

I want you to make a program that takes one argument, a word (only lowercase letters), and outputs "Yes" if the word can be typed with adjacent keys on the keyboard (see the article) and "No" if the word can't be typed with adjacent letters.

Here's the keyboard layout used in this challenge:

 ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
| 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 |
└───┴───┴───┴───┴───┴───┴───┘


Remember: this is codegolf so the the shortest answer wins!

• Can we assume that the input consists only of letters? Can we assume that they are all given in a single case? Apr 3 '15 at 12:27
• I'm confused by this: "Two adjacent keys can max have 1.5 * the space of a key between them." Surely adjacent keys are actually adjacent, that is, they have no space between them, as in the linked puzzle?
– Luke
Apr 3 '15 at 12:51
• How to take argument? STDIN? A function? Apr 3 '15 at 16:58

# Pyth, 66

?"Yes".Am>2sm^-.uk2Cm.Dx"qwertyuiopasdfghjkl*zxcvbnm"b9.5dC,ztz"No


Try it here.

I was surprised to learn Pyth doesn't have a hypotenuse function, so this will likely be beat by a different language. I'll propose a hypotenuse function to Pyth, so this atrocity won't happen in the future.

### Explanation

I transform the keyboard into this:

┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
| 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 |
└───┴───┴───┴───┴───┴───┴───┘


Which I then encode as "qwertyuiopasdfghjkl*zxcvbnm". Then I used divmod with modulo 9.5 to figure out the 2D coordinates of every key. Then I compute distances between consecutive keys, and check if the squared distance < 2.

# CJam, 8375 74 bytes

l_1>]z["qwertyuiop asdfghjkl  zxcvbnm "[__B>]z+s_W%+_]zsf{\#)}:*"Yes""No"?


Try it online.

### Explanation

The general approach is to produce a big adjacency string containing every pair of adjacent keyboard characters and then check that every pair of adjacent input characters is contained in that string.

I'm quite happy with how I managed to build the adjacency string, which uses very simple and compact logic.

l_1>]z          "Read a line of input and create a list of every pair of
adjacent input characters. There will be a trailing element
of just the final character, but that's okay since any single
lowercase letter can be found in the adjacency string.";
["qwertyuiop asdfghjkl  zxcvbnm "
"^ Create the in-row forward adjacency string.";
[__B>]z         "Create the alternating-row forward adjacency string by
interleaving the in-row string with a substring of itself
starting with the middle row letters:
'q w e r t y u i o p   a s d f g h j k l  zxcvbnm '
+ ' a s d f g h j k l     z x c v b n m  '[no interleave here]
-----------------------------------------------------
'qawsedrftgyhujikolp   azsxdcfvgbhnjmk l  zxcvbnm '";
+s              "Append the alternating-row forward adjacency string to the
_W%+            "Append the reverse of the forward adjacency string (the
_]zs            "Double every character in the adjacency string so every
f{\#)}          "Map each pair of input characters to its 1-indexed location in
:*              "Calculate the product of each pair's location in the adjacency
string. This will be nonzero if and only if every pair of
input characters are in fact adjacent.";
"Yes""No"?      "If the product is nonzero, produce 'Yes'; otherwise, produce
'No'.";
"Implicitly print the result.";

• That's it, I'm learning CJam. Apr 4 '15 at 3:17
• @octatoan Looks like we'd both be better off learning Pyth, though. :P Apr 4 '15 at 11:26
• Haha, maybe in this case, yes. Apr 5 '15 at 4:47

# J, 77 bytes

NoYes{::~[:*/2>+/"1@(2|@-/\3(|,.<.@%~+-:@|)'qazwsxedcrfvtgbyhnujmikXolX'i.])


Usage:

   f=.NoYes{::~[:*/2>+/"1@(2|@-/\3(|,.<.@%~+-:@|)'qazwsxedcrfvtgbyhnujmikXolX'i.])

f 'redresser'
Yes
f 'qwergy'
No
f 'ppcg'
No


Method:

For every input letter I generate it's 2D coordinate (similar to the image in the question) based on it's index in the string 'qazwsxedcrfvtgbyhnujmikXolX'. For every pair of letters in the input I check if their coordinates' Manhattan-distance is smaller than 2. If all are, I output Yes, No otherwise (by abusing the  operator).

Try it online here.

• You forgot the letter p. Apr 3 '15 at 21:17
• @mbomb007 For none-found characters the i. operator returns the index of the last element + 1 so I can save 1 byte by not writing out p and still get it's correct index. Apr 3 '15 at 21:21

# CJam, 75

r(1\$+]z[1AB]"qwertyuiop asdfghjkl  zxcvbnm"f/:zSff+s_W%+f{\_|#}W&"No""Yes"?
`

Overlooked the Yes/No part... Fixed.