Fizz Buzz in TMP [geschlossen]


10

Das Fizz Buzz-Problem ist ein sehr grundlegendes Problem, das von einigen verwendet wird, um Befragte auszusondern, die nicht programmieren können. Das Problem ist:

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

Das Ziel dieser Modifikation des Fizz Buzz-Problems besteht darin, den obigen Algorithmus unter Verwendung von C ++ - Vorlagen auszuführen, so dass so wenig Laufzeitoperationen wie möglich erforderlich sind.

Sie können N bei Bedarf auf einen kleineren Bereich reduzieren, um bei Bedarf in TMP-Objekte zu passen.

Es wird nicht erwartet, dass dies ein "Golf" ist.


11
Sie sollten eher "Template Metaprogramming" als "TMP" sagen, da die meisten Nicht-C ++ - Benutzer keine Ahnung haben, was TMP ist.
Chris Jester-Young

6
Ich wusste nicht, dass der durchschnittliche Programmierer Template Metaprogramming kennen muss.
Alexandru

1
Wie definieren Sie den Laufzeitbetrieb? Assembler-Anweisung? In diesem Fall ist es möglicherweise eine gute Idee, einen Compiler und eine Plattform anzugeben, damit keine Mehrdeutigkeiten auftreten.
sepp2k

7
@Alexandru: Er sagte, dass das Fizzbuzz-Problem verwendet wird, um "auszusortieren ...", nicht dass das Lösen des Fizzbuzz-Problems mit Template Metaprogramming ist.
sepp2k

1
Mögliches Duplikat von 1, 2, Fizz, 4, Buzz
pppery

Antworten:


3

Hier ist mein Versuch (hatte es einen Tag oder so herumliegen, weil ich nicht sicher war, ob es als Lösung geeignet war). Überraschenderweise änderte sich das einzige Bit, das ich von @Chris aufgenommen habe, template<int N, int m3, int m5>zutemplate<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;
}

Da dies mein erster Versuch bei TMP ist, wären außerdem Vorschläge zur Verbesserung meines Codes willkommen.


2

Völlig nicht Golf Lösung:

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

Beispieltestcode:

#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

Okay, ich bin endlich dazu gekommen, einen Versuch zu machen. Im Gegensatz zu den bisherigen Lösungen baut meine Lösung die gesamte Ausgabezeichenfolge bei der Kompilierung und der einzigen Laufzeit Anruf ein einziger Aufruf zu cout‚s - <<Operator. Ich verwende boost::mpl, um den Code etwas überschaubar zu halten.

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

Leider wird der Code explodieren, boost::mpl::stringwenn Sie sich über zu große Zeichenfolgen beschweren, wenn Sie nmehr als 9 verwenden.


0

362 Zeichen.

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

Sofern mir nichts fehlt, finden hier alle Vorgänge zur Laufzeit statt.
sepp2k

@ sepp2k: Meinst du ?:? Ich dachte, das könnte zur Kompilierungszeit ausgewertet werden. Natürlich habe ich hier zur Laufzeit eine riesige String-Verkettung.
Ephemient

In erster Linie meinte ich die Zeichenfolgenkonstruktion und -verkettung, aber das ?: Muss auch nicht zur Kompilierungszeit erfolgen (obwohl dies wahrscheinlich der Fall sein wird).
sepp2k

-2

local b = io.read ("* n") local i = 1 während (i <= b) tun, wenn i% 15 == 0, dann drucken ("FizzBuzz"), sonst wenn i% 3 == 0, dann drucken ("Fizz ") elseif i% 5 == 0 dann print (" Buzz ") else print (i) end i = i + 1 end


Willkommen auf der Seite! Welche Sprache ist das? Sie können die Code-Formatierung verwenden, indem Sie Ihren Code markieren und im Editor auf das Symbol klicken.
Ad-hoc-Garf-Jäger

Diese Frage ist speziell für FizzBuzz in C++und Ihre Antwort ist in Lua (?). Wollten Sie auf die generische FizzBuzz-Frage posten ?
Jo King
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.