素数のときだけ"JOJO!"って出力するプログラムを作ってみた

某所で話題(?)になっていたので参加してみた。
http://sue445.hatenablog.com/entry/2012/08/11/164950

とりあえず何も考えずに5分程で作ったバージョン

int main()
{
	std::vector< int > primes;
	for( int num = 2; num < 100; ++num ){
		bool bPrime(true);
		for( std::vector< int >::iterator p = primes.begin(); p != primes.end(); ++p ){
			if( num % *p == 0 ){
				bPrime = false;
				break;
			}
		}
		if( bPrime ){
			std::cout << "JOJO!" << std::endl;
			primes.push_back( num );
		}else{
			std::cout << num << std::endl;
		}
	}
}

素数判定方法は至って単純で、自分より小さい素数すべてで割り切れない場合は素数

ちょっとだけOOPっぽくしたバージョン

class Primes
{
	std::vector< int > primes;
public:
	bool operator()( int num ){
		for( std::vector< int >::iterator p = primes.begin(); p != primes.end(); ++p ){
			if( num % *p == 0 ){
				return false;
			}
		}
		primes.push_back( num );
		return true;
	}
};

int main()
{
	Primes primes;
	for( int num = 2; num < 100; ++num ){
		if( primes( num ) ){
			std::cout << "JOJO!" << std::endl;
		}else{
			std::cout << num << std::endl;
		}
	}
}

まあ単純にクラスにしただけです。

練習も兼ねてテンプレートメタプログラミングで頑張ってみた。例のごとく、ループ使ったら負けかなと思っている

//条件分岐
template< int A, class A1, class A2 > struct IF{ typedef A1 val; };
template< class A1, class A2 > struct IF< 0, A1, A2 >{ typedef A2 val; };

//素数判定のサブクラス
struct PrimeSubEnd{
	enum{ P = 0 };
};

template< int n, int s >
struct PrimeSub{
	enum{ P = 
		IF<
			(n % s),
			PrimeSub< n, s-1 >,
			PrimeSubEnd
		>::val::P
	};
};

template< int n >
struct PrimeSub< n, 1 >{
	enum{ P = 1 };
};

//素数判定
template < int n >
struct Prime{
	enum{ P = PrimePrime< n, n / 2 >::P };
};

template <>
struct Prime<1>{
	enum{ P = 0 };
};

//表示
struct JOJOPrint{
	static void print(){
		std::cout << "JOJO!" << std::endl;
	}
};

template< int i >
struct NumPrint{
	static void print(){
		std::cout << i << std::endl;
	}
};

template< int i >
struct JOJO{
	static void print(){
		JOJO< i-1 >::print();
		IF< Prime<i>::P, JOJOPrint, NumPrint<i> >::val::print();
	}
};

template<>
struct JOJO< 1 >{
	static void print(){
		std::cout << 1 << std::endl;
	}
};

int main()
{
	JOJO< 100 >::print();
}

開発の都合上、一旦素数判定する部分を作ってから表示部分を書いたので直接表示部分を考えればもうちょっと小さくなると思われる。
素数判定をメタプログラミングしているのでコンパイルがクソ重いです。あと数値が大きいとコンパイラがダウンします。