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
- Standard loopholes apply.
- This is code-golf, so the code with the fewest bytes (in each language) wins.
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
27 Answers 27
-
1\$\begingroup\$ There is a way of saving a few bytes by getting rid of the
if... \$\endgroup\$ovs– ovs2021年06月15日 10:12:38 +00:00Commented Jun 15, 2021 at 10:12 -
\$\begingroup\$ @ovs Ah, right, nice one \$\endgroup\$xnor– xnor2021年06月15日 10:19:36 +00:00Commented Jun 15, 2021 at 10:19
-
\$\begingroup\$
1 in->1in\$\endgroup\$user100690– user1006902021年06月15日 10:19:48 +00:00Commented Jun 15, 2021 at 10:19
Jelly, 8 bytes
iⱮ‘aạ\JS
-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
-
\$\begingroup\$ As much as I love to look at the
aaạ, I'm not sure you need the triple dyad there, seeing asIaJhas the same pattern of zero/nonzero asI. (Funny bonus 8-byter:iⱮ‘oJạJS) \$\endgroup\$Unrelated String– Unrelated String2021年06月16日 05:45:02 +00:00Commented Jun 16, 2021 at 5:45 -
1\$\begingroup\$ @UnrelatedString Aww, now I have to redo my whole explanation :P \$\endgroup\$2021年06月16日 08:13:17 +00:00Commented Jun 16, 2021 at 8:13
J, 22 bytes
[:+/&,|@(#\-/#\)*1=-/~
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 01=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
05AB1E, 8 bytes
ãʒÆ}kÆÄO
ã # 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
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
R, 45 bytes
sum(abs(seq(a<-scan())-match(a+1,a)),na.rm=T)
Merged solutions: mine and @Dominic's.
Previous solution:
R, 48 bytes
x=scan();`*`=match;sum(abs(x*x-(x+1)*x),na.rm=T)
-
\$\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\$Kirill L.– Kirill L.2021年06月15日 14:04:23 +00:00Commented Jun 15, 2021 at 14:04 -
1\$\begingroup\$ @Kirill I'll change it to the
scanversion, 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\$pajonk– pajonk2021年06月15日 14:46:56 +00:00Commented Jun 15, 2021 at 14:46 -
1\$\begingroup\$ I couldn't resist joining the competition... \$\endgroup\$Dominic van Essen– Dominic van Essen2021年06月15日 15:24:12 +00:00Commented Jun 15, 2021 at 15:24
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
-
1\$\begingroup\$
(j=n.indexOf(e+1))+1~>~(j=n.indexOf(e+1))\$\endgroup\$Arnauld– Arnauld2021年06月15日 10:24:38 +00:00Commented Jun 15, 2021 at 10:24 -
\$\begingroup\$
(j=n.indexOf(e+1))<i?~j&&i-j:j-iis better still. \$\endgroup\$Neil– Neil2021年06月15日 18:37:31 +00:00Commented Jun 15, 2021 at 18:37
Red, (削除) 88 (削除ここまで) 77 bytes
func[b][s: 0 forall b[s: s + absolute offset? b any[find head b 1 + b/1 b]]s]
Uses @xnor's method - don't forget to upvote it!
-
\$\begingroup\$ Is the
/:an assign at index? \$\endgroup\$Razetime– Razetime2021年06月15日 10:49:53 +00:00Commented Jun 15, 2021 at 10:49 -
\$\begingroup\$ @Razetime No, it's just indexing using the word (think variable)
i. You can't just useb/ibecause it would meanselect b 'iand the blockbdoesn't have a wordiinside itself. \$\endgroup\$Galen Ivanov– Galen Ivanov2021年06月15日 10:53:00 +00:00Commented Jun 15, 2021 at 10:53 -
\$\begingroup\$ @Razetime Assign at index is
b/1: value. If the index is referred to by a wordidx, we need to writeb/:idx: value. \$\endgroup\$Galen Ivanov– Galen Ivanov2021年06月15日 11:49:35 +00:00Commented Jun 15, 2021 at 11:49
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.
Vyxal s, 13 bytes
›vḟv›ƛ&›[\ε|0
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
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
This. Is. Horrible.
-
\$\begingroup\$ Porting jelly somehow could save bytes \$\endgroup\$2021年06月15日 09:41:10 +00:00Commented Jun 15, 2021 at 9:41
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
Brachylog, 15 bytes
sf{↻h2-ȧ1&b}scl
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.
Japt -mx, (削除) 16 (削除ここまで) (削除) 11 (削除ここまで) 10 bytes
Inspired by xnor's solution.
VaWbU+WøUÄ
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])
First version:
!x=sum(abs.([indexin(i,x)-indexin(i+(i+1 in x),x) for i in x]))
-
-
1\$\begingroup\$ -2 bytes by using
*instead ofITry it online! \$\endgroup\$MarcMush– MarcMush2021年06月18日 07:59:37 +00:00Commented Jun 18, 2021 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)
-
1\$\begingroup\$ -1 by switching to Python 3.8. \$\endgroup\$user100690– user1006902021年06月15日 10:27:55 +00:00Commented Jun 15, 2021 at 10:27
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]
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.
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.
Japt -x, (削除) 20 17 (削除ここまで) 12 bytes
ã_ÎaZo)1円©ZÊ
- 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
-
-
-
-
\$\begingroup\$ @Shaggy great! Didn't notice A.o removed the element, that's why it gave me wrong result! \$\endgroup\$AZTECCO– AZTECCO2021年06月16日 09:33:38 +00:00Commented Jun 16, 2021 at 9:33
-
1\$\begingroup\$
A.o(), without an argument, is the same as.pop()in JS. \$\endgroup\$Shaggy– Shaggy2021年06月16日 17:35:29 +00:00Commented Jun 16, 2021 at 17:35
Wolfram Language (Mathematica), 42 bytes
Tr@Abs[s@@@Outer[s=#-#2&,#,#]~Position~1]&
Essentially a port of Jonah's J answer.
Thunno, \$ 24 \log_{256}(96) \approx \$ 19.75 bytes
2zPgAu-1=keez0AhEeAuADES
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
Octave, 54 bytes
@(a){[x j]=sort(a)
sum(abs(j(d=diff(x)<2)-j([!1 d])))}
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 arrayxalong with the ordering indicesj;diff(x)<2condition (==1) for the consecutive adjacent numbers;j(diff(x)<2)andj([false diff(x)<2)]this subsetting allows to find and match the pairs;absandsumis trivial.
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
-
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 final0to-(meaning-$$which is always zero)... \$\endgroup\$Dominic van Essen– Dominic van Essen2024年07月17日 11:31:08 +00:00Commented Jul 17, 2024 at 11:31 -
\$\begingroup\$ @DominicvanEssen Wow! Those are cool observations, I coulda sworn I used the save lol. Thanks!! \$\endgroup\$Conor O'Brien– Conor O'Brien2024年07月17日 18:10:17 +00:00Commented Jul 17, 2024 at 18:10
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
}
3 2 2? \$\endgroup\$