30
\$\begingroup\$

This competition is over.

The winner is CJam with 22 characters, beating TwiNight's answer by one character. Congratulations Dennis!

An honorable mention goes to Falko, who went totally crazy with the free imports.

.


A while ago I wanted to know 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


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!

\$\endgroup\$
11
  • \$\begingroup\$ Are two consecutive spaces bad? \$\endgroup\$ Sep 10, 2014 at 15:31
  • \$\begingroup\$ @MartinBüttner yes! Should probably add a testcase for that. \$\endgroup\$
    – Flonk
    Sep 10, 2014 at 15:31
  • 9
    \$\begingroup\$ I have a nokia dumbphone, if I press space twice, I get a number 0. \$\endgroup\$
    – overactor
    Sep 10, 2014 at 19:21
  • 1
    \$\begingroup\$ Related question: devise a phone keyboard layout which maximises some score based on how easily typeable the most frequently occurring words are. \$\endgroup\$
    – justinpc
    Sep 11, 2014 at 8:30
  • 1
    \$\begingroup\$ @jpcooper like the two mentioned here? I've used 8pen and really like it, except that my phone glass heats up using it (from the contact, not from CPU activity) and the coefficient of friction makes it hard to use for long inputs. Using the s-pen on the Note 3 is so much easier :) \$\endgroup\$
    – Eben
    Sep 11, 2014 at 19:38

19 Answers 19

27
\$\begingroup\$

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)])
\$\endgroup\$
12
  • \$\begingroup\$ And once again we independently post the same solution in Ruby and Python. Looks like this time you're winning though. ;) ... Can't you also save 4 bytes, by assigning ord(c) to a variable (say o) and then subtracting c/112 and c/119 instead of the booleans? \$\endgroup\$ Sep 10, 2014 at 16:10
  • \$\begingroup\$ @MartinBüttner: Yeah, once in a while Python can beat Ruby. Unfortunately I can't assign variables within lambda expressions that easily. With [(o-1-o/112-o/119)/3for o in map(ord,s)] I end up with 80 bytes again. \$\endgroup\$
    – Falko
    Sep 10, 2014 at 16:19
  • \$\begingroup\$ Ah I see. Sick new improvement though! :D \$\endgroup\$ Sep 10, 2014 at 16:26
  • \$\begingroup\$ Very impressive. And you could still save 3 bytes with from sys import argv as s, using s[1] instead of input() \$\endgroup\$
    – Markuz
    Sep 10, 2014 at 16:54
  • \$\begingroup\$ importing input from __builtin__ as well is actually even better :D saving yet another Byte. \$\endgroup\$
    – Markuz
    Sep 10, 2014 at 18:24
20
\$\begingroup\$

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.

\$\endgroup\$
4
  • \$\begingroup\$ Can't you put that {2} outside the alternation, saving 22 bytes? \$\endgroup\$ Sep 11, 2014 at 8:28
  • 1
    \$\begingroup\$ @NiettheDarkAbsol unfortunately not, because then it can pick different alternatives for the two repetitions. \$\endgroup\$ Sep 11, 2014 at 8:29
  • \$\begingroup\$ Aah, of course. I knew there was a reason XD \$\endgroup\$ Sep 11, 2014 at 8:29
  • \$\begingroup\$ Kudos for a readable, understandable, golfed solution! \$\endgroup\$ Sep 14, 2014 at 22:33
12
\$\begingroup\$

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
$ 
\$\endgroup\$
4
  • \$\begingroup\$ Very nice! This would be 46 characters in Perl: perl -pE'y/a-z/aaadddgggjjjmmmpppptttwwww/;$_=!/(.)\1/' <(echo "x") It prints 1 for true and nothing for false. \$\endgroup\$
    – hmatt1
    Sep 10, 2014 at 18:24
  • \$\begingroup\$ @chilemagic Go ahead and post the perl answer :). Don't forget to add one to the score for using the -p command-line parameter (as per code-golf conventions). \$\endgroup\$ Sep 11, 2014 at 0:19
  • \$\begingroup\$ I thought I could find a way to shorten aaadddgggjjjmmmpppptttwwww but I've given up. \$\endgroup\$ Sep 11, 2014 at 20:57
  • 2
    \$\begingroup\$ @BenJackson I figured out a way. We can actually use a string of any distinct characters - 11122233344455566667778888 will do. By base 36 encoding the first 19 digits of this number, we can save 1 char! \$\endgroup\$ Sep 11, 2014 at 21:17
9
\$\begingroup\$

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.

\$\endgroup\$
9
  • \$\begingroup\$ I was going to post something like this, but you beat me to it. Damn Z key! You can still shave 1 char off by saying ∧/2≠/ (all consecutive pairs are typed on different keys) instead of ~∨/2=/ (no consecutive pair is typed on the same key.) APL FTW!!! \$\endgroup\$
    – Tobia
    Sep 10, 2014 at 21:53
  • \$\begingroup\$ Yes tkx. I was thinking "I should be able to shave off 1 char here why can't I do it OMGGGG!!!" But I got to go to class so I just post what I have. And, yes, DAMN Z KEY. Unfortunately I am on my phone so I can't edit it until later \$\endgroup\$
    – TwiNight
    Sep 10, 2014 at 23:12
  • \$\begingroup\$ And I made a conscious thought about De Morgan's Laws and still can't figure it out... How dumb \$\endgroup\$
    – TwiNight
    Sep 10, 2014 at 23:16
  • 1
    \$\begingroup\$ Good luck texting this to your friends. ;) \$\endgroup\$ Sep 10, 2014 at 23:34
  • \$\begingroup\$ This looks very interesting. Is there any way to try this code without purchasing a Dyalog APL interpreter? The online interpreter I usually use doesn't seem to understand the dialect... \$\endgroup\$
    – Dennis
    Sep 11, 2014 at 6:08
7
\$\begingroup\$

Perl - 44

This is basically a Perl adaptation of @DigitalTrauma's answer 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), 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")
\$\endgroup\$
3
  • \$\begingroup\$ Couldn't you shave off two characters from the Perl solution by letting a and z remain untransliterated? y/b-y/aadddgggjjjmmmpppptttzzz/;$_=!/(.)\1/ Also, this won't handle spaces, will it? \$\endgroup\$ Sep 12, 2014 at 7:53
  • \$\begingroup\$ ...oh, right, two spaces in a row is already two identical characters in a row. My bad. \$\endgroup\$ Sep 12, 2014 at 7:59
  • \$\begingroup\$ @KyleStrand nice call on letting a and z remain the same. Updated answer! \$\endgroup\$
    – hmatt1
    Sep 12, 2014 at 17:12
6
\$\begingroup\$

CJam, 34 31 27 22 characters

1l{'h-_9/-D+3/X\:X^*}/

Try it online.

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.

\$\endgroup\$
4
  • \$\begingroup\$ I think the byte (Not character) count for this one is 54 \$\endgroup\$
    – user16402
    Sep 10, 2014 at 19:23
  • \$\begingroup\$ @Optimizer I think the code-golf tag wiki says bytes \$\endgroup\$
    – user16402
    Sep 10, 2014 at 19:26
  • \$\begingroup\$ This answer no longer contains non-ASCII characters. \$\endgroup\$
    – Dennis
    Sep 11, 2014 at 5:57
  • \$\begingroup\$ @professorfish The tag wiki is just the default. If the challenge specifies characters, it's characters. \$\endgroup\$ Sep 11, 2014 at 7:47
4
\$\begingroup\$

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.

\$\endgroup\$
5
  • \$\begingroup\$ At least you can get rid of some whitespaces and if's :) 141 : function g(s){p=n=-1;for(i=0;i<s.length;i++){p=n;n=s.charCodeAt(i)-97;n>17&&n--;n>23&&n--;if(~p)continue;if(~(p/3)==~(n/3))return 0}return 1} \$\endgroup\$
    – Optimizer
    Sep 10, 2014 at 17:07
  • \$\begingroup\$ You use lots of interesting things in your answer that I haven't seen before. I usually write in C++ but I thought I'd give JS a shot as it's quicker to test online. \$\endgroup\$
    – Lozzaaa
    Sep 10, 2014 at 17:16
  • \$\begingroup\$ I only found this place today and thought I'd give it a shot. My next try will be superior :D \$\endgroup\$
    – Lozzaaa
    Sep 10, 2014 at 17:22
  • \$\begingroup\$ You can make your code a character shorter by replacing the != in the for loop by a <. \$\endgroup\$
    – ProgramFOX
    Sep 10, 2014 at 17:48
  • \$\begingroup\$ Yes that was in Optimizer's optimisations :) what's the etiquette on using people's suggestions in my answer? Now that there is another JavaScript entry that I can beat by accepting those modifications. \$\endgroup\$
    – Lozzaaa
    Sep 14, 2014 at 20:45
4
\$\begingroup\$

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
$ 
\$\endgroup\$
7
  • \$\begingroup\$ You can save 3 bytes by changing your while to for(;c=~getchar();d=c/3), and another byte by changing your first if to a ?: operator. \$\endgroup\$
    – Allbeert
    Sep 10, 2014 at 18:35
  • \$\begingroup\$ @Allbeert - Thanks. The parenthesis around c=getchar() are required though because ~ has higher precedence than =. Still, I'll take the other two bytes :) \$\endgroup\$ Sep 10, 2014 at 19:25
  • \$\begingroup\$ For the last bit, does something like exit(d!=c/3); instead of if(d==c/3)exit(0); work? \$\endgroup\$
    – user16402
    Sep 10, 2014 at 19:25
  • \$\begingroup\$ @professorfish That would make the exit at that point unconditional, which I don't want \$\endgroup\$ Sep 10, 2014 at 19:26
  • \$\begingroup\$ You can save one character with r*=d^c/3 \$\endgroup\$
    – Alchymist
    Sep 12, 2014 at 9:43
3
\$\begingroup\$

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).

\$\endgroup\$
3
\$\begingroup\$

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
\$\endgroup\$
3
\$\begingroup\$

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
\$\endgroup\$
4
  • \$\begingroup\$ You can do .some instead of every. Because even if it fails one time, the answer is falsy. \$\endgroup\$
    – Optimizer
    Sep 11, 2014 at 8:14
  • \$\begingroup\$ @Optimizer some and every are interchangeble, fiddling with the conditions. But here simply put some instead of every will not work, try it. \$\endgroup\$
    – edc65
    Sep 11, 2014 at 8:23
  • \$\begingroup\$ Hmm, you are right. I need to understand your logic first. \$\endgroup\$
    – Optimizer
    Sep 11, 2014 at 8:26
  • \$\begingroup\$ Please don't mind if I start using this [...s].every trick in my golfs :) \$\endgroup\$
    – Optimizer
    Sep 11, 2014 at 14:32
2
\$\begingroup\$

Perl, 83 bytes

$_=<>;chop;map{$_=ord;$_=($_-$_/112-$_/119-1)/3;die 0 if$l==$_;$l=$_}split//;die 1

Making heavy abuse of $_ in Perl.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ As you can observe, is allowed to pass command-line parameters to the interpreter, just you have to count the extra parameters. (The bare minimum needed to access the code, -e in Perl, is free.) 71 characters alternative with command-line parameters: perl -nlaF -e 'map{$_=ord;$_=($_-$_/112-$_/119-1)/3;die 0 if$l==$_;$l=$_}@F;die 1'. \$\endgroup\$
    – manatwork
    Sep 10, 2014 at 16:41
  • \$\begingroup\$ @manatwork you don't need the -l, but it looks good! \$\endgroup\$
    – hmatt1
    Sep 10, 2014 at 16:45
  • \$\begingroup\$ @chilemagic, I just tried to reproduce the original code's equivalent, so I added -l as replacement for chop. But of course, you are right. \$\endgroup\$
    – manatwork
    Sep 10, 2014 at 17:04
  • \$\begingroup\$ Thanks @manatwork, I didn't even think to making use of the command line options for Perl. \$\endgroup\$
    – mcreenan
    Sep 10, 2014 at 18:26
2
\$\begingroup\$

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:])))
\$\endgroup\$
2
\$\begingroup\$

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
\$\endgroup\$
2
\$\begingroup\$

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))))
\$\endgroup\$
1
\$\begingroup\$

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.
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...

\$\endgroup\$
3
  • \$\begingroup\$ "if only ... " - Did you see my answer ? :P \$\endgroup\$
    – Optimizer
    Sep 10, 2014 at 21:18
  • \$\begingroup\$ Yes I did. I don't know ES6 (yet), sadly. However, this was interesting to make. \$\endgroup\$
    – DankMemes
    Sep 10, 2014 at 21:19
  • \$\begingroup\$ Yeah, your solution using an interesting approach. \$\endgroup\$
    – Optimizer
    Sep 10, 2014 at 21:21
1
\$\begingroup\$

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 :)

\$\endgroup\$
0
\$\begingroup\$

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)
\$\endgroup\$
0
\$\begingroup\$

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)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.