# Collapse consecutive integers

### Challenge

Given a strictly positive strictly ascending integer list L and an integer 3 ≤ N ≤ length of L, replace the middle integers of L's consecutive integer runs of length ≥ N with a single dash -.

### Rules

• Horizontal whitespace is irrelevant.
• You may optionally preserve the introducer, separator, and terminator characters of your language's default list format. See Format examples, below.

### Data examples

All these examples use L = 3 5 6 7 8 10 11 12 14 16 17 18 19 20 21 22 24.

N = 33 5 - 8 10 - 12 14 16 - 22 24

N = 43 5 - 8 10 11 12 14 16 - 22 24

N = 53 5 6 7 8 10 11 12 14 16 - 22 24

N = 83 5 6 7 8 10 11 12 14 16 17 18 19 20 21 22 24

### Format examples

For the inputs
L = [3,5,6,7,8,10,11,12,14,16,17,18,19,20,21,22,24] and N = 3
all the below lines are examples of valid responses, both as actual lists and as strings:

[3,5,"-",8,10,"-",12,14,16,"-",22,24]
[3,5,-,8,10,-,12,14,16,-,22,24]
[3,5-8,10-12,14,16-22,24]
3,5-8,10-12,14,16-22,24


The same applies with other list formats, like {1 2 3} and (1; 2; 3) etc. In doubt? Ask!

• Is it necessary to use - or are we allowed to use a different symbol? – miles Jul 26 '17 at 5:57
• @miles Will a different symbol save you bytes? – Adám Jul 26 '17 at 6:41
• I am thinking of using infinity _ so that I might remain operating on numeric arrays in J. – miles Jul 26 '17 at 6:45
• @miles Ah, yeah, why don't you go ahead and do that, but make a not about it, and if you can be bothered, write the (I assume much longer) boxed solution with '-'. You might also be able to stringify everything before inserting dashes, no? – Adám Jul 26 '17 at 7:03
• Is the following valid? [3,5,-8,10,-12,14,16,-22,24] (this seems to be the format that makes the most sense in terms of types) – Leaky Nun Jul 26 '17 at 9:02

# Python 2, 132 115 bytes

-17 bytes thanks to Leaky Nun

x,n=input()
o=[]
i=1
while x:
t=x[0]
while[t+i]==x[i:i+1]:i+=1
o+=[[t,'-',t+i-1],x[:i]][i<n];x=x[i:];i=1
print o


Try it online!

• 115 bytes – Leaky Nun Jul 26 '17 at 9:03
• Would while t+i==x[i]: work? Or am I missing something? – Zacharý Jul 26 '17 at 19:19
• @Zacharý it would break if i get higher than the size of x – Rod Jul 26 '17 at 19:37

# Jelly,  26 25  23 bytes

-2 bytes thanks to Erik the Outgolfer (by bringing the if statement into the main link)

Ḣ;Ṫj”-
IỊ¬1;œṗ⁸¹ÇL<¥?€F


A dyadic link returning a list in the [3,5,"-",8,10,"-",12,14,16,"-",22,24] format.

Try it online! (footer separates with spaces, to print the data example format).

### How?

Ḣ;Ṫj”- - Link 1, format a run: list R
Ṫ    -     tail
;     -     concatenate
”- -     literal '-'
j   -     join

IỊ¬1;œṗ⁸¹ÇL<¥?€F - Main link: list L, number N
I                - incremental differences
Ị               - insignificant? (<=1)
¬              - not
1;            - prepend a 1
⁸         - chain's left argument, L
œṗ          - partition (L) at truthy indexes
€  - for €ach row, R, in L:
?   -   if:
L      -     length of R
<     -     is less than N?
¹        -   then: identity - do nothing, yields R
Ç       -   else: call the last link (1) as a monad with argument  R
F - flatten into a single list


# Pyth, 23 bytes

sm?<ldvzd[hd\-ed).ga=hZ


Try it online

### How it works

sm?<ldvzd[hd\-ed).ga=hZkQ

Q    autoinitialized to eval(input())
.g          group by k ↦
=hZ          Z += 1, returning new value (Z is autoinitialized to 0)
a   k         absolute difference with k
m                           map d ↦
?                              if
ld                               length of d
<  vz                             less than eval(z) (z is autoinitialized to input())
d                        then d
[hd\-ed)                else [d[0], '-', d[-1]]
s                            concatenate


# Japt, 24 bytes

óÈÄ¥YÃ®l ¨V?Zv +'-+Zo :Z


Try it online!

### Explanation

óÈ   Ä ¥ YÃ ®   l ¨ V?Zv +'-+Zo :Z
óXY{X+1==Y} mZ{Zl >=V?Zv +'-+Zo :Z}   Ungolfed
Implicit: U = input array, V = input integer
óXY{      }                           Group U into runs such that for each pair X, Y:
X+1==Y                              Y is exactly 1 more than X.
mZ{                   }   Map each run Z to:
Zl >=V?                  If Z has at least V items:
Zv     Zo           Z.unshift() and Z.pop() (the first and last items)
+'-+             joined with a hyphen.
:       Otherwise:
Z        just Z.
Implicit: output result of last expression


# Retina, 101 bytes

\d+
$* \b(1+) (?=1\1\b)$1X
TX \b((X)|1)+\b(?=.*¶(?<-2>1)+(?(2)(?!))11)
TX-
-1+(?=-)|¶1+

1+
$.&  Try it online! Takes the space-separated list L on the first line and the integer N on the second line. Explanation: The first stage converts the input to unary. The second stage changes the space between consecutive integers to an X. The third stage looks for runs of consecutive integers whose length is less than N and changes their Xs back to spaces. The fourth stage changes the Xs to - (this was 3 bytes shorter than using -s in the first place.) The fifth stage deletes all integers still left in the middle of a run, as well as N, while the final stage converts back to decimal. # Mathematica, 128 bytes (s=#2;t=r=1;While[t<Length@s,If[s[[t+1]]-s[[t]]==1,r++,r=1];If[r==#,s[[t-#+3;;t]]="-";r--];t++];s//.{b___,a_,a_,c___}:>{b,a,c})&  input [3,{3,5,6,7,8,10,11,12,14,16,17,18,19,20,21,22,24}] output {3, 5, "-", 8, 10, "-", 12, 14, 16, "-", 22, 24} Try it online! • here – Leaky Nun Jul 26 '17 at 8:52 # APL, 38 bytes {∊⍺{⍺>≢⍵:⍵⋄2⌽'-',2↑¯1⌽⍵}¨⍵⊂⍨1,1≠2-⍨/⍵}  # PHP 7, 137 136 134 117 110 108 bytes for($a=$argv,$i=2;$n=$a[$i++];$k<$a[1]||array_splice($a,$i,$k-2,"-"))for($k=print"$n ";$a[$i+$k]-++$k==$n;);  Takes L from first argument, list elements after that. Run with -nr or try it online. Replace $L=($a=$argv) with $a=$argv,$L= (+1 byte) for PHP<7. breakdown for($a=$argv,$i=2;              # import input
$n=$a[$i++]; # loop$n through list elements
$k<$a[1]||                      # 3. if streak length ($k) is >=L ($a[1])
array_splice($a,$i,$k-2,"-") # then replace with "-" ) for($k=print"$n "; # 1. print element and space$a[$i+$k]-++$k==$n;);           # 2. find consecutive numbers


# Ruby, 68 bytes

->n,l{l.slice_when{|x,y|x<y-1}.map{|x|x[n-1]?x.minmax.uniq*?-:x}*?,}


Returns a string like for example 3,5-8,10-12,14,16-22,24.

Try it online!

# J, 40 bytes

;@((](,_,{:)/)^:(<:#)&.>]<;.1~1,1<}.-}:)


Try it online!

Uses _ instead of -.

## Explanation

;@((](,_,{:)/)^:(<:#)&.>]<;.1~1,1<}.-}:)  Input: integer N (LHS), array L (RHS)
}:   Curtail L
-     Subtract elementwise to get the increments
1<        Test if greater than 1
1,          Prepend a 1
]                 Get L
<;.1~            Partition L into boxes using the previous array
& >                  Operate on each box (partition) with N
^:                            If
#                          The length of the partition
<:                           Is greater than or equal to N
(](     )/)                                Reduce (right-to-left) it using
{:                                     Tail
_,                                       Prepend _
,                                         Append to LHS
&.>                    Box the result
;@                                        Raze - join the contents in each box


# Jelly, 3937 36 bytes

IỊṣ0;€1ṁ@
ÇL€<Ɠ¬TịÇḊ€Ṗ€F;€”-FyµŒgQ€F


Try it online

Takes the array via arguments, and the integer via STDIN. The TIO link uses the footer ÇG so the output is space-separated.

How? (Array: a, Integer: n)

(f)
IỊṣ0;€1ṁ@
I          Deltas of a
Ị         Insignificant (x -> abs(x)<=1) applied to each element
ṣ0       Split at occurrences of 0.
;€1    Append 1 to each element
ṁ@  a shaped like that
ÇL€<Ɠ¬TịÇḊ€Ṗ€F;€”-FyµŒgQ€F
Ç                            f
L€                          Length of each element
<Ɠ                        x -> x < n applied to each element
¬                       Logical not of each element (because Jelly doesn't have <= nor >= atoms)
T                      Nonzero indexes
ịÇ                    Index f at those indexes
Ḋ€Ṗ€                x -> x[1:-1] applied to each element
F               Flatten
;€”-           Append a hyphen to each element
F          Flatten
y         Translate (replaces all elements to be deleted with a hyphen)
Œg      Group runs of equal elements
Q€    Uniquify each element (make runs of hyphens one hypen)
F   Flatten, yet again.


I'm guessing I fell ... flat on this one.

# JavaScript (ES6), 126 119 bytes

(e,c)=>{for(i=0,R='';i<e.length;R+=(R&&',')+(u-m>=c?m+'-'+--u:e.slice(z,i))){m=u=e[i],z=i;while(e[++i]==++u);}return R}


An anonymous function. Takes input in the order Array L, Integer N and returns the result as a comma-separated string.

M=(e,c)=>{for(i=0,R='';i<e.length;R+=(R&&',')+(u-m>=c?m+'-'+--u:e.slice(z,i))){m=u=e[i],z=i;while(e[++i]==++u);}return R}
console.log(M(eval(prompt()),+prompt()))

• Use currying to save a byte e=>c=>. – TheLethalCoder Jul 26 '17 at 10:28

# Dyalog APL v16.0, 828078767565 62 bytes

{S/⍨1,⍨2≠/S←'-'@(⍸⊃∨/(-0,⍳⍺-3)⌽¨⊂(⍴⍵)↑∧/¨(⍺-1),/¯1⌽1=-2-/⍵)⊢⍵}
`

Wow, this is ... bad. There's probably a much much shorter solution with stencil.

Try it online!

Golfing suggestions welcome!

• Yeah, what about it? – Zacharý Jul 27 '17 at 14:55
• Sorry, wrong place. – Adám Jul 27 '17 at 15:02
• ^ What do you mean? – Zacharý Jul 27 '17 at 15:06
• My comment was based on a different challenge. – Adám Jul 27 '17 at 15:18
• I'm assuming that if you have a solution, Adám, then it utilizes v16 builtins? – Zacharý Jul 27 '17 at 16:51