Soma dos vizinhos

22

Este deve ser um desafio bastante simples.

Para uma matriz de números, gere uma matriz na qual, para cada elemento, todos os elementos vizinhos sejam adicionados a ela mesma e retorne a soma dessa matriz.

Aqui está a transformação que ocorre na 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 teste

[]            => 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

Entre os melhores

Bassdrop Cumberwubwubwub
fonte
Precisamos suportar números de ponto flutuante ou apenas números inteiros?
corvus_192
@ corvus_192 Os casos de teste incluem não-inteiros.
Geobits
@ Geobits Eu não percebi isso, vou editar minha resposta.
Corvus_192 14/10
2
Você deve fazer isso com matrizes bidimensionais a seguir.
Bradley Uffner

Respostas:

8

MATL , 5 bytes

7BZ+s

Experimente online!

Explicação

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
fonte
3
Uso muito inteligente de 7Blá para obter[1 1 1]
Suever
Não conheço MATL, mas me pergunto: para uma lista [a,b,c,...], como você consegue a+bevitar evitar a?
Christian Sievers
1
@Christian A adição é feita por meio de uma operação de convolução. Produziria os resultados parciais aos quais você se refere, mas há uma versão da convolução que os evita, porque produz uma matriz de saída com apenas o número de entradas que a entrada. Isso também é usado na resposta de Suever
Luis Mendo
19

Python, 25 bytes

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

Para ver por que isso funciona, gire a expansão no OP em 45 graus:

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

Python 2, 28 bytes

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

Apenas 3 vezes a soma e menos um de cada elemento final

Zoo Zoo
fonte
Eu também encontrei uma solução elegante de 25 bytes .
Lynn
1
Na verdade, e se aa lista estiver vazia (primeiro caso de teste)? a[0]vai jogar um IndexError, não?
Lynn
6

05AB1E , 11 5 bytes

Economizou 6 bytes graças a Adnan .

€Ð¦¨O

Experimente online!

Explicação

€Ð     # triplicate each item in the list
  ¦¨   # remove first and last element
    O  # sum
Emigna
fonte
Funciona €Ð¦¨O:)?
Adnan
@Adnan: Brilhante! Tentei pensar em uma maneira de fazer isso com 3 *, mas nunca €Ðpensei em usar o mesmo €Dantes: P
Emigna
4

JavaScript (ES6), 40 33 bytes

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

Retorna NaNquando recebe uma lista vazia.

Arnauld
fonte
Você pode cortar mais 2 caracteres se mover a multiplicação para a junção da seguinte forma:v=>eval(v.join`*3+`+"*2")-v[0]
Grax32 15/10
@Grax - Nice! No entanto, não seria mais falso para a matriz vazia.
Arnauld 15/10
Sempre há algo que não existe.
Grax32
@ Grax - Não. O primeiro caso de teste é uma matriz vazia.
Arnauld 15/10
4

R, 75 70 52 34 33 31 bytes

Soma vezes três e subtrai o primeiro e o último elemento

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

Edit: salvou 3 bytes extras graças a @rturnbull

Billywob
fonte
3

Scala, 47 bytes

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

Anexa e anexa um 0, depois usa uma janela deslizante de tamanho 3 para somar os vizinhos e calcula a soma total

corvus_192
fonte
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];}
Numberknot
fonte
Eu não acho que adicionar entradas extras indicando o primeiro e o último elemento da matriz esteja no espírito do desafio.
Geobits 14/10
@Geobits I change it .....
Numberknot
Legal. Você pode golfe um pouco mais usando float, em vez de double:)
Geobits
Posso usá-lo em vez disso .... O dobro tem 2x a precisão de flutuação.
NumberKnot #
1
por que não ints?
sidgate
3

Mathematica, 34 32 29 bytes

Tomando alguma inspiração, a pura resposta Python de Lynn ...

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

ou

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

ou

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

Infelizmente, essa abordagem não é tão conveniente no Mathematica quanto no Python, porque não há uma maneira curta e segura de descartar o primeiro e o último elemento de uma lista que pode estar vazia.

Martin Ender
fonte
2
+1 por me ensinarCheck
Greg Martin
2

MATLAB, 31 28 26 bytes

3 bytes salvos graças a @Luis

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

Isso cria uma função anônima chamada ansque pode ser chamada como:ans([1, 2, 3, 4, 5])

Para fornecer uma demonstração on-line (que usa o Octave), tive que usar em 'same'vez da 's'última entrada paraconv

Demo Online

Explicação

Nós executamos convolution ( conv) com um 1 x 3kernel de todos os 1s (criado criando um array 1:3e depois comparando com zero >0) e mantemos o tamanho do original especificando a terceira entrada como 'same'ou no MATLAB, para simplificá-la 's'. Em seguida, aplicamos a soma ao resultado.

Suever
fonte
Você provavelmente pode reduzir para's'
Luis Mendo
1
@LuisMendo Oh good call! MATLAB permite isso, mas Octave não (é claro)
Suever
2

Gelatina , 5 bytes

ẋ3ṖḊS

Experimente online!

Tradução da minha resposta em Python .

ẋ3      Concatenate three copies of the input list
  Ṗ     Remove the last element
   Ḋ    Remove the first element
    S   Sum
Lynn
fonte
Tantos 5 byters, onde estão os 4? ḊṖ+ḤS, Ṗ++ḊS, +Ḋ+ṖS, +Ṗ+ḊS, ...
Jonathan Allan
2

J, 9 bytes

+/@,}.,}:

Pois [1, 2, 3, 4, 5]os vizinhos são

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

Em seguida, observe as diagonais das somas

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

Portanto, precisamos apenas encontrar a soma da entrada com a cabeça removida e a cauda removida.

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

Explicação

+/@,}.,}:  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
milhas
fonte
Agradável. E feliz 6k +!
Conor O'Brien
2

Flak cerebral , 68 bytes

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

Experimente online!

Explicação:

#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
fonte
2

PowerShell v2 +, 40 bytes

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

Semelhante às outras respostas, soma a lista, multiplica por 3, subtrai os elementos finais. Vomita um erro espetacular para entrada vazia e, em seguida, cospe 0, mas como STDERR é ignorado por padrão, isso está OK.

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
fonte
ParameterArgumentValidationErrorEmptyStringNotAllowedಠ_ಠ Que exceção!
Kade
2

Ruby, 35 33 31 bytes

Inspirado na solução de Lynn:

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

O to_asegmento está lá para lidar com a matriz vazia.

EDIT: Graças a m-chrzan e histocrat.

Lee W
fonte
Você não precisa de parênteses :+.
M-chrzan # 14/16
[*(a*3)[1..-2]]faz .to_aem dois bytes a menos.
histocrat
Você pode tentar o Ruby 2.4.0. Vem com 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
}

Teste:

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

PHP, 39 bytes

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

Execute assim:

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

Explicação

O desafio pode ser reduzido para adicionar cada número três vezes, exceto o primeiro e o último número (adicionados duas vezes). Portanto, eu retorno 3 vezes a soma, menos o primeiro e o último número.

aross
fonte
1

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

Pega a entrada da pilha  -ve assume que stdin está vazio, contando com ela para fornecer um -1valor.

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

C # com LINQ, 42 bytes

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

Requer o System.Linqespaço para nome.


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 com casos de teste:

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

Raquete 48 bytes

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

Ungolfed:

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

Teste:

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

Saída:

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

Gloo , 12 bytes

Acontece que um recurso do Gloo não está funcionando conforme o esperado, então eu tive que fazer isso de uma maneira dolorosa.

__]:]:]:,,[+

Explicação:

__                   // 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
fonte
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

Função anônima usando o operador de captura.

Programa completo com casos de teste:

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

Experimente online no ElixirPlayground !

adrianmp
fonte
1

TI-Basic, 17 bytes

Simplesmente três vezes a soma da lista, menos o primeiro e o último elemento.

3sum(Ans)-Ans(1)-Ans(dim(Ans)-1
Timtech
fonte
Acredito que o consenso em meta diz que Ansé uma forma inválida de entrada.
Conor O'Brien
Você pode usá-lo com uma lista, não se preocupe. Passe-o como{1,3,5,7,2,6}:prgmNEIGHBOR
Timtech 15/10/16
Isso ainda Ansé uma entrada.
Conor O'Brien
Parece que eu me importo? Essa é a maneira padrão de transmitir informações no TI-Basic.
Timtech
por mais que eu concorde com você, isso não torna a resposta mais válida.
Conor O'Brien
1

Ruby, 41 bytes

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

Programa completo com casos de teste:

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

Minha primeira tentativa em Ruby.

adrianmp
fonte
A partir do Ruby 2.4.0 existe Array#sum. Ainda não instalei a versão de pré-visualização para testar se isso pode ser simplesmente descartado nesta solução.
Martin Ender
1

Javascript, 46 bytes

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

Obrigado @rlemon pelos 2 bytes extras

Naftali tcp Neal
fonte
1

Java 8, 60

d->d.length>0?Arrays.stream(d).sum()*3-d[0]-d[d.length-1]:0;
dpa97
fonte
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
fonte
1

Haskell, 25 bytes

Do mais rápido

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

via mais bonita

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

até o mais feio, mas o mais curto

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

Lote, 67 bytes

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

Se não houver parâmetros, o último comando será transformado 0 * 3 - -0.

Neil
fonte