Remove leading and trailing zeroes

Given a non-empty list/array containing only non-negative integers like this:

[0, 0, 0, 8, 1, 4, 3, 5, 6, 4, 1, 2, 0, 0, 0, 0]


Output the list with trailing and leading zeroes removed.

The output for this would be:

[8, 1, 4, 3, 5, 6, 4, 1, 2]


Some other test cases:

[0, 4, 1, 2, 0, 1, 2, 4, 0] > [4, 1, 2, 0, 1, 2, 4]
[0, 0, 0, 0, 0, 0] > nothing
[3, 4, 5, 0, 0] > [3, 4, 5]
[6] > [6]


Shortest code wins

• Are the numbers non-negative integers only? I suggest you clarify that or add test cases with other numbers Feb 12, 2016 at 20:08
• Can we assume that there will be at least one leading and one trailing 0? Feb 12, 2016 at 20:24
• What constitutes nothing? I can think of several different things that are variations on nothing in Perl 6. Nil ()/[] slip()/Empty Any {} some of them are undefined, some defined but singular, some that slip into other lists such that they don't increase the number of elements. ( There are as many different variations on Any as there are classes/types and roles ) Feb 13, 2016 at 0:41
• Is it a coincidence that there are no integers over 10 or can we assume that all the numbers are going to be single-digit? Feb 13, 2016 at 17:57
• Can we input/output the list as a delimited string? For example: "0,4,1,2,0,1,2,4,0" => "4,1,2,0,1,2,4" EDIT: Just noticed many languages do this already. Feb 24, 2016 at 18:18

Jelly, 2 bytes

Code:

t0


Explanation:

t   # Trim off...
0  #  zero at both sides


Try it online!

• This works? Jeez. I thought the MATL answers were insane. Feb 12, 2016 at 18:55
• wut y no don do dis jelly Feb 21, 2016 at 16:09
• Of course Jelly beats every other guy out there almost every time... Oct 5, 2016 at 14:35
• Is Jelly used in actual businesses? Oct 5, 2016 at 23:49
• Man, I hope not May 20, 2017 at 16:11

JavaScript (ES6) 43

a=>(f=a=>a.reverse().filter(x=>a|=x))(f(a))


Less golfed

a=>{
f=a=>a.reverse().filter(x=>a|=x) // reverse and remove leading 0
// leverage js cast rules: operator | cast operands to integer
// an array casted to integer is 0 unless the array is made of
// a single integer value (that is ok for me in this case)
return f(f(a)) // apply 2 times
}


Test

F=a=>(f=a=>a.reverse().filter(x=>a|=x))(f(a))

function test(){
var l=(I.value.match(/\d+/g)||[]).map(x=>+x)
O.textContent=F(l)
}

test()
#I { width:90%}
<input id=I oninput='test()' value='0 0 1 3 7 11 0 8 23 0 0 0'>
<pre id=O></pre>

• Nice. f=(a,r=f(a,a))=>r.reverse().filter(x=>a|=x) is also 43 bytes.
– Neil
Feb 13, 2016 at 18:58

CJam, 13 bytes

l~{_{}#>W%}2*


With the array inputted.

Longer version:

l~             Puts input on the stack and parse as array
{       }    Code block
_           Duplicate the first thing on the stack
{}#        Finds the index of the first non-0 value in the array, puts it on the stack
>       Slices the array from that index
W%     Reverses the array
2*  Does the code block twice in total

• I wish I could use the fact that converting to and from a base would remove leading zeros, but it looks like it's too long. May 20, 2017 at 0:19

Pyth, 4 bytes

.sQ0


Demo:

llama@llama:~$pyth -c .sQ0 [0, 0, 0, 1, 2, 0, 3, 4, 0, 0, 5, 0, 0, 0, 0] [1, 2, 0, 3, 4, 0, 0, 5]  .s <seq> <any> Strip from A maximal prefix and suffix of A consisting of copies of B.  05AB1E, 4 bytes Code: 0Û0Ü  Try it online! Explanation: 0Û # Trim off leading zeroes 0Ü # Trim off trailing zeroes  Uses CP-1252 encoding. Retina, 12 bytes ^0 ? ) 0$



The trailing linefeed is significant.

Thanks to @Martin Büttner and @FryAmTheEggman for saving a few bytes.

Try it online

Jelly, 10 bytes

Uo\U,o\PTị


This doesn't use the builtin.

Uo\U            Backward running logical OR
,           paired with
o\         Forward running logical OR
P        Product
T       All indices of truthy elements
ị      Index the input at those values.


Try it here.

R, 43 bytes

function(x)x[cummax(x)&rev(cummax(rev(x)))]


or as read/write STDIN/STDOUT

x=scan();cat(x[cummax(x)&rev(cummax(rev(x)))])


This finds the cumulative maximum from the beginning and the end (reversed) string. The & operator converts these two vectors to logical one of the same size as x, (zeroes will always converted to FALSE and everything else to TRUE), this way it makes it possible to subset from x according to the met conditions.

Haskell, 29 bytes

t=f.f;f=reverse.dropWhile(<1)


Mathematica 34 27 bytes

#//.{0,a___}|{a___,0}:>{a}&


This repeatedly applies replacement rules until such action fails to provide a new output. 7 bytes saved thanks to Alephalpha.

The first rule deletes a zero at the beginning; the second rule deletes a zero at the end of the array.

• #//.{0,a___}|{a___,0}:>{a}& Feb 13, 2016 at 17:46

05AB1E, 4 bytes

0Û0Ü


Basically trimming leading then trailing zeroes of the input, given as an array.

Try it online !

Perl, 19 + 1 = 20 bytes

s/^(0 ?)+|( 0)+$//g  Requires -p flag: $ perl -pE's/^(0 )+|( 0)+$//g' <<< '0 0 0 1 2 3 4 5 6 0 0 0' 1 2 3 4 5 6  • @MartinBüttner I though about the same just after hitting [Add Comment], now I just need to figure out now to let markdown save my newline in a code block Feb 12, 2016 at 19:03 • Via evil HTML hacks. ;) Feb 12, 2016 at 19:04 • 17+1 bytes: s/^0 | 0$//&&redo Feb 21, 2016 at 19:14
• @Kenney That is beautiful :-) You should post that as an answer! Feb 23, 2016 at 11:56
• Thanks! My original was also 19+1 bytes but then I saw your answer which gave me an idea to shave off 2 more, so it's yours if you want it. Btw, your answer is actually 18+1 if you drop the ? as in the example - but that won't reduce "0".. Feb 23, 2016 at 12:10

Ruby, 49 44 bytes

->a{eval ?a+'.drop_while{|i|i<1}.reverse'*2}


Thanks to manatwork for chopping off 5 bytes with a completely different method!

This just drops the first element of the array while it's 0, reverses the array, repeats, and finally reverses the array to return it to the proper order.

• Ouch. Now even a .drop_while() based solution would be shorter (if using 2 functions): f=->a{a.drop_while{|i|i<1}.reverse};->a{f[f[a]]} Feb 12, 2016 at 19:31
• Doh. No need for 2 functions, just some eval ugliness: ->a{eval ?a+'.drop_while{|i|i<1}.reverse'*2}. Feb 12, 2016 at 19:38
• @manatwork Not sure why I didn't think of <1, anyway. Thanks! Feb 12, 2016 at 20:00

Perl, 38 bytes

$\.=$_}{$\=~s/^(0\n)*|(0\n)*\n$//gs


Run with perl -p, (3 bytes added for -p).

Accepts numbers on STDIN, one per line; emits numbers on STDOUT, one per line, as a well-behaved unix utility should.

Only treats numbers represented exactly by '0' as zeroes; it would be possible to support other representations with a few more bytes in the regex.

Longer version, still to be run with -p:

    # append entire line to output record separator
$\.=$_
}{
# replace leading and trailng zeroes in output record separator
$\ =~ s/^(0\n)*|(0\n)*\n$//gs
# output record separator will be implicitly printed


Expanded version, showing interactions with -p flag:

# implicit while loop added by -p
while (<>) {
# append line to output record separator
$\.=$_
}{ # escape the implicit while loop
# replace leading and traling
$\=~s/^(0\n)*|(0\n)*\n$//gs
# print by default prints $_ followed by # the output record separator$\ which contains our answer
;print # implicit print added by -p
} # implicit closing brace added by -p

• Assuming you're running with perl -E, the -p flag usually is only counted as one byte, since there's only one extra byte different between that and perl -pE. May 20, 2017 at 0:19

Elixir, 77 bytes

import Enum
z=fn x->x==0 end
reverse(drop_while(reverse(drop_while(l,z)),z))


l is the array.

Edit:wah! copy/pasta fail. of course one has to import Enum, which raises the byte count by 12 (or use Enum.function_name, which will make it even longer).

a=>a.join(a="").replace(/(^0+|0+$)/g,a).split(a)  Where a is the array. • I think you need to make an anonymous function to take input: a=>a.join(a="").... Feb 13, 2016 at 17:11 • This only handles integers properly when they're a single digit Feb 13, 2016 at 23:30 • @dev-null Done. Feb 14, 2016 at 16:37 • Still returning wrong for multi-digit integers. [14] will return [1, 4]. Feb 23, 2016 at 19:16 • Actually, I was (and am) still awaiting a reply to this comment. Anyway, I unfortunately don't see a way to do handle multi-digit integers using the same technique I've used for my answer and I don't think I'll be able to beat this answer anyway. I may try when I have the time, though. Feb 23, 2016 at 19:43 Vitsy, 13 bytes Vitsy is slowly getting better... (I'm coming for you Jelly. ಠ_ಠ) 1mr1m D)[X1m] This exits with the array on the stack. For readability, the TryItOnline! link that I have provided below the explanation will output a formatted list. Explanation: 1mr1m 1m Do the second line of code. r Reverse the stack. 1m I'ma let you figure this one out. ;) D)[X1m] D Duplicate the top item of the stack. )[ ] If the top item of the stack is zero, do the stuff in brackets. X Remove the top item of the stack. 1m Execute the second line of code. Note that this will throw a StackOverflowException for unreasonably large inputs. TryItOnline! • Vitsy will get Jelly some day. Feb 21, 2016 at 17:40 • Add auto-bracket matching on EOL/EOF Apr 12, 2016 at 21:54 JavaScript (ES6), 34 bytes a=>a.replace(/^(0 ?)*|( 0)*$/g,'')


Input and output are in the form of a space-delimited list, such as "0 4 1 2 0 1 2 4 0".

R, 39 bytes

function(x)x[min(i<-which(x>0)):max(i)]


Four bytes shorter than David Arenburg's R answer. This implementation finds the first and last index in the array which is greater than zero, and returns everything in the array between those two indices.

MATL, 9 bytes

2:"PtYsg)


Try it online!

Explanation

2:"     % For loop (do the following twice)
P     %   Flip array. Implicitly asks for input the first time
t     %   Duplicate
Ys    %   Cumulative sum
g     %   Convert to logical index
)     %   Apply index
% Implicitly end for
% Implicitly display stack contents


Dyalog APL, 15 bytes

{⌽⍵↓⍨+/0=+\⍵}⍣2

⍣2     Apply this function twice:
{             }       Monadic function:
+\⍵        Calculate the running sum.
+/0=           Compare to zero and sum. Number of leading zeroes.
⍵↓⍨               Drop the first that many elements from the array.
⌽                   Reverse the result.


Try it here.

• How about {⌽⍵/⍨×+\⍵}⍣2? Jun 27, 2016 at 13:04

Vim 16 Keystrokes

i<input><esc>?[1-9]<enter>lD0d/<up><enter>


The input is to be typed by the user between i and esc, and does not count as a keystroke. This assumes that there will be at least one leading and one trailing zero. If that is not a valid assumption, we can use this slightly longer version: (18 Keystrokes)

i <input> <esc>?[1-9]<enter>lD0d/<up><enter>

• I don't think you need to include code to allow the user to input the numbers (i and <esc>). In vim golf the golfer starts with the input already in a file loaded the buffer and the cursor in the top left corner, but the user also has to save and exit (ZZ is usually the fastest way). Then you could do something like d[1-9]<enter>$NlDZZ (13 keystrokes). Note N/n instead of /<up><enter> Feb 12, 2016 at 22:45 ES6, 51 bytes f=a=>a.map(x=>x?t=++i:f<i++||++f,f=i=0)&&a.slice(f,t)  t is set to the index after the last non-zero value, while f is incremented as long as only zeros have been seen so far. Perl 6, 23 bytes {.[.grep(?*):k.minmax]} {.[minmax .grep(?*):k]}  Usage: # replace the built-in trim subroutine # with this one in the current lexical scope my &trim = {.[.grep(?*):k.minmax]} say trim [0, 0, 0, 8, 1, 4, 3, 5, 6, 4, 1, 2, 0, 0, 0, 0]; # (8 1 4 3 5 6 4 1 2) say trim [0, 4, 1, 2, 0, 1, 2, 4, 0]; # (4 1 2 0 1 2 4) say trim [0, 0, 0, 0, 0, 0]; # () say trim [3, 4, 5, 0, 0]; # (3 4 5) say trim [6]; # (6)  Retina, 11 bytes +^0 ?| 0$
<empty>


Quite simple. Recursively replaces zeroes at beginning and end of line.

Try it online!

Python, 84 characters

def t(A):
if set(A)<={0}:return[]
for i in(0,-1):
while A[i]==0:del A[i]
return A

• You can do for i in-1,0: Oct 4, 2016 at 14:50
• I count 86 bytes. Oct 5, 2016 at 14:43

a=>/^(0,)*(.*?)(,0)*$/.exec(a.join())[2]  PHP, 5654 52 bytes Uses Windows-1252 encoding String based solution <?=preg_replace(~ÜÒ×ßÏÖÔƒ×ßÏÖÔÛÜ,"",join($argv,~ß));


Run like this:

echo '<?=preg_replace(~ÜÒ×ßÏÖÔƒ×ßÏÖÔÛÜ,"",join($argv,~ß));' | php -- 0 0 123 234 0 500 0 0 2>/dev/null;echo  If your terminal is set to UTF-8, this is the same: echo '<?=preg_replace("#-( 0)+|( 0)+$#","",join(\$argv," "));' | php -- 0 0 123 234 0 500 0 0 2>/dev/null;echo


Tweaks

• Saved 2 bytes by negating strings and dropping string delimiters
• Saved 2 bytes by using short print tag
• Can you please provide an ASCII solution. Nobody can read this! Oct 5, 2016 at 13:34
• @Titus Sure. However, plenty of unreadable esolangs out there.... it's not like my answer doesn't feel right at home. Oct 5, 2016 at 14:09
• An array as first parameter of join? Oct 5, 2016 at 14:30
• @JörgHülsermann Yup. It's documented the other way around but it accepts both. Oct 5, 2016 at 14:32
• You are right I have not realize it Oct 5, 2016 at 14:50

Python 2, 69 67 bytes

def f(a):
for i in(0,-1):
while a and a[i]==0:a.pop(i)
return a

• You can remove the space before your tuple in the second line. Feb 21, 2016 at 19:16
• You can do for i in-1,0: Oct 4, 2016 at 14:51
• Also, you might want to recount your bytes. I count 67 as is. You can also replace [space][space]while with [tab]while. And ==0 can be <1. mothereff.in/… Oct 4, 2016 at 15:00
• I count 67 bytes. Oct 5, 2016 at 14:44

///, 20 bytes

/[0 /[// 0]/]//[0]//


Try it online!

Input as list of integers separated by spaces and surrounded by square brackets ([0 1 2 3 4 5 0]).