TMP의 피즈 버즈 [닫힘]


10

Fizz Buzz 문제는 프로그래밍 방법을 모르는 인터뷰 대상자를 제거하기 위해 사용되는 매우 기본적인 문제입니다. 문제는:

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 문제 수정의 목적은 C ++ 템플릿을 사용하여 위의 알고리즘을 수행하여 가능한 한 적은 런타임 작업이 필요하다는 것입니다.

필요한 경우 TMP 객체에 맞추기 위해 필요한 경우 N을 더 작은 범위로 줄일 수 있습니다.

이것은 "골프"일 것으로 예상되지 않습니다.


11
대부분의 비 - C ++ 사람이 없을 것입니다 때문에, 오히려 TMP보다는 "템플릿 메타 프로그래밍을"말을해야 TMP가 무엇인지 생각.
Chris Jester-Young

6
"프로그래밍 방법을 모르는 인터뷰 대상자를 제거"나는 일반 프로그래머가 템플릿 메타 프로그래밍을 알아야한다는 것을 몰랐습니다.
Alexandru

1
런타임 작업을 어떻게 정의합니까? 어셈블러 명령? 그렇다면 모호하지 않도록 컴파일러와 플랫폼을 지정하는 것이 좋습니다.
sepp2k

7
@Alexandru : Fizzbuzz 문제는 템플릿 메타 프로그래밍을 사용하여 fizzbuzz 문제를 해결하는 것이 아니라 "잡초를 제거하는 데 사용된다"고 말했다.
sepp2k

답변:


3

여기 내 시도가 있습니다 (솔루션으로 적합했는지 확실하지 않기 때문에 하루 동안 누워 있었습니까). 놀랍게도 만 나는 @ 크리스가 변경되었습니다에서 통합 비트 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;
}

또한 이것이 TMP에서 처음 시도한 것이므로 코드 개선에 대한 제안이 있으면 감사하겠습니다.


2

완전히 골프가 아닌 솔루션 :

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

샘플 테스트 코드 :

#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

좋아, 나는 마침내 이것에 총을 쏜다. 이전 솔루션과는 달리 내 솔루션은 컴파일시에 전체 출력 문자열을 구축하고있는 유일한 런타임 호출 단일 호출이다 cout'의 <<운영자입니다. boost::mpl코드를 다소 관리하기 쉽도록 사용 하고 있습니다.

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

슬프게도 코드는 9보다 boost::mpl::string큰 문자열을 사용할 때 너무 큰 문자열에 대한 불평으로 폭발합니다 n.


0

362 자

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

내가 누락 된 것이 아니라면 모든 작업이 런타임에 발생합니다.
sepp2k

@ sepp2k : 무슨 뜻 ?:인가요? 컴파일 타임에 평가할 수 있다고 생각했습니다. 물론 런타임에 거대한 문자열 연결이 발생합니다.
ephemient

주로 문자열 구성과 연결을 의미했지만? :도 컴파일 타임에 발생하지 않아도됩니다 (아마도 가능할 것입니다).
sepp2k

-2

local b = io.read ( "* n") local i = 1 while (i <= b) i % 15 == 0 인 경우 수행 한 다음 print ( "FizzBuzz") else if i % 3 == 0 인 경우 print ( "Fizz ") elseif i % 5 == 0이면 print ("Buzz ") else print (i) end i = i + 1 end


사이트에 오신 것을 환영합니다! 이것이 무슨 언어 지? 코드를 강조 표시하고 편집기에서 아이콘을 클릭하여 코드 형식을 사용할 수 있습니다.
Ad Hoc Garf Hunter

이 질문은 FizzBuzz 전용 C++이며 Lua (?)로 답변됩니다. 일반적인 FizzBuzz 질문 에 게시 하시겠습니까?
Jo King
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.