Складіть список навпіл


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

Спробуйте в Інтернеті!


Коли ви говорите цілі числа, чи включає це нульові чи від’ємні цілі числа?
Ніл


2
@ GrzegorzPuławski Не слід сортувати список. Дозволена будь-яка замовлена ​​колекція, наприклад вектор або масив.
Пшеничний майстер

1
@DavidStarkey Більшість розумних списків не переповнюватиметься достатньою кількістю пам'яті. Розгортання фактично не збільшує суму, тому списки сходяться до одинарної суми вихідного списку.
Пшеничний майстер

2
@WheatWizard Я не знаю про це, я чув, що неможливо скласти будь-який список вдвічі більше ніж у 7 разів.
Кармейстер

Відповіді:


9

Пітон , 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

Emojicode , 203 байти

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

Це була для мене найболючіша відповідь Емоджікоде. Непотрібна довжина: /

Спробуйте в Інтернеті!



3

Гая , 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

Математика, 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, на жаль, довше
Grzegorz Puławski

1

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

sub f {@ a = map {$ + pop} сплайс @ , 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

Піт, 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;}

Використання відомого оператора "перехід до" <--та потрійний плюс+++

Недолікований і приклад:

#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÷⍨≢)(↑↑⍮⌽⍤↓)⊢
Adám

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



0

Скала, 91 байт

(s:Seq[Int])=>(s.take(s.size/2),s.reverse).zipped.map(_+_)++s.drop(s.size/2).take(s.size%2)


0

JavaScript (ES6), 46 43 байт

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

Збережено 3 байти з натхненням від Asaf .


Приємно. Ви можете змінити "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.