# Consecutive Distance Rating

We'll call the consecutive distance rating of an integer sequence the sum of the distances between consecutive integers. Consider 2 9 3 6 8 1.

2 9 3 6 8 1
<----5---->
<-2->
<--3-->


$$\2\$$ and $$\1\$$ are consecutive integers, and their distance apart in the sequence is $$\5\$$.
$$\2\$$ and $$\3\$$ are consecutive integers, and their distance apart in the sequence is $$\2\$$.
$$\9\$$ and $$\8\$$ are consecutive integers, and their distance apart in the sequence is $$\3\$$.
The consecutive distance rating is the sum of these distances: $$\10\$$.

## Challenge

Given a possibly empty list of positive, unique integers, find its consecutive distance rating.

## Format

You must accept a list of integers and output an integer in any reasonable format.

## Test cases

[] -> 0
[33] -> 0
[65 57 78 32 81 19 50 24 85 3 97 43 10 73] -> 0
[1 2] -> 1
[2 1] -> 1
[1 2 3] -> 2
[1 3 2] -> 3
[31 63 53 56 96 62 73 25 54 55 64] -> 26
[54 64 52 39 36 98 32 87 95 12 40 79 41 13 53 35 48 42 33 75] -> 67
[94 66 18 57 58 54 93 53 19 16 55 22 51 8 67 20 17 56 21 59] -> 107

• What about something like 3 2 2? Jun 15 '21 at 9:20
• @Ausername The input will only consist of unique integers. Jun 15 '21 at 9:21
• will the input contain only positive integers? Jun 15 '21 at 9:29
• @Wasif "Given a possibly empty list of positive, unique integers, find its consecutive distance rating." [my emphasis]
Jun 15 '21 at 9:34
• @Shaggy I'm going to say no, because the output format has been an integer from the beginning, and other languages may have had to compromise in bytes to satisfy that requirement. Jun 15 '21 at 23:49

# Python 2, 60 bytes

lambda l:sum(abs(l.index(x)-l.index(x+(x+1in l)))for x in l)


Try it online!

• There is a way of saving a few bytes by getting rid of the if ...
– ovs
Jun 15 '21 at 10:12
• @ovs Ah, right, nice one
– xnor
Jun 15 '21 at 10:19
• 1 in -> 1in
– user100690
Jun 15 '21 at 10:19

# J, 22 bytes

[:+/&,|@(#\-/#\)*1=-/~


Try it online!

Consider f 2 9 3 6 8 1:

• -/~ Table of differences:

0 _7 _1 _4 _6 1
7  0  6  3  1 8
1 _6  0 _3 _5 2
4 _3  3  0 _2 5
6 _1  5  2  0 7
_1 _8 _2 _5 _7 0

• 1= Where are they 1?

0 0 0 0 0 1
0 0 0 0 1 0
1 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0

• |@(#\-/#\) Table of absolute value of index differences:

0 1 2 3 4 5
1 0 1 2 3 4
2 1 0 1 2 3
3 2 1 0 1 2
4 3 2 1 0 1
5 4 3 2 1 0

• * Elementwise product of those tables:

0 0 0 0 0 5
0 0 0 0 3 0
2 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0

• [:+/&, Sum of that table flattened:

10


# Jelly, 8 bytes

iⱮ‘aạ¥JS


Try it online!

-1 byte thanks to Unrelated String!

## How it Works

iⱮ‘aạ¥JS - Main link. Takes a list L on the left
‘      - Increment all elements in L
Ɱ       - Over each incremented element:
i        -   Get its 1-based index in L, or 0 if not present
Call this list of indices I
J  - Indices of L; [1, 2, 3, ..., len(L)]
¥   - Last 2 links as a dyad f(I, J):
ạ    -   Absolute difference, element wise, between I and J
a     -   And; Where there are non-zeroes in I, replace the value with corresponding difference
S - Sum

• As much as I love to look at the aaạ, I'm not sure you need the triple dyad there, seeing as IaJ has the same pattern of zero/nonzero as I. (Funny bonus 8-byter: iⱮ‘oJạJS) Jun 16 '21 at 5:45
• @UnrelatedString Aww, now I have to redo my whole explanation :P Jun 16 '21 at 8:13

# 05AB1E, 8 bytes

ãʒÆ}kÆÄO


Try it online!

ã          # all pairs of integers from the input
ʒ }       # keep those where the following results in 1:
Æ        #   reduce by subtraction
k      # for each integer in each pair get the index in the input list
Æ     # reduce each pair of indices by subtraction
Ä    # take absolute value
O   # sum all distances


# Red, 88 77 bytes

func[b][s: 0 forall b[s: s + absolute offset? b any[find head b 1 + b/1 b]]s]


Try it online!

Uses @xnor's method - don't forget to upvote it!

• Is the /: an assign at index? Jun 15 '21 at 10:49
• @Razetime No, it's just indexing using the word (think variable) i. You can't just use b/i because it would mean select b 'i and the block b doesn't have a word i inside itself. Jun 15 '21 at 10:53
• @Razetime Assign at index is b/1: value. If the index is referred to by a word idx, we need to write b/:idx: value. Jun 15 '21 at 11:49

# JavaScript (Node.js), 60 bytes

n=>n.map((e,i)=>z+=(j=n.indexOf(e+1))+1?j>i?j-i:i-j:0,z=0)|z


Try it online!

• (j=n.indexOf(e+1))+1 ~> ~(j=n.indexOf(e+1)) Jun 15 '21 at 10:24
• (j=n.indexOf(e+1))<i?~j&&i-j:j-i is better still.
– Neil
Jun 15 '21 at 18:37

# R, 47 bytes

sum(abs(seq(a<-scan())-(b=match(a+1,a,0)))*!!b)


Try it online! with test wrapper stolen from pajonk's answer stolen from Kirill L's answer

• The test wrapper is actually by @Kirill ;-) Jun 15 '21 at 16:01
• Then why not merge our solutions? 45 bytes Jun 15 '21 at 16:09

# Ruby, 50 48 bytes

->a{r=-1;a.sum{((a.index(a[r+=1]+1)||r)-r).abs}}


Try it online!

Thanks @ovs for -2 bytes.

# R, 45 bytes

sum(abs(seq(a<-scan())-match(a+1,a)),na.rm=T)


Try it online!

Merged solutions: mine and @Dominic's.

Previous solution:

### R, 48 bytes

x=scan();*=match;sum(abs(x*x-(x+1)*x),na.rm=T)


Try it online!

• This can be 48 as a full program, making it the same length as my answer. However, now when there's \(x) syntax in R 4.1, but not available on TIO, I'm not sure anymore, which format to prefer... Jun 15 '21 at 14:04
• @Kirill I'll change it to the scan version, so the answers are comparable. Which format to prefer? I mainly post functions because I think it's easier to read that way and I mostly care about the internal algorithm not the wrapper or technicalities. Jun 15 '21 at 14:46
• I couldn't resist joining the competition... Jun 15 '21 at 15:24

# Brachylog, 15 bytes

sᶠ{↻h₂-ȧ1&b}ˢcl


Try it online!

sᶠ                 Find every substring of the input.
{        }ˢ      Keep only those for which
ȧ           the absolute value of
-            the difference of
↻h₂             the first and last elements
1          is 1,
&b        and remove their first elements.
c     Concatenate them,
l    and output their combined length.


# Charcoal, 15 bytes

Ｉ↨¹Ｅθ↔↨¹⁻⌕Ａθ⊕ικ


Try it online! Link is to verbose version of code. Explanation:

    θ           Input array
Ｅ            Map over elements
ι  Current value
⊕   Incremented
⌕Ａ     Find all (i.e. at most one) matches
θ    In input array
⁻       Vectorised subtract
κ Current index
↨¹        Take the sum
↔          Take the absolute value
↨¹             Take the sum
Ｉ               Cast to string
Implicitly print


Note that base 1 conversion is used to sum as this works on empty lists.

# Red, 129 bytes

func[a][s: 0
b: sort copy a
while[b/2][s: s + either b/2 - b/1 = 1[absolute(index? find a b/2)- index? find a b/1][0]b: next b]s]


Try it online!

sorts the array, and adds the index difference to s if pair of elements has an absolute difference of 1.

Not sure how to shorten the reuse of index? find, but I think it can be shortened. abs alias for absolute is not available, even in version 0.6.4.

# R, 48 bytes

?=diff;sum(abs(?o<-order(x<-scan()))*!1<?x[o])


Try it online!

• Wow, that's impressive! Great use of order! Jun 15 '21 at 14:42

# Excel, 52 bytes

=LET(x,A:A,SUM(IFERROR(ABS(ROW(x)-XMATCH(x-1,x)),)))


Input numbers in column A. For each number x in column A look for x-1. If found add the difference in rows between x and x-1.

# Vyxals, 13 bytes

›vḟv›ƛ&›[¥ε|0


Try it Online!

A port of the jelly answer, and I think the best I'm gonna get.

## Attempted port of Jonas, 21 bytes

Ẋƛ÷ε1=;?Lɾƛ?Lɾ-ȧ;f*∑½


Try it Online!

## Old version, 23 bytes

L²(⁰Ẋni÷ε1=[n6ḋ÷ε&+])¥½


Try it Online! I still think there's a bit more I can do.

## Older version, 28 bytes

L(x|L(←x i⁰niε1=[n←xε&+]))¥½


Try it Online!

This. Is. Horrible.

• Porting jelly somehow could save bytes Jun 15 '21 at 9:41

# MATL, 9 bytes

tQ!=&f-|s


### How it works

Consider input [2 9 3 6 8 1] as an example.

tQ   % Implicit input. Duplicate, add 1; element-wise
% STACK: [2 9 3 6 8 1], [3 10 4 7 9 2]
!    % Transpose
% STACK: [2 9 3 6 8 1], [3; 10; 4; 7; 9; 2]
=    % Test for equality (element-wise with broadcast)
% STACK: [0 0 1 0 0 0;
0 0 0 0 0 0;
0 0 0 0 0 0;
0 0 0 0 0 0;
0 1 0 0 0 0;
1 0 0 0 0 0]
&f   % Two-output find: row and column indices of nonzeros
% STACK: [6; 5; 1], [1; 2; 3]
-|   % Minus, absolute value (element-wise)
% STACK: [5; 3; 2]
s    % Sum. Implicit display
% STACK: 10


# Japt-mx, 1611 10 bytes

Inspired by xnor's solution.

VaWbU+WøUÄ


Try it

VaWbU+WøUÄ     :Implicit map of each U at 0-based index V in input array W
Va             :Absolute difference of V and
Wb           :  Index in W of
U+Wø       :    U + Does W contain
UÄ     :      U+1
:Implicit output of sum of resulting array


# Julia 1.0, 63 55 bytes

Inspired by the answer of xnor

Improved version, thanks @MarcMush:

!x=sum(abs,[(I=indexin)(i,x)-I(i+(i+1∈x),x) for i=x])


Try it online!

First version:

!x=sum(abs.([indexin(i,x)-indexin(i+(i+1 in x),x) for i in x]))


Try it online!

• 56 bytes Jun 17 '21 at 9:24
• -2 bytes by using * instead of I Try it online! Jun 18 '21 at 7:59

# Python 3, 91 bytes

def f(l):c=sorted(l);return sum(abs(l.index(x)-l.index(y))for x,y in zip(c,c[1:])if y-x==1)


Try it online!

• -1 by switching to Python 3.8.
– user100690
Jun 15 '21 at 10:27

# Wolfram Language (Mathematica), 42 bytes

Tr@Abs[s@@@Outer[s=#-#2&,#,#]~Position~1]&


Try it online!

Essentially a port of Jonah's J answer.

# Japt-x, 20 17 12 bytes

ã_ÎaZo)¥1©ZÊ


Try it

• saved 5 thanks to @Shaggy!
    ã_  - subsections passed trough
ÎaZo) * abs difference of 1st
and last element(then removed)
¥1    * == 1?
©ZÊ   * take lenght/else 0
-x flag to sum

• 15 bytes, or 14 bytes with the -x flag. Jun 16 '21 at 8:57
• 13 bytes Jun 16 '21 at 9:03
• 12 bytes; always forget A.ã() can take a function. I hate that I've just outgolfed myself! Jun 16 '21 at 9:06
• @Shaggy great! Didn't notice A.o removed the element, that's why it gave me wrong result! Jun 16 '21 at 9:33
• A.o(), without an argument, is the same as .pop() in JS. Jun 16 '21 at 17:35

# JavaScript (V8), 54 bytes

$=([o,...a])=>o?a.indexOf(o+1)+a.indexOf(o-1)+2+$(a):0


Try it online!