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]
FryAmTheEggman
fuente
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.

isaacg
fuente
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.
Dennis
fuente
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.

Pomo de la puerta
fuente
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.

xnor
fuente
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.
Zgarb
fuente
¿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
$ 
Trauma digital
fuente
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]
Dendrobium
fuente
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

Retina , 15 bytes

+`(\S+) 0
$1 $1

Pruébalo en línea.

Reemplaza repetidamente un número seguido de un cero con el doble de ese número hasta que la cadena deja de cambiar.

Martin Ender
fuente
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í .

lirtosiast
fuente
6

Pyth, 8 bytes

t.u|YNQ0

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

lirtosiast
fuente
@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.

xnor
fuente
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}&
DavidC
fuente
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
Luis Mendo
fuente
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í.

randomra
fuente
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!

ETHproducciones
fuente
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.

Geobits
fuente
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!

Asistente de trigo
fuente
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.

Ilmari Karonen
fuente
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.

El'endia Starman
fuente
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
Mama Fun Roll
fuente
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
fase
fuente
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!

Alex A.
fuente
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.

Blacklight Shining
fuente
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
Puertas de Zach
fuente
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.

Alex A.
fuente
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))
Brad Gilbert b2gills
fuente
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)
flodel
fuente
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.
Dennis
fuente
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.

Danko Durbić
fuente
@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
3

Japt , 3 bytes

å!ª

Intentalo

å!ª     :Implicit input of array
å       :Cumulatively reduce
 !      :Flip the arguments
  ª     :Logical OR
Lanudo
fuente