Group adjacent values
K, 43 38
{d:(x;0N,x;y)@\:&~~':y;d[1]:(1_d 1),*|x;+d}
{a::*|x;+@[(x;{x,a};y)@\:&~~':y;1;1_]}
.
k){a::*|x;+@[(x;{x,a};y)@\:&~~':y;1;1_]}[1 2 3 4 5 6 7;9 9 15 15 15 30 9]
1 2 9
3 5 15
6 6 30
7 7 9
Explanation
The function takes two vectors, x
and y
, as input
a::*|x
takes the last value of x
and assigns it to a
.
&~~':y
returns a list of indices where the y
vector changes:
k){&~~':y}[1 2 3 4 5 6 7;9 9 15 15 15 30 9]
0 2 5 6
(x;{x,a};y)
creates a three element list containing
1) the x
vector,
2) the function {x,a}
which takes an input variable x
(not to be confused with the x
vector which was input into the original function) and appends a
, and
3) the y
vector
(x;{x,a};y)@\:&~~':y
takes this three element list and applies the indices to each element
so that we return the x
vector at those indices, the indices with a
appended, and the y
vector at those indices
k){b::*|x;(x;{x,b};y)@\:&~~':y}[1 2 3 4 5 6 7;9 9 15 15 15 30 9]
1 3 6 7
0 2 5 6 7
9 15 30 9
@[(x;{x,a};y)@\:&~~':y;1;1_]
takes the matrix we've created and drops the first element of the second row.
k){b::*|x;@[(x;{x,b};y)@\:&~~':y;1;1_]}[1 2 3 4 5 6 7;9 9 15 15 15 30 9]
1 3 6 7
2 5 6 7
9 15 30 9
+
then transposes the result
k){b::*|x;+@[(x;{x,b};y)@\:&~~':y;1;1_]}[1 2 3 4 5 6 7;9 9 15 15 15 30 9]
1 2 9
3 5 15
6 6 30
7 7 9
Mathematica, 40 47 / 40
Updated to handle the new rules:
#~Riffle~{##}[[-1,1]]&@@@Split[#,#2-#=={1,0}&]&
Example of use:
#~Riffle~{##}[[-1,1]]&@@@Split[#,#2-#=={1,0}&]& @
{{1, 9}, {2, 9}, {3, 9}, {4, 15}, {5, 15}, {6, 30}, {7, 9}, {12, 9}}
{{1, 3, 9}, {4, 5, 15}, {6, 6, 30}, {7, 7, 9}, {12, 12, 9}}
Or, since "There are no restrictions on input/output format":
#[[1,1]]|Last@#&/@Split[#,#2-#=={1,0}&]&
Which when used as above outputs:
{1 | {3, 9}, 4 | {5, 15}, 6 | {6, 30}, 7 | {7, 9}, 12 | {12, 9}}
J, 53 48 43
Explicit version (43 chars):
f=.4 :'|:(#&y,{.@:#&x)(1&,,:,&1)2(-.@=/\)x'
Tacit version (48 chars):
(|:@((#{.)~,{.@]#{:@[)[:(1&,,:,&1)2&(-.@=/\)@{:)
Ungolfed version:
(|:@(({.@[#~]),{:@[#~{.@])((1&,),:,&1)@(-.@(0&=)@(2&(-/\)@{:)))
Maybe not the best way, but had a lot of fun golfing it down.
1 2 3 4 5 6 7 f 9 9 15 15 15 30 9
or
(...) 1 2 3 4 5 6 7,:9 9 15 15 15 30 9
1 2 9
3 5 15
6 6 30
7 7 9