将清单对折


24

我们将折叠一个整数列表。这样做的步骤如下:如果列表的长度为偶数,请列出其长度的一半,其中新列表的第n个项是旧列表的第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
@Neil是的。
小麦巫师

2
@GrzegorzPuławski您不应该对列表进行排序。允许任何有序的集合,例如向量或数组。
小麦巫师

1
@DavidStarkey最合理的列表不会在合理的内存量下溢出。折叠实际上并没有增加总和,因此列表将收敛到原始列表总和的一个单例。
小麦巫师

2
@WheatWizard我不知道,我听说不可能将任何列表对折超过7次。
Carmeister '17

Answers:


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先生,17年

“中间立场”解决方案f=lambda l:l[1:]and[l[0]+l.pop()]+f(l[1:])or l的长度也相同...
ETHproductions'Jul

8

05AB1E,5个字节

2ä`R+

使用 05AB1E编码。在线尝试!

说明

2ä        # Split the list into two pieces
  `       # Flatten the stack
   R      # Reverse the second element from the list
    +     # Vectorized addition

8

Emojicode,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

JavaScript,75 71字节

a=>a.slice(0,n=a.length/2).map(b=>b+a[--z],z=n*2).concat(n%1?a[n|0]:[])

在线尝试

ETHproductions节省了2个字节


1

JavaScript(ES6),41个字节

f=a=>1/a[1]?[a.shift()+a.pop(),...f(a)]:a


1

MATL,9个字节

`6L&)swtn

在线尝试!

怎么运行的

给定一个array [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)118111字节

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不幸的是,它的时间更长
GrzegorzPuławski'17

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

17个字节:WtQ aY+.)Q.(Q0;+Y
Xcoder先生

1

C ++ 17, 17、75 73 71字节

作为未命名的lambda,接受类似vector或的容器list通过修改输入来返回:

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

使用著名的“ goes-to”运算符 <--和三元组加号+++

脱节和示例:

#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



1

通用Lisp,106个字节

(lambda(l)(setf(values a b)(floor(length l)2))`(,@(#1=subseq(mapcar'+ l(reverse l))0 a),@(#1#l a(+ a b))))

在线尝试!



0

Scala,91个字节

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

0

Mathematica,52岁

(a=#;i=0;(i++;a[[i;;-i]]*=x)&/@a;(Tr@a+O@x^i)[[3]])&

0

JavaScript(ES6),46 43字节

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

Asaf的灵感中节省了3个字节。


真好 您可以将“ 1 / c [0]”更改为“ [] + c”以节省2个字节。
阿萨夫

@Asaf实际上我认为c+c第三个字节有效。
尼尔

0

Java 8,93字节

两位数!这是一个lambda,取一个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语句中的数组副本似乎是处理奇数长度输入的最终元素古怪的最便宜的方法。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.