Skip to content

Instantly share code, notes, and snippets.

@Artoria2e5
Created October 9, 2019 11:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Artoria2e5/b699437b239d78fbe6c262f79767dda6 to your computer and use it in GitHub Desktop.
Save Artoria2e5/b699437b239d78fbe6c262f79767dda6 to your computer and use it in GitHub Desktop.
perfect nums
#include <iostream>
#include <cstdint>
template<typename T>
class MerssenePerfect {
// A000043
static_assert(std::is_unsigned<T>::value,
"MerssenePerfect should use an unsigned type");
const static int_fast8_t primes[18] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61 };
ptrdiff_t offset;
ptrdiff_t max;
T make_value(int_fast8_t prime) {
// (2^p - 1) * (2 ^ p)
return ((1 << prime) - 1) << prime;
}
public:
bool operator==(MerssenePerfect& b) { return this.offset == b.offset; }
bool operator!=(MerssenePerfect& b) { return this.offset != b.offset; }
operator*() { return make_value(primes[offset]); }
MerssenePerfect& operator++() { ++offset; return *this; }
MerssenePerfect operator++(int) { MerssenePerfect<T> clone(*this); ++offset; return clone; }
MerssenePerfect begin() { return MerssenePerfect( *this, 0 ); }
MerssenePerfect end() { return MerssenePerfect( *this, max ); }
MerssenePerfect()(ptrdiff_t _o = 0): offset(_o) {
ptrdiff_t oo;
for (oo = 0; o < 18; ++o)
if (primes[oo] * 2 - 1 > CHAR_BIT * sizeof(T))
break;
max = oo;
}
}
// divisors:
// 1 .. 2^p, (2^p) * (1 .. 2^p)
// and sort
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment