25
\$\begingroup\$

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!

\$\endgroup\$
7
  • \$\begingroup\$ Is it necessary to use - or are we allowed to use a different symbol? \$\endgroup\$
    – miles
    Commented Jul 26, 2017 at 5:57
  • \$\begingroup\$ @miles Will a different symbol save you bytes? \$\endgroup\$
    – Adám
    Commented Jul 26, 2017 at 6:41
  • \$\begingroup\$ I am thinking of using infinity _ so that I might remain operating on numeric arrays in J. \$\endgroup\$
    – miles
    Commented Jul 26, 2017 at 6:45
  • \$\begingroup\$ @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? \$\endgroup\$
    – Adám
    Commented Jul 26, 2017 at 7:03
  • 1
    \$\begingroup\$ @EzioMercer all the below lines are examples of valid responses, both as actual lists and as strings: \$\endgroup\$
    – Adám
    Commented Mar 5, 2023 at 16:52

14 Answers 14

7
\$\begingroup\$

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!

\$\endgroup\$
3
  • \$\begingroup\$ 115 bytes \$\endgroup\$
    – Leaky Nun
    Commented Jul 26, 2017 at 9:03
  • \$\begingroup\$ Would while t+i==x[i]: work? Or am I missing something? \$\endgroup\$
    – Adalynn
    Commented Jul 26, 2017 at 19:19
  • \$\begingroup\$ @Zacharý it would break if i get higher than the size of x \$\endgroup\$
    – Rod
    Commented Jul 26, 2017 at 19:37
6
\$\begingroup\$

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
\$\endgroup\$
4
  • \$\begingroup\$ A monadic link? \$\endgroup\$
    – Leaky Nun
    Commented Jul 25, 2017 at 20:40
  • \$\begingroup\$ heh, and a "special" one at that. \$\endgroup\$ Commented Jul 25, 2017 at 21:41
  • \$\begingroup\$ Rearranging your stuff a bit helps for -2. \$\endgroup\$ Commented Jul 26, 2017 at 10:08
  • \$\begingroup\$ Nice stuff, thanks @EriktheOutgolfer! \$\endgroup\$ Commented Jul 26, 2017 at 13:00
4
\$\begingroup\$

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
\$\endgroup\$
3
\$\begingroup\$

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
\$\endgroup\$
2
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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!

\$\endgroup\$
1
  • \$\begingroup\$ here \$\endgroup\$
    – Leaky Nun
    Commented Jul 26, 2017 at 8:52
2
\$\begingroup\$

APL, 38 bytes

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

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
\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
1
\$\begingroup\$

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
\$\endgroup\$
1
\$\begingroup\$

Vyxal, 23 bytes

D0J¨pε⁽ṅḋ•ƛL⁰≥[₍ht\-Y}f

Try it Online!

23 bytes seems to be the standard here, so I figured I'd add my own 23 byter. Takes List then N.

Explained

D0J¨pε⁽ṅḋ•ƛL⁰≥[₍ht\-Y}f
D0J                     # Push 3 copies of the input and append 0 to the last
   ¨pε                  # get the absolute difference of each overlapping pair
      ⁽ṅḋ               # group by diff <= 1
         •              # mold to shape
          ƛ          }  # to each consecutive run:
           L⁰≥[         #   if the length is >= N
               ₍ht\-Y   #     [head, "-", tail]
                      f # flatten that
\$\endgroup\$
0
\$\begingroup\$

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.

\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$
2
  • \$\begingroup\$ Use currying to save a byte e=>c=>. \$\endgroup\$ Commented Jul 26, 2017 at 10:28
  • \$\begingroup\$ (e,c)=>eval("for(i=0,R='';m=u=e[z=i],i<e.length;R+=(R&&',')+(u-m<c?e.slice(z,i):m+'-'+--u))while(e[++i]==++u);R") - 113 bytes \$\endgroup\$
    – EzioMercer
    Commented Mar 5, 2023 at 17:45
0
\$\begingroup\$

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!

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

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.