Fold a List in Half

24

1

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!

Post Rock Garf Hunter

Posted 2017-07-31T19:42:43.257

Reputation: 55 382

When you say integers, does this include zero or negative integers? – Neil – 2017-07-31T19:53:41.343

1@Neil Yes it does. – Post Rock Garf Hunter – 2017-07-31T19:54:02.583

Are we supposed to sort the list, or just take what we're given? Also is any type of collection allowed, or just a list (for languages with multiple types of collections)? – Grzegorz Puławski – 2017-07-31T20:40:49.223

2@GrzegorzPuławski You should not sort the list. Any ordered collection is allowed, e.g. vector or array. – Post Rock Garf Hunter – 2017-07-31T20:51:00.623

Now make it recursive and see how many times you can fold a list in half before you overflow. – David Starkey – 2017-08-01T13:49:36.657

1@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. – Post Rock Garf Hunter – 2017-08-01T14:05:47.070

@WheatWizard That's what I meant, keep folding until one of the items in the list overflows. Sure it needs larger lists than your examples, but that's kinda the point. – David Starkey – 2017-08-01T14:49:36.867

2@WheatWizard I don't know about that, I've heard it's impossible to fold any list in half more than 7 times. – Carmeister – 2017-08-02T04:23:19.227

I would find it easier to visualize and follow if the odd length example just kept the [4] as a fourth column, in between the two rows. – Sparr – 2019-03-10T20:00:48.577

Answers

9

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.

xnor

Posted 2017-07-31T19:42:43.257

Reputation: 115 687

Oh, I got terribly outgolfed ÷_÷ – Mr. Xcoder – 2017-07-31T20:10:23.660

The "middle ground" solution f=lambda l:l[1:]and[l[0]+l.pop()]+f(l[1:])or l is also the same length... – ETHproductions – 2017-07-31T20:42:25.507

8

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

Adnan

Posted 2017-07-31T19:42:43.257

Reputation: 41 965

8

Emojicode, 203 bytes

i⏩0➗2➕i➖➕1i1012➗210

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

Try it online!

betseg

Posted 2017-07-31T19:42:43.257

Reputation: 8 493

4

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...

ETHproductions

Posted 2017-07-31T19:42:43.257

Reputation: 47 880

3

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.

Business Cat

Posted 2017-07-31T19:42:43.257

Reputation: 8 927

2

Jelly, 7 bytes

œs2U2¦S

Try it online!

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

Erik the Outgolfer

Posted 2017-07-31T19:42:43.257

Reputation: 38 134

ETH was right, 7 bytes

– Mr. Xcoder – 2017-07-31T19:55:47.127

@ETHproductions Thanks, although I had already figured out after I shut my computer down. – Erik the Outgolfer – 2017-08-01T08:11:31.840

2

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.

Giuseppe

Posted 2017-07-31T19:42:43.257

Reputation: 21 077

2

Mathematica, 88 bytes

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

J42161217

Posted 2017-07-31T19:42:43.257

Reputation: 15 931

2

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.

Kelly Lowder

Posted 2017-07-31T19:42:43.257

Reputation: 3 225

2

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!

Asaf

Posted 2017-07-31T19:42:43.257

Reputation: 121

2

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!

Justin Mariner

Posted 2017-07-31T19:42:43.257

Reputation: 4 746

1

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!

Mr. Xcoder

Posted 2017-07-31T19:42:43.257

Reputation: 39 774

1

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

Dave

Posted 2017-07-31T19:42:43.257

Reputation: 432

Try using c2<list> to split a list in half. Another command that might be useful is .T. – FryAmTheEggman – 2017-07-31T19:58:10.817

17 bytes: WtQ aY+.)Q.(Q0;+Y

– Mr. Xcoder – 2017-07-31T19:58:12.193

1

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

user72349

Posted 2017-07-31T19:42:43.257

Reputation:

1

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!

Business Cat

Posted 2017-07-31T19:42:43.257

Reputation: 8 927

1

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

Grzegorz Puławski

Posted 2017-07-31T19:42:43.257

Reputation: 781

Can you save bytes by setting the length to a variable and switching to an explicit return? – TheLethalCoder – 2017-08-01T08:07:39.963

@TheLethalCoder unfortunately it's longer – Grzegorz Puławski – 2017-08-01T08:33:14.607

1

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)

Luis Mendo

Posted 2017-07-31T19:42:43.257

Reputation: 87 464

1

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

Rick Hitchcock

Posted 2017-07-31T19:42:43.257

Reputation: 2 461

1

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

bytepusher

Posted 2017-07-31T19:42:43.257

Reputation: 149

1Fixed an error that crept in due to my emotional and professional attachment to variables. Refuse to be outgolfed by JS :P – bytepusher – 2017-08-02T12:22:17.570

1

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!

Felix Guo

Posted 2017-07-31T19:42:43.257

Reputation: 211

1

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

Karl Napf

Posted 2017-07-31T19:42:43.257

Reputation: 4 131

1

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

voidhawk

Posted 2017-07-31T19:42:43.257

Reputation: 1 796

Dyalog Extended, 18 bytes: +⌿(⌊2÷⍨≢)(↑↑⍮⌽⍤↓)⊢

– Adám – 2019-02-17T17:54:36.120

Training, 21 bytes: (⌊2÷⍨≢)(↑{+⌿↑⍺⍵}∘⌽↓)⊢`

– Adám – 2019-02-17T17:57:54.970

1

J, 22 bytes

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

Try it online!

Jonah

Posted 2017-07-31T19:42:43.257

Reputation: 8 729

1

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!

Renzo

Posted 2017-07-31T19:42:43.257

Reputation: 2 260

0

JavaScript (Node.js), 62 bytes

a=>a.map((e,i)=>e+a[c=(b=a.length)-i-1]*(c!=i)).slice(0,++b/2)

Try it online!

Ra8

Posted 2017-07-31T19:42:43.257

Reputation: 391

Replace -i-1 with +~i to save a byte. – None – 2017-07-31T21:39:42.743

And also c!=i with c>i for a byte. – None – 2017-07-31T21:41:59.430

0

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.

Neil

Posted 2017-07-31T19:42:43.257

Reputation: 95 035

Nice. You could change '1/c[0]' to '[]+c' to save 2 bytes. – Asaf – 2017-07-31T22:08:42.703

@Asaf Actually I think c+c works for the third byte. – Neil – 2017-07-31T23:41:13.313

0

Scala, 91 bytes

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

Phoenix

Posted 2017-07-31T19:42:43.257

Reputation: 151

0

Mathematica, 52

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

Mr.Wizard

Posted 2017-07-31T19:42:43.257

Reputation: 2 481

0

Java 8, 93 bytes

Double digits! This is a lambda that takes an int[] and returns an 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);}

Ungolfed lambda

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

Quite straightforward. It folds the second half in place onto the first half of the input and returns a copy of just the first half.

Surprisingly, the array copy in the return statement seems to be the cheapest way to handle the final element quirk for odd-length inputs.

Jakob

Posted 2017-07-31T19:42:43.257

Reputation: 2 428

0

PHP, 67 bytes

function($l){while($l)$o[]=array_shift($l)+array_pop($l);return$o;}

Try it online!

640KB

Posted 2017-07-31T19:42:43.257

Reputation: 7 149

0

Perl 6, 28 bytes

{.[^*/2]Z+.[$_-1...$_/2,$_]}

Try it online!

Explanation:

{                          }   # Anonymous code block
 .[^*/2]                       # The first half of the list
        Z+                     # Zip added to
          .[$_-1...$_/2        # The other half of the list
                       ,$_]    # And zero for the middle element

Jo King

Posted 2017-07-31T19:42:43.257

Reputation: 38 234

0

C# (Visual C# Interactive Compiler), 82 bytes

x=>{int i=0,l=x.Count;for(;i<l/2;)x[i]+=x[l-++i];return x.Take(l/2+l%2).ToList();}

Try it online!

dana

Posted 2017-07-31T19:42:43.257

Reputation: 2 541

0

Ruby, 34 bytes

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

Try it online!

G B

Posted 2017-07-31T19:42:43.257

Reputation: 11 099

0

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

GammaFunction

Posted 2017-07-31T19:42:43.257

Reputation: 2 838

0

C (gcc), 55 bytes

f(_,l)int*_;{for(;l--;printf("%d ",l?*_+_++[l--]:*_));}

Try it online!

attinat

Posted 2017-07-31T19:42:43.257

Reputation: 3 495