Somma dei vicini


22

Questa dovrebbe essere una sfida abbastanza semplice.

Per un array di numeri, genera un array in cui per ogni elemento tutti gli elementi vicini vengono aggiunti a se stesso e restituisce la somma di tale array.

Ecco la trasformazione che si verifica sull'array di input [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

Casi test

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

Classifica



Dobbiamo supportare numeri in virgola mobile o solo numeri interi?
corvus_192,

@ corvus_192 I casi di test includono numeri non interi.
Geobits,

@Geobits Non me ne sono accorto, modificherò la mia risposta.
corvus_192,

2
Dovresti farlo con le matrici bidimensionali dopo.
Bradley Uffner,

Risposte:


8

MATL , 5 byte

7BZ+s

Provalo online!

Spiegazione

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

3
Uso molto intelligente di 7Blì per ottenere[1 1 1]
Suever

Non conosco MATL, ma mi chiedo: per un elenco [a,b,c,...], come si ottiene a+bma si evita di farlo a?
Christian Sievers,

1
@Christian L'aggiunta viene eseguita mediante un'operazione di convoluzione. Produrrebbe i risultati parziali a cui ti riferisci, ma esiste una versione di convoluzione che li evita, perché produce un array di output con solo tutte le voci dell'input. Questo è anche usato nella risposta di Suever
Luis Mendo,

19

Python, 25 byte

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

Per capire perché funziona, ruota l'espansione nell'OP di 45 gradi:

             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

14

Python 2, 28 byte

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

Solo 3 volte la somma e meno uno di ciascun elemento finale


Ho anche trovato una soluzione ordinata da 25 byte .
Lynn,

1
In realtà, cosa succede se al'elenco vuoto (primo caso di test)? a[0]lancerà un IndexError, no?
Lynn,

6

05AB1E , 11 5 byte

6 byte salvati grazie ad Adnan .

€Ð¦¨O

Provalo online!

Spiegazione

€Ð     # triplicate each item in the list
  ¦¨   # remove first and last element
    O  # sum

Funziona €Ð¦¨O:)?
Adnan,

@Adnan: geniale! Ho provato a pensare a un modo per farlo con 3 *, ma non ho mai nemmeno preso in considerazione €Ðanche se ho usato €Dprima: P
Emigna

4

JavaScript (ES6), 40 33 byte

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

Restituisce NaNquando viene fornito un elenco vuoto.


Puoi tagliare altri 2 personaggi se sposti la moltiplicazione nell'unione in questo modov=>eval(v.join`*3+`+"*2")-v[0]
Grax32

@Grax - Nice! Tuttavia, non sarebbe più falso per l'array vuoto.
Arnauld,

C'è sempre qualcosa che non c'è?
Grax32,

@Grax - No. Il primo caso di test è un array vuoto.
Arnauld,

4

R, 75 70 52 34 33 31 byte

Somma tre volte e sottrai il primo e l'ultimo elemento

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

Modifica: salvato 3 byte extra grazie a @rturnbull


3

Scala, 47 byte

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

Prepara e accoda uno 0, quindi utilizza una finestra scorrevole di dimensione 3 per sommare i vicini e calcola la somma totale


3

Java 7, 72 byte

float c(float[]a){float s=0,l=0;for(float i:a)s+=l=i;return 3*s-l-a[0];}

Non credo che l'aggiunta di input aggiuntivi che denotano il primo e l'ultimo elemento dell'array sia nello spirito della sfida.
Geobits

@Geobits lo cambio .....
Numberknot

Freddo. Puoi giocare a golf un po 'di più usando floatinvece di double:)
Geobits

Posso usarlo invece .... Double ha una precisione doppia di float.
Numberknot,

1
perché non ints?
Sidgate,

3

Mathematica, 34 32 29 byte

Ispirandomi alla bella risposta di Python di Lynn ...

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

o

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

o

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

Sfortunatamente, questo approccio non è così conveniente in Mathematica come in Python, perché non esiste un modo breve e sicuro per scartare il primo e l'ultimo elemento di un elenco che potrebbe essere vuoto.


2
+1 per avermi insegnatoCheck
Greg Martin,

2

MATLAB, 31 28 26 byte

3 byte salvati grazie a @Luis

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

Questo crea una funzione anonima chiamata ansche può essere chiamata come:ans([1, 2, 3, 4, 5])

Per fornire una demo online (che utilizza Octave), ho dovuto usare 'same'invece 's'come ultimo input perconv

Demo online

Spiegazione

Eseguiamo la convoluzione ( conv) con un 1 x 3kernel di tutti gli 1 (creato creando un array 1:3e quindi confrontandolo con zero >0) e mantenendo le dimensioni dell'originale specificando il terzo input come 'same'o in MATLAB possiamo semplicemente accorciarlo 's'. Quindi applichiamo la somma al risultato.


Probabilmente puoi accorciare a's'
Luis Mendo il

1
@LuisMendo Oh bella chiamata! MATLAB lo consente, ma Octave no (ovviamente)
Suever,


2

J, 9 byte

+/@,}.,}:

Perché [1, 2, 3, 4, 5]i vicini lo sono

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

Quindi guarda lungo le diagonali delle somme

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

Quindi abbiamo solo bisogno di trovare la somma dell'input con la testa rimossa e con la coda rimossa.

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

Spiegazione

+/@,}.,}:  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

Bello. E felice 6k +!
Conor O'Brien,

2

Brain-Flak , 68 byte

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

Provalo online!

Spiegazione:

#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
({}{}<>)

2

PowerShell v2 +, 40 byte

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

Simile alle altre risposte, somma l'elenco, moltiplica per 3, sottrae gli elementi finali. Elimina un errore spettacolare per input vuoto, quindi sputa 0, ma poiché STDERR è ignorato per impostazione predefinita, questo è 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

ParameterArgumentValidationErrorEmptyStringNotAllowedಠ_ಠ Che eccezione!
Kade,

2

Ruby, 35 33 31 byte

Ispirato dalla soluzione di Lynn:

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

Il to_asegmento è lì per gestire l'array vuoto.

EDIT: grazie a m-chrzan e histocrat.


Non hai bisogno di parentesi in giro :+.
m-chrzan,

[*(a*3)[1..-2]]fa .to_ain due meno byte.
istocrato

Potresti provare Ruby 2.4.0. Viene con Array#sum.
Martin Ender,

2

Perl 6 , 25 byte

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

Allargato:

# 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
}

Test:

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;
}

1

PHP, 39 byte

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

Esegui in questo modo:

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

Spiegazione

La sfida può essere ridotta aggiungendo ogni numero 3 volte, tranne il primo e l'ultimo numero (aggiunti due volte). Pertanto restituisco 3 volte la somma, meno il primo e l'ultimo numero.


1

> <> , 25 (+3 per  -v) = 28 byte

Prende input dallo stack con  -ve presuppone che lo stdin sia vuoto, basandosi su di esso per fornire un -1valore.

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

1

C # con LINQ, 42 byte

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

Richiede lo System.Linqspazio dei nomi.


C #, 84 byte

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);};

Programma completo con casi di test:

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
        }
    }
}

1

Racchetta 48 byte

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

test:

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

Produzione:

0
1
10
28
55
-14
1.4000000000000001
12338842

1

Gloo , 12 byte

Si scopre che una caratteristica di Gloo non funziona come previsto, quindi ho dovuto farlo in modo doloroso.

__]:]:]:,,[+

Spiegazione:

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

1

Elisir , 93 byte

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

Funzione anonima che utilizza l'operatore di acquisizione.

Programma completo con casi di test:

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

Provalo online su ElixirPlayground !


1

TI-Basic, 17 byte

Semplicemente tre volte la somma dell'elenco, meno il primo e l'ultimo elemento.

3sum(Ans)-Ans(1)-Ans(dim(Ans)-1

Credo che il consenso su meta affermi che si Anstratta di una forma di input non valida.
Conor O'Brien,

Puoi usarlo con un elenco, non ti preoccupare. {1,3,5,7,2,6}:prgmNEIGHBOR
Passalo

Questo è ancora Anscome input.
Conor O'Brien,

Sembra che mi importi? Questo è il modo standard di trasmettere input in TI-Basic.
Timtech,

per quanto io sia d'accordo con te, ciò non rende più valida la risposta.
Conor O'Brien,

1

Rubino, 41 byte

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

Programma completo con casi di test:

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

Il mio primo tentativo in Ruby.


A partire da Ruby 2.4.0 c'è Array#sum. Non ho ancora installato la versione di anteprima per verificare se questo può essere semplicemente eliminato in questa soluzione.
Martin Ender,



1

Java 8, 60

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

1

C ++, 67 byte

#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;
}

1

Haskell, 25 byte

Dal più veloce

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

via più bello

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

fino al più brutto ma il più breve

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

1

Lotto, 67 byte

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

Se non ci sono parametri, l'ultimo comando diventa 0 * 3 - -0.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.