Summing up ints in vectors for education To get started with C++11/14/17, I decided to write a program that brute forces the problem described in this video (and gives a progress update every few seconds):


  Divide the numbers [0, 31] into two sets A and B such that
  
  
  \$\sum_A {a} = \sum_B{b}\$
  \$\sum_A {a^2} = \sum_B{b^2}\$
  \$\sum_A {a^3} = \sum_B{b^3}\$
  \$\sum_A {a^4} = \sum_B{b^4}\$
  


How can I make this code more C++14-ish? My goal is not to make the code more mathematically clever, or necessarily faster. I mainly wanted to use a reasonable to high number of modern C++ standard features to brute-force-solve this problem.

#include &lt;vector&gt;
#include &lt;iostream&gt;
#include &lt;numeric&gt;
#include &lt;chrono&gt;
#include &lt;iomanip&gt;
#include &lt;cstdlib&gt;

int main() {

    uint32_t split {0};
    uint32_t print_mask { 2048 };
    auto lastPrintTime = std::chrono::system_clock::now();
    auto const SLOWER_THRESHOLD = std::chrono::seconds(5) ;
    auto const FASTER_THRESHOLD = std::chrono::seconds(10) ;

    while (split &lt; std::numeric_limits&lt;uint32_t&gt;::max()) {
        if (split % print_mask == 0) {
            double progress_percentage { (split/(double)std::numeric_limits&lt;uint32_t&gt;::max()) * 100.0 };
            std::cout &lt;&lt; "Currently checking " &lt;&lt; std::setw(20) &lt;&lt; std::setfill(' ') &lt;&lt; split &lt;&lt; ", " &lt;&lt; std::fixed &lt;&lt; progress_percentage &lt;&lt; '%' &lt;&lt; std::endl;

            auto now = std::chrono::system_clock::now();
            auto diff = std::chrono::duration_cast&lt;std::chrono::seconds&gt;(now - lastPrintTime);
            lastPrintTime = now;

            if (diff &lt; SLOWER_THRESHOLD) print_mask *= 2;
            if (diff &gt; FASTER_THRESHOLD &amp;&amp; print_mask &gt; 10) print_mask /= 2;
        }

        std::vector&lt;int&gt; va;
        std::vector&lt;int&gt; vb;

        uint32_t mask {1};
        for (int i=0; i&lt;32; i++) {
            ((mask &amp; split) != 0 ? va : vb).push_back(i);
            mask = mask &lt;&lt; 1;
        }

        int sum_a;
        int sum_b;

        sum_a = std::accumulate(va.begin(), va.end(), 0, [](auto x, auto y){return x + y;});
        sum_b = std::accumulate(vb.begin(), vb.end(), 0, [](auto x, auto y){return x + y;});
        if (sum_a != sum_b) goto next;

        sum_a = std::accumulate(va.begin(), va.end(), 0, [](auto x, auto y){return x + y*y;});
        sum_b = std::accumulate(vb.begin(), vb.end(), 0, [](auto x, auto y){return x + y*y;});
        if (sum_a != sum_b) goto next;

        sum_a = std::accumulate(va.begin(), va.end(), 0, [](auto x, auto y){return x + y*y*y;});
        sum_b = std::accumulate(vb.begin(), vb.end(), 0, [](auto x, auto y){return x + y*y*y;});
        if (sum_a != sum_b) goto next;

        sum_a = std::accumulate(va.begin(), va.end(), 0, [](auto x, auto y){return x + y*y*y*y;});
        sum_b = std::accumulate(vb.begin(), vb.end(), 0, [](auto x, auto y){return x + y*y*y*y;});
        if (sum_a != sum_b) goto next;

        std::cout &lt;&lt; "A = " &lt;&lt; sum_a &lt;&lt; " = [";
        for (auto v: va) {
            std::cout &lt;&lt; v &lt;&lt; ", ";
        }
        std::cout &lt;&lt; ']' &lt;&lt; std::endl &lt;&lt; "B = " &lt;&lt; sum_b &lt;&lt; " = [";
        for (auto v: vb) {
            std::cout &lt;&lt; v &lt;&lt; ", ";
        }
        std::cout &lt;&lt; ']' &lt;&lt; std::endl;
        break;

        next:
        split++;
    }

    puts("Win");

    return EXIT_SUCCESS;
}


I am especially unhappy with the way I print the vectors. I have seen some code examples about ostream_iterators, but these looked even worse to me.
Use Functions
There is a ton of repetition in your code. You could make it much better by just factoring out the common parts.
Printing
You don't like how you print your vector? There's a function for that:
template &lt;typename T&gt;
std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, std::vector&lt;T&gt; const&amp; xs) {
    bool first = true;
    os &lt;&lt; '{';
    for (T const&amp; x : x) {
        if (!first) os &lt;&lt; &quot;, &quot;;
        os &lt;&lt; x;
        first = false;
    }
    return os &lt;&lt; '}';
}

And now you can just do:
std::cout &lt;&lt; &quot;A = &quot; &lt;&lt; va &lt;&lt; &quot;, B = &quot; &lt;&lt; vb &lt;&lt; std::endl;

Checking Summation
There is a huge amount of repetition here. Effectively, we're summing f(x) on each vector, for differing x. So we can write a function for that:
template &lt;typename F&gt;
int accumulate(std::vector&lt;int&gt; const&amp; xs, F f) {
    int sum = 0;
    for (int x : xs) {
        sum += f(x);
    }
    return sum;

    // aka return boost::accumulate(xs | transformed(f), 0);
}

bool matches(std::vector&lt;int&gt; const&amp; A, std::Vector&lt;int&gt; const&amp; B, F f) {
    return accumulate(A, f) == accumulate(B, f);
}

Don't use goto
There is hardly ever a reason to use goto and this is not it. Once you refactor everything, you can just write out your test:
if (matches(va, vb, [](int x){ return x; }) &amp;&amp;
    matches(va, vb, [](int x){ return x*x; }) &amp;&amp;    
    matches(va, vb, [](int x){ return x*x*x; }) &amp;&amp;
    matches(va, vb, [](int x){ return x*x*x*x; }))
{
    std::cout &lt;&lt; &quot;Found: A=&quot; &lt;&lt; va &lt;&lt; &quot;, B=&quot; &lt;&lt; vb &lt;&lt; std::endl;
    break;
}

No goto needed.
Use a for loop
You are looping on split from 0 to the max uint32_t value. This isn't obvious because you're using the wrong loop:
for (uint32_t split=0; split &lt; std::numeric_limits&lt;uint32_t&gt;::max(); ++split)

Returning from main
You don't have to use return EXIT_SUCCESS; or return 0;. As a special case for main, return 0 is implied.
Better algorithm
Looping over a few billion elements isn't going to be the best approach... especially when there are only ~300 million unique sets to check to begin with (those that have 16 elements on each side, ignoring mirrored duplicates for which one ends up being A).