Suma de vecinos

22

Esto debería ser un desafío bastante simple.

Para una matriz de números, genere una matriz donde para cada elemento se agreguen todos los elementos vecinos y devuelva la suma de esa matriz.

Aquí está la transformación que ocurre en la matriz de entrada. [1,2,3,4,5]

[1,2,3,4,5] => [1+2, 2+1+3, 3+2+4, 4+3+5, 5+4] => [3,6,9,12,9] => 39
 0          => neighbours of item 0, including item 0
[1,2]       => 1 + 2      => 3
   1
[1,2,3]     => 1 + 2 + 3  => 6
     2
  [2,3,4]   => 2 + 3 + 4  => 9
       3
    [3,4,5] => 3 + 4 + 5  => 12
         4
      [4,5] => 4 + 5      => 9

               3+6+9+12+9 => 39

Casos de prueba

[]            => 0 (or falsy)
[1]           => 1
[1,4]         => 10 (1+4 + 4+1)
[1,4,7]       => 28
[1,4,7,10]    => 55
[-1,-2,-3]    => -14
[0.1,0.2,0.3] => 1.4
[1,-20,300,-4000,50000,-600000,7000000] => 12338842

Tabla de clasificación

Bassdrop Cumberwubwubwub
fuente
¿Necesitamos admitir números de punto flotante o solo enteros?
corvus_192
@ corvus_192 Los casos de prueba incluyen no enteros.
Geobits
@Geobits No me di cuenta de eso, editaré mi respuesta.
corvus_192
2
Debe hacer esto con las matrices de 2 dimensiones a continuación.
Bradley Uffner

Respuestas:

8

MATL , 5 bytes

7BZ+s

Pruébalo en línea!

Explicación

7B  % Push array [1, 1, 1], obtained as 7 in binary
Z+  % Take input implicitly. Convolve with [1, 1, 1], keeping size
s   % Sum of resulting array. Display implicitly
Luis Mendo
fuente
3
Uso muy inteligente de 7Ballí para llegar[1 1 1]
Suever
No sé MATL, pero me pregunto: para una lista [a,b,c,...], ¿cómo se obtiene a+bpero se evita a?
Christian Sievers
1
@ Christian La adición se realiza mediante una operación de convolución. Produciría los resultados parciales a los que se refiere, pero hay una versión de convolución que los evita, porque produce una matriz de salida con solo tantas entradas como entrada. Esto también se usa en la respuesta de Suever
Luis Mendo
19

Python, 25 bytes

lambda a:sum((a*3)[1:-1])

Para ver por qué esto funciona, gire la expansión en el OP 45 grados:

             1 + 2                        
           + 1 + 2 + 3                            2 + 3 + 4 + 5
               + 2 + 3 + 4          =       + 1 + 2 + 3 + 4 + 5
                   + 3 + 4 + 5              + 1 + 2 + 3 + 4.
                       + 4 + 5
Lynn
fuente
14

Python 2, 28 bytes

lambda a:sum(a)*3-a[0]-a[-1]

Solo 3 veces la suma y menos uno de cada elemento final

Zoo Zoo
fuente
También encontré una solución ordenada de 25 bytes .
Lynn
1
En realidad, ¿qué apasa si es la lista vacía (primer caso de prueba)? a[0]arrojará un IndexError, no?
Lynn el
6

05AB1E , 11 5 bytes

Guardado 6 bytes gracias a Adnan .

€Ð¦¨O

Pruébalo en línea!

Explicación

€Ð     # triplicate each item in the list
  ¦¨   # remove first and last element
    O  # sum
Emigna
fuente
¿ €Ð¦¨OFunciona :)?
Adnan
@Adnan: ¡Genial! Traté de pensar en una forma de hacerlo con 3 *, pero nunca lo consideré €Ðaunque lo haya usado €Dantes: P
Emigna
4

JavaScript (ES6), 40 33 bytes

l=>eval(l.join`+`)*3-l[0]-l.pop()

Devuelve NaNcuando se le da una lista vacía.

Arnauld
fuente
Puede cortar 2 caracteres más si mueve la multiplicación a la unión de esta manerav=>eval(v.join`*3+`+"*2")-v[0]
Grax32
@Grax - ¡Qué bien! Sin embargo, ya no sería falso para la matriz vacía.
Arnauld
Siempre hay algo que no está ahí?
Grax32
@Grax - No. El primer caso de prueba es una matriz vacía.
Arnauld
4

R, 75 70 52 34 33 31 bytes

Suma por tres y resta el primer y el último elemento

sum(x<-scan())*3-x[1]-tail(x,1)

Editar: Guardado 3 bytes adicionales gracias a @rturnbull

Billywob
fuente
3

Scala, 47 bytes

def&(a:Float*)=(0+:a:+0)sliding 3 map(_.sum)sum

Antepone y agrega un 0, luego utiliza una ventana deslizante de tamaño 3 para sumar los vecinos y calcula la suma total

corvus_192
fuente
3

Java 7, 72 bytes

float c(float[]a){float s=0,l=0;for(float i:a)s+=l=i;return 3*s-l-a[0];}
Nudo numérico
fuente
No creo que agregar entradas adicionales que denoten el primer y último elemento de la matriz esté en el espíritu del desafío.
Geobits
@Geobits lo cambio .....
Numberknot
Guay. Puedes jugar golf un poco más usando en floatlugar de double:)
Geobits
¿Puedo usarlo en su lugar ... Doble tiene 2 veces la precisión de flotación.
Numberknot
1
¿por qué no ints?
sidgate
3

Mathematica, 34 32 29 bytes

Tomando un poco de inspiración la aseada respuesta de Lynn a Python ...

Check[3Tr@#-Last@#-#[[1]],0]&

o

Check[3(+##)-#&@@#-Last@#,0]&

o

Check[##-#/3&@@#*3-Last@#,0]&

Desafortunadamente, este enfoque no es tan conveniente en Mathematica como lo es en Python, porque no hay una forma corta y segura de descartar el primer y último elemento de una lista que podría estar vacía.

Martin Ender
fuente
2
+1 por enseñarmeCheck
Greg Martin
2

MATLAB, 31 28 26 bytes

3 bytes guardados gracias a @Luis

@(x)sum(conv(x,1:3>0,'s'))

Esto crea una función anónima llamada ansque se puede llamar así:ans([1, 2, 3, 4, 5])

Para proporcionar una demostración en línea (que usa Octave), tuve que usar en 'same'lugar de 's'como la última entrada paraconv

Demo en línea

Explicación

Realizamos convolución ( conv) con un 1 x 3núcleo de todos los 1 (creados al hacer una matriz 1:3y luego compararlos con cero >0) y mantenemos el tamaño del original especificando la tercera entrada como 'same'o en MATLAB simplemente podemos acortar esto 's'. Luego aplicamos la suma al resultado.

Suever
fuente
Probablemente puedas acortar a's'
Luis Mendo el
1
@LuisMendo ¡Oh, buena llamada! MATLAB lo permite pero Octave no (por supuesto)
Suever
2

Jalea , 5 bytes

ẋ3ṖḊS

Pruébalo en línea!

Traducción de mi respuesta de Python .

ẋ3      Concatenate three copies of the input list
  Ṗ     Remove the last element
   Ḋ    Remove the first element
    S   Sum
Lynn
fuente
Tantos 5 byters, ¿dónde están los 4? ḊṖ+ḤS, Ṗ++ḊS, +Ḋ+ṖS, +Ṗ+ḊS, ...
Jonathan Allan
2

J, 9 bytes

+/@,}.,}:

Para [1, 2, 3, 4, 5], los vecinos son

1 2 3 4 5
1+2
1+2+3
  2+3+4
    3+4+5
      4+5

Luego mira a lo largo de las diagonales de las sumas

(2+3+4+5)+(1+2+3+4+5)+(1+2+3+4)

Por lo tanto, solo necesitamos encontrar la suma de la entrada con su cabeza eliminada y con su cola eliminada.

Uso

   f =: +/@,}.,}:
   f 1 2 3 4 5
39
   f '' NB. Empty array
0
   f 1
1
   f 1 4
10
   f 1 4 7
28
   f 1 4 7 10
55
   f _1 _2 _3
_14
   f 0.1 0.2 0.3
1.4
   f 1 _20 300 _4000 50000 _600000 7000000
12338842

Explicación

+/@,}.,}:  Input: array A
       }:  Return a list with the last value in A removed
    }.     Return a list with the first value in A removed
      ,    Join them
   ,       Join that with A
+/@        Reduce that using addition to find the sum and return
millas
fuente
Agradable. Y feliz 6k +!
Conor O'Brien
2

Brain-Flak , 68 bytes

(<><>)([]){{}({}({})<>{})<>({}<(({})<>{})><>)([][()()])}{}({}{}<>{})

Pruébalo en línea!

Explicación:

#Push a 0
(<><>)

#Push the stack height
([])

#While true:
{

    #Pop the stack height 
    {}

    #Add the sum of the top 3 elements to the other stack, and pop the top of the stack
    ({}({})<>{})<>({}<(({})<>{})><>)

    #Push the new stack height minus two
    ([][()()])

#End
}

#Pop the exhausted counter
{}

#Add the top two numbers to the other stack
({}{}<>)
DJMcMayhem
fuente
2

PowerShell v2 +, 40 bytes

param($a)($a-join'+'|iex)*3-$a[0]-$a[-1]

Similar a las otras respuestas, suma la lista, multiplica por 3, resta los elementos finales. Barfs muestra un error espectacular para la entrada vacía, y luego escupe 0, pero como STDERR se ignora por defecto, esto está bien.

PS C:\Tools\Scripts\golfing> .\sum-of-neighbors.ps1 @()
Invoke-Expression : Cannot bind argument to parameter 'Command' because it is an empty string.
At C:\Tools\Scripts\golfing\sum-of-neighbors.ps1:1 char:22
+ param($a)($a-join'+'|iex)*3-$a[0]-$a[-1]
+                      ~~~
    + CategoryInfo          : InvalidData: (:String) [Invoke-Expression], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.InvokeExpressionCommand

0

PS C:\Tools\Scripts\golfing> .\sum-of-neighbors.ps1 @(1)
1

PS C:\Tools\Scripts\golfing> .\sum-of-neighbors.ps1 @(1,4)
10

PS C:\Tools\Scripts\golfing> .\sum-of-neighbors.ps1 @(1,4,7)
28

PS C:\Tools\Scripts\golfing> .\sum-of-neighbors.ps1 @(1,4,7,10)
55

PS C:\Tools\Scripts\golfing> .\sum-of-neighbors.ps1 @(-1,-2,-3)
-14

PS C:\Tools\Scripts\golfing> .\sum-of-neighbors.ps1 @(0.1,0.2,0.3)
1.4

PS C:\Tools\Scripts\golfing> .\sum-of-neighbors.ps1 @(1,-20,300,-4000,50000,-600000,7000000)
12338842
AdmBorkBork
fuente
ParameterArgumentValidationErrorEmptyStringNotAllowedಠ_ಠ ¡Qué excepción!
Kade
2

Ruby, 35 33 31 bytes

Inspirado por la solución de Lynn:

->a{[*(a*3)[1..-2]].reduce:+}

los to_a segmento está ahí para manejar la matriz vacía.

EDITAR: Gracias a m-chrzan e histocrat.

Lee W
fuente
No necesitas paréntesis :+.
m-chrzan
[*(a*3)[1..-2]]lo hace .to_aen dos bytes menos.
histocrat
Es posible que desee probar Ruby 2.4.0. Viene con Array#sum.
Martin Ender
2

Perl 6 , 25 bytes

{.sum*3-.[0]-(.[*-1]//0)}    # generates warning
{+$_&&.sum*3-.[0]-.[*-1]}

Expandido:

# bare block lambda with implicit parameter 「$_」
{
  +$_        # the number of elements

  &&         # if that is 0 return 0, otherwise return the following

  .sum * 3   # sum them up and multiply by 3
  - .[ 0 ]   # subtract the first value
  - .[*-1]   # subtract the last value
}

Prueba:

use v6.c;
use Test;

my &code = {+$_&&.sum*3-.[0]-.[*-1]}

my @tests = (
  []            => 0,
  [1]           => 1,
  [1,4]         => 10,
  [1,4,7]       => 28,
  [1,4,7,10]    => 55,
  [-1,-2,-3]    => -14,
  [0.1,0.2,0.3] => 1.4,
  [1,-20,300,-4000,50000,-600000,7000000] => 12338842,
);

plan +@tests;

for @tests -> $_ ( :key(@input), :value($expected) ) {
  is code(@input), $expected, .gist;
}
Brad Gilbert b2gills
fuente
1

PHP, 39 bytes

<?=3*array_sum($a=$argv)-$a[1]-end($a);

Corre así:

echo '<?=3*array_sum($a=$argv)-$a[1]-end($a);' | php -- 1 -20 300 -4000 50000 -600000 7000000 2>/dev/null;echo

Explicación

El desafío se puede reducir a sumar cada número 3 veces, excepto el primer y el último número (agregado dos veces). Por lo tanto, devuelvo 3 veces la suma, menos el primer y el último número.

aross
fuente
1

> <> , 25 (+3 para  -v) = 28 bytes

Toma datos de la pila con  -vy asume que stdin está vacío, confiando en que proporcione un -1valor.

:{:}+i*v
:$v?=1l<+++:
;n<
Aaron
fuente
1

C # con LINQ, 42 bytes

a=>3*a.Sum()-(a.Length>0?a[0]+a.Last():0);

Requiere el System.Linqespacio de nombres.


C #, 84 bytes

a=>{int i=0,l=a.Length;var r=0d;for(;i<l;)r+=3*a[i++];return(l>0?r-a[0]-a[l-1]:0);};

Programa completo con casos de prueba:

using System;

namespace SumOfNeighbours
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<double[],double>f= a=>{int i=0,l=a.Length;var r=0d;for(;i<l;)r+=3*a[i++];return(l>0?r-a[0]-a[l-1]:0);};


            // test cases:
            double[] x = new double[]{1,2,3,4,5};
            Console.WriteLine(f(x));    // 39

            x = new double[] {};
            Console.WriteLine(f(x));    // 0

            x = new double[] {1};
            Console.WriteLine(f(x));    // 1

            x = new double[] {1,4};
            Console.WriteLine(f(x));    // 10 (1+4 + 4+1)

            x = new double[] {1,4,7};
            Console.WriteLine(f(x));    // 28

            x = new double[] {1,4,7,10};
            Console.WriteLine(f(x));    // 55

            x = new double[] {-1,-2,-3};
            Console.WriteLine(f(x));    // -14

            x = new double[] {0.1,0.2,0.3};
            Console.WriteLine(f(x));    // 1.4

            x = new double[] {1,-20,300,-4000,50000,-600000,7000000};
            Console.WriteLine(f(x));    // 12338842
        }
    }
}
adrianmp
fuente
1

Raqueta 48 bytes

(if(null? l)0(-(* 3(apply + l))(car l)(last l)))

Sin golf:

(define (f lst)
  (if (null? lst)
      0
      (- (* 3 (apply + lst))
         (first lst)
         (last lst))))

Pruebas:

(f '()) 
(f '(1))
(f '(1 4)) 
(f '(1 4 7)) 
(f '(1 4 7 10)) 
(f '(-1 -2 -3)) 
(f '(0.1 0.2 0.3)) 
(f '(1 -20 300 -4000 50000 -600000 7000000)) 

Salida:

0
1
10
28
55
-14
1.4000000000000001
12338842
rnso
fuente
1

Gloo , 12 bytes

Resulta que una característica de Gloo no funciona según lo previsto, así que tuve que hacerlo de una manera dolorosa.

__]:]:]:,,[+

Explicación:

__                   // duplicate the input list twice
  ]:]:]:             // flatten each list, and rotate stack left 
        ,,           // pop the last 2 numbers 
                     // (which are the first and last element of the list)
          [+         // wrap all items in a list and sum.
Kade
fuente
1

Elixir , 93 bytes

&if (length(&1)>0),do: Enum.reduce(&1,fn(n,r)->n+r end)*3-Enum.at(&1,0)-List.last(&1),else: 0

Función anónima utilizando el operador de captura.

Programa completo con casos de prueba:

s=&if (length(&1)>0),do: Enum.reduce(&1,fn(n,r)->n+r end)*3-Enum.at(&1,0)-List.last(&1),else: 0
# test cases:
IO.puts s.([])            # 0
IO.puts s.([1])           # 1
IO.puts s.([1,4])         # 10 (1+4 + 4+1)
IO.puts s.([1,4,7])       # 28
IO.puts s.([1,4,7,10])    # 55
IO.puts s.([-1,-2,-3])    # -14
IO.puts s.([0.1,0.2,0.3]) # 1.4
IO.puts s.([1,-20,300,-4000,50000,-600000,7000000]) # 12338842

¡Pruébelo en línea en ElixirPlayground !

adrianmp
fuente
1

TI-Basic, 17 bytes

Simplemente tres veces la suma de la lista, menos el primer y el último elemento.

3sum(Ans)-Ans(1)-Ans(dim(Ans)-1
Timtech
fuente
Creo que el consenso sobre meta dice que Anses una forma de entrada no válida.
Conor O'Brien
Puedes usarlo con una lista, no te preocupes. Pásalo como{1,3,5,7,2,6}:prgmNEIGHBOR
Timtech
Eso sigue siendo Anscomo entrada.
Conor O'Brien
¿Parece que me importa? Esa es la forma estándar de pasar la entrada en TI-Basic.
Timtech
Por mucho que esté de acuerdo con usted, eso no hace que la respuesta sea más válida.
Conor O'Brien el
1

Ruby, 41 bytes

->a{a.reduce(0,:+)*3-(a[0]?a[0]+a[-1]:0)}

Programa completo con casos de prueba:

f=->a{a.reduce(0,:+)*3-(a[0]?a[0]+a[-1]:0)}

#test cases
a=[]            
puts f.call(a)  # 0

a=[1]           
puts f.call(a)  # 1

a=[1,4]         
puts f.call(a)  # 10

a=[1,4,7]       
puts f.call(a)  # 28

a=[1,4,7,10]    
puts f.call(a)  # 55

a=[-1,-2,-3]    
puts f.call(a)  # -14

a=[0.1,0.2,0.3] 
puts f.call(a)  # 1.4

a=[1,-20,300,-4000,50000,-600000,7000000] 
puts f.call(a)  # 12338842

Mi primer intento en Ruby.

adrianmp
fuente
A partir de Ruby 2.4.0 hay Array#sum. Sin embargo, aún no he instalado la versión de vista previa para probar si esto simplemente se puede incluir en esta solución.
Martin Ender
1

Javascript, 46 bytes

a.reduce((t,c,i)=>t+(a[i-1]|0)+c+(a[i+1]|0),0)

Gracias @rlemon por los 2 bytes adicionales

Naftali aka Neal
fuente
1

Java 8, 60

d->d.length>0?Arrays.stream(d).sum()*3-d[0]-d[d.length-1]:0;
dpa97
fuente
1

C ++, 67 bytes

#import<valarray>
int f(std::valarray<int>v){return 3*v.sum()-v[0]-v[v.size()-1];}

Uso:

#include <iostream>
int main() {
    std::cout << f({1,2,1});
    return 0;
}
Anedar
fuente
1

Haskell, 25 bytes

Desde el más rápido

sum.sequence[(0-).head,(3*).sum,(0-).last]$[1..5]

vía más bonita

sum.sequence[sum.init,sum,sum.tail]$[1..5]

hasta el más feo pero más corto

let y x=sum$init x++x++tail x in y[1..5]     
--  1234567890123456789012345
Roman Czyborra
fuente
1

Lote, 67 bytes

@set/as=l=0
@for %%n in (%*)do @set/as+=l=%%n
@cmd/cset/as*3-%1-l

Si no hay parámetros, el último comando se convierte en 0 * 3 - -0.

Neil
fuente