17
\$\begingroup\$

Given a list of 2 or more strictly positive integers, sum the first and last half of the list, with the middle element being counted only in the right half if the list has an odd number of elements

Some examples of the middle element being counted in the right half:

[1, 2, 3, 4]       -> Left: [1, 2];    Right: [3, 4]
[1, 2, 3]          -> Left: [1];       Right: [2, 3]
[1, 2, 3, 4, 5]    -> Left: [1, 2];    Right: [3, 4, 5]
[1, 2, 3, 4, 5, 6] -> Left: [1, 2, 3]; Right: [4, 5, 6]

Test Cases

Input

[1, 9]
[9, 5, 5, 7]
[6, 7, 5, 1, 3, 9, 7, 1, 6]
[2, 8, 10, 9, 9, 3, 7, 8, 9, 8, 6, 1, 2, 9, 8, 3, 8, 9, 5]
[2, 3, 1, 8, 6, 2, 10, 6, 7, 6]

Output

[1, 9]
[14, 12]
[19, 26]
[65, 59]
[20, 31]

Reference Program With Two Output Methods

Rules

  • Input/Output can be Taken/Given in any convenient and reasonable format.
  • Functions and full programs are both acceptable.
\$\endgroup\$
  • \$\begingroup\$ So just to confirm, we're permitted to return the two sums in reverse order (right sum then left sum)? \$\endgroup\$ – math junkie May 2 at 18:17
  • \$\begingroup\$ Yes you are allowed to. \$\endgroup\$ – Lyxal May 2 at 18:44
  • \$\begingroup\$ Can the output be in reverse order? \$\endgroup\$ – Shaggy May 2 at 19:28
  • 1
    \$\begingroup\$ @Shaggy The question is asked and answered above \$\endgroup\$ – math junkie May 2 at 19:59

33 Answers 33

2
\$\begingroup\$

Brachylog, 3 bytes

ḍ+ᵐ

Try it online!

Brachylog's cut-a-list-in-half predicate just so happens to already make the right half larger.

| improve this answer | |
\$\endgroup\$
14
\$\begingroup\$

Python 2, 40 bytes

Takes as input a list \$ l \$, and outputs the two sums in reverse order ([right, left]).

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

Explanation

In sum(l.pop()for x in l), we pop the last element, in each iteration, and sum the popped elements. Surprisingly, the loop only runs \$ \lceil{\frac{|l|}{2}}\rceil \$ times, since for every element we iterate from the left, we are removing an element from the right, resulting in the loop terminating somewhere in the middle. Therefore it gives us the sum of the right portion of the list. The sum of the remaining elements make up the left portion.

Try it online!

| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ That's a clever use of .pop() to ensure that only half of the list is summed... That took me a while to figure out how it was doing it! \$\endgroup\$ – Lyxal May 2 at 17:28
6
\$\begingroup\$

Python 3.8, 41 bytes

lambda l:[t:=sum(l[:len(l)//2]),sum(l)-t]

Try it online!

Straightforward solution. Takes in a list, and returns the list of left and right sum.


Interesting idea that didn't go anywhere :(

Python 3, 45 bytes

lambda l,t=1j:l>[]and l[-1]+t*f(l[-2::-1],-t)

Try it online!

Returns a+bj where a, b is the right and left sum respectively.

| improve this answer | |
\$\endgroup\$
5
\$\begingroup\$

Haskell, 44 43 bytes

f x=[sum$y(div(length x)2)x|y<-[take,drop]]

Try it online!

Based on Steven Fontanella's answer with some non-trivial modification.

| improve this answer | |
\$\endgroup\$
5
\$\begingroup\$

K (ngn/k) / oK / K4, 8 bytes

+/'2 0N#

Try it online!

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ ...also works in K4 and oK if you wanted to add them to the title \$\endgroup\$ – streetster May 19 at 11:54
  • \$\begingroup\$ @streetster Thanks! I think I tried it in oK. \$\endgroup\$ – Galen Ivanov May 19 at 13:03
4
\$\begingroup\$

J, 14 bytes

-@>.@-:@#+/\|.

Try it online!

Output is in reverse.

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Pyth, 6 5 bytes

Outputs the two sums in reverse order (right sum, then left sum)

sMc2_

Try it online!

 sMc2_
     _  Reverse the input
   c2   Chop into 2 equal-sized chunks, with the first chunk 
         one element longer if necessary
 sM     Sum each chunk
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Rust, 71 bytes

|x:&[u8]|{let s=x[..x.len()/2].iter().sum();(s,x.iter().sum::<u8>()-s)}

A closure that takes a reference to a slice of 8-bit unsigned numbers and returns a tuple of two 8-bit unsigned numbers.

try it online on the rust playground.

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Haskell, 50 bytes

f x=(\(a,b)->sum<$>[a,b])$splitAt(length x`div`2)x

Try it online!

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Lambdas almost always have a shorter alternative. In this case you save a bye with a helper \$\endgroup\$ – Ad Hoc Garf Hunter May 2 at 22:27
  • \$\begingroup\$ @AdHocGarfHunter Would love to see it! For some reason, it the TIO link shows up empty, though... (on my phone) \$\endgroup\$ – AviFS May 3 at 0:23
3
\$\begingroup\$

Octave, 33 bytes

@(x)x*[u=(t=find(x))<mean(t);~u]'

Try it online!

How it works

@(x)x*[u=(t=find(x))<mean(t);~u]'

@(x)                               % Define an anonynous function with input x
            find(x)                % Indices of nonzero entries of x. Gives [1 2 ... n]
                                   % where n is the length of x
         (t=       )               % Assign that to variable t
                    <mean(t)       % Test if each entry of t is less than the mean of t.
                                   % This gives [1 ... 1 0 ... 0], with floor(n/2) ones
                                   % and n-floor(n/2) zeros
       u=                          % Assign that to variable u
      [                     ;~u]   % Build a 2×n matrix containing u in the first row
                                   % and u negated in the second row
                                '  % Conjugate transpose. Gives an n×2 matrix
    x*                             % Matrix-multiply x (size 1×n) times the above n×2
                                   % matrix. Gives a 1×2 vector containing the result
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

brainfuck, 180 bytes

++>>>>>+>,[[<]>+[>],]<[<]>[<+>-]<[<<<<[>>+<+<-]>[<+>-]>[<+>>>-[<<<[-]>>+>-]<[>+<-]<<[>-[>>>-<<<[-]]+<-]>-]>>>+<]>[<<+>+>-]<<[>>+<<-]>[>-<[-]]>[[>]<[<+>-]<[<]>-]>>>[<<[->+<]>>>]<.<.

Try it online! (testcase [2, 8, 10, 9, 9, 3, 7, 8, 9, 8, 6, 1, 2, 9, 8, 3, 8, 9, 5])

Takes input as bytes on stdin. Outputs the two sums as bytes on stdout in reverse order.

Compiled from this VBF 1.0 code with mapping requirement x:5 :

# set y to 2
y++

# Input is to the right of x; which is the length and the divdend
# Ensure that x is the rightmost variable
# x is the length of a length-prefixed array of numbers
x+>,[[<]>+[>],]
<[<]>
#cursor is at x
# x = x / y
# from user Calamari from esolangs wiki at https://esolangs.org/wiki/Brainfuck_algorithms
x[A+x-]
A[
 y[B+C+y-]
 C[y+C-]
 B[
  C+
  A-[C[-]D+A-]
  D[A+D-]
  C[
   B-
   [x-B[-]]+
  C-]
 B-]
 x+
A]
# After this, x = x / 2, A,B,C,D = 0, y = y
# If x, x = x - 1
# from https://esolangs.org/wiki/Brainfuck_algorithms#if_.28x.29_.7B_code_.7D
x[D+A+x-]D[x+D-]
A[
  x-
  A[-]
]

# Add up first half, cursor starts at x
# Requires that the cell to the left of x is 0
x[
  [>]<   # last input
  [<+>-] # add into left neighbor
  <[<]>- # back to x, decrement x
]

>>>
[
  <<[->+<]>>>
]<.<.
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

brainfuck, 45 43 bytes

>>>,[>,[[<]>[<+>-]>[>]],]<[[>[<+>-]<<]>.<<]

Shorter, but assumes ',' continues to return 0 after EOF, not just the first time after EOF.

Earlier version:

>>>>>,[>+[<<]+>>->>[>>]+>,]<[[<[<<+>>-]<]<.<]

Reads numbers as characters, outputs right sum first.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6),  47  45 bytes

Outputs in reverse order.

a=>[a.reduce(s=>s+a.pop(),0),eval(a.join`+`)]

Try it online!

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 4 bytes

R2äO

Try it online!

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

APL (Dyalog Extended), 12 bytes

Anonymous tacit prefix function

+/2 ¯.5⍴⌽,0⍨

Try it online!

0⍨ zero

⌽, appended the the reverse of the argument

2 ¯.5⍴reshape to 2 rows and as many columns as needed, chopping trailing elements if uneven

+/ sum the rows

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Clojure, 47 bytes

#(for[x(split-at(quot(count %)2)%)](apply + x))

Try it online!

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Jelly, 4 bytes

ŻŒH§

A monadic Link accepting a list which yields the pair: first-half-sum, last-half-sum.

Try it online!

How?

ŻŒH§ - Link: list, A
Ż    - prepend a zero to A
 ŒH  - split that in half (if the length is odd the first half gets the extra element)
   § - sums
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

R, 46 45 bytes

sum((v=scan())[l<-1:(sum(v|1)/2)]);sum(v[-l])

Try it online!

Edit: thanks to Giuseppe: -1 byte

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ use l<-... instead of (l=...); it's a byte shorter :-) \$\endgroup\$ – Giuseppe May 19 at 17:03
  • \$\begingroup\$ Thanks again Giuseppe! BTW: do you have any idea why <- should be designed to behave differently to = in this context (apart from sneaky code golf use)? \$\endgroup\$ – Dominic van Essen May 19 at 19:36
  • 1
    \$\begingroup\$ The docs say The operators <- and = assign into the environment in which they are evaluated. The operator <- can be used anywhere, whereas the operator = is only allowed at the top level (e.g., in the complete expression typed at the command prompt) or as one of the subexpressions in a braced list of expressions. So since l is actually an argument to the [ function, it's not at the top level. Or so I believe. \$\endgroup\$ – Giuseppe May 19 at 19:43
  • \$\begingroup\$ Thank you: I will try to digest what that means. It's quite disconcerting to imagine that I might actually learn something useful while trying to just waste my time code golfing... \$\endgroup\$ – Dominic van Essen May 19 at 19:54
  • \$\begingroup\$ You're not the only one! Myself included, haha. Sometimes my golfing habits kick in when writing real R code, though... \$\endgroup\$ – Giuseppe May 19 at 19:55
1
\$\begingroup\$

Charcoal, 12 bytes

Fθ⊞υ⊟θI⟦ΣθΣυ

Try it online! Link is to verbose version of code. Port of @dingledooper's answer. Explanation:

Fθ

Loop over the list.

⊞υ⊟θ

Move the last element of the list to the empty list.

I⟦ΣθΣυ

Output the sums of the lists.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

C (gcc), 77 bytes

i,l;f(a,n)int*a;{l=0;for(n-=i=n/2;i--;!i?i=n,n=l=!printf("%u ",l):0)l+=*a++;}

Takes as input an array and its size.

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

APL+WIN, 18 bytes

Prompts for vector of integers:

+/(2,⌈.5×⍴s)⍴s←0,⎕

Try it online! Coutesy of Dyalog Classic

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Red, 52 bytes

func[a][reduce[sum take/part a(length? a)/ 2 sum a]]

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Husk, 4 bytes

mΣ½↔

Try it online!

Explanation

   ↔ Reverse the input
  ½  Split the input into about-equal parts of 2
m    For every item in the list:
 Σ       Sum this list
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

dc, 35 bytes

?[zRla+salFx]sU[lb+sbz0<U]dsFxlblaf

Try it online!

Verify the test cases online.

Input is a space-separated list of numbers on stdin.

Output is on stdout, on two lines: the sum of the left part, then the sum of the right part.

How it works:

?        Read the input and push it on the stack.
            (The last number in the list is at the top of the stack.)

[        Start a macro.
 zR        Move the bottom item on the stack to the top, 
              moving the rest of the stack down one item.
 la+sa     Pop the top item on the stack and add it to register a.
              This number comes from the left part.
 lFx       Execute F recursively.
]sU      End the macro and name it U.

[        Start a macro.
 lb+sb     Pop the top item on the stack and add it to register b.
              This number comes from the right part.
              (Note that if the stack is empty so that there's
              nothing to pop, then b is left unchanged.
              This will happen the last time through when the
              original list had an even number of items.)
 z0<     If there's anything still on the stack,
 U         then execute macro U (which adds the bottom item on the
           stack to register a and then executes F recursively).
]dsFx    End the macro, name it F, and execute it.

lblaf    Print a, then print b.
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

C (gcc), 67 bytes

f(x,y,a,b)int*x,*y,*a,*b;{for(*a=*b=0;x<y--;*a+=x<y?*x++:0)*b+=*y;}

Try the test cases online!

This is a function with two "in" parameters (x and y) and two "out" parameters (a and b).

Input is taken as an array of ints, and is passed as a pointer x to the beginning of the array and a pointer y to (the location immediately after) the end of the array.

The function returns the left and right sums in *a and *b, respectively.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Rust macro, 480 bytes

macro_rules!f{($($r:expr)*)=>{f!(@I;[$($r),*];[];)};(@$($d:ident)*;[];[$($a:tt)*];$($b:tt)*)=>{f!(%($)0;0;[$($a)*]$($b)*)};(@$($d:ident)*;[$x:expr$(,$r:tt)*];[$($a:tt)*];$($b:tt)*)=>{f!(@I$($d)*;[$($r),*];[$($a)*;($($d)*,$x)];($($d)*,$x);$($b)*)};(%($m:tt)$s:expr;$t:expr;[;($($d:ident)+,$x:expr)$($a:tt)*]$(;)*($($e:ident)*,$y:expr)$($b:tt)*)=>{{macro_rules!i{($($d)*$m(I)+)=>{f!(%($m)$s+$x;$t+$y;[$($a)*];$($b)*)};($($d)*)=>{($s,$t+$y)};($m(I)*)=>{($s,$t)}}i!($($e)*)}};}

try it online

This is kind of insane and I kind of hate myself now. The code defines a macro that takes a sequence of whitespace-seperated numbers and expands to a tuple of 2 integers. Everything is calculated at compile-time, so the code runs in \$O(1)\$, but compile times may vary.

For an introduction to Rust macros, I recommend the Rust book, the Rust refeence and The Little Book of Rust Macros.

Explanation

So rust macros operate on token streams that are matched against patterns. For our case, the main difficulty is that you basically have to consume the token stream front-to-back.

To defeat this, I first replace the list of numbers with two numbers, where one of them is reversed. Also, to be able to find the middle, I put an index next to each number. Since yout can't evaluate integer expression like 0+1, I use a tally counter made up of I identifier tokens. That way, I can detect the midpoint by comparing the length of the tally counter. Each part is replaced with ad addition of all its components, which can be evaluated at compile time.

Example

Let's use 1 2 3 as an example. This shows the basic idea, but is still simplified a bit.

1 2 3
[1 2 3] [] []  // input forward backward
[2 3] [(I, 1)] [(I, 1)]
[3] [(I, 1); (I I, 2)] [(I I, 2); (I, 1)]
[] [(I, 1); (I I, 2); (I I I, 3)] [(I I I, 3); (I I, 2); (I, 1)]
0; 0; [(I, 1); (I I, 2); (I I I, 3)] [(I I I, 3); (I I, 2); (I, 1)]  // two accumulators
0 + 1; 0 + 3; [(I I, 2); (I I I, 3)] [(I I, 2); (I, 1)]
(0 + 1; 0 + 3 + 2)

Refer to the compiler output in the rust playground for the complete expansion.

// Define a macro called f
macro_rules! f {

    // This rule is the starting point
    // It matches any number of expressions
    ($($r:expr)*) => {
        // Use the internal rules with an at sign.
        // Provide the I as the first index.
        f!(@ I; [$($r),*]; [];)
    };

    // The rules starting with an at sign are responsible for producing a reversed version
    // of the input and counting with tallys.
    // This pattern is known as tt-muncher because it consumes a token tree recursively.

    // This is the base case. It matches when the input is an empty set of brackets.
    (@ $($d:ident)*; []; [$($a:tt)*]; $($b:tt)*) => {
        // Call the second set of internal macros (the ones starting with a percent sign).
        // We use zeros as the accumulators
        f!(% ($) 0; 0; [$($a)*] $($b)*)
    };
    // This is the recursive case.
    // It extracts one expression (called x) from the input.
    (@ $($d:ident)*; [$x:expr $(,$r:tt)*]; [$($a:tt)*]; $($b:tt)*) => {
        // Call the at-macro recursively.
        // Add one I to the current tally list.
        // append (tallys, $x) to the first "array".
        // prepend (tallys, $x) to the second "array".
        f!(@ I $($d)*; [$($r),*]; [$($a)*; ($($d)*, $x)]; ($($d)*,$x); $($b)*)
    };

    // This part of the macro is called with the original and the reversed version.
    // The first argument is a dollar sign because that it needed later.
    // It extracts the count $d and value $x of the forwards array,
    // and count $e and value $y of the backwards array.
    (% ($m:tt) $s:expr; $t:expr; [; ($($d:ident)+, $x:expr) $($a:tt)*] $(;)* ($($e:ident)*, $y:expr) $($b:tt)*) => {
        {
            // To compare the two tally counters at compile time, we use an internal macro.
            // It defined rules based on $d.
            // The argument of this macro will be $e.
            macro_rules! i {
                // This case matches when $e is larger than $d.
                // That means we haven't found the end yet.
                ($($d)* $m(I)+) => {
                    // call this part recursively, adding $x and $y to their accumulators
                    f!(% ($m) $s+$x; $t+$y; [$($a)*]; $($b)*)
                };
                // $e and $d are equal.
                // This case is reached when there is an odd number of element in the input.
                ($($d)*) => {
                    // Add the value to the right accumulator and expand to a tuple
                    ($s, $t+$y)
                };
                // $e is less than $d.
                // We have moved past the midpoint.
                ($m(I)*) => {
                    // Expand to a tuple containing the accumulators
                    ($s, $t)
                }
            }
            // call the internal macro with $e
            i!($($e)*)
        }
    };
}
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Julia, 41 bytes

a->[sum(a[1:(e=end÷2)]),sum(a[e+1:end])]
| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Scala, 42 bytes

val(a,b)=l.splitAt(l.size/2);(a.sum,b.sum)

Sorry but i'm not sure if it has to be a function if it is the case it costs 74 bytes.

val f:List[Int]=>(Int,Int)=l=>{val(a,b)=l.splitAt(l.size/2);(a.sum,b.sum)}

It should be written using a tail recursion to be more efficient but the cost in caracters would be higher.

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Hello and welcome to CGCC! To answer your question, yes your code should be formatted as a function to be considered a valid submission (you could also format it as a full program by reading from STDIN, but I'm guessing that would be longer). \$\endgroup\$ – math junkie May 3 at 22:22
  • \$\begingroup\$ Thank you for joining Codegolf! We allow an anonymous function l=>..., because that is a expression that be assigned to a variable. That way, you don't need to count the type annotation. Also, you can take a look our tips for golfing in scala. \$\endgroup\$ – corvus_192 May 4 at 6:23
1
\$\begingroup\$

PHP, 60 bytes

for(;$a=$argv[++$i];)$r[$i<count($argv)/2]+=$a;var_dump($r);

Try it online!

Like often, much shorter with a straight loop.. PHP and arrays, sigh

PHP, 79 bytes

fn($l,$g=array_sum,$h=array_slice)=>[$g($h($l,0,$n=count($l)/2)),$g($h($l,$n))]

Try it online!

PHP takes care itself of the right bias.. it's long mostly because array functions have lengthy names..

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

MathGolf, 8 bytes

h½‼<≥αmΣ

Try it online.

Explanation:

h        # Get the length of the (implicit) input-list (without popping the list itself)
 ½       # Halve it (integer-divided by 2)
  ‼      # Apply the following two commands separately:
   <     #  Take all elements of the list smaller than the length//2
   ≥     #  Take alle elements of the list larger than or equal to the length//2
    α    # Wrap both lists into a list
     m   # Map over this list of lists:
      Σ  #  And sum each inner list
         # (after which the entire stack joined together is output implicitly as result)
| improve this answer | |
\$\endgroup\$

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.