Suma en columnas de cortes superpuestos

19

Tarea

Dada una lista de enteros L y otro número entero s , el objetivo es calcular las sumas en columna de todos los segmentos de L de longitud (potencialmente superpuestos) , mientras se relacionan sus posiciones con respecto a L (ver más abajo).

Definiciones

Los s -Longitud rebanadas (superpuestas) de la lista L son todas las subsecuencias contiguos (sin envoltura) de L que son de longitud s .

Para pertenecer a las posiciones de los cortes s con relación a L , puede imaginarse construyendo una "escalera", donde cada corte s i tiene un desplazamiento de las posiciones i desde el principio.


Especificaciones

  • s es un número entero mayor que 1 y estrictamente menor que la longitud de L .
  • L siempre contendrá al menos 3 elementos.
  • Puede competir en cualquier lenguaje de programación y puede tomar entradas y proporcionar salidas a través de cualquier método estándar , mientras toma nota de que estas lagunas están prohibidas por defecto. Este es el , por lo que gana el envío más corto (en bytes) para cada idioma .

Ejemplos y casos de prueba

Aquí hay un ejemplo trabajado:

[1, 2, 3, 4, 5, 6, 7, 8, 9], 3

[1, 2, 3]
   [2, 3, 4]
      [3, 4, 5]
         [4, 5, 6]
            [5, 6, 7]
               [6, 7, 8]
                  [7, 8, 9]
-------------------------------- (+)  | column-wise summation
[1, 4, 9, 12, 15, 18, 21, 16, 9]

Y algunos casos de prueba más:

[1, 3, 12, 100, 23], 4         -> [1, 6, 24, 200, 23]
[3, -6, -9, 19, 2, 0], 2       -> [3, -12, -18, 38, 4, 0]
[5, 6, 7, 8, 2, -4, 7], 3      -> [5, 12, 21, 24, 6, -8, 7]
[1, 2, 3, 4, 5, 6, 7, 8, 9], 3 -> [1, 4, 9, 12, 15, 18, 21, 16, 9]
[1, 1, 1, 1, 1, 1, 1], 6       -> [1, 2, 2, 2, 2, 2, 1]
[1, 2, 3, 4, 5, 6, 7, 8, 9], 6 -> [1, 4, 9, 16, 20, 24, 21, 16, 9]
Sr. Xcoder
fuente
2
Ese primer caso de prueba es molesto. ;) Simplemente porque ses más grande que L/2. Tal vez agregue algunos casos de prueba más donde ese es el caso [1, 1, 1, 1, 1, 1, 1], 6 -> [1, 2, 2, 2, 2, 2, 1] `o [1, 2, 3, 4, 5, 6, 7, 8, 9], 6 -> [1, 4, 9, 16, 20, 24, 21, 16, 9]?
Kevin Cruijssen
2
@KevinCruijssen ¿Puedes editar para mí? Esos son algunos buenos casos de prueba, pero ahora estoy en el móvil;) ¡Gracias!
Sr. Xcoder

Respuestas:

11

J , 11, 9 8 bytes

-1 byte gracias a millas!

[:+//.]\

¿Cómo funciona?

El argumento izquierdo es s, el derecho - L

]\ - divide L en sublistas con longitud s

/. - extrae las diagonales oblicuas (anti-diagonales)

+/ - los suma

[: - hace un tenedor de los verbos anteriores

Aquí hay un ejemplo de sesión J para el primer caso de prueba:

   a =. 1 2 3 4 5 6 7 8 9

   ] 3 ]\ a 
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9

   ] </. 3 ]\ a 
┌─┬───┬─────┬─────┬─────┬─────┬─────┬───┬─┐
│1│2 2│3 3 3│4 4 4│5 5 5│6 6 6│7 7 7│8 8│9│
└─┴───┴─────┴─────┴─────┴─────┴─────┴───┴─┘

   ] +//. 3 ]\ a 
1 4 9 12 15 18 21 16 9

Pruébalo en línea!

Galen Ivanov
fuente
¿Hay alguna diferencia entre una "diagonal oblicua" y una "diagonal"?
Luis Mendo
@Luis Mendo - Creo que "oblicuo" significa ir de abajo a la izquierda a arriba a la derecha en el caso del adverbio J /., en oposición a la diagonal principal que va de arriba a la izquierda a abajo a la derecha.
Galen Ivanov
1
Ah gracias. Así que eso es lo que generalmente se llama antiagoniales
Luis Mendo
2
Se podría sustituir ,/\con]\
millas
@miles ¡Sí, por supuesto! ¡Gracias!
Galen Ivanov
9

Haskell , 59 56 bytes

s#n=[x*minimum[n,i,length s+1-max i n]|(i,x)<-zip[1..]s]

Pruébalo en línea!

Define una función (#)que toma una lista sy un número ncomo argumentos.

Esto se basa en la observación de que para s = [1, 2, 3, 4, 5, 6, 7, 8, 9]yn = 3

[1, 2, 3]
   [2, 3, 4]
      [3, 4, 5]
         [4, 5, 6]
            [5, 6, 7]
               [6, 7, 8]
                  [7, 8, 9]
---------------------------- (+)
[1, 4, 9,12,15,18,21,16, 9]

es lo mismo que

[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 3, 3, 3, 3, 2, 1]
---------------------------- (*)
[1, 4, 9,12,15,18,21,16, 9]

Para generar esta lista inicialmente creciente, luego constante y finalmente decreciente, podemos comenzar con

[minimum[i, length s + 1 - i] | i<-[1..length s]]

que rinde [1, 2, 3, 4, 5, 4, 3, 2, 1]. Agregar ncomo restricción adicional a la minimumexpresión produce la [1, 2, 3, 3, 3, 3, 3, 2, 1]respuesta de lista correcta para n = 3, aunque para n = 6(o en general cualquiera n > lengths s/2) la restricción adicional length s + 1 - nes necesaria:

[minimum[i, n, length s + 1 - i, length s + 1 - n] | i<-[1..length s]]

o más corto:

[minimum[i, n, length s + 1 - max i n] | i<-[1..length s]]

Para la multiplicación por pares [1..length s]se comprime con s, y debido a que ziptrunca la lista más larga a la longitud de la más corta, [1..]se puede usar la lista infinita :

[x * minimum[i, n, length s + 1 - max i n] | (i,x)<-zip[1..]s]
Laikoni
fuente
6

JavaScript (ES6), 65 62 58 bytes

Guardado 4 bytes gracias a @Shaggy

Toma entrada en la sintaxis de curry (a)(n).

a=>n=>a.map((v,i)=>v*Math.min(++i,n,a.length+1-(n>i?n:i)))

Casos de prueba

Arnauld
fuente
¿ a=>n=>a.map((v,i)=>v*Math.min(++i,n,a.length+1-(n>i?n:i)))Funciona para 58 bytes?
Shaggy
@ Shaggy De alguna manera, sabía que había algo realmente estúpido en mi código, pero no pude resolverlo ... ¡Muchas gracias!
Arnauld
6

Java 8, 83 bytes

L->s->{for(int i=0,l=L.length+1,t,u;++i<l;u=l-(s>i?s:i),L[i-1]*=t<u?t:u)t=i<s?i:s;}

Ese primer caso de prueba (y los dos últimos que he agregado) me fastidió varias veces, pero finalmente funciona ahora ...: D

Modifica la matriz de entrada en lugar de devolver una nueva.

Explicación:

Pruébalo en línea.

L->s->{                  // Method with int-array and int parameters, and no return-type
  for(int i=0,           //  Index-integer, starting at 0
      l=L.length+1,      //  The length of the input-array + 1
      t,u;               //  Two temp integers
      ++i<l              //  Loop `i` from 1 to the length (inclusive)
      ;                  //    After every iteration:
       u=l               //     Set temp integer `u` to the length plus 1,
          -(s>i?s:i),    //     minus the highest of `s` and `i`
       L[i-1]*=t<u?t:u)  //     And replace the item with the lowest of `t` and `u`
    t=i<s?i:s;}          //   Set temp integer `t` to the lowest of `i` or `s`
Kevin Cruijssen
fuente
5

MATL , 8 bytes

YCPT&Xds

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

Considere las entradas [1, 3, 12, 100, 23]y 4.

YC     % Implicit inputs: row vector L and number s. Create matrix of 
       % overlapping blocks of L with length s, where each block is a column
       % STACK: [  1   3;
                   3  12;
                  12 100;
                 100  23]
P      % Flip vertically
       % STACK: [100  23;
                  12 100;
                   3  12;
                   1   3]
&TXd   % Extract all diagonals, starting from bottom-left, and arrange them as
       % columns of a matrix, with zero padding
       % STACK: [1   3  12 100   0;
                 0   3  12 100  23]
s      % Sum of each column. Since s is less than the length of L, there are
       % at least two rows. Thus function `s` can be used instead of `Xs`.
       % Implicit display
       % STACK: [1   6  24 200  23]
Luis Mendo
fuente
5

APL (Dyalog Unicode) , 19 14 bytes SBCS

-5 gracias a ngn.

Función infija tácita anónima que toma s como argumento izquierdo y L como argumento derecho. Asume ⎕IO( I ndex O rigin) para ser 0como es por defecto en muchos sistemas.

+⌿∘↑((0,⊢)\,/)

Pruébalo en línea!

Explicación con caso de ejemplo [1,3,12,100,23]

(... ) aplique la siguiente función tácita anónima:

,/ ventanas superpuestas de ese tamaño; [[1,3,12],[3,12,100],[12,100,23]]

(… De forma )\ acumulativa, aplique este tácito la siguiente función tácita anónima:

   el argumento correcto (la mayoría)

  0, con un cero a la izquierda

La reducción acumulativa significa que insertamos la función en cada "espacio" entre términos sucesivos, trabajando de derecha a izquierda. Para cada "espacio", la función descartará el argumento izquierdo pero agregará un cero adicional. Efectivamente, esto agrega tantos ceros a cada término como haya "espacios" a su izquierda, por lo que el primer término obtiene cero espacios, el segundo obtiene uno y el tercero obtiene dos:[[1,3,12],[0,3,12,100],[0,0,12,100,23]]

 subir el rango combinando las listas en una única matriz, rellenando con ceros;
┌ ┐
│1 3 12 0 0│
│0 3 12 100 0│
│0 0 12 100 23│
└ ┘
 luego
+⌿ suma verticalmente;[1,6,36,200,23]

Adán
fuente
1
⊢,⍨¨0⍴⍨¨⍳∘≢->{0,⍵}\
ngn
@ngn Siempre piensas en estas ingeniosas reducciones, pero realmente debes publicar esto por separado. Por cierto, me parece +⌿∘↑((0,⊢)\,/)más elegante.
Adám
Oh, vamos, este es un caso claro de simplificar una parte de una solución, no una idea nueva
ngn
@ngn Mientras tanto, ¡resuelve este CMC!
Adám
No estoy seguro de que esto sea sobre el tema en los comentarios aquí, pero ¿por qué no usas "cada uno"? 2{(⊃⌽⍺),⊃⍵}/⊢->2{⊃¨(⌽⍺)⍵}/⊢
ngn
4

Jalea , 6 bytes

JṡṬS×ḷ

Pruébalo en línea!

Cómo funciona

JṡṬS×ḷ  Main link. Left argument: A (array). Right argument: n (integer)

J       Indices; yield [1, ..., len(A)].
 ṡ      Split the indices into overlapping slices of length n.
  Ṭ     Untruth; map each array of indices to a Boolean vector, with 1's at the
        specified indices and 0's elsewhere.
        For example, [3, 4, 5] maps to [0, 0, 1, 1, 1].
   S    Sum the rows, essentially counting how many times each index appears in
        the arrays returned by the ṡ atom.
     ḷ  Left; yield A.
    ×   Multiply the counts to the left with the integers to the right.
Dennis
fuente
3

Japt , 13 bytes

¡Tomó demasiado tiempo hacer que esto funcionara cuando s> L/2!

Ë*°EmVUÊÄ-EwV

Intentalo


Explicación

                 :Implicit input of array U and integer V
Ë                :Map over each element at 0-based index E in U
 *               :  Multiply by
    m            :  The minumum of
  °E             :    E incremented,
     V           :    V,
          EwV    :    and the maximum of E & V
         -       :    subtracted from
      UÊÄ        :    the length of U plus 1
Lanudo
fuente
" Se tomó demasiado tiempo para conseguir este trabajo cuando s > L/2! " Tenía exactamente la misma. Los otros casos de prueba son fáciles, ¡pero el primero (y los dos que he agregado al final) fueron molestos! .. ¡+1 de mi parte!
Kevin Cruijssen
1

R , 52 51 bytes

function(l,s)l*pmin(s,x<-seq(l),y<-rev(x),y[1]+1-s)

Pruébalo en línea!

Esto es equivalente a la respuesta de Laikoni .

seq(l)produce los índices 1...length(l)desde entonces length(l)>1(de lo contrario produciría 1...l[1]). ¡Lo guardo como, guardo xsu reverso como y, y tomo el primer elemento de y( length(l)) para portar cuidadosamente la respuesta de Laikoni y guardar un byte!

Respuesta original, 52 bytes.

function(l,s,L=sum(l|1)+1)l*pmin(s,x<-2:L-1,L-x,L-s)

Pruébalo en línea!

La salida se lelementwise multiplica por el mínimo de s, el índice de 1 a base de del elemento x, length(l)-x+1y length(L)-s+1.

Esto también es equivalente a la respuesta de Laikoni, usando en L-xlugar de rev(x)como es más corto.

Giuseppe
fuente
1

APL + WIN, 25 bytes

Solicita la entrada de pantalla de L seguido de s

+/(1-⍳⍴z)⌽¨(⍴L)↑¨s←⎕,/L←⎕

Explicación:

L←⎕ prompt for screen input of L

s←⎕,/ prompt for screen input of s and create nested vector of successive s elements of L

(⍴L)↑¨ pad each element of the nested vector with zeros to the length of L

(1-⍳⍴z)⌽¨ incrementally rotate each element of the nested vector

+/ sum the elements of the nested vector
Graham
fuente
1

K (oK) , 30 bytes

Solución:

{+/t,'(y':x),'|t:(!1-y-#x)#'0}

Pruébalo en línea!

Ejemplo:

{+/t,'(y':x),'|t:(!1-y-#x)#'0}[3 -6 -9 19 2 0;2]
3 -12 -18 38 4 0

Explicación:

No creo que pueda competir con J en este caso. Genere una lista de ceros para agregar y agregar a la lista de la ventana deslizante, luego resuma:

{ t,'(y':x),'|t:(!(#x)+1-y)#'0 }[1 2 3 4 5 6 7 8 9;3]
(1 2 3 0 0 0 0 0 0
 0 2 3 4 0 0 0 0 0
 0 0 3 4 5 0 0 0 0
 0 0 0 4 5 6 0 0 0
 0 0 0 0 5 6 7 0 0
 0 0 0 0 0 6 7 8 0
 0 0 0 0 0 0 7 8 9)

El desglose es el siguiente ... aunque esto todavía se siente torpe.

{+/t,'(y':x),'|t:(!1-y-#x)#'0} / the solution
{                            } / lambda taking x and y implicitly
                          #'0  / take (#) each (') zero
                 (       )     / do this together
                       #x      / count (#) length of x
                     y-        / take count away from length y
                   1-          / take that result from 1
                  !            / til, generate range to that number
               t:              / save in variable t
              |                / reverse it
            ,'                 / join with each
      (y':x)                   / sliding window size y over x
    ,'                         / join with each
   t                           / prepend t
 +/                            / sum up
callejero
fuente
1

Casco , 4 bytes

mΣ∂X

Pruébalo en línea!

Utiliza la idea de la respuesta J de Galen Ivanov .

Explicación

     -- implicit input number n and list s, e.g. s = [1,2,3,4,5,6] and n = 4 
   X -- get sublists of length n of list s           [[1,2,3,4],[2,3,4,5],[3,4,5,6]]
  ∂  -- anti-diagonals                               [[1],[2,2],[3,3,3],[4,4,4],[5,5],[6]]
mΣ   -- get the sum of each of the lists             [1,4,9,12,10,6]
Laikoni
fuente
0

C (gcc) , 100 bytes

j,x;f(L,l,s)int*L;{for(j=0;j<l;j++)L[j]*=j<s&j<l-s?-~j:j>s&j>l-s?l-j:(x=s<l-j?s:l-j)<l-~-s?x:l-~-s;}

Pruébalo en línea!

Jonathan Frech
fuente
0

C (gcc) , 83 81 79 bytes

Básicamente, hay tres "fases" en la manipulación de la lista: aumento, sostenimiento y enfriamiento. A medida que avanzamos en la lista, aumentaremos nuestro factor hasta que alcancemos un máximo. Si una serie completa de sectores puede caber en la lista, este máximo será el mismo que la longitud de los sectores. De lo contrario, será igual a la cantidad de cortes que quepan. En el otro extremo, disminuiremos el factor nuevamente, para aterrizar en 1 en el último elemento.

La duración de las fases de aceleración y enfriamiento que refuerzan esta meseta es uno menos que ese factor máximo.

Con suerte, los bucles sin golf antes de combinarlos lo aclaran (R = duración de la fase de aceleración):

for (r = 1; r <= R; r++) L[r - 1] *= r;
for (; r < n - R; r++)   L[r - 1] *= R + 1;
for (; r < n; r++)       L[r - 1] *= n - r + 1;

Tres bucles es demasiado, por lo que decidir el factor basado en r nos da un bucle (usando s para R para guardar algunos bytes):

r;f(L,n,s)int*L;{for(r=0,s=2*s-1>n?n-s:s-1;r++<n;)*L++*=r>s?r<n-s?s+1:n-r+1:r;}

Pruébalo en línea!

gastropner
fuente
0

Perl, 45 44 bytes

Incluye +4 para -ai También tenga en cuenta que este código da 2 advertencias perl en el inicio. Puede suprimirlos a costa de un golpe agregando la Xopción

Indique la longitud de la máscara después de la -iopción y la matriz en una línea en STDIN:

perl -ai4 -E 'say$_*grep$_~~[$^I..@F],$a..$^I+$a++for@F' <<< "1 3 12 100 23"

Solo el código:

say$_*grep$_~~[$^I..@F],$a..$^I+$a++for@F
Ton Hospel
fuente
0

Ruby , 62 bytes

->a,l{a.map.with_index{|x,i|x*[i+1,l,a.size-[l-1,i].max].min}}

Pruébalo en línea!

Esencialmente un puerto de la respuesta de JavaScript de Arnauld , excepto que la necesidad with_indexes mucho más dolorosa.

En el tiempo que tardé en decidir enviar esto, aproveché esta versión de 70 bytes, que está más cerca del algoritmo de Dennis .

->a,l{c=a.map{0};(0...a.size).each_cons(l){|h|h.map{|i|c[i]+=a[i]}};c}
benj2240
fuente
0

Clojure, 72 bytes

#(let[R(range 1(inc(count %)))](map *(map min(repeat %2)R(reverse R))%))
NikoNyrh
fuente
0

Pyt , 106 bytes

ĐŁĐ←⇹řĐ↔Đ04ȘĐ04Ș>Đ04Ș03Ș¬*07ȘážÁ*+04Ș⇹Đ3ȘĐ3Ș-⁺Đ4Ș⇹ŕĐ3Ș<Ь3Ș*3Ș*+⇹ĐŁ⑴04Ș3Ș⇹04Ș*Đ04ȘĐ04Ș<Đ04Ș*06ȘážÁ03Ș¬*++*

Toma L en la primera línea como una matriz y toma s en la segunda línea

Explicación:

                     Implicit input (L)
Đ                    Duplicate L
ŁĐ                   Get length of L (len) and push it twice
←                    Get s
⇹ř                   Push [1,2,...,len]
Đ↔Đ                  Push [len,...,2,1] twice
04ȘĐ                 Push 0, flip top 4 on stack, and duplicate top [1,2,...,len]
04Ș>                 Is [len,...,2,1]>[1,2,...,len] (element-wise) [boolean array]
Đ                    Duplicate top of stack                   
04Ș03Ș¬*             Pushes [1,2,...,ceil(len/2),0,...,0]
07ȘážÁ               Push 0, flip top seven on stack, and remove all 0s from stack
*                    Pushes [0,0,...,0,floor(len/2),floor(len/2)-1,...,1]
+                    Adds top two on stack element-wise

The top of the stack is now:
     [1,2,...,ceil(len/2),floor(len/2),...,2,1] (let's call it z)

04Ș                  Push zero and swap top four on stack
⇹                    Swap top two on stack
Đ3ȘĐ3Ș-⁺Đ4Ș⇹ŕĐ3Ș<Ь3Ș*3Ș*+     Pushes min of (len-s+1,s) [let's call it m]
⇹ĐŁ⑴04Ș3Ș⇹04Ș*                Pushes an array [m,m,...,m] with length len
Đ04ȘĐ04Ș<Đ04Ș*06ȘážÁ03Ș¬*++    Pushes element-wise min of [m,m,...,m] and z
*                              Element-wise multiplication of above with L

Pruébalo en línea!

mudkip201
fuente
0

Python + numpy, 64 bytes

from pylab import *
lambda l,N:convolve(*ones((2,len(l)-N-1)))*l

Llame a esto con l como la lista y N como la longitud.

usuario2699
fuente