28
\$\begingroup\$

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]

Task

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!

\$\endgroup\$
9
  • \$\begingroup\$ When you say integers, does this include zero or negative integers? \$\endgroup\$
    – Neil
    Jul 31, 2017 at 19:53
  • 1
    \$\begingroup\$ @Neil Yes it does. \$\endgroup\$
    – Wheat Wizard
    Jul 31, 2017 at 19:54
  • 2
    \$\begingroup\$ @GrzegorzPuławski You should not sort the list. Any ordered collection is allowed, e.g. vector or array. \$\endgroup\$
    – Wheat Wizard
    Jul 31, 2017 at 20:51
  • 1
    \$\begingroup\$ @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. \$\endgroup\$
    – Wheat Wizard
    Aug 1, 2017 at 14:05
  • 5
    \$\begingroup\$ @WheatWizard I don't know about that, I've heard it's impossible to fold any list in half more than 7 times. \$\endgroup\$
    – Carmeister
    Aug 2, 2017 at 4:23

41 Answers 41

11
\$\begingroup\$

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.

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

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!

\$\endgroup\$
8
\$\begingroup\$

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
    +     # Vectorized addition
\$\endgroup\$
4
\$\begingroup\$

Japt, 21 18 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...

\$\endgroup\$
0
3
\$\begingroup\$

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.
\$\endgroup\$
3
\$\begingroup\$

Jelly, 7 bytes

œs2U2¦S

Try it online!

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

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

Mathematica, 88 bytes

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

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.

\$\endgroup\$
0
2
\$\begingroup\$

Japt, 12 bytes

å@o +Y*(Z<Ul

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

Alternate solution, 14 bytes

o(½*Ul)c)íU mx

Try it online!

\$\endgroup\$
2
\$\begingroup\$

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!

\$\endgroup\$
2
\$\begingroup\$

R, 81 70 68 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.

\$\endgroup\$
2
\$\begingroup\$

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 }
\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
0
1
\$\begingroup\$

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!

\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
0
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

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)
\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
1
\$\begingroup\$

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
.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
);
\$\endgroup\$
2
  • \$\begingroup\$ Can you save bytes by setting the length to a variable and switching to an explicit return? \$\endgroup\$ Aug 1, 2017 at 8:07
  • \$\begingroup\$ @TheLethalCoder unfortunately it's longer \$\endgroup\$ Aug 1, 2017 at 8:33
1
\$\begingroup\$

JavaScript (ES6), 46 43 bytes

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

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

console.log(f([1,2,3,4,5,6,7,8]).join(', ')) // 9, 9, 9, 9  ✓
console.log(f([1,2,3,4,5,6,7]).join(', '))   // 8, 8, 8, 4  ✓
.as-console-wrapper{max-height:100%!important}

Saved 3 bytes with inspiration from Asaf.

\$\endgroup\$
2
  • \$\begingroup\$ Nice. You could change '1/c[0]' to '[]+c' to save 2 bytes. \$\endgroup\$
    – Asaf
    Jul 31, 2017 at 22:08
  • \$\begingroup\$ @Asaf Actually I think c+c works for the third byte. \$\endgroup\$
    – Neil
    Jul 31, 2017 at 23:41
1
\$\begingroup\$

Perl, 42 38 chars

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

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

Try for example like so:

perl -e 'my @input=(1..9); sub f{(map{$_+pop}splice@_,0,@_/2),@_}  print join(",",f(@input));
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Fixed an error that crept in due to my emotional and professional attachment to variables. Refuse to be outgolfed by JS :P \$\endgroup\$
    – bytepusher
    Aug 2, 2017 at 12:22
1
\$\begingroup\$

Pyth, 18 17 13 bytes

V.Tc2Q aYsN;Y

My original approach was

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

-1 byte thanks to Mr. Xcoder

-4 bytes thanks to FryAmTheEggman

\$\endgroup\$
2
  • \$\begingroup\$ Try using c2<list> to split a list in half. Another command that might be useful is .T. \$\endgroup\$ Jul 31, 2017 at 19:58
  • \$\begingroup\$ 17 bytes: WtQ aY+.)Q.(Q0;+Y \$\endgroup\$
    – Mr. Xcoder
    Jul 31, 2017 at 19:58
1
\$\begingroup\$

C++17, 75 73 71 bytes

As unnamed lambda, accepting a container like vector or list, returns via modifying the input:

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

Using the well known 'goes-to' operator <-- and the triple plus +++

Ungolfed and example:

#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);
}
\$\endgroup\$
1
\$\begingroup\$

J, 22 bytes

({.+/@,:|.@}.)~>.@-:@#

Try it online!

\$\endgroup\$
1
+100
\$\begingroup\$

APL (Dyalog Unicode), 21 bytesSBCS

-3 bytes thanks to @Adám.

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

Try it online!

Explanation:

(⌊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
\$\endgroup\$
2
1
\$\begingroup\$

Ruby, 34 bytes

f=->l{l[1]?[l.shift+l.pop]+f[l]:l}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Common Lisp, 106 bytes

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

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Java (JDK), 102 95 bytes

i->{int l=i.length,o=l/2+l%2,r[]=new int[o];for(;o-->0;)r[o]=i[o]+(o<l+~o?i[l+~o]:0);return r;}

Try it online!

-7 Thanks to Kevin Cruijssen

\$\endgroup\$
2
  • 1
    \$\begingroup\$ l-j-1 can be simplified to l+~j. Also, you don't need the j if you loop in reverse order and reuse the o: 95 bytes. \$\endgroup\$ Sep 29, 2021 at 9:02
  • \$\begingroup\$ There we go! Credited without alt-tabbing :PP \$\endgroup\$
    – 0xff
    Sep 29, 2021 at 12:08
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

Vyxal , 7 4 bytes

½C÷Ṙ

Try it Online!

Takes input as a string of characters with corresponding ASCII values.

-1 thanks to lyxal
-2 thanks to Aaroneous Miller

\$\endgroup\$
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.