# sum of multiples by 3 or 5 using ranges

This program calculates the sum of all integers in the range $$\[1, 1000)\$$ which are multiples of either 3 or 5 or both.

Inspired by x86-64 Assembly - Sum of multiples of 3 or 5 the other day, and also drawing from some of what I learned through Calculate the centroid of a collection of complex numbers I decided to try to tackle this using C++20 ranges. By heavy use of constexpr, I had hoped to find a solution that would calculate everything at compile time, and indeed this does as you can see if you try it online.

This version is inspired by this talk C++20 Ranges in Practice - Tristan Brindle - CppCon 2020.

I'm interested in general improvements.

## euler1.cpp

#include <iostream>
#include <concepts>
#include <ranges>
#include <iterator>
#include <functional>
#include <numeric>

template <std::ranges::input_range R,
typename Init = std::ranges::range_value_t<R>>
constexpr Init accumulate(R&& rng, Init init = Init{})
{
return std::reduce(std::ranges::begin(rng), std::ranges::end(rng),
std::move(init));
}

int main() {
constexpr auto div3_or_5 = [](int i){ return i % 3 == 0 || i % 5 == 0; };
std::cout << accumulate(std::ranges::iota_view{1, 1000}
| std::views::filter(div3_or_5)
| std::views::common)
<< '\n';
}

• That hat really does have your name on it.... :_) – Toby Speight Dec 24 '20 at 11:24

## 2 Answers

The optional init argement is never used, so we could omit that for this application, and use the two-argument form of std::reduce().

That would solve the other issue neatly - failure to include <utility> before using std::move().

I see you already solved your own questions from before your latest edit. Just two very minor things that can be improved: you can omit repeating the type name Init in two places:

template <std::ranges::input_range R, typename Init = std::ranges::range_value_t<R>>
constexpr auto accumulate(R&& rng, Init init = {})
{
return std::reduce(std::ranges::begin(rng), std::ranges::end(rng), std::move(init));
}


And you don't need to use std::views::common in main().