掩盖列表中的零


41

受到这个SO问题的启发

作为输入,您将得到一个非空的整数列表,其中第一个值保证为非零。要构造输出,请从列表的开头开始,沿途输出每个非零值。当您遇到零时,请重复最近添加到输出中的值。

您可以编写程序或函数,并让输入/输出采用任何方便的格式,只要仍为整数的有序序列,该格式就不会编码额外的信息。如果从程序输出,则可以打印尾随换行符。除了该尾随的换行符之外,您的输出应为提交的可接受输入。

以字节为单位的最短代码获胜。

测试用例

[1, 0, 2, 0, 7, 7, 7, 0, 5, 0, 0, 0, 9] -> [1, 1, 2, 2, 7, 7, 7, 7, 5, 5, 5, 5, 9]
[1, 0, 0, 0, 0, 0] -> [1, 1, 1, 1, 1, 1]
[-1, 0, 5, 0, 0, -7] -> [-1, -1, 5, 5, 5, -7]
[23, 0, 0, -42, 0, 0, 0] -> [23, 23, 23, -42, -42, -42, -42]
[1, 2, 3, 4] -> [1, 2, 3, 4]
[-1234] -> [-1234]

21
琐事:在统计领域中,此操作的名称为LOCF(最后结转的观察结果)推算。
Alex A.

如果输入是什么会发生什么[0,0]
Kritixi Lithos 2015年

4
@KριτικσιΛίθος“ ...保证第一个值不为零”
Sp3000

如果输入是[1,01]什么?使用issac的Pyth答案,将此this进行比较。
Arcturus

@Eridan 01在Pyth输入中不是有效的整数,因此isaac不必考虑这一点。其他答案只要愿意就可以接受这样的输入,只要它们是一致的(例如isaac的答案将永远不会产生该列表作为输出)
FryAmTheEggman 2015年

Answers:


19

Pyth,6个字节

mJ|dJQ

示范

m ... Q表示这将功能映射到输入上。正在映射的函数是J|dJ。这意味着J = d or J在Python中,因为J在首次使用时会隐式地将其分配给以下值。与Python不同,赋值表达式返回在Pyth中赋值的值,因此映射J根据需要返回的每个连续值。


23

果冻,不竞争

3个字节 该答案是非竞争性的,因为它使用了挑战后的功能。

o@\

在线尝试!

这个怎么运作

o      Take the logical OR of its arguments.
 @     Reverse the argument order of the link to the left.
  \    Do a cumulative reduce, using the link to the left.

6
我的大脑无法理解...丹尼斯终于找到了永久性地打高尔夫球的方法。好像他还没有。ಠ_ಠ–
艾迪生·克伦普

1
该解释不再符合该程序的要求
quintopia

18

Ruby,25个字节

->a{a.map{|x|x==0?a:a=x}}

这实际上是非常邪恶的。

具体来说,是代码段x==0 ? a : (a=x)

如果我对a(先前的非零值)使用了其他任何变量名,比如说,y我将不得不在之外声明它map(因为y=x该范围仅在单个map迭代内)。这将多使用四个字符(y=0;)。

但是,如果我使用变量名a...是,您猜对了。我实际上是在重新分配作为输入(原始数组)的参数。

map无关紧要,因为它只关心被调用事物的原始值,因此这实际上可行。


17

Haskell,21个字节

a%0=a
a%b=b
scanl1(%)

我们做的(匿名)函数在最后一行。前两行定义了一个辅助函数。

scanl1(%) [1,0,2,0,7,7,7,0,5,0,0,0,9]
[1,1,2,2,7,7,7,7,5,5,5,5,9]

二进制函数%输出第二个参数,除非它为0,在这种情况下,它将输出第一个参数。scanl1在输入列表上迭代此函数,并在每一步输出结果。


13

J,8个字节

{:@-.&0\

这是一元函数,调用如下。

   f =: {:@-.&0\
   f 2 0 0 4 0 _1 0
2 2 2 4 4 _1 _1

说明

{:@-.&0\
       \  Map over non-empty prefixes:
   -.      remove all occurrences
     &0    of the number 0 and
{:@        take the last element.

您可以按绝对值复制而不是删除0吗?
lirtosiast

@ThomasKwa那是我的第一次尝试。是{:@(#~|)\,因此增加了一个字节。
Zgarb 2015年

13

塞德,8岁

/^0$/g
h
  • /^0$/匹配一行上的零-如果是,g则将保留空间复制到模式空间
  • h 将模式空间复制到保留空间

整数以换行符分隔。例如:

$ printf -- "-1\n0\n5\n0\n0\n7\n" | sed -f zerocover.sed
-1
-1
5
5
5
7
$ 

11

Javascript ES6,19个字节

s=>s.map(i=>p=i||p)

直接解决方案,循环输入,分配p给当前元素ipif iis 0并输出。

运行示例(将匿名函数分配给f):

>> f([1, 0, 2, 0, 7, 7, 7, 0, 5, 0, 0, 0, 9])
<< Array [1, 1, 2, 2, 7, 7, 7, 7, 5, 5, 5, 5, 9]

每当我运行此命令时,我都会收到一条错误消息:“找不到变量p”
Downgoat 2015年

@Downgoat那是因为解释器是严格模式下唯一的解释器。如果您未在严格模式下运行该代码,那么它应该可以工作。
wizzwizz4 2015年

@ wizzwizz4哦,好吧
Downgoat

1
@ wizzwizz4严格模式很傻。
SuperJedi224 2015年

1
@ SuperJedi224这并不傻。这非常有用;它可以确保您的代码没有歧义,并且即使进行重大更新也可以使用,并且不使用未定义的行为,等等。但是默认情况下启用此功能是很愚蠢的,因为严格模式未指定自行关闭的方式,如果您不将严格模式字符串放在开头,则表示您不想要它和/或正在进行代码搜寻。
wizzwizz4 2015年


7

Dyalog APL,12 10 9字节

(⊃0~⍨,⍨)\

受到@Zgarb的J答案的启发。

(⊃0~⍨,⍨)\      Monadic function:
        \      Cumulative reduce by
(⊃0~⍨,⍨)       the dyadic function:
     ,⍨           Arguments concatenated in reverse order
  0~⍨             With zeroes removed
 ⊃                Take the first element

在这里尝试。


6

Pyth,8个字节

t.u|YNQ0

.u|(Python or)的基础上使用(累积减少),基本情况为0。


@isaacg .u即使JK被绑在一起,看起来也更长。它曾经是最优的吗?
lirtosiast

这里(至少是afaik)。当您出于某种原因想要所有结果时,通常会有所帮助。
FryAmTheEggman

5

Python 2,29个字节

while 1:x=input()or x;print x

将输入作为每行给定的数字,并以相同的格式输出。完成后错误终止。

利用的短路特性or,变量x将更新为输入,除非该输入为0(即Falsey),在这种情况下它将保留其当前值。然后,x被打印。请注意,由于第一个列表值非零,x因此在分配前不会在右侧进行评估。


这是Pyth中的6个字节,并抑制了错误:#\nJ|EJ
isaacg

5

Mathematica 38字节

模式匹配反复替换...a,0,......a,a...

#//.{b___,a_/;a!=0,0,e___}:>{b,a,a,e}&

5

Matlab,41 46字节

我的原始答案启发了这一点,但有以下区别:

  1. 使用逻辑索引而不是nonzeros
  2. 双重逻辑否定,而不是与进行比较0
  3. 由于输出格式灵活,可以删除转置
  4. 删除中间变量。

感谢汤姆·卡彭特Tom Carpenter)的第4项,以及他建议使用程序代替函数;这些一起减少了5个字节。

x=input('');u=x(~~x);disp(u(cumsum(~~x)))

例:

>> x=input('');u=x(~~x);disp(u(cumsum(~~x)))
[4 0 3 2 0 5 6 0]
     4     4     3     2     2     5     6     6

您可以通过将一个字节转换为程序来保存它-使用x=input('')而不是函数声明,而disp(u(t)不是y=位。此外,您还可以摆脱的保存四个字节t变量,产生x=input('');u=x(~~x);disp(u(cumsum(~~x)))了41
汤姆·卡彭特

@TomCarpenter非常感谢!编辑
路易斯·门多

我没有Matlab,但是@(x)x(~~x)(cumsum(~~x))可以在Octave中工作。
alephalpha

@alephalpha Matlab不允许迭代索引。
AlexR 2015年

5

Gol> <>,8个字节

IE;:Z~:N

输入和输出是换行符分隔的数字。

说明:

I         push next integer to stack
 E;       halt if EOF
   :Z~    remove top stack element if 0
      :N  print top stack element while also keeping it on the stack
          wrap around code implicitly

在这里在线尝试。


5

Japt,8个 7字节

N£U=XªU

很简单 接受输入,并以逗号分隔。在线尝试!

脱节和解释

N£    U=Xª U
NmXYZ{U=X||U

        // Implicit: N = input, U = first item
NmXYZ{  // Map each item X to:
U=Z||U  //  Set U to (X || U) and return.
        //  If X is non-zero, this sets U to X.
        //  Otherwise, this leaves U as the last non-zero we've encountered.
        // Implicit: output last expression

非竞争4个字节的版本:(å命令!-自动功能的挑战后加入)

Nå!ª

说明:

Nå!ª
Nå!||
NåXY{Y||X}

        // Implicit: N = input, U = first item
NåXY{   // Cumulatively reduce N; take each item Y and prev value X,
Y||X}   //  and return Y if it is non-zero; return X otherwise.
        // Implicit: output last expression

在线尝试!


等待,ª是OR,而不是º?是ºAND吗?
caird coinheringaahing

@cairdcoinheringaahing不,º((。当我发现需要它们时,它们是按Unicode值分配的:虽然P ªnd和ºr是个天才,但我可能会将其用于Japt 2.0 ...
ETHproductions

5

爪哇,78

int[]f(int[]a){for(int i=-1,b=i;++i<a.length;a[i]=b=a[i]==0?b:a[i]);return a;}

在这里,我们只是跟踪最后一个非零值并将其推入适当的位置。似乎是显而易见的方法。


5

Prolog(SWI),54个字节

[X,0|T]+[X,X|Y]:-[X|T]+[X|Y].
[X|T]+[X|Y]:-T+Y.
[]+[].

在线尝试!

说明

我对这个答案非常满意。

首先我们说空列表是空列表的解决方案:

[]+[].

然后,如果删除其余每个解决方案的第二个条目,则说这[X,X|Y]是的解决[X,0|T]方案。

[X,0|T]+[X,X|Y]:-[X|T]+[X|Y].

最后,我们说,如果剩下的任何东西以相同的值开头并且两个列表的其余部分相互匹配,那么任何东西都是有效的。

如果该说明对您不起作用,则将代码翻译为Haskell:

g(a:0:x)=a:g(a:x)
g(a:x)=a:g x
g x=x

在线尝试!


非常简洁!我喜欢某些功能和逻辑编程语言如何使您进行规则的字面翻译。这是一种很自然的书写方式!
ThePlasmaRailgun

4

GolfScript,10个字节

~{1$or}*]`

此程序以GolfScript数组文字(例如[1 0 2 0])的形式从stdin获取输入,并将其输出以相同的格式(例如[1 1 2 2])写入stdout 。

在线尝试。

由于需要将其包装在一个块中并将其分配给一个符号,因此一个函数(获取和返回GolfScript数组)将长三个字节:

{[{1$or}*]}:f

当然,如果仅计算函数(即[{1$or}*]),那么与独立程序相比,我实际上可以节省一个字节。


新的较短的版本与Dennis的CJam条目非常相似,也许并不奇怪。它赢得一个字节,因为GolfScript自动读取输入,因此不需要额外的命令。
Ilmari Karonen 2015年

4

Minkolang 0.1412 10个字节

$I?.nd?xdN

在这里尝试。可以像问题中那样输入,但不带括号

说明

$I      Push the length of the input on the stack.
  ?.    If this is 0, stop. Otherwise, continue.

nd        Take number from input and duplicate it.
  ?x      If this number is 0, dump the top of stack.
    dN    Duplicate the top of stack and output as number

Minkolang是环形的,因此此循环一直循环到起点,一直持续到它撞到.并停止为止。


4

𝔼𝕊𝕄𝕚𝕟,7个字符/ 12个字节

ïⓜa=$⋎a

Try it here (Firefox only).

说明

        // implicit: ï = input array
ïⓜ     // map over input
  a=    // set a to:
    $   // (if element is truthy (not 0)) element itself
     ⋎a // else whatever a was set to before
        // implicit output

4

O,31个字节

[[I',T%T/]{n#}d]{n.{:V}{;V}?}d]

这将使用一个输入分隔,并在中输出相同的列表[]

7,0,3,0,0,2,-50,0,0 => [7,7,3,3,3,2,-50,-50,-50]

说明:

[]将结果放入数组
 [I',T%T /] {n#} d]将输入格式设置为数字数组
                {n。{:V} {; V}?} d填写零(有关工作原理,请参见下文)


17字节

I~]{n.{:V}{;V}?}d

使用后缀表示法将输入作为用空格分隔的数字列表,并且只能处理一位数字的十六进制数字。负数后缀为_

5 4 0 0 1 0 0 => 5 4 4 4 1 1 1
A 3 0 0 1 B 0 => 10 3 3 3 1 11 11
67* 0 0 78* 0 => 42 42 42 56 56
67*_ 4 3_ 0 0 => -42 4 -3 -3 -3

说明:

I〜]将输入放入整数数组
   {} d对于输入中的每个数字
    n。{; V} {:V}?如果数字为0,请按V
                  如果不是,则将V设置为数字

您可以使用保存两个字节I~]{n.{:V}{;V}?}d。我想知道是否d应该将值放到堆栈上而不是n...
kirbyfan64sos

您确定O可以处理吗?我找不到传递它的方法-42满足“您的输出应该是您提交的可接受输入”的要求。
manatwork

@manatwork我现在有一个适用于的更好的版本-42,但是它在输出周围添加了括号。
阶段

4

R,39 37 33字节

function(x)zoo::na.locf(x*(x|NA))

这是一个未命名的函数,它接受一个向量并返回一个向量。它需要zoo安装软件包。请注意,zoo由于我们直接引用它,因此不需要将其附加到名称空间。

在统计领域中,此操作的名称是LOCF推算,其中LOCF表示“上次进行的观察”。到R中做到这一点,我们可以使用na.locfzoo包,它取代NA与最后已知的非值NA的值。我们只需要将输入中的零替换为NA要先 s。

要做到这一点,我们使用x|NA,这将是TRUEx != 0NA其他。如果将其乘以xTRUE元素将被和的相应元素替换xNAs NA,从而替换所有零。然后将zoo::na.locf其传递给我们,这正是我们想要的。

感谢flodel,节省了4个字节!


4

锈,100字节

fn f(i:&[i64])->Vec<i64>{let(mut o,mut l)=(i.to_vec(),0);
for x in&mut o{if *x==0{*x=l}else{l=*x}};o}

偶然发现了这个挑战,以为我会用自己喜欢的语言尝试一下。首先尝试使用[T]::windows_mut(),然后才发现它不存在。实际上可能比这更长。无论如何,事实证明,打高尔夫球的Rust很丑陋,也很没有竞争力(尤其是那些所有经过深思熟虑的神秘主义者!)1

换行符不包含在字节数中;它只是在那里,所以您不必横向滚动。它不会改变代码的含义。

取消高尔夫:

fn cover_zeroes(input: &[i64]) -> Vec<i64> {
    let mut output = input.to_vec();
    let mut last_nonzero = 0;
    for item in &mut output {
        if *item == 0 {
            *item = last_nonzero;
        }
        else {
            last_nonzero = *item;
        }
    }
    output
}

[1]至少它不像Java那样糟糕。


7
至少它不像Java那样糟糕 ”?
哎呀

1
@Geobits哦,对。我指望你需要那个public static void main样板……
Blacklight Shining 15'8

3

银河1.2.1,33字节

:y;=<:&{~<?{0b_^;:3≤_;}1-}^<Ω!

这假定整数列表仅在堆栈上。


说明

:    : :           :              # duplicate the TOS
 y                                # push the length of the TOS
  ;               ;    ;          # swap the TOS and STOS
   =                              # dump a list to the stack
    < <    <                 <    # rotate the stack leftward
        &{~                }      # while loop
            ?{  _     _ }         # if-else statements
              0     3    1        # push an integer
               b                  # == on the TOS and STOS
                 ^          ^     # pop the TOS without output
                     ≤            # rotate the top N stack elements leftward
                          -       # subtract the TOS from the STOS
                              Ω   # push a list made of the top N stack elements
                               !  # output the TOS

我很确定TOS和STOS表示“堆栈顶部”和“倒数第二”,对吗?
Addison Crump 2015年

是的@FlagAsSpam
Zach Gates

3

朱莉娅,33个字节

g(x,a=0)=[(i!=0&&(a=i);a)for i=x]

这是一个g接受数组并返回数组的函数。我们从a0 开始一个临时变量。对于i输入的每个元素,如果i不为0,则将其分配ai。如果i为0,a则在该迭代中不更改。我们将其a用作输出数组中该位置的值。


3

Perl 6,21个字节

*.map: {$_=($^a||$_)}

用法:

# store the Whatever lambda as a subroutine
# just so that we don't have to repeat it
my &code = *.map: {$_=($^a||$_)}

say code [1, 0, 2, 0, 7, 7, 7, 0, 5, 0, 0, 0, 9];
# (1 1 2 2 7 7 7 7 5 5 5 5 9)

say [-1, 0, 5, 0, 0, -7].&code;
# (-1 -1 5 5 5 -7)

say ([1, 0, 0, 0, 0, 0],[-1, 0, 5, 0, 0, -7]).map: &code;
# ((1 1 1 1 1 1) (-1 -1 5 5 5 -7))

3

R,36个字节

function(x)x[cummax(seq(a=x)*(!!x))]

让我们看看如何使用 x=

c(1, 0, 2, 0, 7, 7, 7, 0, 5, 0, 0, 0, 9)

举个例子。在这里,!!x将是逻辑(True / False)向量:

c(T, F, T, F, T, T, T, F, T, F, F, F, T)

另外,seq(a=x)给出一个索引向量,只要x

c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13)

我们将两者相乘,得到:

c(1, 0, 3, 0, 5, 6, 7, 0, 9, 0, 0, 0, 13)

我们采用累计最大值:

c(1, 1, 3, 3, 5, 6, 7, 7, 9, 9, 9, 9, 13)

最后,我们使用最后一个向量作为要从中提取的索引x

c(1, 1, 2, 2, 7, 7, 7, 7, 5, 5, 5, 5, 9)

3

CJam,11个字节

q~{1$e|}*]p

在线尝试。

这个怎么运作

q~             Read and evaluate all input.
  {    }*      Fold; for each element but the first:
   1$e|          Copy the previous element and take their logical OR.
         ]p   Wrap all results in an array and print it.

3

Powershell,32字节

param($x)$x|%{($t=($_,$t)[!$_])}

$x|%{...}对中的每个元素执行脚本块$x($_,$t)是当前元素和的数组$t[!$_]表示我们!$_用来索引该数组。0对于非零元素,索引将为(false),1当当前元素为零时,索引为(true),因此$t将是当前元素或$t。括号括住赋值表达式,以便发出其值。如果没有括号,这将是对的“安静”分配$t


@TimmyD,您当然是对的。我添加param($x)了将其转换为程序。输出是整数的集合,您可以将其作为参数提交给程序,例如$a = .\program.ps1 1,2,3,4,0,0,5,然后.\program.ps1 $a按预期工作。
DankoDurbić2015年

$args|%{($p=($_,$p)[!$_])}-使用$ args为26个字节。
TessellatingHeckler,2015年

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.