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".


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.


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

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.


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

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


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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.