2013年6月13日木曜日

1から1000

最近stackoverflowというサイトを知りました。
その中であった質問の一つにこういうのがありました。

Task: Print numbers from 1 to 1000 without using any loop or conditional statements. Don't just write the printf() or cout statement 1000 times.
How would you do that using C or C++?
printing-1-to-1000-without-loop-or-conditionals

簡単な日本語に訳すと
「1から1000までの数字をループや条件分岐を使わずに表示しなさい。ただしprintf()やcoutを1000回書くのは無しね。CかC++を使ってあなたならどうする?」
といったところでしょうか。

ループを書けば一瞬で終わる処理もこれらがないと普通じゃないやり方になるようです。
一番投票が多かった回答は、

#include <iostream>
template<int N>
struct NumberGeneration{
  static void out(std::ostream& os)
  {
    NumberGeneration<N-1>::out(os);
    os << N << std::endl;
  }
};
template<>
struct NumberGeneration<1>{
  static void out(std::ostream& os)
  {
    os << 1 << std::endl;
  }
};
int main(){
   NumberGeneration<1000>::out(std::cout);
}

というものでした。
テンプレート関数を使ってひたすら関数を展開していく方法でした。
このプログラムを手元の環境でコンパイルすると

$clang++ 1000.cc -o 1000 
175890 Jun 12 18:55 1000*
     339 Jun 11 03:32 1000.cc

実行形のサイズがかなり大きいですね。

私が気に入ったのは以下の様なサンプルです。(自分で書きなおしたものです。)

#include <iostream>

static int n=1;

class out
{
public:
    out()
    {
        std::cout << n++ << std::endl;
    }
};
int main()
{
    out o[1000];
}

コンストラクターに出力を書いてます。
これなら

$clang++ my1000.cc -o my1000 
6064 Jun 11 08:00 my1000*
  136 Jun 11 07:59 my1000.cc

実行形のサイズも小さくてすみますね。
もちろん、パフォーマンスはこの問題には関係ないとは思いますが・・・。




0 件のコメント:

コメントを投稿