Buzz fizz ใน 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 ++ ที่จำเป็นต้องมีการใช้งานรันไทม์เพียงเล็กน้อย

คุณสามารถลด N ให้อยู่ในช่วงที่เล็กลงได้ถ้าคุณต้องการเพื่อให้พอดีกับวัตถุ TMP หากจำเป็น

นี่ไม่ใช่สิ่งที่คาดว่าจะเป็น "กอล์ฟ"


11
คุณควรจะพูดว่า "แม่แบบ metaprogramming" มากกว่า TMP เพราะไม่ใช่-C ++ ส่วนใหญ่คนจะต้องไม่มีความคิดว่าเป็น TMP
Chris Jester-Young

6
"กำจัดผู้ให้สัมภาษณ์ที่ไม่รู้วิธีการเขียนโปรแกรม" ฉันไม่รู้ว่าโปรแกรมเมอร์โดยเฉลี่ยจำเป็นต้องรู้เทมเพลตการเขียนโปรแกรม
Alexandru

1
คุณจะกำหนดการดำเนินการรันไทม์อย่างไร คำแนะนำผู้ประกอบ? ถ้าเป็นเช่นนั้นอาจเป็นความคิดที่ดีที่จะระบุคอมไพเลอร์และแพลตฟอร์มเพื่อให้ไม่มีความคลุมเครือ
sepp2k

7
@Alexandru: เขาบอกว่าปัญหา fizzbuzz ถูกใช้เพื่อ "กำจัดวัชพืช ... " ไม่ใช่ว่าการแก้ปัญหา fizzbuzz โดยใช้ Template Metaprogramming คือ
sepp2k

1
เป็นไปได้ซ้ำของ1, 2, Fizz, 4, Buzz
pppery

คำตอบ:


3

นี่คือความพยายามของฉัน (ถ้ามันโกหกรอบวันหรือมากกว่านั้นเพราะฉันไม่แน่ใจว่ามันเหมาะกับการแก้ปัญหา) น่าแปลกใจเพียงบิตเดียวที่ฉันรวมจาก @Chris ก็เปลี่ยน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;
}

น่าเศร้าที่รหัสจะระเบิดด้วยการboost::mpl::stringบ่นเกี่ยวกับสายใหญ่เกินไปเมื่อใช้ใด ๆ ที่nมากกว่า 9


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: คุณหมายถึง?:อะไร? ฉันคิดว่าสามารถประเมินได้ในเวลารวบรวม แน่นอนฉันมีการต่อสายใหญ่เกิดขึ้นที่ runtime ที่นี่
ephemient

ในขั้นต้นฉันหมายถึงการสร้างสายอักขระและการต่อข้อมูล แต่?: ยังไม่ต้องเกิดขึ้นในเวลารวบรวม (แม้ว่ามันอาจจะ)
sepp2k

-2

local b = io.read ("* n") local i = 1 ในขณะที่ (i <= b) ทำอย่างไรถ้า i% 15 == 0 แล้วพิมพ์ ("FizzBuzz") elseif i% 3 == 0 แล้วพิมพ์ ("Fizz ") elseif i% 5 == 0 จากนั้นพิมพ์ (" Buzz ") พิมพ์อื่น (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.