Remova os zeros à esquerda e à direita


31

Dada uma lista / matriz não vazia contendo apenas números inteiros não negativos como este:

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

Saída da lista com os zeros à direita e à esquerda removidos.

A saída para isso seria:

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

Alguns outros casos de teste:

[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]

O código mais curto vence


Os números são números inteiros não negativos? Eu sugiro que você esclarecer que ou adicionar casos de teste com outros números
Luis Mendo

1
Podemos supor que haverá pelo menos um inicial e um final 0?
DJMcMayhem

4
O que não constitui nada? Eu posso pensar em várias coisas diferentes que são variações sobre nada no Perl 6. Nil ()/[] slip() / Empty Any {}algumas delas são indefinidas, algumas definidas, mas singulares, outras que se inserem em outras listas e não aumentam o número de elementos. (Existem tantas variações diferentes em Anycomo existem classes / tipos e papéis)
Brad Gilbert b2gills

7
É coincidência que não haja números inteiros acima de 10 ou podemos assumir que todos os números serão de um dígito?
1 Simmons

1
Podemos inserir / enviar a lista como uma string delimitada? Por exemplo: "0,4,1,2,0,1,2,4,0" => "4,1,2,0,1,2,4"EDIT: Acabei de notar que muitos idiomas já fazem isso.
Mwr247

Respostas:



10

JavaScript (ES6) 43

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

Menos golfe

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
}

Teste

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>


1
Agradável. f=(a,r=f(a,a))=>r.reverse().filter(x=>a|=x)também é 43 bytes.
Neil

6

CJam, 13 bytes

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

Com a matriz inserida.

Versão mais longa:

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

Eu gostaria de poder usar o fato de que converter para e de uma base removeria zeros à esquerda, mas parece que é muito longo.
Esolanging Fruit

5

Pitão, 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]

De Pyth'srev-doc.txt :

.s <seq> <any>
    Strip from A maximal prefix and suffix of A consisting of copies of B.



5

R, 43 bytes

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

ou como leitura / gravação STDIN / STDOUT

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

Este encontra o máximo cumulativo desde o início e a sequência final (invertida). O &operador converte esses dois vetores em um lógico do mesmo tamanho que x, (os zeros serão sempre convertidos em FALSEe tudo o mais em TRUE), dessa forma, é possível fazer o subconjunto de xacordo com as condições atendidas.



4

Mathematica 34 27 bytes

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

Isso se aplica repetidamente às regras de substituição até que essa ação não forneça uma nova saída. 7 bytes salvos graças a Alephalpha.

A primeira regra exclui um zero no início; a segunda regra exclui um zero no final da matriz.


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


3

Perl, 19 + 1 = 20 bytes

s/^(0 ?)+|( 0)+$//g

Requer -psinalizador:

$ 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 embora sobre o mesmo apenas depois de bater [comentário], agora eu só preciso descobrir agora para deixar remarcação salvar minha nova linha em um bloco de código
andlrc

Via hacks HTML maléficos. ;)
Martin Enders

1
17 + 1 bytes:s/^0 | 0$//&&redo
Kenney

@ Kenney Isso é lindo :-) Você deve postar isso como resposta!
23616 andlrc

Obrigado! O meu original também tinha 19 + 1 bytes, mas depois vi a sua resposta, que me deu a idéia de cortar mais 2, por isso é sua, se você a quiser. Aliás, a sua resposta é realmente 18 + 1 se você deixar cair a ?como no exemplo - mas isso não vai reduzir "0"..
Kenney

3

Gelatina, 10 bytes

Uo\U,o\PTị

Isso não usa o 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.

Experimente aqui .


3

Perl, 38 bytes

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

Execute com perl -p, (3 bytes adicionados para -p).

Aceita números no STDIN, um por linha; emite números no STDOUT, um por linha, como um utilitário unix bem comportado.

Apenas trata números representados exatamente por '0' como zeros; seria possível oferecer suporte a outras representações com mais alguns bytes no regex.

Versão mais longa, ainda a ser executada com -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

Versão expandida, mostrando interações com o sinalizador -p:

# 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

Supondo que você esteja usando perl -E, o -psinalizador geralmente é contado apenas como um byte, pois há apenas um byte extra diferente entre esse e perl -pE.
Chris

3

Elixir, 77 bytes

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

l é a matriz.

Edit: wah! cópia / pasta falhar. é claro que é preciso importar o Enum, que aumenta a contagem de bytes em 12 (ou use Enum.function_name, que aumentará ainda mais).


3

Vitsy, 13 bytes

Vitsy está lentamente melhorando ... (Estou indo atrás de você Jelly. ಠ_ಠ)

1mr1m
D)[X1m]

Isso sai com a matriz na pilha. Para facilitar a leitura, o TryItOnline! O link que forneci abaixo da explicação produzirá uma lista formatada.

Explicação:

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!


2
Vitsy will get Jelly some day.
Conor O'Brien

Add auto-bracket matching on EOL/EOF
Cyoce

3

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.


3

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

2

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?
lstefano

2

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]]}
manatwork

Doh. No need for 2 functions, just some eval ugliness: ->a{eval ?a+'.drop_while{|i|i<1}.reverse'*2}.
manatwork

@manatwork Not sure why I didn't think of <1, anyway. Thanks!
Doorknob

2

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>

1
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>
daniero

2

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.


2

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)


2

JavaScript (ES6), 47 bytes

a=>a.join(a="").replace(/(^0+|0+$)/g,a).split(a)

Where a is the array.


4
I think you need to make an anonymous function to take input: a=>a.join(a="")....
andlrc

2
This only handles integers properly when they're a single digit
aross

@dev-null Done.
user2428118

Still returning wrong for multi-digit integers. [14] will return [1, 4].
Mwr247

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.
user2428118


2

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".


2

Javascript (ES6) 40 bytes

a=>/^(0,)*(.*?)(,0)*$/.exec(a.join())[2]

2

PHP, 56 54 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

1
Can you please provide an ASCII solution. Nobody can read this!
Titus

1
@Titus Sure. However, plenty of unreadable esolangs out there.... it's not like my answer doesn't feel right at home.
aross

An array as first parameter of join?
Jörg Hülsermann

1
@JörgHülsermann Yup. It's documented the other way around but it accepts both.
aross

You are right I have not realize it
Jörg Hülsermann


1

PowerShell, 49 bytes

($args[0]-join',').trim(',0').trim('0,')-split','

Takes input $args[0] and -joins them together with commas to form a string. We then use the .Trim() function called twice to remove first the trailing and then the leading zeros and commas. We then -split the string on commas back into an array.


Alternate version, without using conversion
PowerShell, 81 bytes

function f{param($a)$a=$a|%{if($_-or$b){$b=1;$_}};$a[$a.Count..0]}
f(f($args[0]))

Since PowerShell doesn't have a function to trim arrays, we define a new function f that will do half of this for us. The function takes $a as input, then loops through each item with a foreach loop |%{...}. Each iteration, we check a conditional for $_ -or $b. Since non-zero integers are truthy, but $null is falsey (and $b, being not previously defined, starts as $null), this will only evaluate to $true once we hit our first non-zero element in the array. We then set $b=1 and add the current value $_ onto the pipeline. That will then continue through to the end of the input array, with zeros in the middle and the end getting added onto the output, since we've set $b truthy.

We encapsulate and store the results of the loop all back into $a. Then, we index $a in reverse order (i.e., reversing the array), which is left on the pipeline and thus is the function's return value.

We call the function twice on the $args[0] input to the program in order to "trim" from the front, then the front again (which is the back, since we reversed). The order is preserved since we're reversing twice.

This version plays a little loose with the rules for an input array of all zeros, but since ignoring STDERR is accepted practice, the program will spit out two (verbose) Cannot index into a null array errors to (PowerShell's equivalent of) STDERR and then output nothing.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.