2010年7月25日
#
ドミニオン、ボーズが持ち込んだわけですが。
僕もカミさんもハマっちゃってさ、
陰謀 /
海辺 /
錬金術 も揃えちゃいましたですよ。
こともあろうに
へそくり までも。...あかんなー、陰謀セットだと勝てない orz
きっと魅力的なアクション満載なもんだから財宝を買いそびれ、
資金難に陥っている模様。
ネタ元 → 無駄に並列化してみる
まけるもんかぁ! なTBB版。
#include <iostream>
#include <tbb/tbb.h>
int main() {
const int N = 1000;
std::cout
<< tbb::parallel_reduce(tbb::blocked_range<int>(0,N+1), 0,
// 部分的に積算
[](tbb::blocked_range<int>& range, int count) -> int {
for ( int i = range.begin(); i != range.end(); ++i ) {
int n = i;
do {
if ( n % 10 == 0 ) ++count;
n /= 10;
} while ( n > 0 );
}
return count;
},
// んでもってreduce
[](int x, int y) { return x+y; })
<< std::endl;
}
祭りらしいですのつづき:
文字列に変換して'0'を勘定すんじゃなく、まぢめに各桁の0を勘定するます。
// Radix進数での'桁'
template<unsigned Radix>
class Digit {
private:
unsigned value_; // 値
Digit* next_; // 次の桁
public:
Digit() : value_(), next_(nullptr) { clear(); }
~Digit() { delete next_; }
// increment
void inc() {
// +1して桁あふれコいちまったら
if ( ++value_ == Radix ) {
value_ = 0; // 0に戻して
if ( !next_ ) next_ = new Digit(); // ひとつ上の桁を
next_->inc(); // +1する。
}
}
// n の個数を返す
unsigned count(unsigned n) const
{ return (value_ == n ? 1 : 0) + ( next_ ? next_->count(n) : 0 ); }
void clear() { value_ = 0; if ( next_ ) next_->clear(); }
};
#include <iostream>
int main() {
Digit<10> counter;
unsigned sum = 0;
for ( int i = 0; i < 1001; ++i ) {
sum += counter.count(0); // 0の個数を積算しつつ
counter.inc(); // +1をくりかえす
}
std::cout << sum << std::endl;
}