[Question]
  [
**This competition is over.**
The winner is CJam with 22 characters, beating [TwiNight](https://codegolf.stackexchange.com/users/6972/twinight)'s answer by one character. Congratulations [Dennis](https://codegolf.stackexchange.com/users/12012/dennis)!
An honorable mention goes to [Falko](https://codegolf.stackexchange.com/users/30372/falko), who went totally crazy with the free imports.
.
---
A while ago [I wanted to know](https://codegolf.stackexchange.com/questions/24696/optimizing-the-telephone-keypad) how I can out-type modern smartphones with my Nokia 3310, and while some answers were really good, I still can't keep up! Maybe I should take a different approach and simply not write any words that are awkward to type.
We'll call a piece of text easily typeable if no two consecutive letters are on the same button on the telephone keyboard, given the standard layout:
![Telephone Keyboard](https://i.stack.imgur.com/WYOQu.png)
---
## Your task
Your task is to write a program/function that accepts a string `s` from stdin/as a parameter and returns a truthy value if `s` is easily typeable and a falsy value otherwise. The input will only consist of lowercase letters and spaces and is guaranteed to be non-empty!
## Scoring
This is codegolf, so lowest character-count wins.
Import statements will not be counted towards your final score, so if you've ever wanted to use `std::set_symmetric_difference`, `liftM4`, or `itertools.combinations` in your code, now is the time!
**-3** if your source code is easily typeable, assuming everything that's not a letter is on button 0. After all, I might want to message your code to some friends!
## Testcases
Here are a few testcases to check if your code is working as intended:
```
"x" -> True
"aardvark" -> False
"ardvark" -> True
"flonk" -> False
"im codegolfing all day long" -> False
"i indulge in minimizing bytecount" -> True
"havent heard from you in a long time" -> False
"your silence was of undue permanence" -> True
"how are  you" -> False
"how are you" -> True
```
Happy golfing!
  
[Answer]
# Python 2 - ~~80, 68, 64, 61, 58, 50, 48, 45, 44~~ 42
Even though it's getting a little ridiculous now, I'll keep on making use of free library imports, even the `__builtin__` library:
```
from numpy import diff as D
from pprint import pprint as P
from __builtin__ import all as A
from __builtin__ import raw_input as I
from __builtin__ import bytearray as B
```
So only the following short line counts towards the code length:
```
P(A(D([(o-o/112-o/59)/3for o in B(I())])))
```
Credits to Markuz for the ideas regarding `input()`! These free-import challenges always introduce you to some lesser known libraries. ;)
---
Alternative using only the `operator` library (~~98, 83~~ 79):
```
from operator import ne as n
K=[(ord(c)-1-(c>'p')-(c>'w'))/3for c in input()]
print all(map(n,K[1:],K[:-1]))
```
I'll stop here. But you could further golf this version using `sys`, `pprint` and other libraries...
---
Alternative without libraries (105):
```
s=input()
n=lambda c:(ord(c)-1-(c>'p')-(c>'w'))/3
print all([n(s[i])!=n(s[i+1])for i in range(len(s)-1)])
```
[Answer]
# ~~Ruby~~ Regex (most popular flavours), ~~106~~ 83 bytes
Because regex
```
^(?!.*(  |[abc]{2}|[def]{2}|[ghi]{2}|[jkl]{2}|[mno]{2}|[p-s]{2}|[tuv]{2}|[w-z]{2}))
```
I've just cut the middleman (Ruby) and made this a pure-regex solution. Works in a lot of flavours and only finds a match if the string does not contain two consecutive characters on the same button.
[Answer]
# Bash+coreutils, 49
```
tr a-z $[36#8g7e9m4ddqd6]7778888|grep -Pq '(.)\1'
```
Returns an exit code of 1 for TRUE and 0 for FALSE:
```
$ for s in "x" "aardvark" "ardvark" "flonk" "im codegolfing all day long" "i indulge in minimizing bytecount" "havent heard from you in a long time" "your silence was of undue permanence" "how are  you" "how are you"; do echo "./3310.sh <<< \"$s\" returns $(./3310.sh <<< "$s"; echo $?)"; done
./3310.sh <<< "x" returns 1
./3310.sh <<< "aardvark" returns 0
./3310.sh <<< "ardvark" returns 1
./3310.sh <<< "flonk" returns 0
./3310.sh <<< "im codegolfing all day long" returns 0
./3310.sh <<< "i indulge in minimizing bytecount" returns 1
./3310.sh <<< "havent heard from you in a long time" returns 0
./3310.sh <<< "your silence was of undue permanence" returns 1
./3310.sh <<< "how are  you" returns 0
./3310.sh <<< "how are you" returns 1
$ 
```
[Answer]
## APL(Dyalog), ~~24~~ 23
```
~∨/2=/⌊¯13⌈.21-.31×⎕AV⍳⍞
```
---
```
∧/2≠/⌊¯13⌈.21-.31×⎕AV⍳⍞
```
**Explanation**
`⍞`: Takes string input from screen  
`⎕AV`: This is the atomic vector which is bascially a string of all characters APL recognizes, which of course include all lowercase letters (index 18~43) and space (index 5)  
`⍳`: `IndexOf` function. For many functions in APL that takes one or two scalar arguments, you can feed it an array in place of a scalar - APL will do the looping for you. So `⍳` returns a numeric array of indices.
`.21-.31×`: Times 0.31 and then subtract from 0.21. This is a little trick that maps letter on the same key (especially PQRS) to the same number (when rounded down to integers), except Z, which get mapped to its own group  
`¯13⌈`: `max` with -13. This brings Z back to the group with WXY  
`⌊`: Round down to integers  
`2≠/`: Pairwise-`≠`. Returns a boolean array for each consecutive pair.  
`∧/`: AND together all entries of the resulting array.
[Answer]
## Perl - 44
This is basically a Perl adaptation of @DigitalTrauma's [answer](https://codegolf.stackexchange.com/a/37578/29438) posted with his permission. Shaved off 2 characters thanks to @KyleStrand.
```
y/b-y/aadddgggjjjmmmpppptttzzz/;$_=!/(.)\1/
```
43 characters + 1 for `-p` flag. `y///` is the same as `tr///`. It prints `1` for true and nothing for false. I can post a detailed explanation if requested.
Example run:
```
perl -pE'y/b-y/aadddgggjjjmmmpppptttzzz/;$_=!/(.)\1/' <(echo "x")
```
---
## Perl - 81
```
$s=join"]{2}|[",qw(abc def ghi jkl mno p-s tuv w-z);say/^(?!.*(  |[$s]{2}))/?1:0
```
+1 for `-n` flag. It works by using `join` to create the regex (same one as [Martin's](https://codegolf.stackexchange.com/a/37578/29438)), which shaves of a few bytes.
Example run:
```
perl -nE'$s=join"]{2}|[",qw(abc def ghi jkl mno p-s tuv w-z);say/^(?!.*(  |[$s]{2}))/?1:0' <(echo "your silence was of undue permanence")
```
[Answer]
# CJam, ~~34~~ ~~31~~ ~~27~~ 22 characters
```
1l{'h-_9/-D+3/X\:X^*}/
```
[Try it online.](http://cjam.aditsu.net/ "CJam interpreter")
### Example run
```
$ cjam <(echo "1l{'h-_9/-D+3/X\:X^*}/") <<< 'aardvark'; echo
0
$ cjam <(echo "1l{'h-_9/-D+3/X\:X^*}/") <<< 'ardvark'; echo
66000
```
### How it works
```
1l                         " Push a R := 1 and read a line L from STDIN.                  ";
                           " Initialize X := 1. (implicit)                                ";
  {                  }/    " For each character C of L, do the following:                 ";
    'h-                    "     C -= 'h'                                                 ";
       _9/-D+3/            "     Y := (C - C / 9 + 13) / 3                                ";
               X\  ^*      "     R *= X ^ Y                                               ";
                 :X        "     X := Y                                                   ";
                           " Print R. (implicit)                                          ";
```
### Background
The core of the code consists in applying a map **F** to each character **C** of the input string so that the images of symbols on the same key match. I found the a suitable map by observing the following:
The map **T : C ↦ (C - 'h') + 13** transforms the string **S := " abcdefghijklmnopqrstuvxyz"** as follows:
```
[-59   6  7  8   9 10 11  12 13 14  15 16 17  18 19 20  21 22 23 24  25 26 27  28 29 30 31]
```
For the keys `0` to `6`, it would suffice to divide **T(C)** by **3**, but we have to apply some sort of correction to the characters in **s**, **t**, **v**, **y** and **z**.
The map **D : C ↦ (C - 'h') / 9** transforms the string **S** into the following array: 
```
[ -8   0  0  0   0  0  0   0  0  0   0  0  0   0  0  0   0  1  1  1   1  1  1   1  1  1  2]
```
This corrects the quotients of **s**, **t**, **v**, **y** and **z**, without affecting the others.
Finally, the map **F : C ↦ (T(C) - D(C)) / 3** transforms the string **S** as follows:
```
[-17   2  2  2   3  3  3   4  4  4   5  5  5   6  6  6   7  7  7  7   8  8  8   9  9  9  9]
```
All that rests is to compare the consecutive characters somehow. For that purpose, we XOR **F(C)** with the image of the previous character – for the first, we XOR **F(C)** with **1** (default value of the variable **X**), which has no preimage – and multiply all the results.
The product will be falsy if and only if one of the factors is zero, i.e., if and only if two consecutive characters have the same image by **F**.
[Answer]
# JavaScript - 159 156 bytes
```
function g(s){p=n=-1;for(i=0;i!=s.length;i++){p=n;n=s.charCodeAt(i);n-=97;if(n>17)n--;if(n>23)n--;if(p==-1)continue;if(~~(p/3)==~~(n/3))return 0;}return 1;}
```
Returns 1 for truthy and 0 for falsy.
If only I could get rid of the keywords.
[Answer]
# c, 74 bytes
```
main(c,d,r){for(;~(c=getchar());r*=d!=c/3,d=c/3)c-=--c/'p'*(c-'k')/7;c=r;}
```
Returns a non-zero exit status for TRUE and 0 for FALSE:
```
$ for s in "x" "aardvark" "ardvark" "flonk" "im codegolfing all day long" "i indulge in minimizing bytecount" "havent heard from you in a long time" "your silence was of undue permanence" "how are  you" "how are you"; do echo "./3310 <<< \"$s\" returns $(./3310 <<< "$s"; echo $?)"; done
./3310 <<< "x" returns 40
./3310 <<< "aardvark" returns 0
./3310 <<< "ardvark" returns 216
./3310 <<< "flonk" returns 0
./3310 <<< "im codegolfing all day long" returns 0
./3310 <<< "i indulge in minimizing bytecount" returns 72
./3310 <<< "havent heard from you in a long time" returns 0
./3310 <<< "your silence was of undue permanence" returns 232
./3310 <<< "how are  you" returns 0
./3310 <<< "how are you" returns 8
$ 
```
[Answer]
## Ruby 1.8, ~~89~~ ~~83~~ ~~81~~ 78 bytes
```
p$*[0].chars.map{|c|c=c[0];(c-c/?p-c/?w-1)/3}.each_cons(2).map{|a,b|a!=b}.all?
```
Here is another submission. To my shame, it beats the regex. :(
This takes the string via command-line argument and prints a boolean.
As for the algorithm, I'm shifting down the letters after `p` by one and after `z` by two, and then I check that there are no collisions after integer division by 3.
PS: This is the first time, that using Ruby 1.8 shortened the code (due to the shorter way to get character codes).
[Answer]
# Cobra - 80
```
def f(s)
    for c in s
        for x in 9,if' adgjmptw'[x]>c,break
        t,f=x,t<>x
    print f
```
[Answer]
# JavaScript (ES6) 66 ~~74~~
```
F=s=>[...s].every(c=>[...' adgjmptw'].map(x=>s+=c<x,w=s,s=0)|s!=w)
```
The inner loop find the group for each character. Conceptually is a 'reduce' but 'map' is shorter. The outer loop compare the group of consecutive chars and exits with false if they are equal.
**Test** In Firefox/Firebug console
```
;["x","aardvark","ardvark","flonk","im codegolfing all day long",
"i indulge in minimizing bytecount","havent heard from you in a long time",
"your silence was of undue permanence","how are  you","how are you"]
.forEach(x=>console.log(x + ' -> ' + F(x)))
```
*Output*
```
x -> true
aardvark -> false
ardvark -> true
flonk -> false
im codegolfing all day long -> false
i indulge in minimizing bytecount -> true
havent heard from you in a long time -> false
your silence was of undue permanence -> true
how are  you -> false
how are you -> true
```
[Answer]
# Perl, 83 bytes
```
$_=<>;chop;map{$_=ord;$_=($_-$_/112-$_/119-1)/3;die 0 if$l==$_;$l=$_}split//;die 1
```
Making heavy abuse of $\_ in Perl.
[Answer]
Two tasks are tricky in Python; detecting chains, and assigning the groups. Both can be assisted using numpy, but it is not in the standard library. 
# Python 2 (only standard library) - 59 chars function
```
from itertools import imap as M
from __builtin__ import bytearray as A, all as E
from operator import ne as D, not_ as N
from re import S, sub as X, search as F
# 68
#def f(s):
# g=[(n-n/115-n/61)/3for n in A(s)]
# return E(M(D,g,g[1:]))
# 67 with regex via regex
#f=lambda s:N(F(X('(\S)(.)',r'|[\1-\2]{2}','  acdfgijlmopstvwz'),s))
# 59 slightly optimized ordinal classifier and regex sequence detector
f=lambda s:N(F(r'(.)\1',A((n-n/23-n/30)/3for n in A(s)),S))
# 69 using itertools.groupby
#from itertools import groupby as G
#from __builtin__ import sum as S, len as L
#f=lambda s:N(S(L(A(g))-1for _,g in G((n-n/115-n/61)/3for n in A(s))))
```
# Python 2 (only standard library) - 53 chars stdin to exit value
Here I abuse the fact that `issubclass(bool,int)`, so changing `all()` to `any()` gets me a valid exit value, shaving off the `not()` from the return value. The removal of function overhead made the regex versions fall behind in size. 
```
from itertools import groupby as G, imap as M
from __builtin__ import bytearray as A, any as E
from __builtin__ import raw_input as I
from sys import exit as Q
from operator import eq as S
g=[(n-n/23-n/30)/3for n in A(I())]
Q(E(M(S,g,g[1:])))
```
[Answer]
# J - 42 char
Function taking string on the right.
```
*/@(2~:/\(I.4 3 4 1,~5#3){~(u:97+i.26)&i.)
```
First we map the alphabet (`u:97+i.26`) into the numbers 0 through 25, all other characters (including spaces) going to 26 (`i.`). Then we map (`{~`) the first three elements map to the first key, the next three to the next key, and so on through the keys of the phone pad, making sure to map the space/other punctuation to a separate key at the end. (`4 3 4 1,~5#3` is equal to `3 3 3 3 3 4 3 4 1` and `I.` turns that into a 27-item array where the first three are key 1, etc.) Then we check for pairwise inequality (`2~:/\`) and AND all the results together (`*/`).
```
   */@(2~:/\(I.4 3 4 1,~5#3){~(u:97+i.26)&i.) 'i indulge in minimizing bytecount'
1
   f =: */@(2~:/\(I.4 3 4 1,~5#3){~(u:97+i.26)&i.)
   f 'im codegolfing all day long'
0
   f '*/@(2~:/\(I.4 3 4 1,~5#3){~(u:97+i.26)&i.)'  NB. no -3 bonus :(
0
```
[Answer]
# Racket, 119
```
(define(f t)(for*/and([s(map ~a'(abc def ghi jkl mno pqrs tuv wxyz))][i s][j s])(not(regexp-match(format"~a~a"i j)t))))
```
Ungolfed (combinatoric regexing):
```
(define(f t)
  (for*/and([s (map ~a '(abc def ghi jkl mno pqrs tuv wxyz))]
            [i s]
            [j s])
    (not (regexp-match (format "~a~a" i j) t))))
```
[Answer]
# JavaScript - 152
Not a winner but I gave it a shot. Beats @Lozzaaa by 4 bytes as of posting time :)
```
function m(a){c="abc-def-ghi-jkl-mno-pqrstuv-wxyz";j=a.split("");for(z in j)if(j[z]=Math.floor(c.indexOf(j[z])/4),0!=z&&j[z-1]==j[z])return 0;return 1};
```
[Passes all the tests.](http://jsfiddle.net/jqqhso5o/)  
Takes advantage of JS's lack of typing to make a multi type array, and it takes advantage of indexOf returning -1 for space support.
Usage:
```
m("string here")
```
Assumes lowercase alphabetic characters and spaces only. Returns 1 for true, 0 for false.
Maybe if I knew ES6 I could try the second challenge...
[Answer]
## ES6, JavaScript ~~89~~ 70 characters
I know its not a winner because when coming to handy operations like getting ASCII value of character, JS puts a lot of bloat (`.charCodeAt()`).
```
N=s=>[...s].every(c=>l-(l=(c.charCodeAt()-(c>"r")-(c>"y")-1)/3|0),l=1)
```
Run it in Web Console of latest Firefox.
Usage:
```
N("testing if this works")
```
The function returns either true or false.
**EDIT**: Golfed a lot using the `[...x].every` trick learned from @edc65 (Thanks!)
I will try to golf it more :)
[Answer]
# GML (Game Maker Language), 149
```
s=argument0p=n=-1for(i=0;i<string_length(s);i++){p=n;n=string_char_at(s,i)-97;x=n>17&&n--;x=n>23&&n--‌​;if(!p)x=1if(!(p/3)=!(n/3))x=0}show_message(x)
```
[Answer]
# Python 3 - 152 chars
Not the shortest I could go, but it'll do for now
```
k=['abc','def','ghi','jkl','mno','pqrs','tuv','wxyz',' ']
x=input()
l=2>1
for i in range(len(x)-1):
 for j in k:
  if x[i+1] in j and x[i] in j:l=1>2
print(l)
```
]