Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Port ruby solution to C++

Tags:

c++

range

ruby

Is there any way to do this in C++ especially the range section.

answer = (0..999).select { |a| a%3 ==0 || a%5==0 }
puts answer.inject { |sum, n| sum+n }

I have created my own c++ solution but using a more standard for loop and wondered if there was a cooler way to do it?

like image 829
sayth Avatar asked Oct 08 '11 03:10

sayth


2 Answers

Template metaprogramming solution:

The following assumes the lower bound of the range is 0.

template <int N>
struct sum
{
  static const int value = sum<N-1>::value + (N % 3 == 0 || N % 5 == 0 ? N : 0);
};

template <>
struct sum<0>
{
  static const int value = 0;
};

int main(int argc, char** argv)
{
  int n = sum<999>::value;
  return 0;
}

The following will allow you to specify a range of numbers (e.g. 0-999, 20-400). I'm not a master of template metaprogramming so I couldn't think of a cleaner solution (and I did this for my own benefit and practice).

template <int N, int Upper, bool IsLast>
struct sum_range_helper
{
  static const int value = (N % 3 == 0 || N % 5 == 0 ? N : 0) + sum_range_helper<N + 1, Upper, N + 1 == Upper>::value;
};

template <int N, int Upper>
struct sum_range_helper<N, Upper, true>
{
  static const int value = (N % 3 == 0 || N % 5 == 0 ? N : 0);
};

template <int Lower, int Upper>
struct sum_range
{
  static const int value = sum_range_helper<Lower, Upper, Lower == Upper>::value;
};

int main(int argc, char** argv)
{
  int n = sum_range<0, 999>::value;
  return 0;
}
like image 73
Marlon Avatar answered Sep 23 '22 01:09

Marlon


Untested code. Uses C++ 0x feature (lambda function and iota)

vector<int> v(1000);

//fill the vector
iota(v.begin(),v.end(),0);

v.erase(remove_if(v.begin(),v.end(),[](int a) { return !(a%3 && a%5); }),v.end());
int sum = accumulate(v.begin(),v.end(),0);
like image 37
suresh Avatar answered Sep 22 '22 01:09

suresh