zumbido de fizz no TMP [fechado]

10

O problema do Fizz Buzz é um problema muito básico de solução usado por alguns para eliminar os entrevistados que não sabem como programar. O problema é:

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

O objetivo dessa modificação do problema do Fizz Buzz é executar o algoritmo acima, usando modelos C ++, de modo que o mínimo de operações de tempo de execução seja necessário.

Você pode reduzir N para um intervalo menor, se necessário, para caber nos objetos TMP, quando necessário.

Não se espera que seja um "golfe".


fonte
11
Você deve dizer "Template Metaprogramação" em vez de TMP, porque a maioria das pessoas não-C ++ teria nenhuma idéia do que TMP é.
perfil completo de Chris Jester-Young
6
"eliminando entrevistados que não sabem programar" Eu não sabia que o programador médio precisa conhecer a metaprogramação de modelos.
Alexandru
11
Como você define a operação de tempo de execução? Instruções de montagem? Nesse caso, pode ser uma boa ideia especificar um compilador e uma plataforma para que não haja ambiguidade.
sepp2k
7
@Alexandru: Ele disse que o problema do fizzbuzz é usado para "eliminar" ..., e não para resolver o problema do fizzbuzz usando a metaprogramação de modelos.
precisa saber é o seguinte
11
Possível duplicata de 1, 2, Fizz, 4, Buzz
pppery

Respostas:

3

Aqui está minha tentativa (ela ficou por mais ou menos um dia, porque eu não tinha certeza se era adequado como solução). Surpreendentemente, o único pedaço que incorporei do @Chris estava mudando template<int N, int m3, int m5>paratemplate<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;
}

Além disso, como esta é minha primeira tentativa no TMP, todas as sugestões para melhorar meu código serão apreciadas.

JPvdMerwe
fonte
2

Solução totalmente sem golfe:

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

Código de teste de amostra:

#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
fonte
1

Ok, finalmente cheguei a dar uma chance a isso. Diferentemente das soluções anteriores, minha solução cria toda a cadeia de saída em tempo de compilação e a única chamada em tempo de execução é uma única chamada para couto <<operador. Estou usando boost::mplpara manter o código um pouco gerenciável.

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

Infelizmente, o código explode com boost::mpl::stringreclamações sobre cadeias muito grandes quando se usa algo nmaior que 9.

sepp2k
fonte
0

362 caracteres.

#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;
}
efémero
fonte
A menos que eu esteja perdendo alguma coisa, todas as operações acontecem em tempo de execução aqui.
sepp2k
@ sepp2k: Você quer dizer ?:? Eu pensei que poderia ser avaliado em tempo de compilação. Claro, eu tenho uma concatenação gigante de cordas acontecendo em tempo de execução aqui.
ephemient 30/10
Primeiramente, eu quis dizer a construção e concatenação de strings, mas o?: Também não precisa acontecer em tempo de compilação (embora provavelmente aconteça).
sepp2k
-2

local b = io.read ("* n") local i = 1 enquanto (i <= b) faz se i% 15 == 0 e depois imprime ("FizzBuzz") elseif i% 3 == 0 e imprime ("Fizz ") elseif i% 5 == 0, em seguida, imprima (" Buzz ") else print (i) end i = i + 1 end

juan diego grisales callejas
fonte
Bem vindo ao site! Que língua é essa? Você pode usar a formatação de código destacando seu código e clicando no ícone no editor.
Ad Hoc Garf Hunter
Esta pergunta é especificamente para o FizzBuzz C++, e sua resposta está em Lua (?). Você queria postar na pergunta genérica do FizzBuzz ?
Jo rei