Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

In this challenge, you are passed two words: Your job is to determine if they are adjacent.

Two letters are adjacent if:

  1. They are the same letter, or
  2. They are lexicographically adjacent.

For example, J is adjacent to I,J, and K only. Z is not adjacent to A

Two words are adjacent if:

  1. They are the same length, and
  2. Each letter is adjacent to a unique letter in the other word.

For example, CAT is adjacent to SAD, as C>D, A>A, T>S.
FREE is not adjacent to GRRD (each E needs a letter to pair with)
.

Input/Output

You are passed two strings, and you need to return a truthy value if they are adjacent, otherwise a falsy value. You should return within a minute for all test cases below.

You can assume that the strings will only contain uppercase, alphabetic letters.

The two strings can be passed as a list, or concatenated, with or without quotes.

Test Cases

Truthy:

A A
A B
C B
DD CE
DE FC
ABCD BCDE
AACC DBBB
DJENSKE FDJCLMT
DEFGHIJKL HJLEHMCHE
IKLIJJLIJKKL LJLJLJLJLJHI
ACEGIKMOQSUWY BLNPRDFTVHXJZ
QQSQQRRQSTTUQQRRRS PQTTPPTTQTPQPPQRTP
ELKNSDUUUELSKJFESD DKJELKNSUELSDUFEUS

Falsy:

A C
A Z
B J
JK J
CC BA
CE D
DJENSKE GDJCLMT
DEFGHIJKL HJLHMCHE
IJKLIJKLKIJL LIJLLHJLJLLL 
AWSUKMEGICOQY RSHXBLJLNQDFZ
QQSQQRRQSTTUQQQRRS PQTTPPTTQTPQPPQRTT
ELKNSDUVWELSKJFESD DKJELKNSUELSDUFEUS

This is , so the shortest valid answer wins!

share|improve this question
    
Can the input have quotes around them, like "A A"? – TanMath Jan 25 at 3:04
    
Fixed test cases. Quotes are fine. – Nathan Merrill Jan 25 at 3:06
    
Will the be input only be uppercase? – TanMath Jan 25 at 3:24
    
You can assume that, yes. – Nathan Merrill Jan 25 at 3:24
    
I think you should mention in the challenge text that you allow defining the input strings with quotes. Would a single array of the form {'string1' 'string2'} be acceptable as well? – Luis Mendo Jan 25 at 21:57

12 Answers 12

CJam, 14 13 12 bytes

r$r$.-:)3,-!

Try it online! or verify all test cases at once.

Algorithm

Let s and t be two sorted words of the same length. For s and t to be lexicographically adjacent (LA), it is necessary and sufficient that all pairs of its corresponding characters are also LA.

The condition is clearly sufficient for all words, and necessary for words of length 1.

Now, assume s and t have length n > 1, and let a and b be the first characters, resp., of s and t.

Since s and t are LA, there is some bijective mapping φ between the characters of s and the characters of t such that x and φ(x) are LA for all x in s, meaning that |x - φ(x)| ≤ 1 for all x in s.

Let c = φ(a) and d = φ-1(b). Because of a's and b's minimality, a ≤ d (1) and b ≤ c (2).

Furthermore, since b and d, and a and c, and LA, d ≤ b + 1 (3) and c ≤ a + 1 (4).

By combining (1) and (3), and (2) and (4), we get that a ≤ d ≤ b + 1 and b ≤ c ≤ a + 1, from which we deduce that a - 1 ≤ b ≤ a + 1 and, therefore, that a and b are LA.

Now, by combining (1) and (4), and (2) and (3), we get that c - 1 ≤ a ≤ d and d - 1 ≤ b ≤ c, from which we deduce that c - 1 ≤ d ≤ c + 1 and, therefore that c and d are LA.

Thus, if we redefine φ by φ(a) = b and φ(d) = c, |x - φ(x)| ≤ 1 will still hold for all x in s and, in particular, for all x in s[1:].

This way, s[0] = a and t[0] = b, and s[1:] and t[1:], are LA.

Since s[1:] has length n - 1, this proves the necessity by induction.

Code

r               e# Read the first word from STDIN.
 $              e# Sort its characters.
  r             e# Read the second word from STDIN.
   $            e# Sort its characters.
    .-          e# Perform vectorized subtraction.
                e# This pushes either the difference of char codes of two
                e# corresponding characters or a character that has no does not
                e# correspond to a character in the other, shorter word.
      :)        e# Increment all results.
                e# In particular, this maps [-1 0 1] to [0 1 2].
        3,      e# Push the range [0 1 2].
          -     e# Perform set difference, i.e., remove all occurrences of 0, 1 and
                e# 2 from the array of incremented differences.
           !    e# Apply logical NOT. This gives 1 iff the array was empty iff
                e# all differences gave -1, 0 or 1.
share|improve this answer
    
The proof is nice and all, but it seems kind of too obvious to need a proof...what I really need is the code explained :P (I guess $ means sort?) – quintopia Jan 25 at 4:35
1  
It seems intuitive, but I figured why not. I've just finished the annotated code. – Dennis Jan 25 at 4:37
1  
You could stick closer to the original version with 2f/0-. Also at same count, :z2,-. – Peter Taylor Jan 25 at 7:07
2  
@PeterTaylor These fail when the inputs are of different lengths, since neither 2/ nor z work on a character. – Martin Ender Jan 25 at 11:00
1  
Gotta love solutions with a smiley face (with a dimpled chin!) – Doddy Jan 25 at 12:36

MATL, 10 12 17 bytes

c!S!odXl2<

This uses Dennis' approach: sort first and compare characters in matching positions.

Input is an array of strings, with the format {'CAT 'SAD'}.

Output is an array of zeros and ones. A result is truthy iff it contains all ones (this is agreed to be truthy).

Uses current release (10.2.1), which is earlier than this challenge.

Try it online!

Explanation:

c         % implicitly cell array of strings and convert to 2D char array. 
          % This pads with spaces if needed
!S!       % sort each row
o         % convert array from char to double
d         % difference between elements in the same column
Xl        % absolute value of each entry
2         % number literal
<         % each entry becomes 1 if smaller than 2 (adjacent letters), and 0 otherwise

Old approach, which accepts the strings as separate inputs: 12 bytes:

SiSXhcodXl2<

Try it online!

Explanation:

S         % implicitly input first string and sort
iS        % input second string and sort
Xh        % build cell array with these two strings
c         % convert to 2D char array. This pads with spaces if needed
o         % convert array from char to double
d         % difference between elements in the same column
Xl        % absolute value of each entry
2         % number literal
<         % each entry becomes 1 if smaller than 2 (adjacent letters), and 0 otherwise
share|improve this answer
1  
So the array [1 0 1] is falsy in MATL. That's useful. – Dennis Jan 25 at 19:56
    
@Dennis Isn't that falsey in other languages as well? In Matlab/Octave it works that way: all elements have to be nonzero – Luis Mendo Jan 25 at 21:51
1  
No. In fact, I don't know another language that behaves this way. In Python and CJam, e.g., arrays are truthy iff they're non-empty. In JavaScript and Ruby, e.g., all arrays are truthy. – Dennis Jan 26 at 0:26
    
@Dennis That's weird to my Matlab way of thinking. So in Python an array [0 0] is truthy? – Luis Mendo Jan 26 at 0:27
1  
Yes, because it has a positive length. That's usually annoying when golfing. – Dennis Jan 26 at 0:35

C, 233 bytes

#include <stdlib.h>
#include <string.h>
#define h char
#define r return
int c(void*a,void*b){r*(h*)a-*(h*)b;}int a(h*s,h*t){int l=strlen(s),m=strlen(t);if(l!=m)r 0;qsort(s,l,1,c);qsort(t,m,1,c);while(l--)if(abs(s[l]-t[l])>1)r 0;r 1;}

You can test it by saving that as adj.h and then using this adj.c file:

#include <stdio.h>
#include "adj.h"

int main() {
  char aa[] = "A", A[] = "A";
  char b[] = "A", B[] = "B";
  char cc[] = "C", C[] = "B";
  char d[] = "DD", D[] = "CE";
  char e[] = "DE", E[] = "FC";
  char f[] = "ABCD", F[] = "BCDE";
  char g[] = "AACC", G[] = "DBBB";
  char hh[] = "DJENSKE", H[] = "FDJCLMT";
  char i[] = "DEFGHIJKL", I[] = "HJLEHMCHE";
  char j[] = "IKLIJJLIJKKL", J[] = "LJLJLJLJLJHI";
  char k[] = "ACEGIKMOQSUWY", K[] = "BLNPRDFTVHXJZ";
  char l[] = "QQSQQRRQSTTUQQRRRS", L[] = "PQTTPPTTQTPQPPQRTP";
  char m[] = "ELKNSDUUUELSKJFESD", M[] = "DKJELKNSUELSDUFEUS";
  char n[] = "A", N[] = "C";
  char o[] = "A", O[] = "Z";
  char p[] = "B", P[] = "J";
  char q[] = "JK", Q[] = "J";
  char rr[] = "CC", R[] = "BA";
  char s[] = "CE", S[] = "D";
  char t[] = "DJENSKE", T[] = "GDJCLMT";
  char u[] = "DEFGHIJKL", U[] = "HJLHMCHE";
  char v[] = "IJKLIJKLKIJL", V[] = "LIJLLHJLJLLL";
  char w[] = "AWSUKMEGICOQY", W[] = "RSHXBLJLNQDFZ";
  char x[] = "QQSQQRRQSTTUQQQRRS", X[] = "PQTTPPTTQTPQPPQRTT";
  char y[] = "ELKNSDUVWELSKJFESD", Y[] = "DKJELKNSUELSDUFEUS";
  char *z[] = {aa,b,cc,d,e,f,g,hh,i,j,k,l,m,n,o,p,q,rr,s,t,u,v,w,x,y};
  char *Z[] = {A ,B,C ,D,E,F,G,H ,I,J,K,L,M,N,O,P,Q,R ,S,T,U,V,W,X,Y};

  for(int _=0;_<25;_++) {
    printf("%s %s: %s\r\n", z[_], Z[_], a(z[_], Z[_]) ? "true" : "false");
  }

  return 0;
}

Then compile using gcc adj.c -o adj. The output is:

A A: true
A B: true
C B: true
DD CE: true
DE CF: true
ABCD BCDE: true
AACC BBBD: true
DEEJKNS CDFJLMT: true
DEFGHIJKL CEEHHHJLM: true
IIIJJJKKKLLL HIJJJJJLLLLL: true
ACEGIKMOQSUWY BDFHJLNPRTVXZ: true
QQQQQQQRRRRRSSSTTU PPPPPPPQQQQRTTTTTT: true
DDEEEFJKKLLNSSSUUU DDEEEFJKKLLNSSSUUU: true
A C: false
A Z: false
B J: false
JK J: false
CC AB: false
CE D: false
DEEJKNS CDGJLMT: false
DEFGHIJKL HJLHMCHE: false
IIIJJJKKKLLL HIJJJLLLLLLL: false
ACEGIKMOQSUWY BDFHJLLNQRSXZ: false
QQQQQQQQRRRRSSSTTU PPPPPPQQQQRTTTTTTT: false
DDEEEFJKKLLNSSSUVW DDEEEFJKKLLNSSSUUU: false
share|improve this answer

Python 2, 90 bytes

lambda A,B:all(ord(b)-2<ord(a)<ord(b)+2for a,b in zip(sorted(A),sorted(B)))*len(A)==len(B)

Simple anonymous function, I have to have a separate check for length because zip will just contatenate. Theres a similar function in itertools (zip_longest) which would pad empty strings, but that would be quite costly.

Testing with

f=lambda A,B:all(ord(b)-2<ord(a)<ord(b)+2for a,b in zip(sorted(A),sorted(B)))*len(A)==len(B)

for case in testCases.split('\n'):
    print case, f(*case.split())

produces:

A A True
A B True
C B True
DD CE True
DE FC True
ABCD BCDE True
AACC DBBB True
DJENSKE FDJCLMT True
DEFGHIJKL HJLEHMCHE True
IKLIJJLIJKKL LJLJLJLJLJHI True
ACEGIKMOQSUWY BLNPRDFTVHXJZ True
QQSQQRRQSTTUQQRRRS PQTTPPTTQTPQPPQRTP True
ELKNSDUUUELSKJFESD DKJELKNSUELSDUFEUS True
A C False
A Z False
B J False
JK J False
CC BA False
CE D False
DJENSKE GDJCLMT False
DEFGHIJKL HJLHMCHE False
IJKLIJKLKIJL LIJLLHJLJLLL  False
AWSUKMEGICOQY RSHXBLJLNQDFZ False
QQSQQRRQSTTUQQQRRS PQTTPPTTQTPQPPQRTT False
ELKNSDUVWELSKJFESD DKJELKNSUELSDUFEUS False
share|improve this answer

JavaScript (ES6), 86 90 94

Edit 4 bytes saved thx @Neil
Edit 2 4 bytes save thx @Mwr247

(a,b)=>[...[...a].sort(),0].every((x,i)=>parseInt(x+([...b].sort()[i]||0),36)%37%36<2)

Note: adjacency check on a pair of letters. Take the pair as a base 36 number n, if the letters are equal, then n = a*36+a = a*37. If there is a difference of 1 then n = a*36+a+1 = a*37+1 or n = a*36+a-1 = a*37-1. So n % 37 must be 0, 1 or 36. And n%37%36 must be 0 or 1.

Note 2: the added '0' is used to ensure that a and b are the same length. It's shorter then a.length==b.length

F=(a,b)=>[...[...a].sort(),0].every((x,i)=>parseInt(x+([...b].sort()[i]||0),36)%37%36<2)

console.log=x=>O.textContent+=x+'\n';

testOK=[['A','A'],['A','B'],['C','B'],['DD','CE'],['DE','FC'],
['ABCD','BCDE'],['AACC','DBBB'],['DJENSKE','FDJCLMT'],
['DEFGHIJKL','HJLEHMCHE'],['IKLIJJLIJKKL','LJLJLJLJLJHI'],
['ACEGIKMOQSUWY','BLNPRDFTVHXJZ'],
['QQSQQRRQSTTUQQRRRS','PQTTPPTTQTPQPPQRTP'],
['ELKNSDUUUELSKJFESD','DKJELKNSUELSDUFEUS']];
testFail=[['A','C'],['A','Z'],['B','J'],['JK','J'],['CC','BA'],['CE','D'],
['DJENSKE','GDJCLMT'],['DEFGHIJKL','HJLHMCHE'],
['IJKLIJKLKIJL','LIJLLHJLJLLL',''],
['AWSUKMEGICOQY','RSHXBLJLNQDFZ'],
['QQSQQRRQSTTUQQQRRS','PQTTPPTTQTPQPPQRTT'],
['ELKNSDUVWELSKJFESD','DKJELKNSUELSDUFEUS']];

console.log('TRUE')
testOK.forEach(t=>{
  var a=t[0],b=t[1],r=F(a,b)
  console.log(r+' '+a+' '+b)
})  
console.log('FALSE')
testFail.forEach(t=>{
  var a=t[0],b=t[1],r=F(a,b)
  console.log(r+' '+a+' '+b)
})
<pre id=O></pre>

share|improve this answer
    
I think you can use '' in place of the first '0' since it doesn't change the value of the parse. – Neil Jan 25 at 20:00
    
@Neil right, and thinking again it's even better. I can use numeric 0 and 0. When adding to a string it become a string anyway, and numeric 0+0 is still 0 mod whatever – edc65 Jan 25 at 22:32
    
I believe you can collapse your b sort with the character reference: (a,b)=>[...[...a].sort(),0].every((x,i)=>parseInt(x+([...b].sort()[i]||0),36)%3‌​7%36<2) = 86 bytes – Mwr247 Feb 1 at 23:17
    
@Mwr247 clever. Thanks – edc65 Feb 2 at 7:21

JavaScript ES6, 117 bytes 116 bytes 111 bytes 109 bytes

(j,k)=>j.length==k.length&&(f=s=>[...s].sort())(j).every((c,i)=>Math.abs(c[h='charCodeAt']()-f(k)[i][h]())<2)

Test Cases

a=(j,k)=>j.length==k.length&&(f=s=>[...s].sort())(j).every((c,i)=>Math.abs(c[h='charCodeAt']()-f(k)[i][h]())<2);
// true
console.log('A A:', a('A', 'A'));
console.log('A B:', a('A', 'B'));
console.log('C B:', a('C', 'B'));
console.log('DD CE:', a('DD', 'CE'));
console.log('DE FC:', a('DE', 'FC'));
console.log('ABCD BCDE:', a('ABCD', 'BCDE'));
console.log('AACC DBBB:', a('AACC', 'DBBB'));
console.log('DJENSKE FDJCLMT:', a('DJENSKE', 'FDJCLMT'));
console.log('DEFGHIJKL HJLEHMCHE:', a('DEFGHIJKL', 'HJLEHMCHE'));
console.log('IKLIJJLIJKKL LJLJLJLJLJHI:', a('IKLIJJLIJKKL', 'LJLJLJLJLJHI'));
console.log('ACEGIKMOQSUWY BLNPRDFTVHXJZ:', a('ACEGIKMOQSUWY', 'BLNPRDFTVHXJZ'));
console.log('QQSQQRRQSTTUQQRRRS PQTTPPTTQTPQPPQRTP:', a('QQSQQRRQSTTUQQRRRS', 'PQTTPPTTQTPQPPQRTP'));
console.log('ELKNSDUUUELSKJFESD DKJELKNSUELSDUFEUS:', a('ELKNSDUUUELSKJFESD', 'DKJELKNSUELSDUFEUS'));

// false
console.log('A C:', a('A', 'C'));
console.log('A Z:', a('A', 'Z'));
console.log('B J:', a('B', 'J'));
console.log('JK J:', a('JK', 'J'));
console.log('CC BA:', a('CC', 'BA'));
console.log('CE D:', a('CE', 'D'));
console.log('DJENSKE GDJCLMT:', a('DJENSKE', 'GDJCLMT'));
console.log('DEFGHIJKL HJLHMCHE:', a('DEFGHIJKL', 'HJLHMCHE'));
console.log('IJKLIJKLKIJL LIJLLHJLJLLL:', a('IJKLIJKLKIJL', 'LIJLLHJLJLLL'));
console.log('AWSUKMEGICOQY RSHXBLJLNQDFZ:', a('AWSUKMEGICOQY', 'RSHXBLJLNQDFZ'));
console.log('QQSQQRRQSTTUQQQRRS PQTTPPTTQTPQPPQRTT:', a('QQSQQRRQSTTUQQQRRS', 'PQTTPPTTQTPQPPQRTT'));
console.log('ELKNSDUVWELSKJFESD DKJELKNSUELSDUFEUS:', a('ELKNSDUVWELSKJFESD', 'DKJELKNSUELSDUFEUS'));
<!-- results pane console output; see http://meta.stackexchange.com/a/242491 -->
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

Credit

  • @rink.attendant.6 shaved off 5 bytes
  • @user81655 shaved off 2 bytes
share|improve this answer
    
Can you use [...s] instead of s.split('')? – rink.attendant.6 Jan 25 at 6:08
    
@rink.attendant.6, yes, thank you. Still getting used to ES6 and that is one shortcut I need to remember! – Patrick Roberts Jan 25 at 6:18

Pyth, 37 31 bytes

&qZ-FmldK.zqY-m.a-FdCmmCkSdK[Z1

Try it online with all test cases!

Shaved off 6 bytes by using the shortened reduce notation (-F instead of .U-bZ)

Solution inspired by Dennis

First submission to codegolf!

Explanation

We can split the expression in two parts, which are compared with & to output the result. I'll try to explain by writing some pseudo-Python

First we check that the length of the two words are the same

mldK.z         lengths = map(lambda d: len(d), K=all_input())
.U-bZmldK.z    diff = reduce(lambda b, Z: b - Z, lengths)
qZ.U-bZmldK.z  diff == 0

Then, we apply Dennis' method:

       K                                                      # ['CAT', 'SAD']
 m   SdK           sort = map(lambda d: sorted(d), K)         # ['ACT', 'ADS']
 mmCkSdK           ascii = map(lambda d: sorted(d), map(lambda k: ord(k), K))
                                                              # [[65, 67, 84], [65, 68, 83]]
CmmCkSdK           zipped = zip(*ascii)                       # [[65, 65], [67, 68], [84, 83]]
m.U-bZd CmmCkSdK   map(lambda d: d[0] - d[1], zipped)         # [0, -1, 1]
m.a.U-bZd CmmCkSdK map(lambda d: abs(d[0] - d[1]), zipped)    # [0, 1, 1] 

We then use the - operator to filter all elements of that list that are not in [Z1 ([0, 1]), and check that the result is an empty list with qY

share|improve this answer

JavaScript (ES6), 87 bytes

(a,b)=>![...a].sort().some((d,i)=>(d[c='charCodeAt']()-([...b].sort()[i]||c)[c]())/2|0)

Uses a zero-centric symmetrical range check by dividing by the max value, then truncating with a bitwise "or" (|). Shorter than having to do two checks, or one with Math.abs().

share|improve this answer

C, 172 bytes

#define q(x)qsort(x,strlen(x),1,c)
c(x,y)char*x,*y;{return*x-*y;}main(a,v,w)char**v,*w,*a;{for(q(w=v[1]),q(a=v[2]);*w&&*a&&abs(*w-*a)<2;w++,a++);printf("%d",abs(*w-*a)<2);}

Test Cases

$ bash -x test.sh
+ bash -x test.sh
+ ./a.out A A
1+ ./a.out A B
1+ ./a.out C B
1+ ./a.out DD CE
1+ ./a.out DE FC
1+ ./a.out ABCD BCDE
1+ ./a.out AACC DBBB
1+ ./a.out DJENSKE FDJCLMT
1+ ./a.out DEFGHIJKL HJLEHMCHE
1+ ./a.out IKLIJJLIJKKL LJLJLJLJLJHI
1+ ./a.out ACEGIKMOQSUWY BLNPRDFTVHXJZ
1+ ./a.out QQSQQRRQSTTUQQRRRS PQTTPPTTQTPQPPQRTP
1+ ./a.out ELKNSDUUUELSKJFESD DKJELKNSUELSDUFEUS
1+ ./a.out A C
0+ ./a.out A Z
0+ ./a.out B J
0+ ./a.out JK J
0+ ./a.out CC BA
0+ ./a.out CE D
0+ ./a.out DJENSKE GDJCLMT
0+ ./a.out DEFGHIJKL HJLHMCHE
0+ ./a.out IJKLIJKLKIJL LIJLLHJLJLLL
0+ ./a.out AWSUKMEGICOQY RSHXBLJLNQDFZ
0+ ./a.out QQSQQRRQSTTUQQQRRS PQTTPPTTQTPQPPQRTT
0+ ./a.out ELKNSDUVWELSKJFESD DKJELKNSUELSDUFEUS
0++
share|improve this answer

PowerShell, 140 bytes

param($a,$b)(($a=[char[]]$a|sort).Count-eq($b=[char[]]$b|sort).Count)-and(($c=0..($a.Count-1)|%{+$a[$_]-$b[$_]}|sort)[0]-ge-1-and$c[-1]-le1)

Might be possible to get this shorter. It's not currently competitive with Python or JavaScript, but it uses a slightly different approach, so I figured I'd post it.

Explanation

This code is really confusing for someone not fluent in PowerShell, so I'll try to break it down into English as best I can...

We start with taking input param($a,$b) as normal.

The whole rest of the code is actually one statement, and can be broken as (...)-and(...) to test two Boolean statements with the -and operator.

The left-hand parens can be broken as (... -eq ...) to test equality of two objects. In this instance, the objects are the .Counts (that is, the length) of two new char-arrays. Each inner paren ($a=[char[]]$a|sort) takes the original input word, re-casts it as a char-array, then sorts it and re-saves back into the same variable. We do that for both $a and $b. The left-hand side thus verifies that the input words are the same length. If they are not the same length, this half of the outer Boolean statement will fail and False will be output.

Moving to the right-hand side, we're again testing two Boolean statements with (... -and ...). The left-hand side tests whether something is greater-than-or-equal-to negative 1 with -ge-1. The something is the zeroth-element of a constructed array $c, which is created by:

  • taking a range of the allowed indices 0..($a.count-1)
  • piped into a loop |%{...}
  • each iteration of the loop, we take the ASCII values of the indexed character in $a and subtract the ASCII value of the indexed character in $b
  • which is then |sorted by numerical value

The other side of the statement takes the maximal value $c[-1] of the array and ensures it's less-than-or-equal to 1 with -le1.

Thus, if the two input strings are indeed adjacent, the $c array will be something like @(-1,-1,-1...0,0,0...1,1,1). So the first element will be -1 and the last element will be 1. If they are not adjacent, the difference in ASCII values for a particular pair will either be < -1 or > 1, so this half of the outer Boolean test will fail, and False will be output.

Only if both sides pass will True be output, and the strings are therefore LA.

share|improve this answer

Rust, 269 264 bytes

fn a(w:&str,x:&str)->bool{if w.len()==x.len(){return{let mut c:Vec<char>=w.chars().collect();let mut d:Vec<char>=x.chars().collect();c.sort();d.sort();for(e,f)in c.iter().zip(d.iter()){if(((*e as u8)as f64)-((*f as u8)as f64)).abs()>1f64{return false}}true}}false}

Expanded:

fn are_adjacent(w: &str, x: &str)->bool{

    if w.len() == x.len(){

        return {

            let mut c : Vec<char> = w.chars().collect();
            let mut d : Vec<char> = x.chars().collect();

            c.sort();
            d.sort();

            for (e,f) in c.iter().zip(d.iter()){
                if (((*e as u8) as f64) - ((*f as u8) as f64)).abs() > 1f64{
                    return false
                } 
            }

            true
        }
    }

    false
}

Test Cases:

fn main(){
    assert_eq!(true,are_adjacent("A","B"));
    assert_eq!(true,are_adjacent("A","B"));
    assert_eq!(true,are_adjacent("C","B"));
    assert_eq!(true,are_adjacent("DD","CE"));
    assert_eq!(true,are_adjacent("DE","FC"));
    assert_eq!(true,are_adjacent("ABCD","BCDE"));
    assert_eq!(true,are_adjacent("AACC","DBBB"));
    assert_eq!(true,are_adjacent("DJENSKE","FDJCLMT"));
    assert_eq!(true,are_adjacent("DEFGHIJKL","HJLEHMCHE"));
    assert_eq!(true,are_adjacent("IKLIJJLIJKKL","LJLJLJLJLJHI"));
    assert_eq!(true,are_adjacent("ACEGIKMOQSUWY","BLNPRDFTVHXJZ"));
    assert_eq!(true,are_adjacent("QQSQQRRQSTTUQQRRRS","PQTTPPTTQTPQPPQRTP"));
    assert_eq!(true,are_adjacent("ELKNSDUUUELSKJFESD","DKJELKNSUELSDUFEUS"));

    assert_eq!(false,are_adjacent("A","C"));
    assert_eq!(false,are_adjacent("A","Z"));
    assert_eq!(false,are_adjacent("B","J"));
    assert_eq!(false,are_adjacent("JK","J"));
    assert_eq!(false,are_adjacent("CC","BA"));
    assert_eq!(false,are_adjacent("CE","D"));
    assert_eq!(false,are_adjacent("DJENSKE","GDJCLMT"));
    assert_eq!(false,are_adjacent("DEFGHIJKL","HJLHMCHE"));
    assert_eq!(false,are_adjacent("IJKLIJKLKIJL","LIJLLHJLJLLL"));
    assert_eq!(false,are_adjacent("AWSUKMEGICOQY","RSHXBLJLNQDFZ"));
    assert_eq!(false,are_adjacent("QQSQQRRQSTTUQQQRRS","PQTTPPTTQTPQPPQRTT"));
    assert_eq!(false,are_adjacent("QQSQQRRQSTTUQQQRRS","PQTTPPTTQTPQPPQRTT"));
    assert_eq!(false,are_adjacent("ELKNSDUVWELSKJFESD","DKJELKNSUELSDUFEUS"));
}
share|improve this answer

APL, 59 bytes (characters)

(61 if we have to supply the { and }, 63 with f←)

I'm not the greatest APLer, but it's just too much fun.

(0=+/2≤|¨∊-/{⎕av⍳⍵}¨(⍺{⌈/⍴¨⍺⍵}⍵)⍴¨⍺[⍋⍺]⍵[⍋⍵])∧=/⍴¨∊¨⍺⍵

=/⍴¨∊¨⍺⍵ are the inputs equally long?

and all of the below

(⍺{⌈/⍴¨⍺⍵}⍵)⍴¨⍺[⍋⍺]⍵[⍋⍵] sort both inputs and shape them to be as long as the longest of the two (they wrap around if you make them longer than they are)

|¨∊-/{⎕av⍳⍵} convert both char vectors to int vectors of their ascii values, do a vector subtraction and absolute all values

0=+/2≤ sum up values larger than or equal to two and check if the result is equal to 0

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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