Collapse consecutive integers

22

2

Related: Tell me how many math problems I have to do!

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!

Adám

Posted 2017-07-25T19:34:12.813

Reputation: 37 779

Is it necessary to use - or are we allowed to use a different symbol? – miles – 2017-07-26T05:57:42.703

@miles Will a different symbol save you bytes? – Adám – 2017-07-26T06:41:32.997

I am thinking of using infinity _ so that I might remain operating on numeric arrays in J. – miles – 2017-07-26T06:45:05.980

@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 – 2017-07-26T07:03:32.973

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 – 2017-07-26T09:02:38.980

@LeakyNun Uh, are those negative numbers? If so, no. Not because the format is bad per se, but because I should have permitted it from the outset so others could do it to. However, can't you just stringify and replace ,- with -? – Adám – 2017-07-26T09:07:32.083

Answers

7

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!

Rod

Posted 2017-07-25T19:34:12.813

Reputation: 17 588

115 bytes – Leaky Nun – 2017-07-26T09:03:47.430

Would while t+i==x[i]: work? Or am I missing something? – Zacharý – 2017-07-26T19:19:10.733

@Zacharý it would break if i get higher than the size of x – Rod – 2017-07-26T19:37:15.163

6

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
Ḣ      -     head
  Ṫ    -     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:
            ¥    -   condition: last two links as a dyad:
          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

Jonathan Allan

Posted 2017-07-25T19:34:12.813

Reputation: 67 804

A monadic link? – Leaky Nun – 2017-07-25T20:40:30.133

heh, and a "special" one at that. – Jonathan Allan – 2017-07-25T21:41:51.473

Rearranging your stuff a bit helps for -2. – Erik the Outgolfer – 2017-07-26T10:08:01.963

Nice stuff, thanks @EriktheOutgolfer! – Jonathan Allan – 2017-07-26T13:00:43.290

4

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

Anders Kaseorg

Posted 2017-07-25T19:34:12.813

Reputation: 29 242

3

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

ETHproductions

Posted 2017-07-25T19:34:12.813

Reputation: 47 880

2

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!

J42161217

Posted 2017-07-25T19:34:12.813

Reputation: 15 931

here – Leaky Nun – 2017-07-26T08:52:32.037

2

Retina, 101 bytes

\d+
$*
\b(1+) (?=1\1\b)
$1X
T`X` `\b((X)|1)+\b(?=.*¶(?<-2>1)+(?(2)(?!))11)
T`X`-
-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.

Neil

Posted 2017-07-25T19:34:12.813

Reputation: 95 035

2

APL, 38 bytes

{∊⍺{⍺>≢⍵:⍵⋄2⌽'-',2↑¯1⌽⍵}¨⍵⊂⍨1,1≠2-⍨/⍵}

marinus

Posted 2017-07-25T19:34:12.813

Reputation: 30 224

1

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

Titus

Posted 2017-07-25T19:34:12.813

Reputation: 13 814

1

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!

daniero

Posted 2017-07-25T19:34:12.813

Reputation: 17 193

1

J, 40 bytes

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

Try it online!

Uses _ instead of -.

Explanation

;@((](,_,{:)/)^:(<:#)&.>]<;.1~1,1<}.-}:)  Input: integer N (LHS), array L (RHS)
                                  }.      Behead L
                                     }:   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

miles

Posted 2017-07-25T19:34:12.813

Reputation: 15 654

0

Jelly, 39 37 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)
                    µ        Start a new monadic link
                     Œ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.

Zacharý

Posted 2017-07-25T19:34:12.813

Reputation: 5 710

0

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()))

R. Kap

Posted 2017-07-25T19:34:12.813

Reputation: 4 730

Use currying to save a byte e=>c=>. – TheLethalCoder – 2017-07-26T10:28:47.023

0

Dyalog APL v16.0, 82 80 78 76 75 65 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!

Zacharý

Posted 2017-07-25T19:34:12.813

Reputation: 5 710

Yeah, what about it? – Zacharý – 2017-07-27T14:55:40.550

Sorry, wrong place. – Adám – 2017-07-27T15:02:10.057

^ What do you mean? – Zacharý – 2017-07-27T15:06:13.337

My comment was based on a different challenge. – Adám – 2017-07-27T15:18:45.700

I'm assuming that if you have a solution, Adám, then it utilizes v16 builtins? – Zacharý – 2017-07-27T16:51:31.740

No it doesn't. Also, we've hired another golfer.

– Adám – 2017-07-27T18:59:27.883

Dyalog hired him? Or am I misunderstanding something? – Zacharý – 2017-07-27T22:12:34.987

He's a summer intern at our office here in England. – Adám – 2017-07-27T22:13:14.627

Yes. I'm being 100% serious when I say that we want people from PPCG! Interested? – Adám – 2017-07-27T22:22:25.437

Maybe some day. – Zacharý – 2017-07-27T22:37:20.237