Fold a List in Half

We are going to fold a list of integers. The procedure to do so is as follows, If the list is of even length, make a list of half of its length where the nth item of the new list is the sum of the nth item of the old list and the nth-to-last item of the old list. For example if we had the list

[1 2 3 4 5 6 7 8]

We would fold it like so

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

If the list is of odd length, to fold it we first remove the middle item, fold it as if it were even and the append the middle item to the result.

For example if we had the list

[1 2 3 4 5 6 7]

We would fold it like so

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

Write a program or function that takes a list of integers as input and outputs that list folded.

This is a question so answers will be scored in bytes, with fewer bytes being better.

Sample implementation

Here's an implementation in Haskell that defines a function f that performs a fold.

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

Try it online!

• When you say integers, does this include zero or negative integers?
– Neil
Jul 31, 2017 at 19:53
• @Neil Yes it does. Jul 31, 2017 at 19:54
• @GrzegorzPuławski You should not sort the list. Any ordered collection is allowed, e.g. vector or array. Jul 31, 2017 at 20:51
• @DavidStarkey Most reasonable lists will not overflow with a reasonable amount of memory. Folding doesn't actually increase the sum so lists will converge to a singleton of the sum of the original list. Aug 1, 2017 at 14:05
• @WheatWizard I don't know about that, I've heard it's impossible to fold any list in half more than 7 times. Aug 2, 2017 at 4:23

Python, 46 bytes

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

Try it online!

Same length:

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

A much shorter solution works for even-length lists (30 bytes)

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

Try it online!

I'm still trying to find a short way to correct it for odd length.

• Oh, I got terribly outgolfed ÷_÷ Jul 31, 2017 at 20:10
• The "middle ground" solution f=lambda l:l[1:]and[l[0]+l.pop()]+f(l[1:])or l is also the same length... Jul 31, 2017 at 20:42

Emojicode, 203 bytes

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

This was the most painful Emojicode answer to code for me. The unnecessary length :/

Try it online!

05AB1E, 5 bytes

Code

2äR+

Uses the 05AB1E encoding. Try it online!

Explanation

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

Japt, 2118 16 bytes

l
íUj°V/2V w)mx

Test it online!

Completely awful Slightly less awful thanks to @Oliver. BRB after I implement more built-ins and fix some bugs...

Gaia, 7 bytes

e2÷ev+†

Explanation

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.

Jelly, 7 bytes

œs2U2¦S

Try it online!

-2 thanks to ETHproductions...and me realizing before.

• ETH was right, 7 bytes Jul 31, 2017 at 19:55
• @ETHproductions Thanks, although I had already figured out after I shut my computer down. Aug 1, 2017 at 8:11

Vyxal, 4 bytes

I÷Ṙ+

Try it Online!

I    # Halve the list
÷   # Push each half
Ṙ  # Reverse the second half
+ # Add them together (vectorising)

Mathematica, 88 bytes

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

Mathematica 57 Bytes

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

Inserts a zero at the midpoint, adds the list to its reverse and takes the appropriate length.

JavaScript (ES6), 41 bytes

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

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

console.log(JSON.stringify(f([1,2,3,4,5,6,7,8])));
console.log(JSON.stringify(f([1,2,3,4,5,6,7])));

Japt, 12 bytes

å@o +Y*(Z<Ul

Try it online! with the -Q flag to view the formatted array.

o(½*Ul)c)íU mx

Try it online!

JavaScript (Node.js), 53 bytes

x=>x.splice(0,x.length/2).map(y=>y+x.pop()).concat(x)

Try it online!

Another suggestion:

JavaScript (Node.js), 43 bytes

f=x=>x+x?[x.pop()+(0|x.shift()),...f(x)]:[]

Try it online!

• (0|x.shift()) => ~~x.shift()
– l4m2
Jan 17 at 14:29

R, 817068 57 bytes

function(l)c((l+rev(l))[1:(w=sum(l|1)/2)],l[w+1][!!w%%1])

Try it online!

anonymous function; returns the result.

Zsh, 55 bytes

If the answer must be put to stdout, but output whitespace is flexible, 55 bytes:

for ((;++i<=#/2;))<<<$[$@[i]+$@[-i]] <<<$@[#%2*(1+#/2)]

Try it online!

If the output must be stored in an array, 53 bytes: (We can't use this method in place of the above because of <<<...[--i].... The here-string forces a subshell, so the decremented value of i never makes it out.)

for n ($@[1,#/2])y+=($[$@[--i]+n]) y+=$@[#%2*(1+#/2)]

Try it online!

If the answer must be output in one line separated by spaces, then append <<<$y for a 6 byte penalty. Zsh arrays are indexed from the start starting at 1, or from the end starting at -1. So what happens if you attempt to index at 0? Well, nothing! We take advantage of that here to only output the middle number based on a parity check:$@[#%2*(1+#/2)]
#      #       # parameter count
(1+#/2)    # index of the middle element when count is odd
#%2*(1+#/2)    # multiply by 0 if even, or 1 if odd
$@[ ] # Index the parameter array Factor, 35 bytes [ halves reverse 0 pad-longest v+ ] Try it online! Explanation It's a quotation (anonymous function) that takes a sequence from the data stack and leaves a sequence on the data stack. Assuming { 1 2 3 4 5 6 7 } is on the data stack when this quotation is called... Snippet Comment Data stack (top on right) halves Split a sequence in half { 1 2 3 } { 4 5 6 7 } reverse Reverse a sequence { 1 2 3 } { 7 6 5 4 } 0 pad-longest Pad the shorter of two sequences with 0s until it's the same length as the longer sequence { 1 2 3 0 } { 7 6 5 4 } v+ Vector addition; element-wise addition between two sequences { 8 8 8 4 } C (gcc), 55 41 bytes f(_,l)int*_;{for(;l--;*_+++=l?_[l--]:0);} Try it online! Overwrites the first $$\\left\lfloor\frac{l}{2}\right\rfloor\$$ entries of the input array. C (gcc), 46 bytes f(_,l)int*_;{_=l>1?*_+=_[l-1],1+f(_+1,l-2):l;} Try it online! Additionally returns the length $$\\left\lceil\frac{l}{2}\right\rceil\$$ of the output. Go, 115 bytes func(x[]int)(o[]int){s:=len(x) for i:=range x[:s/2]{o=append(o,x[i]+x[s-i-1])} if s%2>0{o=append(o,x[s/2])} return} Attempt This Online! Generic with custom operator, 136 bytes func f[T any](x[]T,O func(T,T)T)(o[]T){s:=len(x) for i:=range x[:s/2]{o=append(o,O(x[i],x[s-i-1]))} if s%2>0{o=append(o,x[s/2])} return} Attempt This Online! Curry (PAKCS), 34 bytes f(a:b++[c])=a+c:f b f x@([]?[_])=x Attempt This Online! Based on the sample implementation in Haskell. C (gcc), 62 bytes 60 bytes -2 bytes thanks to @ceilingcat i;f(v,l)int*v;{for(i=0;i<l/2;++i)v[i]+=v[l+~i];return~l/-2;} f is a function taking vector (v) and length (l) as arguments. It modifies the vector and returns the new length. Try It Online! How it works: i; f(v,l) int*v; // v is an integer pointer (or array), l is an integer { for (i = 0; i < l / 2; ++i) // iterate through half the indices using i (if l is odd, the middle element won't be included) v[i] += v[l + ~i]; // add the value at the i'th index from the back to the i'th index from the front. ~i == -i - 1, so l + ~i == l + -i -1 = l - i - 1 (l - 1 is the first index from the back, and we subtract i for each index beyond the first) return ~l / -2; // return half the length rounded up (~l == -l - 1 => ~l / -2 == (-l - 1) / -2 => (l + 1) / 2 } • Welcome to Code Golf! Nice first answer. Jan 18 at 7:27 BQN, 15 12 bytes (⌊≠÷2˙)⊸↑⊢+⌽ Try it online! -3 thanks to Marshall Lochbaum Sum the list and its reverse, then take the first ⌊≠÷2˙ digits. ⌊≠÷2˙ the floor of the length divide 2. Floor is necessary because there is no integer division in BQN. is used to bind the output of ⌊≠÷2˙ to the take operator on the left and also puts the output of (⊢+⌽) on the right. Better explanation here. • Welcome to Code Golf, and nice answer! Jan 20 at 20:45 • Thank you! I only wish my explanation was as concise... Jan 20 at 20:49 Pip, 14 12 bytes YCHa;@y+Ry@1 -2 Thanks to DLosc! How? YCHa;@y+Ry@1 : One arg; list a : First input CH : Chop iterable into 2 pieces of roughly equal length Y : Yank value y : The two halves @1 : Get item/slice at index 1; The second half R : Reverse + : Add with y : The two halves @ : Get item at index 0; The first half Try It Online! • @DLosc that was so obvious I don't know how I missed it lol, thanks for the spot! Jan 20 at 14:07 • @DLosc I see what you mean, it made sense when I wrote it, should be fixed now! :) Jan 21 at 7:45 Fig, $$\23\log_{256}(96)\approx\$$ 18.932 bytes J+t_HLxxt_HLx$xs_HLxtHL

Try it online!

$$\-26\log_{256}(96)\approx21.401\$$ thanks to Seggan

First time using Fig. Any golfing tips are welcome.

Explanation (outdated):

fw+[yfy$fy$fyx[yfy$fy$fy$x?h%1HLx[]yfy$fy$fyx]yW1 [yfy$fy$fyx First Mid + Add [yfy$fy$fy$x                        Second Mid
fw                                                Concat
?                       If
h%1HLx                 List length is odd,
[]yfy$fy$fyx     Mid
]yW1 Else Empty list
• the entire if (?h%1HLx[]yfy$fy$fyx]yW1) can be replaced with s_HLxtHL (take half, drop half; will return empty list if even, middle item if odd). fw can be J Jan 19 at 15:28
• J+t_HLxxt_HLx\$xs_HLxtHL works Jan 19 at 15:37

Python 3, 101 bytes

lambda l:[sum(x)for x in zip(l[:len(l)//2],l[int(len(l)/2+.5):][::-1])]+[[],[l[len(l)//2]]][len(l)%2]

Try it online!

Python 3, 70 bytes

lambda l:[l[i]+l[~i]for i in range(len(l)//2)]+len(l)%2*[l[len(l)//2]]

Try it online!

JavaScript, 75 71 bytes

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

Try it online

Saved 2 bytes thanks to ETHproductions

MATL, 9 bytes

6L&)swtn

Try it online!

How it works

Given an array [a b c ... x y z], let [a z] be called the "crust" subarray and [b c ... y z] the "core" subarray.

The code consists in a loop that removes the crust, computes its sum, and moves the core to the top of the stack, ready for the next iteration. The loop condition is the number of elements in the core subarray

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

WendyScript, 72 bytes

<<f=>(l){<<r=[]<<b=l.size#i:0->b/2r+=l[i]+l[b-i-1]?b%2!=0r+=l[(b/2)]/>r}

f([1,2,3,4,5,6,7,8]) // => [9,9,9,9]
f([1,2,3,4,5,6,7]) // => [8,8,8,4]

Try it online!

Scala, 91 bytes

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

C# (.NET Core), 118 111 bytes

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

Byte count also includes

using System.Linq;

Try it online!

As input please use numbers separated either with commas (,) or space. Explanation:

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