删除前导和尾随零


31

给定一个仅包含非负整数的非空列表/数组,如下所示:

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

其他一些测试用例:

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

最短代码胜出


数字是否仅是非负整数?我建议您澄清一下,或添加其他数字的测试用例
Luis Mendo

1
我们是否可以假设至少有一个前导0和一个尾随0?
DJMcMayhem

4
什么不构成什么?我能想到的几个不同的东西,是就没什么用Perl 6的变化Nil ()/ [] slip()/ Empty Any {}他们中的一些是不确定的,一些定义,但奇异的是,一些滑到其它列表,使得它们不增加元素的数量。(关于Any类,类型和角色,存在各种不同的变体)
布拉德·吉尔伯特b2gills

7
是不是巧合的是没有超过10的整数,或者我们可以假定所有数字都将是一位数字吗?
西蒙斯(Simmons)

1
我们可以输入/输出列表作为定界字符串吗?例如:"0,4,1,2,0,1,2,4,0" => "4,1,2,0,1,2,4"编辑:刚注意到许多语言已经这样做了。
Mwr247 '16

Answers:



10

JavaScript(ES6)43

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

少打高尔夫球

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
}

测试

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
真好 f=(a,r=f(a,a))=>r.reverse().filter(x=>a|=x)也是43个字节。
尼尔

6

CJam,13个字节

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

输入数组。

较长版本:

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

我希望我可以利用这样的事实,即与基准之间的转换会删除前导零,但是看起来太长了。
硕果累累

5

Pyth,4个字节

.sQ0

演示:

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]

Pyth的rev-doc.txt

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



5

R,43个字节

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

或作为读/写STDIN / STDOUT

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

这将从字符串的开头和结尾(反向)中找到累积最大值。所述&操作者这两个向量的大小相同的逻辑一作为转换x,(零将总是被转换为FALSE和其他一切向TRUE),这样,使得有可能从子集x根据满足的条件。



4

Mathematica 34 27字节

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

这将反复应用替换规则,直到此类操作无法提供新的输出为止。感谢Alephalpha,节省了7个字节。

第一条规则在开头删除零;第二条规则删除数组末尾的零。


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


3

Perl,19 +1 = 20字节

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

需要-p标志:

$ 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我在点击[添加评论]之后就差不多了,现在我只需要弄清楚让markdown将我的换行符保存在代码块中
andlrc 2016年

通过邪恶的HTML hacks。;)
Martin Ender 2016年

1
17 + 1字节:s/^0 | 0$//&&redo
肯尼

@Kenney太好了:-)您应该将其发布为答案!
andlrc '16

谢谢!我的原始文件也是19 + 1字节,但后来我看到了您的回答,这使我有了一个想法,要再减少2个,因此如果您愿意,它是您的。顺便说一句,如果您?像示例中那样删除,您的答案实际上是18 + 1- 但这不会减少"0"..
Kenney 2016年

3

果冻,10个字节

Uo\U,o\PTị

这不使用内置函数。

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.

在这里尝试。


3

Perl,38个字节

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

使用perl -p,运行(为添加了3个字节-p)。

接受STDIN上的数字,每行一个;在STDOUT上发射数字,每行一个,就像行为良好的Unix实用程序应该的那样。

仅将正好由“ 0”表示的数字视为零;可以在正则表达式中使用更多字节来支持其他表示形式。

较长的版本,仍然可以使用-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

扩展版本,显示与-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

假设您使用perl -E,则该-p标志通常仅计为一个字节,因为该和之间只有一个额外的字节不同perl -pE
克里斯(Chris)

3

Elixir,77个字节

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

l是数组。

编辑:哇!复制/意大利面失败。当然,必须导入Enum,这会将字节数增加12(或使用Enum.function_name,这将使其更长)。


3

Vitsy,13个字节

Vitsy慢慢好起来了……(我来为你Jelly。ಠ_ಠ)

1mr1m
D)[X1m]

这与堆栈上的数组一起退出。为了提高可读性,请使用TryItOnline!我在解释下方提供的链接将输出格式化列表。

说明:

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.

请注意,这将为不合理的大输入引发StackOverflowException。

TryItOnline!


2
Vitsy有一天会得到果冻。
Conor O'Brien

在EOL / EOF上添加自动括弧式匹配
Cyoce '16

3

R,39个字节

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

David Arenburg的R答案短四个字节。此实现找到大于零的数组中的第一个和最后一个索引,并返回这两个索引之间的数组中的所有内容。


3

MATL,9个字节

2:"PtYsg)

在线尝试!

说明

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个字节

{⌽⍵↓⍨+/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.

在这里尝试。


怎么{⌽⍵/⍨×+\⍵}⍣2
lstefano

2

Ruby,49个 44字节

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

感谢manatwork用完全不同的方法切掉5个字节!

这只是drop数组的第一个元素,while它为0,反转数组,重复,最后反转数组以使其返回正确的顺序。


哎哟。现在,即使是.drop_while()基于解决方案的解决方案也将更短(如果使用2个功能):f=->a{a.drop_while{|i|i<1}.reverse};->a{f[f[a]]}
manatwork 2016年

h 无需2层的功能,只是一些eval丑陋:->a{eval ?a+'.drop_while{|i|i<1}.reverse'*2}
manatwork '16

@manatwork不知道为什么我还是没想到<1。谢谢!
门把手

2

Vim 16击键

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

该输入将由用户在i和之间键入esc,并且不算作按键。假定至少有一个前导零和一个尾随零。如果这不是一个有效的假设,我们可以使用以下稍长的版本:(18个击键)

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

1
我认为您不需要包含允许用户输入数字(i<esc>)的代码。在vim golf中,高尔夫球手首先将输入保存在已加载缓冲区的文件中,并将光标放在左上角,但用户还必须保存并退出(ZZ通常是最快的方法)。然后,您可以执行类似的操作d[1-9]<enter>$NlDZZ(13次击键)。请注意N/ n代替/<up><enter>
daniero '16

2

ES6,51个字节

f=a=>a.map(x=>x?t=++i:f<i++||++f,f=i=0)&&a.slice(f,t)

t设置为最后一个非零值之后的索引,而f只要到目前为止只看到零,就将其递增。


2

Perl 6、23个字节

{.[.grep(?*):k.minmax]}
{.[minmax .grep(?*):k]}

用法:

# 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个字节

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

a数组在哪里。


4
我认为您需要创建一个匿名函数来接受输入:a=>a.join(a="")...
andlrc '16

2
仅当整数是一位数字时,它才能正确处理整数
2016年

@ dev-null完成。
user2428118

对于多位数整数仍然返回错误。[14]会回来的[1, 4]
Mwr247 '16

实际上,我仍在(并且还在)等待对此评论的答复。无论如何,不​​幸的是,我没有看到一种使用与答案相同的技术来处理多位整数的方法,而且我认为无论如何我都无法击败这个答案。不过,我可以在有空的时候尝试一下。
user2428118 '16


2

JavaScript(ES6),34个字节

a=>a.replace(/^(0 ?)*|( 0)*$/g,'')

输入和输出采用以空格分隔的列表的形式,例如"0 4 1 2 0 1 2 4 0"


2

Javascript(ES6)40字节

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

2

PHP,56 54 52字节

使用Windows-1252编码

基于字符串的解决方案

<?=preg_replace(~ÜÒ×ßÏÖÔƒ×ßÏÖÔÛÜ,"",join($argv,~ß));

像这样运行:

echo '<?=preg_replace(~ÜÒ×ßÏÖÔƒ×ßÏÖÔÛÜ,"",join($argv,~ß));' | php -- 0 0 123 234 0 500 0 0 2>/dev/null;echo

如果您的终端设置为UTF-8,则相同:

echo '<?=preg_replace("#-( 0)+|( 0)+$#","",join($argv," "));' | php -- 0 0 123 234 0 500 0 0 2>/dev/null;echo

调整

  • 否定字符串并删除字符串定界符可节省2个字节
  • 使用短打印标签节省了2个字节

1
您能否提供ASCII解决方案?没有人可以阅读!
泰特斯(Titus)

1
@Titus当然。但是,那里有很多无法理解的残障人士……。这似乎不像我的回答在家里不舒服。
2016年

数组作为连接的第一个参数?
约尔格Hülsermann

1
@JörgHülsermann是。它以相反的方式记录在案,但它都接受。
2016年

你是对的,我还没有意识到这一点
约尔格Hülsermann


1

PowerShell,49个字节

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

接受输入$args[0]并将-join它们与逗号一起形成字符串。然后,我们使用被.Trim()调用两次的函数来删除尾部,然后删除前导零和逗号。然后-split,我们将逗号上的字符串放回数组中。


备用版本,不使用转换
PowerShell,81字节

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

由于PowerShell没有修剪数组的函数,因此我们定义了一个新函数f,它将为我们完成一半的工作。该函数$a作为输入,然后使用foreach循环遍历每个项目|%{...}。每次迭代,我们都会检查条件$_ -or $b。由于非零整数是真实的,但是$null虚假的(并且$b,以前未定义,并且以开头$null),因此只有$true当我们命中数组中的第一个非零元素时,这才会求值。然后$b=1,我们设置当前值$_并将其添加到管道中。然后,这将一直持续到输入数组的末尾,中间为零,末尾被添加到输出中,因为我们已经设置了$btrue。

我们将循环结果封装并存储回$a。然后,我们$a以相反的顺序索引(即,反转数组),该索引保留在管道上,因此是函数的返回值。

我们$args[0]在程序的输入上两次调用该函数,以便从前端“修剪”,然后从前端“修剪”(由于反向,所以是后端)。由于我们两次反转,因此顺序得以保留。

这个版本与全零输入数组的规则有点松散,但是由于忽略了STDERR是公认的惯例,因此程序将向(Cannot index into a null arrayPowerShell等效的) STDERR 吐出两个(详细)错误,然后不输出任何内容。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.