35
\$\begingroup\$

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.

Rules

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
caird coinheringaahing
50.9k11 gold badges133 silver badges364 bronze badges
asked Jun 15, 2021 at 9:17
\$\endgroup\$
7
  • \$\begingroup\$ What about something like 3 2 2? \$\endgroup\$ Commented Jun 15, 2021 at 9:20
  • 1
    \$\begingroup\$ @Ausername The input will only consist of unique integers. \$\endgroup\$ Commented Jun 15, 2021 at 9:21
  • \$\begingroup\$ will the input contain only positive integers? \$\endgroup\$ Commented Jun 15, 2021 at 9:29
  • 2
    \$\begingroup\$ @Wasif "Given a possibly empty list of positive, unique integers, find its consecutive distance rating." [my emphasis] \$\endgroup\$ Commented Jun 15, 2021 at 9:34
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ Commented Jun 15, 2021 at 23:49

27 Answers 27

11
\$\begingroup\$

Python 2, 60 bytes

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

Try it online!

answered Jun 15, 2021 at 10:00
\$\endgroup\$
3
  • 1
    \$\begingroup\$ There is a way of saving a few bytes by getting rid of the if ... \$\endgroup\$ Commented Jun 15, 2021 at 10:12
  • \$\begingroup\$ @ovs Ah, right, nice one \$\endgroup\$ Commented Jun 15, 2021 at 10:19
  • \$\begingroup\$ 1 in -> 1in \$\endgroup\$ Commented Jun 15, 2021 at 10:19
9
\$\begingroup\$

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
answered Jun 15, 2021 at 9:24
\$\endgroup\$
2
  • \$\begingroup\$ 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) \$\endgroup\$ Commented Jun 16, 2021 at 5:45
  • 1
    \$\begingroup\$ @UnrelatedString Aww, now I have to redo my whole explanation :P \$\endgroup\$ Commented Jun 16, 2021 at 8:13
8
\$\begingroup\$

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
    
answered Jun 15, 2021 at 11:28
\$\endgroup\$
6
\$\begingroup\$

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
answered Jun 15, 2021 at 9:51
\$\endgroup\$
6
\$\begingroup\$

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

answered Jun 15, 2021 at 15:23
\$\endgroup\$
2
  • \$\begingroup\$ The test wrapper is actually by @Kirill ;-) \$\endgroup\$ Commented Jun 15, 2021 at 16:01
  • \$\begingroup\$ Then why not merge our solutions? 45 bytes \$\endgroup\$ Commented Jun 15, 2021 at 16:09
6
\$\begingroup\$

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!

answered Jun 15, 2021 at 12:58
\$\endgroup\$
3
  • \$\begingroup\$ 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... \$\endgroup\$ Commented Jun 15, 2021 at 14:04
  • 1
    \$\begingroup\$ @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. \$\endgroup\$ Commented Jun 15, 2021 at 14:46
  • 1
    \$\begingroup\$ I couldn't resist joining the competition... \$\endgroup\$ Commented Jun 15, 2021 at 15:24
5
\$\begingroup\$

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!

answered Jun 15, 2021 at 10:18
\$\endgroup\$
2
  • 1
    \$\begingroup\$ (j=n.indexOf(e+1))+1 ~> ~(j=n.indexOf(e+1)) \$\endgroup\$ Commented Jun 15, 2021 at 10:24
  • \$\begingroup\$ (j=n.indexOf(e+1))<i?~j&&i-j:j-i is better still. \$\endgroup\$ Commented Jun 15, 2021 at 18:37
5
\$\begingroup\$

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!

answered Jun 15, 2021 at 10:39
\$\endgroup\$
3
  • \$\begingroup\$ Is the /: an assign at index? \$\endgroup\$ Commented Jun 15, 2021 at 10:49
  • \$\begingroup\$ @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. \$\endgroup\$ Commented Jun 15, 2021 at 10:53
  • \$\begingroup\$ @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. \$\endgroup\$ Commented Jun 15, 2021 at 11:49
5
\$\begingroup\$

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.

answered Jun 15, 2021 at 14:16
\$\endgroup\$
0
4
\$\begingroup\$

Charcoal, 15 bytes

I↨1Eθ↔↨1−⌕Aθ⊕ικ

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

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

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

answered Jun 15, 2021 at 10:03
\$\endgroup\$
4
\$\begingroup\$

R, 48 bytes

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

Try it online!

answered Jun 15, 2021 at 14:01
\$\endgroup\$
1
  • \$\begingroup\$ Wow, that's impressive! Great use of order! \$\endgroup\$ Commented Jun 15, 2021 at 14:42
4
\$\begingroup\$

Vyxal s, 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*∑1⁄2

Try it Online!

Old version, 23 bytes

L2(0Ẋni÷ε1=[n6ḋ÷ε&+])1円⁄2

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

Older version, 28 bytes

L(x|L(←x i0niε1=[n←xε&+]))1円⁄2

Try it Online!

This. Is. Horrible.

answered Jun 15, 2021 at 9:30
\$\endgroup\$
1
  • \$\begingroup\$ Porting jelly somehow could save bytes \$\endgroup\$ Commented Jun 15, 2021 at 9:41
4
\$\begingroup\$

MATL, 9 bytes

tQ!=&f-|s

Try it online! Or verify all test cases.

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
answered Jun 15, 2021 at 21:35
\$\endgroup\$
4
\$\begingroup\$

Brachylog, 15 bytes

sf{↻h2-ȧ1&b}scl

Try it online!

sf Find every substring of the input.
 { }s Keep only those for which
 ȧ the absolute value of
 - the difference of
 ↻h2 the first and last elements
 1 is 1,
 &b and remove their first elements.
 c Concatenate them,
 l and output their combined length.
answered Jun 16, 2021 at 6:05
\$\endgroup\$
4
\$\begingroup\$

Japt -mx, (削除) 16 (削除ここまで) (削除) 11 (削除ここまで) 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
answered Jun 15, 2021 at 22:10
\$\endgroup\$
4
\$\begingroup\$

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!

answered Jun 16, 2021 at 14:18
\$\endgroup\$
2
  • \$\begingroup\$ 56 bytes \$\endgroup\$ Commented Jun 17, 2021 at 9:24
  • 1
    \$\begingroup\$ -2 bytes by using * instead of I Try it online! \$\endgroup\$ Commented Jun 18, 2021 at 7:59
3
\$\begingroup\$

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!

answered Jun 15, 2021 at 9:46
\$\endgroup\$
1
  • 1
    \$\begingroup\$ -1 by switching to Python 3.8. \$\endgroup\$ Commented Jun 15, 2021 at 10:27
3
\$\begingroup\$

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.

answered Jun 15, 2021 at 10:22
\$\endgroup\$
3
\$\begingroup\$

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.

answered Jun 15, 2021 at 14:21
\$\endgroup\$
3
\$\begingroup\$

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
answered Jun 15, 2021 at 13:52
\$\endgroup\$
5
  • \$\begingroup\$ 15 bytes, or 14 bytes with the -x flag. \$\endgroup\$ Commented Jun 16, 2021 at 8:57
  • \$\begingroup\$ 13 bytes \$\endgroup\$ Commented Jun 16, 2021 at 9:03
  • \$\begingroup\$ 12 bytes; always forget A.ã() can take a function. I hate that I've just outgolfed myself! \$\endgroup\$ Commented Jun 16, 2021 at 9:06
  • \$\begingroup\$ @Shaggy great! Didn't notice A.o removed the element, that's why it gave me wrong result! \$\endgroup\$ Commented Jun 16, 2021 at 9:33
  • 1
    \$\begingroup\$ A.o(), without an argument, is the same as .pop() in JS. \$\endgroup\$ Commented Jun 16, 2021 at 17:35
2
\$\begingroup\$

Wolfram Language (Mathematica), 42 bytes

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

Try it online!

Essentially a port of Jonah's J answer.

answered Jun 15, 2021 at 19:39
\$\endgroup\$
2
\$\begingroup\$

JavaScript (V8), 54 bytes

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

Try it online!

answered Jun 19, 2021 at 8:13
\$\endgroup\$
2
\$\begingroup\$

Thunno, \$ 24 \log_{256}(96) \approx \$ 19.75 bytes

2zPgAu-1=keez0AhEeAuADES

Attempt This Online!

Explanation

2zP # All pairs in the input
 g # Filtered by:
 Au- # Does the difference
 1= # Equal 1?
k # End filter
 e # Map over the list:
 e # Map over the pair
 z0Ah # Get the index in the input
 E # End both maps
e # Map over this list:
 AuAD # Get the absolute difference
 E # End map
 S # Sum this list
 # Implicit output
answered Feb 17, 2023 at 11:20
\$\endgroup\$
2
\$\begingroup\$

Octave, 54 bytes

@(a){[x j]=sort(a)
sum(abs(j(d=diff(x)<2)-j([!1 d])))}

Try it online!

My idea was to sum the absolute values of the differences of ordering indices of the elements while filtering away the lone elements (there is a possible similarity to one R answer, but I haven't check it in details).

  • [x j]=sort(a) outputs the sorted array x along with the ordering indices j;
  • diff(x)<2 condition (==1) for the consecutive adjacent numbers;
  • j(diff(x)<2) and j([false diff(x)<2)] this subsetting allows to find and match the pairs;
  • abs and sum is trivial.
answered Jul 16, 2024 at 18:03
\$\endgroup\$
2
\$\begingroup\$

Nibbles, (削除) 17 (削除ここまで) 16 nibbles ((削除) 8.5 (削除ここまで) 8 bytes)

+.$??@+$~!=$?_@-

Attempt This Online! Corresponds to the 8 bytes 8c 3f f4 83 0c 03 f5 49. -0.5 bytes thanks to @Dominic van Essen, for observing that the if/else ? saves the value used for the conditional as additional context, allowing me to use my longer solution while avoiding the explicit save!

Previous 8.5 byte solution: +.$*!=?@$;?@+$~`$.

Explanation

This is similar in execution to @caird coinheringaahin g's 8-byte Jelly answer.

+.$??@+$~!=$?_@-
+.$??@+$~!=$?_@-$$ # (with implicit argument)
 .$ # map over each element X in the input:
 +$~ # compute X+1
 ?@ # and its index in the original list
 ? # if it is positive (aka found):
 # then that value is saved in $
 != # so we take the absolute difference of...
 $ # that saved index
 ?_@ # and the index of X in the original list
 -$$ # otherwise, return X-X, aka 0

Old Explanation

+.$*!=?@$;?@+$~`$
+.$*!=?@$;?@+$~`$$ # (with implicit argument)
 .$ # map over each element X in the input:
 != # absolute difference of...
 ? # ...index of
 +$~ # X+1
 @ # in the original list input
 ; # (save this index for later)
 ?@$ # ..and the current index (1-based)
 * # multiplied by
 `$ # the sign of
 $ # the index of X+1 we saved (which is 0 when not found)
+ # sum resulting list
answered Jul 17, 2024 at 4:43
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Nice! Your 9.5 byter can be reduced to 8 bytes by leaving-out the save (;), which isn't used, letting you change ;$_ to _@ (by moving up one DeBruijn index), and swapping the final 0 to - (meaning -$$ which is always zero)... \$\endgroup\$ Commented Jul 17, 2024 at 11:31
  • \$\begingroup\$ @DominicvanEssen Wow! Those are cool observations, I coulda sworn I used the save lol. Thanks!! \$\endgroup\$ Commented Jul 17, 2024 at 18:10
1
\$\begingroup\$

Uiua, 12 bytes

/+⌵/-⍉⊚=1⊞-.

Try it!

/+⌵/-⍉⊚=1⊞-.
 ⊞-. # difference table
 ⊚=1 # coordinates of ones
 ⍉ # transpose
 ⌵/- # absolute difference of columns
/+ # sum
answered Nov 18, 2023 at 21:11
\$\endgroup\$
1
\$\begingroup\$

Scala 3, 122 bytes

Golfed version. Attempt This Online!

l=>l.flatMap(x=>l.indexOf(x+(if(l.contains(x+1))1 else 0))match{case -1=>None;case i=>Some(Math.abs(l.indexOf(x)-i))}).sum

Ungolfed version. Attempt This Online!

def calculate(list: List[Int]): Int = {
 list
 .flatMap(x =>
 list.indexOf(x + (if (list.contains(x + 1)) 1 else 0)) match {
 case -1 => None
 case i => Some(Math.abs(list.indexOf(x) - i))
 }
 )
 .sum
}
answered Nov 19, 2023 at 0:01
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.