Сумма соседей


22

Это должно быть довольно простой задачей.

Для массива чисел сгенерируйте массив, в котором для каждого элемента все соседние элементы будут добавлены к нему, и верните сумму этого массива.

Вот преобразование, которое происходит на входном массиве [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

Контрольные примеры

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

Leaderboard



Нужно ли поддерживать числа с плавающей запятой или только целые числа?
corvus_192

@ corvus_192 Тестовые случаи включают нецелые числа.
Geobits

@ Geobits Я этого не заметил, я отредактирую свой ответ.
corvus_192

2
Вы должны сделать это с помощью двухмерных массивов.
Брэдли Аффнер

Ответы:


8

MATL , 5 байтов

7BZ+s

Попробуйте онлайн!

объяснение

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
Очень умное использование 7Bтам, чтобы получить[1 1 1]
Suever

Я не знаю MATL, но мне интересно: для списка [a,b,c,...], как вы получаете, a+bно избегаете получать a?
Кристиан Сиверс

1
@Christian Добавление выполняется посредством операции свертки. Это приведет к частичным результатам, на которые вы ссылаетесь, но есть версия свертки, которая их избегает, потому что она создает выходной массив с таким количеством записей, сколько входных данных. Это также используется в ответе Суэвера
Луис Мендо

19

Python, 25 байт

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

Чтобы понять, почему это работает, поверните расширение в OP на 45 градусов:

             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 байт

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

Всего в 3 раза больше суммы и минус один из каждого конечного элемента


Я также нашел аккуратное 25-байтовое решение .
Линн

1
На самом деле, что, если aэто пустой список (первый контрольный пример)? a[0]выкинет IndexError, нет?
Линн

6

05AB1E , 11 5 байтов

Сохранено 6 байтов благодаря Аднану .

€Ð¦¨O

Попробуйте онлайн!

объяснение

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

Работает ли €Ð¦¨O:)?
Аднан

@Adnan: Отлично! Я пытался придумать, как сделать это с 3 *, но я даже не €Ðподумал, хотя уже использовал €D: P
Emigna

4

JavaScript (ES6), 40 33 байта

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

Возвращает NaNкогда дан пустой список.


Вы можете отрубить еще 2 символа, если переместите умножение в соединение следующим образомv=>eval(v.join`*3+`+"*2")-v[0]
Grax32

@Grax - Отлично! Тем не менее, это больше не будет ложным для пустого массива.
Арно

Там всегда что-то не так?
Grax32

@Grax - Нет. Первый контрольный пример - пустой массив.
Арно

4

R, 75 70 52 34 33 31 байт

Суммируйте три раза и вычтите первый и последний элемент

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

Редактировать: 3 дополнительных байта сохранены благодаря @rturnbull


3

Скала, 47 байт

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

Предварительно добавляет и добавляет 0, затем использует скользящее окно размером 3 для суммирования соседей и вычисляет общую сумму


3

Java 7, 72 байта

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

Я не думаю, что добавление дополнительных входных данных, обозначающих первый и последний элементы массива, соответствует духу задачи.
Geobits

@Geobits, я изменяю это .....
Numberknot

Круто. Вы можете floatdouble
играть в

Могу ли я использовать его вместо .... Double имеет 2x точность float.
Numberknot

1
почему не intс?
Сидгейт

3

Mathematica, 34 32 29 байт

Принимая вдохновение аккуратный ответ Линн на Python ...

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

или

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

или

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

К сожалению, этот подход не так удобен в Mathematica, как в Python, потому что нет короткого и безопасного способа отбросить первый и последний элемент списка, который может быть пустым.


2
+1 за то, что научил меняCheck
Грег Мартин

2

MATLAB, 31 28 26 байт

3 байта сохранены благодаря @Luis

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

Это создает анонимную функцию с именем, ansкоторая может быть вызвана следующим образом:ans([1, 2, 3, 4, 5])

Для того, чтобы предоставить онлайн демо (которое использует Octave), мне пришлось использовать 'same'вместо's' последнего входаconv

Демо онлайн

объяснение

Мы выполняем сверток ( conv) с 1 x 3ядром всех 1 (созданным путем создания массива 1:3с последующим сравнением с нулем >0) и сохраняем размер оригинала, указав третий вход как 'same'или в MATLAB, к которому мы можем просто сократить это значение 's'. Затем мы применяем сумму к результату.


Вероятно, вы можете сократить до's'
Луис Мендо

1
@ LuisMendo О, хороший звонок! MATLAB позволяет это, но Октава этого не делает (конечно)
Suever


2

J, 9 байт

+/@,}.,}:

Ведь [1, 2, 3, 4, 5]соседи

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

Затем посмотрите по диагоналям сумм

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

Таким образом, нам нужно только найти сумму входных данных с удаленной головой и удаленным хвостом.

использование

   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

объяснение

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

Ницца. И счастливого 6к +!
Конор О'Брайен

2

Brain-Flak , 68 байт

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

Попробуйте онлайн!

Объяснение:

#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 байт

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

Подобно другим ответам, суммирует список, умножает на 3, вычитает конечные элементы. Выдает исключительную ошибку при пустом вводе, а затем выплевывает 0, но, поскольку STDERR по умолчанию игнорируется, это нормально.

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ಠ_ಠ Какое исключение!
Каде

2

Рубин, 35 33 31 байт

Вдохновленный решением Линн:

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

to_aСегмент там обрабатывать пустой массив.

РЕДАКТИРОВАТЬ: Благодаря м-Chrzan и гистократ.


Вам не нужны круглые скобки :+.
m-chrzan

[*(a*3)[1..-2]]делает .to_aв два раза меньше байтов.
гистократ

Вы можете попробовать Ruby 2.4.0. Это идет с Array#sum.
Мартин Эндер

2

Perl 6 , 25 байт

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

Expanded:

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

Тест:

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 байт

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

Запустите так:

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

объяснение

Вызов может быть уменьшен до добавления каждого номера 3 раза, кроме первого и последнего номера (добавляется дважды). Поэтому я возвращаю 3 раза сумму, за вычетом первого и последнего числа.


1

> <> , 25 (+3 для  -v) = 28 байт

Принимает входные данные из стека  -vи предполагает, что стандартный ввод пуст, полагаясь на него для предоставления -1значения.

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

1

C # с LINQ, 42 байта

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

Требуется System.Linqпространство имен.


C #, 84 байта

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

Полная программа с тестовыми примерами:

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

Ракетка 48 байтов

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

Тестирование:

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

Выход:

0
1
10
28
55
-14
1.4000000000000001
12338842

1

Gloo , 12 байт

Оказалось, что функция Gloo не работает, как задумано, поэтому мне пришлось сделать это болезненным способом.

__]:]:]:,,[+

Объяснение:

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

Эликсир , 93 байта

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

Анонимная функция с использованием оператора захвата.

Полная программа с тестовыми примерами:

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

Попробуйте онлайн на ElixirPlayground !


1

TI-Basic, 17 байтов

Просто в три раза больше суммы списка, минус первый и последний элемент.

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

Я считаю, что консенсус в отношении мета говорит, что Ansэто недопустимая форма ввода.
Конор О'Брайен

Вы можете использовать его со списком, не волнуйтесь. Передайте это как{1,3,5,7,2,6}:prgmNEIGHBOR
Timtech

Это все еще в Ansкачестве ввода.
Конор О'Брайен

Похоже, я забочусь? Это стандартный способ передачи ввода в TI-Basic.
Timtech

насколько я с вами согласен, это не делает ответ более действительным.
Конор О'Брайен

1

Рубин, 41 байт

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

Полная программа с тестовыми примерами:

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

Моя первая попытка в Ruby.


Начиная с Ruby 2.4.0 Array#sum. Я еще не установил предварительный выпуск, чтобы проверить, можно ли просто добавить это решение.
Мартин Эндер




1

C ++, 67 байт

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

Использование:

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

1

Haskell, 25 байт

От самого быстрого

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

через самый красивый

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

вплоть до самых уродливых, но самых коротких

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

1

Пакетный, 67 байт

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

Если параметров нет, последняя команда превращается в 0 * 3 - -0.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.