37
\$\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
  • 7
    \$\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

52 Answers 52

1
2
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\$

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.

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

PHP, 67 bytes

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

Try it online!

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

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
\$\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\$
3
  • 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
  • \$\begingroup\$ Suggest l-l/2 instead of l/2+l%2 \$\endgroup\$
    – ceilingcat
    Jan 16 at 15:47
1
\$\begingroup\$

jq, 58 bytes

[reverse[:length/2],.[:length/2|floor]]|transpose|map(add)

Try it online!

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

Scala, 65 bytes

l=>l take(l.size+1)/2 zipAll(l.reverse take l.size/2,0,0)map(_+_)

Try it in Scastie!

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

k9, 12 bytes

+/++(;|)@'2^

Version 2021.09.20.

Cut in two, reverse second list, pad with zeroes, add.

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

Thunno, \$ 10 \log_{256}(96) \approx \$ 8.23 bytes

2APAur0Tz+

Attempt This Online!

Sort-of port of Adnan's 05AB1E answer

Explanation:

2APAur0Tz+  # Implicit input
2AP         # Split in half
   Au       # Dump onto stack
     r      # Reverse top item
      0T    # Append a 0
        z+  # Zipped addition

Thunno's normal addition (+) will provide a nested list of each element of the first list plus each element of the second list.

Thunno's zipped addition (z+) zips the two lists together, discarding items if they are not of equal length.

So, we must append a 0 to the top list (since it will be the shorter one if the input contained an odd number of items) and then use zipped addition.

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

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

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

Try it online!

-2 bytes thanks to @ceilingcat!

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

JavaScript (Node.js), 41 bytes

f=([b,...c])=>1/b?[b+~~c.pop(),...f(c)]:c

Try it online!

So many ways to reach 41

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

Japt, 10 bytes

There's gotta be a 9 here, somewhere.

òUÊ/2 oÔyx

Try it

òUÊ/2 oÔyx     :Implicit input of array U
ò              :Partitions of length
 UÊ            :  Length of U
   /2          :  Divided by 2
      o        :Modify last element
       Ô       :  Reverse
        y      :Transpose
         x     :Reduce each by addition

Also 10 bytes

íUÔoUÊz¹mx

Try it

íUÔoUÊz¹mx     :Implicit input of array U
í              :Interleave with
 UÔ            :  Reverse U (mutates the original)
   o           :  Pop this many items (also mutates the original)
    UÊ         :    Length of U
      z        :    Floor divided by 2
       ¹       :End interleave
        m      :Map
         x     :  Reduce by addition
\$\endgroup\$
1
\$\begingroup\$

Nibbles, 6.5 bytes

/`\~_!:\@0@+

Attempt This Online!

/   Fold
`\~  split into two parts
_     input (row from STDIN as a list of integers)
!    zip
:     join
\      reverse
@       the second part
0      0
@     the first part
+     with addition
\$\endgroup\$
1
\$\begingroup\$

Julia 1.0, 69 68 bytes

!s=(~=length;~s%2>0&&insert!(s,(1+~s)÷2,0);(s+reverse(s))[1:~s÷2])

Try it online!

-1 byte thanks to MarcMush: replace ==1 with >0

\$\endgroup\$
1
  • 1
    \$\begingroup\$ -1 byte: >0 instead of ==1 \$\endgroup\$
    – MarcMush
    Feb 24 at 12:58
0
\$\begingroup\$

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!

\$\endgroup\$
2
  • \$\begingroup\$ Replace -i-1 with +~i to save a byte. \$\endgroup\$
    – user72349
    Jul 31, 2017 at 21:39
  • \$\begingroup\$ And also c!=i with c>i for a byte. \$\endgroup\$
    – user72349
    Jul 31, 2017 at 21:41
1
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.