TMPでのfizz buzz [終了]


10

Fizz Buzz問題は、プログラムする方法がわからないインタビュー対象者を排除するために一部で使用されている解決すべき非常に基本的な問題です。問題は:

Set N = [0,100]
Set F = x in N where x % 3 == 0
Set B = x in N where x % 5 == 0
Set FB = F intersect B

For all N:
  if x in F: print fizz
  if x in B: print buzz
  if x in FB: print fizzbuzz
  if x not in F|B|FB print x

Fizz Buzz問題のこの変更の目的は、実行可能な操作が最小限で済むように、C ++テンプレートを使用して上記のアルゴリズムを実行することです。

必要に応じてTMPオブジェクト内に収めるために必要な場合は、Nをより小さな範囲に減らすことができます。

これは「ゴルフ」ではありません。


11
ほとんどの非C ++の人々はTMPが何であるかを知らないため、TMPではなく「テンプレートメタプログラミング」と言うべきです。
Chris Jester-Young

6
「プログラミングの方法がわからないインタビュー対象者を排除する」私は、平均的なプログラマがテンプレートメタプログラミングを知る必要があることを知りませんでした。
Alexandru

1
ランタイム操作をどのように定義しますか?アセンブラー命令?もしそうなら、曖昧さがないようにコンパイラとプラットフォームを指定することは良い考えかもしれません。
sepp2k 2011年

7
@Alexandru:彼は、fizzbuzz問題は「取り除かれる...」に使用されていると述べました。テンプレートメタプログラミングを使用してfizzbuzz問題を解決することではありません。
sepp2k 2011年

回答:


3

ここに私の試みがあります(それが解決策として適しているかどうかわからなかったので、それが1日かそこらに横たわっていたなら)。驚いたことに、@ Chrisから取り入れた唯一の変化は変化していたtemplate<int N, int m3, int m5>template<int N, int m3=N%3, int m5=N%5>

#include <iostream>

using namespace std;

template<int N, int m3=N%3, int m5=N%5>
struct fizzbuzz_print {
  static void print() {
    cout << N << '\n';
  }
};

template<int N, int m5>
struct fizzbuzz_print<N, 0, m5> {
  static void print() {
    cout << "fizz\n";
  }
};

template<int N, int m3>
struct fizzbuzz_print<N, m3, 0> {
  static void print() {
    cout << "buzz\n";
  }
};

template<int N>
struct fizzbuzz_print<N, 0, 0> {
  static void print() {
    cout << "fizzbuzz\n";
  }
};

template<int N>
struct fizzbuzz:public fizzbuzz<N-1> {
  fizzbuzz<N>() {
    fizzbuzz_print<N>::print();
  }
};

template<>
struct fizzbuzz<1> {
  fizzbuzz<1>() {
    fizzbuzz_print<1>::print();
  }
};

int main() {
  fizzbuzz<100> t;
}

さらに、これはTMPでの最初の試みであるため、コードの改善に関する提案があれば幸いです。


2

完全にゴルフではないソリューション:

template <int n, int m3 = n % 3, int m5 = n % 5>
struct FizzBuzz {
    static int value() {return n;}
};

template <int n, int m5>
struct FizzBuzz<n, 0, m5> {
    static char const* value() {return "Fizz";}
};

template <int n, int m3>
struct FizzBuzz<n, m3, 0> {
    static char const* value() {return "Buzz";}
};

template <int n>
struct FizzBuzz<n, 0, 0> {
    static char const* value() {return "FizzBuzz";}
};

サンプルテストコード:

#include <iostream>

int
main()
{
    std::cout << FizzBuzz<1>::value() << '\n'
              << FizzBuzz<2>::value() << '\n'
              << FizzBuzz<3>::value() << '\n'
              << FizzBuzz<4>::value() << '\n'
              << FizzBuzz<5>::value() << '\n'
              << FizzBuzz<13>::value() << '\n'
              << FizzBuzz<14>::value() << '\n'
              << FizzBuzz<15>::value() << '\n'
              << FizzBuzz<16>::value() << '\n';
}

1

さて、やっとこれでショットを取り始めました。以前のソリューションとは異なり、私のソリューションはコンパイル時に出力文字列全体を構築し、実行時の呼び出しはcout<<演算子への1回の呼び出しのみです。私はboost::mplコードをいくらか扱いやすく保つために使用しています。

#include <boost/mpl/string.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/char.hpp>
#include <boost/mpl/if.hpp>

using namespace boost::mpl;
using std::cout;

template<int n> struct IntToString {
    typedef typename push_back<typename IntToString<n/10>::str, char_<'0'+n%10> >::type str;
};


template<> struct IntToString<0> {
    typedef string<> str;
};


template<int n> struct FizzBuzzHelper {
    typedef typename push_back<typename IntToString<n>::str, char_<'\n'> >::type intstring;
    typedef typename if_< bool_<n%15==0>, string<'fizz','buzz','\n'>,
                          typename if_< bool_<n%5==0>, string<'buzz','\n'>,
                                        typename if_< bool_<n%3==0>, string<'fizz','\n'>,
                                                      intstring>::type >::type >::type str;
};

template<int n> struct FizzBuzz {
    typedef typename insert_range<typename FizzBuzz<n-1>::str,
                                  typename end<typename FizzBuzz<n-1>::str>::type,
                                  typename FizzBuzzHelper<n>::str>::type str;
};

template<> struct FizzBuzz<0> {
    typedef string<> str;
};


#include <iostream>

int main() {
    cout << c_str<FizzBuzz<9>::str>::value;
    return 0;
}

悲しいことに、9を超えるboost::mpl::string文字列を使用すると、文字列が大きすぎるという不満が出てコードが爆発しnます。


0

362文字。

#include <iostream>
#include <string>

using namespace std;

template<int N>
struct S {
    static string s, f, l;
};

template<int N>
string S<N>::s =
    N > 9
      ? S<N / 10>::s + S<N % 10>::s
      : string(1, '0' + N);

template<int N>
string S<N>::f =
    N % 15
      ? N % 5
          ? N % 3
              ? s
              : "fizz"
          : "buzz"
      : "fizzbuzz";

template<>
string S<0>::l = f;
template<int N>
string S<N>::l = S<N - 1>::l + "\n" + f;

int main() {
    cout << S<100>::l << endl;
    return 0;
}

私が何かを逃していない限り、すべての操作はここで実行時に行われます。
sepp2k

@ sepp2k:どういう意味?:ですか?コンパイル時に評価できると思いました。もちろん、実行時に巨大な文字列連結が発生します。
象1991年

主に文字列の構築と連結を意味しましたが、?:もコンパイル時に発生する必要はありません(おそらくそうなるでしょう)。
sepp2k '30年

-2

local b = io.read( "* n")local i = 1 while(i <= b)do if i%15 == 0 then print( "FizzBu​​zz")elseif i%3 == 0 then print( "Fizz ")elseif i%5 == 0 then print(" Buzz ")else print(i)end i = i + 1 end


サイトへようこそ!これは何語?コードを強調表示し、エディターのアイコンをクリックすると、コードのフォーマットを使用できます。
アドホックガーフハンター

この質問は、特にFizzBu​​zzに関するものでC++あり、あなたの答えはLua(?)です。一般的なFizzBu​​zz質問に投稿するつもりでしたか?
Jo King
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.