fizz buzz dans TMP [fermé]

10

Le problème Fizz Buzz est un problème très basique à résoudre qui est utilisé par certains pour éliminer les personnes interrogées qui ne savent pas comment programmer. Le problème est:

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

L'objet de cette modification du problème Fizz Buzz est d'exécuter l'algorithme ci-dessus à l'aide de modèles C ++ de manière à ce que le moins d'opérations d'exécution nécessaires soient possibles.

Vous pouvez réduire N à une plage plus petite si vous le souhaitez afin de tenir dans les objets TMP si nécessaire.

Cela ne devrait pas être un "golf".


la source
11
Vous devriez dire "Template Metaprogramming" plutôt que TMP, car la plupart des personnes non C ++ n'auraient aucune idée de ce qu'est TMP.
Chris Jester-Young
6
"éliminer les interviewés qui ne savent pas programmer" Je ne savais pas que le programmeur moyen avait besoin de connaître la métaprogrammation de modèles.
Alexandru
1
Comment définissez-vous l'opération d'exécution? Instruction d'assembleur? Si tel est le cas, il peut être judicieux de spécifier un compilateur et une plate-forme afin qu'il n'y ait aucune ambiguïté.
sepp2k
7
@Alexandru: Il a dit que le problème des fizzbuzz est utilisé pour "éliminer" ..., pas que la résolution du problème des fizzbuzz en utilisant la métaprogrammation des modèles soit.
sepp2k
1
Copie

Réponses:

3

Voici ma tentative (l'avais traîné pendant un jour ou deux, parce que je ne savais pas si cela convenait comme solution). Étonnamment le seul bit de I incorporé @ Chris changeait 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;
}

De plus, comme c'est ma première tentative de TMP, toute suggestion sur l'amélioration de mon code serait appréciée.

JPvdMerwe
la source
2

Solution totalement non golfée:

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";}
};

Exemple de code de test:

#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';
}
Chris Jester-Young
la source
1

D'accord, j'ai finalement réussi à tenter ma chance. Contrairement aux solutions précédentes, ma solution crée la chaîne de sortie entière au moment de la compilation et le seul appel au moment de l'exécution est un seul appel à coutl' <<opérateur de. J'utilise boost::mplpour garder le code quelque peu gérable.

#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;
}

Malheureusement, le code explosera en se boost::mpl::stringplaignant de chaînes trop grandes lors de l'utilisation de nplus de 9.

sepp2k
la source
0

362 caractères.

#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;
}
éphémère
la source
Sauf si je manque quelque chose, toutes les opérations se produisent au moment de l'exécution ici.
sepp2k
@ sepp2k: Tu veux dire ?:? J'ai pensé que cela pourrait être évalué au moment de la compilation. Bien sûr, j'ai une concaténation de chaînes géante qui se produit lors de l'exécution ici.
éphémère
Je voulais principalement parler de la construction et de la concaténation des chaînes, mais le?: Ne doit pas non plus se produire au moment de la compilation (bien que ce soit probablement le cas).
septembre 2011
-2

local b = io.read ("* n") local i = 1 tandis que (i <= b) faire si i% 15 == 0 puis imprimer ("FizzBuzz") elseif i% 3 == 0 puis imprimer ("Fizz ") elseif i% 5 == 0 puis print (" Buzz ") else print (i) end i = i + 1 end

juan diego grisales callejas
la source
Bienvenue sur le site! Quelle langue est-ce? Vous pouvez utiliser la mise en forme du code en surlignant votre code et en cliquant sur l'icône dans l'éditeur.
Ad Hoc Garf Hunter
Cette question est spécifiquement pour FizzBuzz C++, et votre réponse est en Lua (?). Vouliez-vous publier une question générique sur FizzBuzz ?
Jo King