Diferente camino a seguir

23

Dada una lista de enteros, se produce una diferencia directa en un orden / profundidad especificada.

Para la lista de enteros:

(10, 18, -12, 4, 8, -3, -5, 67, 9, 14)

Las diferencias de avance en los distintos órdenes / profundidades son:

0   10,   18,  -12,    4,    8,   -3,   -5,  67,  9,  14
1      8,  -30,   16,    4,  -11,   -2,   72, -58,  5
2       -38,   46,  -12,  -15,    9,   74, -130, 63
3           84,  -58,   -3,   24,   65, -204, 193
4            -142,   55,   27,   41, -269, 397
5               197,  -28,   14, -310, 666
6                 -225,   42, -324, 976
7                    267, -366, 1300
8                      -633, 1666
9                         2299

Entonces con la entrada de

4, (10, 18, -12, 4, 8, -3, -5, 67, 9, 14)

Devolverías la lista

(-142,   55,   27,   41, -269, 397)

Entrada

La entrada puede ser a través de STDIN o parámetros de función.

Un entero que especifica la profundidad a devolver. Esto será 0 a la longitud de la lista menos 1

Una lista de enteros para calcular la diferencia de avance para

Salida

La salida puede ser a través de STDOUT o devuelta por la función.

Las diferencias de avance para la profundidad especificada como una lista de enteros

Reglas

Las funciones integradas y de terceros que hacen esto directamente no están permitidas.

Se aplican restricciones de escapatoria estándar .

El código más corto gana

MickyT
fuente

Respuestas:

19

J, 15 9 7 bytes

Muy fácil. Toma profundidad y enumera como argumentos izquierdo y derecho.

-~/\~&2

Como una definición explícita sin todos los trucos adverbiales, esto se reduce a

4 : '(2 -~/\ ])^:x y'
  • -~/\~&2 y- La diferencia hacia adelante de y.
  • x -~/\~&2 y- La xenésima diferencia hacia adelante de y.

Si tuviera que hacer una definición seria (es decir, sin golf) de esta función, probablemente haría algo como esto:

(}. - }:) : ($:@[&0)

El caso monádico calcula la diferencia hacia adelante mientras que el caso diádico calcula la xenésima diferencia hacia adelante.

Aún más simple, pero no exactamente igual:

+/\inv

+/\produce un vector de las sumas de los prefijos del argumento. inv(definido como ^:_1) es una conjunción que invierte un verbo. Esto funciona donde J sabe cómo invertir un verbo y para el caso de +/\J sabe cómo hacerlo.

FUZxxl
fuente
3
Esto muestra el poder de los adverbios y las conjunciones, ya que -es el único verbo en esta función.
randomra
14

Python, 61 59 bytes

f=lambda n,L:n and f(n-1,[x-y for x,y in zip(L[1:],L)])or L

Aquí realizamos la resta comprimiendo todos menos el último de la lista con todos menos el primero de la lista. zip(L[1:],L)es equivalente a zip(L[1:],L[:-1]), debido a zipla naturaleza de tomar la longitud mínima de las dos listas:

>>> zip([1,2,3],[4,5])
[(1, 4), (2, 5)]

Una alternativa que es igual de larga (solo Python 2):

f=lambda n,L:n and f(n-1,map(int.__sub__,L[1:],L[:-1]))or L

Lamentablemente, Python 2 no corta el final de la lista, por lo que no puedo hacerlo map(int.__sub__,L,L[1:]). Molesto, Python 3 lo hace , pero mapya no devuelve una lista, por lo que esto termina siendo un byte más (60 bytes):

f=lambda n,L:n and f(n-1,list(map(int.__sub__,L[1:],L)))or L

Sin embargo, si permitimos que la entrada sea la profundidad seguida por la lista como f(3, 2, 5, 6, 7, 5, 10, 25)(es decir, profundidad 3 y lista [2, 5, 6, 7, 5, 10, 25]), entonces esto es 56 bytes :

f=lambda n,*T:n and f(n-1,*map(int.__sub__,T[1:],T))or T

Aquí hay otra alternativa que realmente molestaría a cualquiera que haya visto esto en el código de producción (este destruye la lista original):

f=lambda n,L:n and f(n-1,[L[1]-L.pop(0)for _ in L[1:]])or L
Sp3000
fuente
Tu último código es incorrecto. Necesitarías en su L[1]-L.pop(0)lugar.
mbomb007
@ mbomb007 Gracias por la captura. Eso fue incómodo: he tenido argumentos en torno al camino equivocado todo el tiempo.
Sp3000
Estaba cerca, pero algo como cualquier otra profundidad tenía los signos invertidos.
mbomb007
9

Mathematica 23 57 23 bytes

La sugerencia de Martin Büttner, explotando la listabilidad de la resta.

 Rest@#-Most@#&~Nest~##&

p.ej

Rest@# - Most@# &~Nest~## & @@ {{10, 18, -12, 4, 8, -3, -5, 67, 9, 14}, 4}

{-142, 55, 27, 41, -269, 397}


Rest@#-Most@# realiza la resta que produce diferencias.

Nest realiza dicha operación el número especificado de veces, operando siempre en la lista más reciente.

DavidC
fuente
7

Haskell, 40 34 bytes

n#l=iterate(zipWith(-)=<<tail)l!!n

Ejemplo de uso: 4 # [10,18,-12,4,8,-3,-5,67,9,14]que salidas [-142,55,27,41,-269,397].

Cómo funciona: calcule repetidamente la diferencia entre elementos vecinos y almacene los resultados intermedios en una lista. Tome el nelemento th de esta lista.

Editar: @Zgarb encontró 6 bytes para guardar. ¡Increíble!

nimi
fuente
Puede usar la función mónada y acortar la lambda a (zipWith(-)=<<tail).
Zgarb
7

JavaScript (ES6), 52 49 bytes

Función recursiva simple, que se usa mappara escanear la matriz y slicesoltar el primer elemento en cada llamada recursiva.

Editar 3 bytes guardados, gracias @DocMax, sugerencia realmente inteligente

F=(n,l)=>n?F(n-1,l.slice(1).map((a,k)=>a-l[k])):l

Prueba en la consola Firefox / FireBug

for(i=0;i<10;i++)console.log(F(i,[10, 18, -12, 4, 8, -3, -5, 67, 9, 14]))

[10, 18, -12, 4, 8, -3, -5, 67, 9, 14]
[8, -30, 16, 4, -11, -2, 72, -58, 5]
[-38 , 46, -12, -15, 9, 74, -130, 63]
[84, -58, -3, 24, 65, -204, 193]
[-142, 55, 27, 41, -269, 397 ]
[197, -28, 14, -310, 666]
[-225, 42, -324, 976]
[267, -366, 1300]
[-633, 1666]
[2299]

edc65
fuente
1
Rebanada antes mapa para evitar eficazmente la necesidad de py guardar 3 caracteres: H=(n,l)=>n?H(n-1,l.slice(1).map((a,k)=>a-l[k])):l.
DocMax
6

CJam, 15 bytes

l~{{_@-\}*;]}*p

Toma la entrada como una matriz de estilo CJam y luego la profundidad:

[10 18 -12 4 8 -3 -5 67 9 14] 4

e imprime el resultado como una matriz de estilo CJam.

Pruébalo aquí.

Explicación

l~              "Read and eval input.";
  {         }*  "Repeat this block N times, which computes the forward differences.";
   {    }*      "Fold this block onto the list - this is quite an abuse of folding semantics.";
    _           "Duplicate the current element (for the use in the next difference).";
     @          "Pull up the other copy of the last element.";
      -         "Subtract.";
       \        "Swap the difference and the other copy of the current element.";
          ;     "Discard the last element.";
           ]    "Wrap everything in an array again.";
Martin Ender
fuente
5

Java, 122 119 bytes

int[]a(int[]a,int b){if(b<1)return a;int e=a.length-1,c[]=new int[e],i=e;for(;i-->0;)c[i]=a[i+1]-a[i];return a(c,b-1);}

Ejemplo de uso: http://ideone.com/ALgYez

3 bytes gracias a Geobits: v)>

El numero uno
fuente
Debes deshacerte del segundo int y simplemente asignarlo i=econ los demás.
Geobits
5

> <> 53 50 bytes

l:[2-&\~~]r1-:?!vr
&}-@:$/!?&:-1
:;!? &&  lo*84n~<       

Uso: rellene previamente la pila (-v en el intérprete de python) con profundidad primero, seguida de los enteros.

Por ejemplo:

forward.fish -v 3 2 5 6 7 5 10 25

Devoluciones

2 -3 10 3

Gracias a Sp3000 por la ayuda.

cirpis
fuente
1
¿Es posible usar ?!y mover algunos componentes en lugar de hacerlo 0=??
Sp3000
¡Buena atrapada! Eso ayuda mucho
cirpis
5

Preludio , 95 92 79 78 bytes

?    (1-vv- # ) v  !
  ?     #   ^   #
?(1-)   1  (#)  1)(#)
  1   #(# ) 1  (#

El formato de entrada es

N
M
n_1
n_2
...
n_M

donde Nes la profundidad de las diferencias y Mes el número de enteros en la entrada. MFue necesario agregar , porque Prelude no tiene forma de distinguir a 0desde el final de la entrada. La salida también es como una lista de enteros separada por una nueva línea. Tuve que asumir la especificación de Preludio ligeramente ajustada que diseñamos para este desafío , porque el Preludio estándar lee enteros como valores de bytes, lo que hace que sea imposible ingresar números negativos. Esencialmente, este es el intérprete de Python con una NUMERIC_INPUTbandera adicional .

Como referencia, solo hay 48 38 37 caracteres que no son espacios; el resto simplemente se necesitaba para alinear el código correctamente.

Explicación

En Prelude, cada línea es una "voz" separada que opera en su propia pila. El programa se ejecuta columna por columna, donde se toman las voces separadas para operar "en paralelo". Todos los comandos son caracteres individuales y los paréntesis son bucles tipo Brainfuck (que se ingresan y repiten cada vez que la parte superior de la pila no es cero). Tenga en cuenta que la posición vertical del paréntesis de cierre es irrelevante: ponerlo en una voz diferente todavía cuenta como coincidencia con el paréntesis de apertura más reciente, y la pila que se verifica para la condición del bucle es siempre la voz donde (apareció. Ahora a este programa ...

El programa básicamente se puede separar en dos partes. Las dos líneas inferiores se usan simplemente para la mayoría de los bucles del programa (excepto el bucle principal N), pasando 1s de un lado a otro. Las dos líneas superiores contienen el bucle principal y la diferencia real. La siguiente anotación tiene el código transpuesto, por lo que puedo anotar las columnas individuales:

? ?   # Read two integers. Read instructions are processed top to bottom, so the first voice 
      # reads N and the third voice reads M.
  (   # Start a loop on the third voice. This loop will execute M times, reading the input list
      # and pushing M 1s onto the fourth voice - i.e. a unary representation of M.
 ?11  # Read an integer onto the second voice, push 1s onto the third and fourth voice.
  -   # Subtract the 1 from the third voice, decrementing M down to 0.
  )   # End of loop, if the third voice is not 0 yet, to back two columns.
(     # Start a loop on the first voice. This is the main loop and will execute N times. Each
      # iteration will compute the forward differences once and thereby shorten the list by one
      # element and also reduce the stack of 1s on the bottom voice by one.
1  #  # Push a 1 onto the first voice and pop a 1 from the last. Together with the next column,
      # this decrements both N and (the unary) M.
-  (  # Subtract the 1 from the first voice (decrementing N), and start a loop on the fourth 
      # voice over whatever is left of M (the length of the resulting difference list). Note 
      # that this column is *not* part of the loop, so the - on the first voice will only be 
      # executed once. This loop builds the differences in reverse order on the first voice.
v#1#  # Pop a 1 from the fourth voice and push a 1 onto the third. This loops over M while
      # shifting its unary representation to the other stack. In addition, shift the top stack
      # element from the second to the first voice.
v     # Copy the next element from the second voice to the first, without popping.
-  )  # Subtract the two elements on the first voice and end the loop if the fourth voice is 
      # empty. Note that his column *is* part of the loop.
  (   # Start a loop on the third voice. This is another loop over M, shifting the stack of 1s 
      # back to the fourth voice, and reversing the differences by shifting them onto the 
      # second.
#^#1  # As stated above, shift an element from the first to the second voice, a 1 from the
      # third to the fourth.
  )   # End the loop. After this point, we're back to the original situation, except that the
      # second voice has been replaced by its differences. The bottom stack element the
      # previous list is also still on that stack, but the decreasing loop lengths on the third
      # and fourth voices ensures that this element is never touched again.
)     # End the main loop when N has been reduced to 0.
   (  # Start another loop over the remaining list length, shifting and reversing the result.
v#1#  # Shift a 1 back to the third voice and an element from the second to the first voice.
  )   # End the loop. Note that this parenthesis is not on the same voice as the corresponding
      # opening parenthesis, but its exact position is irrelevant. Moving it to this voice
      # saves a byte.
  (   # Start one last loop over the length of the result.
! #   # Pop a 1 from the third voice while printing (and popping) one element of the result.
  )   # End the loop.
Martin Ender
fuente
5

Python, 70 68 67 59 bytes

f=lambda x,n:n and f([x[1]-x.pop(0)for i in x[1:]],n-1)or x

Versión sin golf antes de que fuera recursiva:

def f(x,n):
    for j in range(n):
        for i in range(len(x)-1):
            x[i]=x[i+1]-x[i]
    return x[:-n]
mbomb007
fuente
5

R, 48 39 46 44 bytes

Recursión!

function(x,y)if(x)Recall(x-1,diff(y)) else y
  • xes el número de iteraciones a realizar y yes un vector de enteros.
  • if(x)es cierto siempre y cuando x>0.
  • Recall llama a la función actual pero con nuevos argumentos.
  • Diff genera las diferencias entre elementos consecutivos de lista / vector.

Versión anterior:

#does not work for x=0:
function(x,y){for(i in 1:x)y=diff(y);y}

#does not use diff function:
function(x,y){for(i in 1:x)y=y[-1]-head(y,-1);y}

y[-1]       is a list minus its first element
head(y,-1)  is a list minus its last element
Freekvd
fuente
¿Hay una mejor manera de repetir la función diff x veces? Usar un bucle for se siente excesivo.
freekvd
Hay Reducir, pero creo que costaría más personajes.
MickyT
Hay un pequeño problema. Cuando se llama con profundidad 0, devuelve profundidad 2
MickyT
Fue por un enfoque diferente, el problema se resolvió pero tuvo que agregar 7 caracteres.
freekvd
2
Buen uso de Recall().
Alex A.
3

Python, 92 87 86 bytes

def a(b,c):
 if c<1:return b
 d=[];e=b[0]
 for f in b[1:]:d+=f-e,;e=f
 return a(d,c-1)

Este es mi primer golf de Python. Cualquier sugerencia será apreciada :)

5 6 bytes gracias a Sp3000: D

El numero uno
fuente
Recomiendo una lista de comprensión.
mbomb007
Puedes convertirlo appenden d+=f-e,. En general, para code-golf nunca necesitará usar L.appenddebido a esto.
Sp3000
3

c, 68 55 bytes

f(int *l){for(--l[-1]?f(l):0;*l;l++)*l=l[1]-*l;*--l=0;}

Esto podría estar tomando libertades con la especificación de entrada un poco. Una matriz int se construye de tal manera que el elemento 0 es la profundidad y los elementos 1 a (n + 1) son los elementos de la lista de entrada 0 a n. Luego, la dirección del elemento 1 se pasa a la función.

La matriz debe estar terminada en cero. La matriz se edita en su lugar.

P.ej:

#include <stdio.h>

f(int *l){for(--l[-1]?f(l):0;*l;l++)*l=l[1]-*l;*--l=0;}

int main (int argc, char **argv)
{
  int list[] = {4, 10, 18, -12, 4, 8, -3, -5, 67, 9, 14, 0};
  int *elem;

  f(list + 1);

  for (elem = list + 1; *elem; elem++) {
    printf("%d, ", *elem);
  }
}

http://ideone.com/m5PDgF

Trauma digital
fuente
¿Por qué dejaste un espacio int *l?
Jonathan Frech
2

Powershell 115 111 bytes

$p={param($a, $b)0..($a-1)|%{$b=@($l=$b.length;for($i=0;$i-lt$l;$i++){$b[$i+1]-$b[$i]})[0..($l-2)]};$b-join','}

Ejecutar como tal:

.$p 4 @(10,18,-12,4,8,-3,-5,67,9,14)

Salida:

-142,55,27,41,-269,397

Mover una llave rizada a un lugar diferente permite que esto muestre cada paso de la respuesta.

8,-30,16,4,-11,-2,72,-58,5
-38,46,-12,-15,9,74,-130,63
84,-58,-3,24,65,-204,193
-142,55,27,41,-269,397
StephenP
fuente
2

STATA, 126 bytes

di _r(a)_r(b)
token $b
gl $c=wordcount($b)
forv x=1/$a{
gl $c--
forv y=1/$c{
loc `y'=``y'+1'-``y''
}
}
forv z=1/$c{
di ``z''
}

Espera la entrada como un entero que representa la profundidad, seguido de una lista de enteros separados por espacios, ambos dados a través del indicador estándar. La salida es una lista de enteros separada por una nueva línea.

Primero convierte la lista de enteros (que ve como 1 cadena larga) en una lista de variables locales cuyos nombres son 1,2,3, ... Luego calcula las diferencias hacia adelante al establecer el valor de la variable local enésima como el valor de la variable local y + 1ª menos el valor de la variable local y (18-10 = 8), que sobrescribe los valores existentes solo después de su uso. Hace esto $ a (valor de la variable global a) veces. Luego muestra el valor de cada variable local, 1 a la vez.

comentarios
fuente
+1 para explicación. Esta es una forma increíblemente complicada de procesar listas.
Zgarb
@ Zgarb, no sé cómo STATA puede tomar la entrada como una matriz / lista, excepto a través de un archivo (que no funcionaría aquí debido a la otra entrada). Por eso tiene que funcionar así.
comentarios
2

T-SQL, demasiados :)

Cuando vi este problema por primera vez, me preguntaba si había una manera de hacer esto en una consulta. Si bien es trivial para la mayoría de los idiomas, no es tanto para la consulta SQL.

La entrada entra en las variables @ (para profundidad) y @L para la lista de enteros. @L es un tipo de tabla definida por el usuario

CREATE TYPE L AS TABLE(n INT IDENTITY(0,1),v INT)

Configuración de entrada

DECLARE @L L,@ INT=4
INSERT @L(v)values(10),(18),(-12),(4),(8),(-3),(-5),(67),(9),(14)

La consulta con algunos comentarios.

WITH R AS( 
    -- Recursive query to calculate the level of a pascal triangle with alternating negatives
    -- For 4 this is 1 -4  6 -4  1  
    SELECT 1c,0g UNION ALL SELECT-c*(@-g)/(g+1),g+1FROM r WHERE g<@
    ),
    O AS( 
    --Multiple N values of list by reversed pascal triangle values
    --shifting the start for each iteration (list length) - N
    SELECT c*v v,F 
    FROM @L L 
        CROSS APPLY(
            SELECT TOP((SELECT COUNT(*)FROM @L)-@)ROW_NUMBER()OVER(ORDER BY(SELECT\))-1F FROM sys.all_views a,sys.all_views b)c 
        JOIN R ON N=F+@-G
    )
-- Sum the multiplied values
SELECT SUM(V)FROM o GROUP BY F ORDER BY F

Resultado

-142
55
27
41
-269
397
MickyT
fuente
2

Japt -h , 17 5 bytes

12 bytes guardados gracias a @Shaggy

VÆ=än

Pruébalo en línea!

Luis felipe De jesus Munoz
fuente
13 bytes
Shaggy
O una implementación diferente da 12 bytes
Shaggy
Puede reemplazar äÏ-Xcon änambos para ahorrar 2 bytes más.
Shaggy
¡Lo bajé a 5 bytes !
Shaggy
@Shaggy maldita sea, eres demasiado bueno en japt xD Deberías publicar tu respuesta de 5 bytes
Luis felipe De jesus Munoz
0

SmileBASIC, 76 bytes

Finalmente una razón para usar ARYOP!

DEF F L,D
IF!D THEN@R
DIM B[0]COPY B,L
T=SHIFT(L)ARYOP 1,L,L,B
F L,D-1@R
END
12Me21
fuente
0

Clojure, 47 bytes

#(if(= 0 %)%2(recur(dec %)(map -(rest %2)%2))))

Una simple recursión en la función anónima. Guarda 1 byte si el orden de los argumentos se intercambia como ahora %2ocurre con más frecuencia que %.

NikoNyrh
fuente
0

Jalea , 2 bytes

Pruébalo en línea!

Explicación

I¡  Main Link
 ¡  Repeat `n` times; this repeats the previous link by <right argument> times
I   Get forward differences

Respuesta muy directa: P

HyperNeutrino
fuente