TMP'de fizz vızıltı [kapalı]


10

Fizz Buzz sorunu, bazı programcılar tarafından nasıl programlanacağını bilmeyen yabancı otları ayıklamak için kullanılan, çözülmesi gereken çok temel bir sorundur. Problem şu:

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 sorununun bu modifikasyonunun amacı, C ++ şablonlarını kullanarak yukarıdaki algoritmayı gerçekleştirmek, böylece yapılabilecek kadar az çalışma zamanı işlemi yapmaktır.

Gerekirse TMP nesnelerine sığdırmak için N'yi daha küçük bir aralığa düşürebilirsiniz.

Bunun bir "golf" olması beklenmiyor.


11
TMP yerine "Şablon Metaprogramlama" demelisiniz, çünkü C ++ olmayan çoğu kişinin TMP'nin ne olduğu hakkında hiçbir fikri yoktur .
Chris Jester-Young

6
"Nasıl programlanacağını bilmeyen mülakatçıları ayıkla" Ortalama bir programcının Şablon Meta Programı'nı bilmesi gerektiğini bilmiyordum.
Alexandru

1
Çalışma zamanı işlemini nasıl tanımlarsınız? Assembler talimatı? Eğer öyleyse, bir derleyici ve platform belirtmek iyi bir fikir olabilir, böylece belirsizlik olmaz.
sepp2k

7
@Alexandru: Fizzbuzz sorununun "ayıklamak için" kullanıldığını söyledi, Şablon Metaprogramlama kullanarak fizzbuzz sorununun çözülmesinin değil.
sepp2k

Yanıtlar:


3

İşte benim girişimim (bir gün kadar etrafta yatıyordu, çünkü bir çözüm olarak uygun olup olmadığından emin değildim). Şaşırtıcı bir şekilde, sadece bir @Chris değişiyordu gelen dahil bit template<int N, int m3, int m5>içintemplate<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;
}

Buna ek olarak, bu benim TMP'deki ilk denemem olduğu için, kodumu geliştirmeyle ilgili herhangi bir öneriniz takdir edilecektir.


2

Tamamen golf dışı çözüm:

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

Örnek test kodu:

#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

Tamam, nihayet bu konuda bir çekim yaptım. Önceki çözümlerin aksine benim çözüm derleme zamanında tüm çıkış dizesi oluşturur ve sadece çalışma zamanı çağrı için tek çağrıdır coutbireyin <<operatörü. boost::mplKodu biraz yönetilebilir tutmak için kullanıyorum .

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

Ne yazık ki kod, 9'dan büyük boost::mpl::stringherhangi birini kullanırken çok büyük dizelerden şikayet ederek patlayacak n.


0

362 karakter.

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

Ben bir şey eksik sürece tüm operasyonlar burada çalışma zamanında gerçekleşir.
sepp2k

@ sepp2k: Bunu mu demek istediniz ?:? Bunun derleme zamanında değerlendirilebileceğini düşündüm. Tabii ki, burada çalışma zamanında gerçekleşen dev bir dize birleştirme var.
ephemient

Öncelikle dize yapımı ve birleştirme demek istedim, ama?: Da derleme zamanında olması gerekmiyor (muhtemelen olacak).
sepp2k

-2

local b = io.read ("* n") yerel i = 1 iken (i <= b) i% 15 == 0 ise bunu yaparsanız ("FizzBuzz") yazdırırsanız (% F == 0) yazdırırsanız ("Fizz ") else i i% 5 == 0 sonra yazdır (" Buzz ") başka yazdır (i) bitiş i = i + 1 bitiş


Siteye Hoşgeldiniz! Bu hangi dil? Kod biçimlendirmesini ve düzenleyicideki simgeyi tıklatarak kod biçimlendirmeyi kullanabilirsiniz.
Ad Hoc Garf Hunter

Bu soru özellikle FizzBuzz için C++ve cevabınız Lua (?). Genel FizzBuzz sorusuna mesaj göndermek mi istediniz ?
Jo King
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.