Сложите список пополам


24

Мы собираемся сложить список целых чисел. Процедура для этого заключается в следующем: если список имеет четную длину, составьте список из половины его длины, где n-й элемент нового списка представляет собой сумму n-го элемента старого списка и n-го до последний пункт старого списка. Например, если бы у нас был список

[1 2 3 4 5 6 7 8]

Мы бы сложили это так

 [8 7 6 5]
+[1 2 3 4]
__________
 [9 9 9 9]

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

Например, если бы у нас был список

[1 2 3 4 5 6 7]

Мы бы сложили это так

 [7 6 5]
+[1 2 3]
__________
 [8 8 8]
++     [4]
__________
 [8 8 8 4]

задача

Напишите программу или функцию, которая принимает список целых чисел в качестве входных данных и выводит их в сложенном виде.

Это вопрос по поэтому ответы будут оцениваться в байтах, при этом меньшее количество байтов будет лучше.

Пример реализации

Вот реализация в Haskell, которая определяет функцию, fкоторая выполняет свертывание.

f(a:b@(_:_))=a+last b:f(init b)
f x=x

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


Когда вы говорите целые числа, это включает в себя ноль или отрицательные целые числа?
Нил

1
@ Нейл Да, это так.
Пшеничный волшебник

2
@ GrzegorzPuławski Вы не должны сортировать список. Разрешается любая упорядоченная коллекция, например, вектор или массив.
Пшеничный волшебник

1
@DavidStarkey Большинство разумных списков не будут переполнены разумным объемом памяти. Складывание фактически не увеличивает сумму, поэтому списки будут сходиться к единственному значению суммы исходного списка.
Пшеничный волшебник

2
@WheatWizard Я не знаю об этом, я слышал, что невозможно сложить любой список пополам более чем в 7 раз.
Carmeister

Ответы:


9

Python , 46 байт

f=lambda l:l[1:]and[l[0]+l[-1]]+f(l[1:-1])or l

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

Одинаковая длина:

f=lambda l:l[1:]and[l.pop(0)+l.pop()]+f(l)or l

Гораздо более короткое решение работает для списков четной длины (30 байт)

lambda l:[x+l.pop()for x in l]

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

Я все еще пытаюсь найти короткий способ исправить это для нечетной длины.


О, я получил ужасное превосходство ÷ _ ÷
мистер Xcoder

Решение «среднего уровня» f=lambda l:l[1:]and[l[0]+l.pop()]+f(l[1:])or lтакже имеет ту же длину ...
ETHproductions


8

Эмоджикод , 203 байта

🐋🍨🍇🐖🔢🍇🔂i⏩0➗🐔🐕2🍇😀🔡➕🍺🔲🐽🐕i🚂🍺🔲🐽🐕➖🐔🐕➕1i🚂10🍉🍊😛1🚮🐔🐕2🍇😀🔡🍺🔲🐽🐕➗🐔🐕2🚂10🍉🍉🍉

Это был самый болезненный ответ Emojicode на код для меня. Ненужная длина: /

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



3

Gaia , 7 байт

e2÷ev+†

объяснение

e        Eval the input (push the list).
 2÷      Split it in half. The first half will be longer for an odd length.
   e     Dump the two halves on the stack.
    v    Reverse the second.
     +†  Element-wise addition. If the first half has an extra element, it is simply appended.

2

Mathematica, 88 байт

(d=Array[s[[#]]+s[[-#]]&,x=⌊t=Length[s=#]/2⌋];If[IntegerQ@t,d,d~AppendTo~s[[x+1]]])&

2

Mathematica 57 байт

(#+Reverse@#)[[;;d-1]]&@Insert[#,0,d=⌈Length@#/2⌉+1]&

Вставляет ноль в средней точке, добавляет список к его обратному и принимает соответствующую длину.










1

MATL , 9 байт

`6L&)swtn

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

Как это работает

Учитывая массив [a b c ... x y z], пусть [a z]будет называться «корочка» подмассив и [b c ... y z]«ядро» подмассив.

Код состоит из цикла, который удаляет корку, вычисляет ее сумму и перемещает ядро ​​на вершину стека, готовое к следующей итерации. Условие цикла - это количество элементов в подмассиве ядра.

`       % Do...while
  6L    %   Push [2 -1+1j]. As an index, this is interpreted as 2:end-1
  &)    %   2-output reference indexing: pushes a subarray with the indexed 
        %   elements (core) and another with the ramaining elements (crust)
  s     %   Sum of (crust) subarray
  w     %   Swap. Moves the core subarray to the top
  t     %   Duplicate
  n     %   Number of elements.
        % End (implicit). Procced with next iteration if top of the stack is
        % nonzero; else exit
        % Display stack (implicit)


1

C # (.NET Core) , 118 111 байтов

a=>a.Reverse().Zip(a,(c,d)=>c+d).Take(a.Length/2).Concat(a.Skip(a.Length/2).Take(a.Length%2))

Количество байтов также включает в себя

using System.Linq;

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

В качестве входных данных используйте числа, разделенные запятыми ( ,) или пробелом. Объяснение:

a =>                                  // Take one input parameter (array)
a.Reverse()                           // Reverse it
.Zip(a, (c, d) => c + d)              // Take every corresponding member of reversed
                                      //    and original, and add them together
.Take(a.Length / 2)                   // Get first half of the collection
.Concat(                              // Add another collection
    a.Skip(a.Length / 2)              // Take input and leave out first half of it
    .Take(a.Length % 2)               // If length is odd, take first element (so the middle)
                                      //    otherwise create an empty collection
);

Можете ли вы сохранить байты, задав длину переменной и переключившись на явный возврат?
TheLethalCoder

@TheLethalCoder, к сожалению, это длиннее
Гжегож Пулавски

1

Perl, 42 38 символов

sub f {@ a = map {$ + pop} splice @ , 0, @ / 2; @ a, @ }

sub f{(map{$_+pop}splice@_,0,@_/2),@_} 

Попробуйте, например, так:

perl -e 'my @input=(1..9); sub f{(map{$_+pop}splice@_,0,@_/2),@_}  print join(",",f(@input));

1
Исправлена ​​ошибка, которая появлялась из-за моей эмоциональной и профессиональной привязанности к переменным. Отказаться от одоления от JS: P
bytepusher

1

Pyth, 18 17 13 байтов

V.Tc2Q aYsN;Y

Мой оригинальный подход был

WtQ aY+.)Q.(Q0;+Y

-1 байт благодаря мистеру Xcoder

-4 байта благодаря FryAmTheEggman


Попробуйте использовать, c2<list>чтобы разделить список пополам. Еще одна команда , которая может быть полезна .T.
FryAmTheEggman


1

C ++ 17, 75 73 71 байт

Как и безымянная лямбда, принимая контейнер как vectorили list, возвращается через изменение ввода:

[](auto&L){for(auto a=L.begin(),b=L.end();a<--b;L.pop_back())*a+++=*b;}

Использование хорошо известного оператора «переход» <--и тройной плюс+++

Ungolfed и пример:

#include<iostream>
#include<vector>

using namespace std;

auto f=
[](auto&L){
 for(
  auto a=L.begin(),b=L.end();
  a<--b;
  L.pop_back()
 )
 *a+++=*b;
}
;

void test(auto L) {
 for(auto x:L)cout << x << ", ";
 cout << endl;
 f(L);
 for(auto x:L)cout << x << ", ";
 cout << endl << endl;
}

int main() { 
 vector<int> A = {1,2,3,4,5,6,7,8}, B = {1,2,3,4,5,6,7};
 test(A);
 test(B);
}


1

APL (Dyalog Unicode) , 21 байт SBCS

-3 байта благодаря @ Adám.

(⌊2÷⍨≢)(↑{+⌿↑⍺⍵}∘⌽↓)⊢

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

Объяснение:

(⌊2÷⍨≢)(↑{+⌿↑⍺⍵}∘⌽↓)⊢   Monadic function train
(⌊2÷⍨≢)                   Left portion:
                         Take the length of the input...
  2÷⍨                     Divide it by two...
                         And floor it. This gives our midpoint index. Call it "X"
                         Right portion: return the original input. Call it "Y"
       (↑{+⌿↑⍺⍵}∘⌽↓)    Midddle portion: takes X and Y as arguments
                        Take and drop Y by X. Essentially splits Y in half
                          Presents the two halves to the next function
                 ∘⌽      Reverse the second half
         {+⌿↑⍺⍵}        Final function, takes first half and reversed second half
              ⍺⍵         Construct a nested list of first and second halves...
                        ...and "mix" them into a matrix. Has the nice property that
                         it will pad the first half with a zero if needed.
          +⌿            Sum the matrix along the columns, return resulting vector

Dyalog Extended, 18 байт:+⌿(⌊2÷⍨≢)(↑↑⍮⌽⍤↓)⊢
Адам

Тренировка, 21 байт: (⌊2÷⍨≢)(↑{+⌿↑⍺⍵}∘⌽↓)⊢`
Адам





0

JavaScript (ES6), 46 43 байта

f=(a,[b,...c]=a)=>c+c?[b+c.pop(),...f(c)]:a

Сохранено 3 байта с вдохновением от Асафа .


Ницца. Вы можете изменить «1 / c [0]» на «[] + c», чтобы сохранить 2 байта.
Асаф

@Asaf На самом деле я думаю, что c+cработает для третьего байта.
Нил

0

Java 8, 93 байта

Двойные цифры! Это лямбда, которая принимает int[]и возвращает int[].

l->{int n=l.length,i=0;for(;i<n/2;)l[i]+=l[n-++i];return java.util.Arrays.copyOf(l,n/2+n%2);}

Неуправляемая лямбда

l -> {
    int n = l.length, i = 0;
    for (; i < n / 2; )
        l[i] += l[n - ++i];
    return java.util.Arrays.copyOf(l, n / 2 + n % 2);
}

Довольно просто. Он сворачивает вторую половину на первой половине ввода и возвращает копию только первой половины.

Удивительно, но копия массива в операторе return кажется самым дешевым способом обработки причуды последнего элемента для входных данных нечетной длины.


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