Encobrir zeros em uma lista


41

Inspirado por esta pergunta SO

Como entrada, você receberá uma lista não vazia de números inteiros, onde o primeiro valor é garantido como diferente de zero. Para construir a saída, caminhe desde o início da lista, produzindo cada valor diferente de zero ao longo do caminho. Quando você encontrar um zero, repita o valor que você adicionou mais recentemente à saída.

Você pode escrever um programa ou função e fazer com que a entrada / saída assuma qualquer formato conveniente que não codifique informações extras, desde que ainda seja uma sequência ordenada de números inteiros. Se estiver produzindo a partir de um programa, você poderá imprimir uma nova linha à direita. Exceto por esta nova linha à direita, sua saída deve ser uma entrada aceitável para o envio.

O código mais curto em bytes vence.

Casos de teste

[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
Um pouco de trivialidades: o nome dessa operação no mundo das estatísticas é imputação de LOCF (última observação transportada).
Alex A.

O que acontece se a entrada foi [0,0]?
Kritixi Lithos

4
@ KριτικσιΛίθος "... onde o primeiro valor é garantido como diferente de zero"
Sp3000 5/15/15

E se a entrada for [1,01]? Usando, a resposta Pyth do issac, compare isso e isso .
quer

@Eridan 01não é um número inteiro válido na entrada Pyth, portanto o isaac não precisa dar conta disso. Outras respostas pode aceitar a entrada como que se eles querem, contanto que eles são consistentes (como a forma como a resposta de isaac nunca produzirá essa lista como saída)
FryAmTheEggman

Respostas:


19

Pitão, 6 bytes

mJ|dJQ

Demonstração

m ... Qsignifica que isso mapeia uma função sobre a entrada. A função que está sendo mapeada é J|dJ. Isso significa J = d or Jem Python, já que Jé implícito atribuído ao seguinte valor no primeiro uso. Diferentemente do Python, as expressões de atribuição retornam o valor atribuído em Pyth, portanto, o mapa retorna cada valor sucessivo de J, conforme desejado.


23

Gelatina , não concorrente

3 bytes Esta resposta não é concorrente, pois usa recursos que pós-datam o desafio.

o@\

Experimente online!

Como funciona

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
Meu cérebro não consegue compreender ... Dennis finalmente encontrou uma maneira de nos jogar permanentemente. Como ele já não tinha. ಠ_ಠ
Addison Crump

11
A explicação não está mais alinhada com o programa
quintopia

18

Ruby, 25 bytes

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

Isso é realmente muito ruim.

Especificamente, o trecho x==0 ? a : (a=x).

Se eu tivesse usado outro nome de variável para a(o valor diferente de zero anterior) - digamos y- eu teria que declará-lo fora do map(porque y=xsó teria um escopo dentro dessa mapiteração única ). Isso usaria mais quatro caracteres ( y=0;).

Mas se eu usar o nome da variável a... sim, você adivinhou. Na verdade, estou reatribuindo ao argumento que recebemos como entrada (a matriz original).

mapnão se importa, porque se importa apenas com o valor original da coisa que está sendo chamada, então isso realmente funciona.


17

Haskell, 21 bytes

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

A função (anônima) que criamos está na última linha. As duas primeiras linhas definem uma função auxiliar.

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]

A função binária %gera o segundo argumento, a menos que seja 0, nesse caso, gera o primeiro argumento. scanl1itera essa função na lista de entrada, exibindo o resultado a cada etapa.


13

J, 8 bytes

{:@-.&0\

Esta é uma função unária, invocada da seguinte maneira.

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

Explicação

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

Você pode replicar por valor absoluto em vez de remover 0s?
precisa saber é o seguinte

@ThomasKwa Essa foi minha primeira tentativa. É {:@(#~|)\, então, um byte a mais.
Zgarb

13

Sed, 8

/^0$/g
h
  • /^0$/corresponde a zero em uma linha - se sim, gcopia o espaço de espera para o espaço do padrão
  • h copia o espaço do padrão para o espaço de espera

Os números inteiros são separados por nova linha. por exemplo:

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

11

Javascript ES6, 19 bytes

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

Solução simples, faça um loop na entrada, atribua pao elemento atual iou a pif iis 0e faça a saída.

Exemplo de execução (atribuindo função anônima a 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]

Sempre que executo isso , recebo um erro dizendo "não é possível encontrar a variável p"
Downgoat

@ Downgoat Isso ocorre porque o intérprete é apenas um intérprete no Modo Estrito. Se você não executar esse código no modo estrito, ele deverá funcionar.
Wizzwizz4

@ wizzwizz4 ohh, r okay #
Downgoat 6/12/15

11
@ wizzwizz4 O modo estrito é bobo.
precisa saber é o seguinte

11
@ SuperJedi224 Não é bobo. É muito útil; ele garante que seu código não seja ambíguo e funcione mesmo com uma atualização importante, e não use comportamento indefinido etc. Mas o que é bobagem é ativá-lo por padrão, pois o modo Estrito não especifica uma maneira de se desligar , e se você não colocar a string de modo estrito no começo, não a desejará e / ou fará código de golfe.
Wizzwizz4


7

Dyalog APL, 12 10 9 bytes

(⊃0~⍨,⍨)\

Inspirado pela resposta J de @ Zgarb.

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

Experimente aqui .


6

Pitão, 8 bytes

t.u|YNQ0

Usa .u(redução cumulativa) por |(Python or), com o caso base 0.


@isaacg Parece que .ué mais longo, mesmo se Je Ksão amarrados. É sempre ideal?
lirtosiast

Foi (pelo menos afaik) aqui . Geralmente ajuda quando você deseja obter todos os resultados por algum motivo.
FryAmTheEggman

5

Python 2, 29 bytes

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

Recebe a entrada como números dados um por linha e sai no mesmo formato. Termina com erro após o término.

Usando a natureza de curto-circuito de or, a variável xé atualizada para a entrada, a menos que essa entrada seja 0 (que é Falsey), caso em que permanece seu valor atual. Então, xé impresso. Observe que, como o primeiro valor da lista é diferente de zero, xnão é avaliado no lado direito antes de ser atribuído.


Isso é 6 bytes em Pyth e suprime o erro:#\nJ|EJ
isaacg 4/15/15

5

Mathematica 38 bytes

A correspondência de padrões substitui repetidamente ...a,0,...por...a,a...

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

5

Matlab, 41 46 bytes

Isso é inspirado na minha resposta original , com as seguintes diferenças:

  1. Use indexação lógica em vez de nonzeros.
  2. Negação lógica dupla em vez de comparar com 0.
  3. A transposição pode ser removida, pois o formato de saída é flexível
  4. Removendo uma variável intermediária.

Agradecemos a Tom Carpenter pelo item 4 e por sua sugestão de usar um programa em vez de uma função; juntos, eles permitiram uma redução de 5 bytes.

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

Exemplo:

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

Você pode salvar um byte convertendo-o em um programa - use em x=input('')vez da declaração da função e em disp(u(t)vez do y=bit. Além disso, você pode salvar mais quatro bytes, livrando-se da tvariável, resultando x=input('');u=x(~~x);disp(u(cumsum(~~x)))em 41.
Tom Carpenter

@TomCarpenter Muito obrigado! Editado
Luis Mendo

Eu não tenho Matlab, mas @(x)x(~~x)(cumsum(~~x))funciona no Octave.
Alephalpha

@alephalpha O Matlab não permite indexação iterada.
AlexR

5

Gol> <> , 8 bytes

IE;:Z~:N

Entrada e saída são números separados por nova linha.

Explicação:

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

Experimente online aqui.


5

Japonês, 8 7 bytes

N£U=XªU

Bem simples. Separa a entrada por vírgulas. Experimente online!

Ungolfed e explicação

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

Versão não concorrente de 4 bytes : ( åcomando e !-auto-function adicionados após o desafio)

Nå!ª

Explicação:

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

Experimente online!


Espere, ªé OR, em vez de º? ºE é por acaso?
caird coinheringaahing

@cairdcoinheringaahing Não, ºé ((. Eles foram designados pelo valor Unicode como eu encontrei a necessidade para eles: P ªnd e ºr é um gênio, porém, eu poderia usar isso para Japt 2.0 ...
ETHproductions

5

Java, 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;}

Aqui, apenas controlamos o último diferente de zero e o inserimos onde for apropriado. Parece a maneira óbvia de fazê-lo.


5

Prolog (SWI) , 54 bytes

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

Experimente online!

Explicação

Estou muito feliz com esta resposta.

Primeiro, dizemos que a lista vazia é a solução da lista vazia:

[]+[].

Então dizemos que [X,X|Y]é a solução de [X,0|T], se removendo a segunda entrada de cada uma das soluções restantes.

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

Por fim, dizemos que qualquer coisa restante é válida se começarem com o mesmo valor e o restante das duas listas coincidirem.

Se essa explicação não estiver funcionando para você, aqui está o código traduzido para Haskell:

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

Experimente online!


Muito conciso! Gosto de como algumas linguagens de programação lógicas e funcionais permitem que você faça uma tradução literal dessas regras. É uma maneira tão natural de escrever!
ThePlasmaRailgun 27/09

4

GolfScript, 10 bytes

~{1$or}*]`

Este programa recebe a entrada de stdin, na forma de uma matriz GolfScript literal (por exemplo [1 0 2 0]), e grava sua saída em stdout no mesmo formato (por exemplo [1 1 2 2]).

Experimente online.

Uma função (obtendo e retornando uma matriz GolfScript) teria três bytes a mais, devido à necessidade de envolvê-la em um bloco e atribuí-la a um símbolo:

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

Obviamente, se apenas o corpo da função (ou seja [{1$or}*]) for contado, então eu posso salvar um byte em comparação com o programa independente.


Talvez não seja de surpreender que a nova versão mais curta tenha sido muito semelhante à entrada de Dennis no CJam . Ele ganha por um byte porque o GolfScript lê a entrada automaticamente e, portanto, não precisa de um comando extra para isso.
Ilmari Karonen

4

Minkolang 0.14 , 12 10 bytes

$I?.nd?xdN

Experimente aqui. A entrada pode ser fornecida como na pergunta, mas sem colchetes .

Explicação

$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 é toroidal, então isso faz um loop até o início e continua até que ele atinja .e pare.


4

, 7 caracteres / 12 bytes

ïⓜa=$⋎a

Try it here (Firefox only).

Explicação

        // 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 bytes

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

Isso leva uma entrada separada por ,e gera a mesma lista em [].

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

Explicação:

[] Colocar resultado na matriz
 [I ', T% T /] {n #} d] Formate a entrada na matriz de números
                {n. {: V} {; V}?} d Preencha zeros (veja abaixo como isso funciona)


17 bytes

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

Recebe a entrada como uma lista de números separados por espaços usando a notação postfix e pode lidar apenas com números hexadecimais de um dígito. Os negativos são postfixados com _.

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

Explicação:

I ~] Coloca a entrada na matriz inteira
   {} d Para cada número na entrada
    n. {; V} {: V}? Se o número for 0, pressione V
                  Caso contrário, defina V como o número

Você pode salvar dois bytes com I~]{n.{:V}{;V}?}d. Gostaria de saber se ddeve apenas colocar o valor na pilha em vez de n...
kirbyfan64sos

Tem certeza de que O pode lidar com isso? Não consigo encontrar a maneira de transmiti-lo satisfazendo o requisito "sua saída deve ser uma entrada aceitável para sua submissão".
Manatwork

@ manatwork Eu tenho uma versão melhor agora que funciona -42, mas adiciona colchetes ao redor da saída.
fase

4

R, 39 37 33 bytes

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

Esta é uma função sem nome que aceita um vetor e retorna um vetor. Requer que o zoopacote esteja instalado. Observe que ele não precisa zooser anexado ao espaço para nome, pois estamos fazendo referência direta a ele.

O nome para esta operação no mundo das estatísticas é imputação LOCF, em que LOCF significa Última Observação Realizada. Para fazer isso em R, podemos usar na.locfo zoopacote, que substitui NAvalores pelo último não NAvalor conhecido . Nós apenas temos que substituir os zeros na entrada por NAs primeiro.

Para fazer isso, usamos x|NA, que será TRUEquando x != 0e de NAoutra forma. Se multiplicarmos por x, os TRUEelementos serão substituídos pelos elementos correspondentes de xe NAs permanecem NA, substituindo todos os zeros. Isso é passado para o zoo::na.locfque nos dá exatamente o que queremos.

Economizou 4 bytes graças ao flodel!


4

Ferrugem, 100 bytes

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}

Tropecei nesse desafio, e pensei em tentar no meu idioma favorito. Tentei usar [T]::windows_mut()primeiro, antes de descobrir que não existe . E pode ter sido realmente mais longo do que isso. De qualquer forma, acontece que o Rust jogado no golfe é muito feio e não é competitivo (especialmente com todos aqueles esotéricos malditos!) 1

A nova linha não está incluída no bytecount; está lá apenas para que você não precise rolar para o lado. Não altera o significado do código.

Ungolfed:

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] Pelo menos não é tão ruim quanto o Java.


7
" Pelo menos não é tão ruim quanto o Java "? Ahem ... ;)
Geobits

11
@ Geobits Oh, certo. Eu estava contando com você precisando desse public static void mainclichê ...
Blacklight Shining

3

Via Láctea 1.2.1 , 33 bytes

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

Isso pressupõe que a lista de números inteiros esteja apenas na pilha.


Explicação

:    : :           :              # 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

Tenho certeza de que TOS e STOS significam Top of Stack e Second-to-Top of Stack, não é mesmo?
Addison Crump

Simp @FlagAsSpam
Zach Gates

3

Julia, 33 bytes

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

Esta é uma função gque aceita uma matriz e retorna uma matriz. Iniciamos uma variável temporária aem 0. Para cada elemento ida entrada, se inão for 0, atribuímos aa i. Se ifor 0, anão muda nessa iteração. Nós usamos acomo valor nessa posição na matriz de saída.


3

Perl 6 , 21 bytes

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

uso:

# 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 bytes

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

Vamos ver como isso funciona usando x=

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

como um exemplo. Aqui, !!xserá o vetor lógico (Verdadeiro / Falso):

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

Além disso, seq(a=x)fornece um vetor de índices desde que x:

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

Multiplicamos ambos, dando:

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

Tomamos o máximo cumulativo:

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

Por fim, usamos esse último vetor como índices para extrair de x:

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

3

CJam, 11 bytes

q~{1$e|}*]p

Experimente online.

Como funciona

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 bytes

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

$x|%{...}faz o bloco de scripts para cada elemento em $x. ($_,$t)é uma matriz do elemento atual e $t, e [!$_]significa que usamos !$_para indexar a matriz. O índice será 0(falso) para elementos diferentes de zero e 1(verdadeiro) quando o elemento atual for zero, também $tserá o elemento atual ou $t. Os parênteses cercam a expressão de atribuição para que seu valor seja emitido. Sem parênteses, seria apenas uma tarefa "silenciosa" $t.


@ TimmyD, você está certo, é claro. Eu adicionei o param($x)que transforma isso em um programa. A saída é uma coleção de números inteiros que você pode enviar como um parâmetro para o programa, por exemplo, $a = .\program.ps1 1,2,3,4,0,0,5e depois .\program.ps1 $afunciona como esperado.
Danko Durbić

$args|%{($p=($_,$p)[!$_])}- 26 bytes usando $ args.
TessellatingHeckler

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.