Encubrir ceros en una lista


41

Inspirado por esta pregunta SO

Como entrada, se le dará una lista no entera de enteros, donde se garantiza que el primer valor no sea cero. Para construir la salida, camine desde el principio de la lista, generando cada valor distinto de cero en el camino. Cuando encuentre un cero, repita el valor que agregó más recientemente a la salida.

Puede escribir un programa o función, y hacer que la entrada / salida tome cualquier formato conveniente que no codifique información adicional, siempre y cuando siga siendo una secuencia ordenada de enteros. Si sale de un programa, puede imprimir una nueva línea final. Excepto por esta nueva línea final, su salida debe ser una entrada aceptable para su envío.

El código más corto en bytes gana.

Casos de prueba

[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
Un poco de trivia: el nombre de esta operación en el mundo de las estadísticas es la imputación LOCF (última observación realizada).
Alex A.

¿Qué sucede si la entrada fue [0,0]?
Kritixi Lithos

44
@ KριτικσιΛίθος "... donde se garantiza que el primer valor sea distinto de cero"
Sp3000

¿Qué pasa si la entrada es [1,01]? Usando la respuesta Pyth de issac, compare esto y esto .
Arcturus

@Eridan 01no es un número entero válido en la entrada de Pyth, por lo que Isaac no tiene que dar cuenta de eso. Otras respuestas pueden aceptar entradas como esa si lo desean, siempre y cuando sean consistentes (como la respuesta de
Isaac

Respuestas:


19

Pyth, 6 bytes

mJ|dJQ

Demostración

m ... Qsignifica que esto asigna una función sobre la entrada. La función que se está mapeando es J|dJ. Eso significa J = d or Jen Python, ya que Jes implícitamente asignado al siguiente valor en el primer uso. A diferencia de Python, las expresiones de asignación devuelven el valor asignado en Pyth, por lo que el mapa devuelve cada valor sucesivo de J, según se desee.


23

Gelatina , no competidora

3 bytes Esta respuesta no es competitiva, ya que utiliza características que son posteriores al desafío.

o@\

Pruébalo en línea!

Cómo 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.

66
Mi cerebro no puede comprender ... Dennis finalmente ha encontrado una manera de sacarnos el golf permanentemente. Como si ya no lo hubiera hecho. ಠ_ಠ
Addison Crump

1
La explicación ya no se alinea con el programa
quintopia

18

Rubí, 25 bytes.

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

Esto es realmente muy malvado.

Específicamente, el fragmento x==0 ? a : (a=x).

Si hubiera utilizado cualquier otro nombre de variable para a(el valor anterior distinto de cero), digamos: ytendría que declararlo fuera de map(porque y=xsolo tendría un alcance dentro de esa única mapiteración). Eso usaría cuatro caracteres más ( y=0;).

Pero si uso el nombre de la variable a... sí, lo has adivinado. Realmente estoy reasignando al argumento que obtuvimos como entrada (la matriz original).

mapno le importa porque solo le importa el valor original de la cosa a la que se llama, por lo que esto realmente funciona.


17

Haskell, 21 bytes

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

La función (anónima) que hacemos está en la última línea. Las dos primeras líneas definen una función 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]

La función binaria %genera el segundo argumento, a menos que sea 0, en cuyo caso genera el primer argumento. scanl1itera esta función sobre la lista de entrada, generando el resultado en cada paso.


13

J, 8 bytes

{:@-.&0\

Esta es una función unaria, invocada de la siguiente manera.

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

Explicación

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

¿Se puede replicar por valor absoluto en lugar de eliminar 0s?
lirtosiast el

@ThomasKwa Ese fue mi primer intento. Es {:@(#~|)\, así que un byte más.
Zgarb

13

Sed, 8

/^0$/g
h
  • /^0$/coincide con un cero en una línea; si es así, gcopia el espacio de espera en el espacio del patrón
  • h copia el espacio del patrón en el espacio de espera

Los enteros están separados por una nueva línea. p.ej:

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

Solución directa, bucle a través de la entrada, asignar pal elemento actual io psi ies 0y generarlo.

Ejemplo ejecutado (asignando una función 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]

Cada vez que ejecuto esto recibo un error que dice "no puedo encontrar la variable p"
Downgoat

@Downgoat Esto se debe a que el intérprete es un intérprete solo en modo estricto. Si no ejecuta ese código en modo estricto, debería funcionar.
wizzwizz4

@ wizzwizz4 ohh, r está bien
Downgoat

1
@ wizzwizz4 El modo estricto es una tontería.
SuperJedi224

1
@ SuperJedi224 No es tonto. Es muy útil; se asegura de que su código no sea ambiguo, y que funcione incluso con una actualización importante, y no use un comportamiento indefinido, etc. , y si no coloca la cadena de modo estricto al principio, no la quiere y / o está jugando al código.
wizzwizz4


7

Dyalog APL, 12 10 9 bytes

(⊃0~⍨,⍨)\

Inspirado por la respuesta 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

Probarlo aquí .


6

Pyth, 8 bytes

t.u|YNQ0

Usos .u(reducción acumulativa) por |(Python or), con el caso base 0.


@isaacg Parece que .ues más largo, incluso si Jy Kestán atados. ¿Alguna vez es óptimo?
lirtosiast

Fue (al menos afaik) aquí . Por lo general, ayuda cuando desea obtener todos los resultados por algún motivo.
FryAmTheEggman

5

Python 2, 29 bytes

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

Toma la entrada como números dados uno por línea, y las salidas en el mismo formato. Termina con error después de terminar.

Usando la naturaleza de cortocircuito de or, la variable xse actualiza a la entrada, a menos que esa entrada sea 0 (que es Falsey), en cuyo caso permanece su valor actual. Entonces, xse imprime. Tenga en cuenta que, dado que el primer valor de la lista no es cero, xno se evalúa en el lado derecho antes de ser asignado.


Esto es 6 bytes en Pyth, y suprime el error:#\nJ|EJ
isaacg

5

Mathematica 38 bytes

La coincidencia de patrones reemplaza repetidamente ...a,0,...con...a,a...

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

5

Matlab, 41 46 bytes

Esto está inspirado en mi respuesta original , con las siguientes diferencias:

  1. Utilice la indexación lógica en lugar de nonzeros.
  2. Doble negación lógica en lugar de comparar con 0.
  3. La transposición se puede eliminar, ya que el formato de salida es flexible
  4. Eliminar una variable intermedia.

Gracias a Tom Carpenter por el ítem 4, y por su sugerencia de usar un programa en lugar de una función; juntos permitieron una reducción de 5 bytes.

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

Ejemplo:

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

Puede guardar un byte convirtiéndolo en un programa: use en x=input('')lugar de la declaración de función y en disp(u(t)lugar del y=bit. Además, puede guardar cuatro bytes más al deshacerse de la tvariable, produciendo x=input('');u=x(~~x);disp(u(cumsum(~~x)))41.
Tom Carpenter

@TomCarpenter ¡Muchas gracias! Editado
Luis Mendo

No tengo Matlab, pero @(x)x(~~x)(cumsum(~~x))funciona en Octave.
alephalpha

@alephalpha Matlab no permite la indexación iterada.
AlexR

5

Gol> <> , 8 bytes

IE;:Z~:N

Entrada y salida son números separados por nueva línea.

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

Pruébelo en línea aquí.


5

Japt, 8 7 bytes

N£U=XªU

Bastante simple. Toma entradas separadas por comas. Pruébalo en línea!

Sin golfos y explicación

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

Versión de 4 bytes no competitiva : ( åcomando y !función automática añadidos después del desafío)

Nå!ª

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

Pruébalo en línea!


Espera, ªes OR, en lugar de º? ¿ ºY es por casualidad?
caird coinheringaahing

@cairdcoinheringaahing No, ºes ((. Fueron asignados por valor Unicode ya que encontré la necesidad de ellos: P ªnd and ºr es genial, aunque podría usar eso 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;}

Aquí solo hacemos un seguimiento del último valor distinto de cero y lo introducimos donde corresponda. Parece la forma obvia de hacerlo.


5

Prólogo (SWI) , 54 bytes

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

Pruébalo en línea!

Explicación

Estoy realmente feliz con esta respuesta.

Primero decimos que la lista vacía es la solución de la lista vacía:

[]+[].

Luego decimos que esa [X,X|Y]es la solución [X,0|T], si eliminamos la segunda entrada de cada una de las soluciones restantes.

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

Por último, decimos que cualquier cosa sobrante es válida si comienzan con el mismo valor y el resto de las dos listas coinciden entre sí.

Si esa explicación no funciona para usted, aquí está el código traducido a Haskell:

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

Pruébalo en línea!


Muy conciso! Me gusta cómo algunos lenguajes de programación funcionales y lógicos le permiten hacer una traducción literal de las reglas. ¡Es una forma tan natural de escribirlo!
ThePlasmaRailgun

4

GolfScript, 10 bytes

~{1$or}*]`

Este programa toma la entrada de stdin, en forma de una matriz de GolfScript literal (por ejemplo [1 0 2 0]), y escribe su salida en stdout en el mismo formato (por ejemplo [1 1 2 2]).

Pruébalo en línea.

Una función (tomar y devolver una matriz GolfScript) sería tres bytes más larga, debido a la necesidad de envolverla en un bloque y asignarla a un símbolo:

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

Por supuesto, si solo se cuenta el cuerpo de la función (es decir, [{1$or}*]), entonces puedo guardar un byte en comparación con el programa independiente.


Tal vez no sea sorprendente, la nueva versión más corta resultó muy similar a la entrada de Dennis en CJam . Gana un byte porque GolfScript lee la entrada automáticamente y, por lo tanto, no necesita un comando adicional para eso.
Ilmari Karonen

4

Minkolang 0.14 , 12 10 bytes

$I?.nd?xdN

Pruébalo aquí La entrada se puede dar como en la pregunta, pero sin corchetes .

Explicación

$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 es toroidal, por lo que gira hasta el principio y continúa hasta que golpea .y se detiene.


4

𝔼𝕊𝕄𝕚𝕟, 7 caracteres / 12 bytes

ïⓜa=$⋎a

Try it here (Firefox only).

Explicación

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

Esto toma una entrada separada por ,y genera la misma lista [].

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

Explicación:

[] Poner el resultado en la matriz
 [I ', T% T /] {n #} d] Formatea la entrada en una matriz de números
                {n. {: V} {; V}?} d Complete los ceros (vea a continuación cómo funciona esto)


17 bytes

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

Toma datos como una lista de números separados por espacios usando notación postfix y solo puede manejar números hexadecimales de un solo dígito. Los negativos se posponen con _.

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

Explicación:

I ~] Pone la entrada en una matriz entera
   {} d Para cada número en la entrada
    n. {; V} {: V}? Si el número es 0, presione V
                  Si no, establezca V en el número

Puede guardar dos bytes con I~]{n.{:V}{;V}?}d. Me pregunto si ddebería poner el valor en la pila en lugar de n...
kirbyfan64sos

¿Estás seguro de que O puede manejar esto? No puedo encontrar la manera de pasarlo -42 satisfaciendo el requisito de "su salida debe ser una entrada aceptable para su envío".
manatwork

@manatwork Tengo una versión mejor ahora que funciona -42, pero agrega corchetes alrededor de la salida.
fase

4

R, 39 37 33 bytes

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

Esta es una función sin nombre que acepta un vector y devuelve un vector. Requiere zooque se instale el paquete. Tenga en cuenta que no es necesario zooque se adjunte al espacio de nombres ya que lo estamos haciendo referencia directamente.

El nombre de esta operación en el mundo de las estadísticas es imputación de LOCF, donde LOCF significa última observación llevada adelante. Para lograr esto en R, podemos usarlo na.locfdesde el zoopaquete, que reemplaza los NAvalores con el último no NAvalor conocido . Solo tenemos que reemplazar los ceros en la entrada con NAs primero.

Para hacer eso, usamos x|NA, que será TRUEcuando x != 0y de NAotra manera. Si multiplicamos esto por x, los TRUEelementos se reemplazan por los elementos correspondientes de xy los NAs permanecen NA, reemplazando así todos los ceros. Esto se pasa a lo zoo::na.locfque nos da exactamente lo que queremos.

¡Guardado 4 bytes gracias a flodel!


4

Óxido, 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}

Tropecé con este desafío, pensé en probarlo en mi idioma favorito. Intenté usarlo [T]::windows_mut()al principio, antes de descubrir que no existe . Y en realidad podría haber sido más largo que esto. De todos modos, resulta que el Rust golfizado es muy feo y no es muy competitivo (¡especialmente con todos esos esotéricos anticuados!) 1

La nueva línea no está incluida en el bytecount; solo está ahí para que no tenga que desplazarse hacia los lados. No cambia el significado del código.

Sin golf:

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] Al menos no es tan malo como Java.


77
" Al menos no es tan malo como Java "? Ejem ... ;)
Geobits

1
@Geobits Oh, cierto. Contaba con que necesitaras esa public static void mainplaca repetitiva ...
Blacklight Shining

3

Vía Láctea 1.2.1 , 33 bytes

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

Esto supone que la lista de enteros está únicamente en la pila.


Explicación

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

Estoy bastante seguro de que TOS y STOS significan Top of Stack y Second to Top of Stack, ¿es así?
Addison Crump

Sí @FlagAsSpam
Zach Gates

3

Julia, 33 bytes

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

Esta es una función gque acepta una matriz y devuelve una matriz. Comenzamos una variable temporal aen 0. Para cada elemento ide la entrada, si ino es 0, entonces asignamos aa i. Si ies 0, ano cambia en esa iteración. Usamos acomo el valor en esa posición en la matriz de salida.


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

Veamos cómo funciona esto usando x=

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

como ejemplo. Aquí, !!xserá el vector lógico (Verdadero / Falso):

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

Además, seq(a=x)proporciona un vector de índices siempre 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 el máximo acumulativo:

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

Finalmente, usamos ese último vector como los índices para extraer de x:

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

3

CJam, 11 bytes

q~{1$e|}*]p

Pruébalo en línea.

Cómo 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|%{...}hace el bloque de script para cada elemento en $x. ($_,$t)es una matriz de elementos actuales $ty [!$_]significa que usamos !$_para indexar en la matriz. El índice será 0(falso) para elementos distintos de cero y 1(verdadero) cuando el elemento actual sea cero, por $tlo que será el elemento actual o $t. Los paréntesis rodean la expresión de asignación para que se emita su valor. Sin paréntesis, sería una tarea "silenciosa" $t.


@TimmyD, tienes razón, por supuesto. He agregado lo param($x)que convierte esto en un programa. El resultado es una colección de enteros que puede enviar como parámetro al programa, por ejemplo, $a = .\program.ps1 1,2,3,4,0,0,5y luego .\program.ps1 $afunciona como se espera.
Danko Durbić

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.