{"id":810,"date":"2018-02-23T00:02:41","date_gmt":"2018-02-22T23:02:41","guid":{"rendered":"https:\/\/www.numbercrunch.de\/blog\/?p=810"},"modified":"2023-01-10T23:27:33","modified_gmt":"2023-01-10T22:27:33","slug":"fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17","status":"publish","type":"post","link":"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/","title":{"rendered":"FizzBuzz or the beauty of compile-time calculations in C++17"},"content":{"rendered":"<p style=\"text-align: justify;\"><a href=\"https:\/\/en.wikipedia.org\/wiki\/Fizz_buzz\">FizzBuzz<\/a> is a popular test that is commonly used in job interviews for software developers. In this test one is asked to write a function that prints the numbers from 1 to 100. But for multiples of three \u201cFizz\u201d has to be printed instead of the number and for the multiples of five the word \u201cBuzz\u201d shall be printed. For numbers which are multiples of both three and five the word \u201cFizzBuzz\u201d results. This popular exercise has been solved in many <a href=\"https:\/\/rosettacode.org\/wiki\/FizzBuzz\">different programming languages<\/a>.<\/p>\n<p style=\"text-align: justify;\">This is not really a challenging task. It is designed to divide candidates with virtually no programming expertise from those with some programming skills. In fact, the test requires very little programming skills and can be solved manually because it has no variable input parameters. An admissible solution would be to print just a fixed string:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#include &lt;cstdlib&gt;\n#include &lt;iostream&gt;\n\nint main() {\n  std::cout &lt;&lt; \"1\\n2\\nFizz\\n4\\nBuzz\\nFizz\\n7\\n8\\nFizz\\nBuzz\\n\"\n    \"11\\nFizz\\n13\\n14\\nFizzBuzz\\n16\\n17\\nFizz\\n19\\nBuzz\\n\"\n    \"Fizz\\n22\\n23\\nFizz\\nBuzz\\n26\\nFizz\\n28\\n29\\nFizzBuzz\\n\"\n    \"31\\n32\\nFizz\\n34\\nBuzz\\nFizz\\n37\\n38\\nFizz\\nBuzz\\n\"\n    \"41\\nFizz\\n43\\n44\\nFizzBuzz\\n46\\n47\\nFizz\\n49\\nBuzz\\n\"\n    \"Fizz\\n52\\n53\\nFizz\\nBuzz\\n56\\nFizz\\n58\\n59\\nFizzBuzz\\n\"\n    \"61\\n62\\nFizz\\n64\\nBuzz\\nFizz\\n67\\n68\\nFizz\\nBuzz\\n\"\n    \"71\\nFizz\\n73\\n74\\nFizzBuzz\\n76\\n77\\nFizz\\n79\\nBuzz\\n\"\n    \"Fizz\\n82\\n83\\nFizz\\nBuzz\\n86\\nFizz\\n88\\n89\\nFizzBuzz\\n\"\n    \"91\\n92\\nFizz\\n94\\nBuzz\\nFizz\\n97\\n98\\nFizz\\nBuzz\\n\";\n  return EXIT_SUCCESS;\n}\n<\/pre>\n<p style=\"text-align: justify;\">This solution is easy to program.\u00a0 It has the nice feature, that actually nothing is computed at run-time. The whole string is known at compile-time. Coming up with such a solution is, however, tedious. What if we increase the upper limit from 100 to, let&#8217;s say, 1000?<\/p>\n<p style=\"text-align: justify;\">Luckily, the compiler can do this job for us, at least in C++, and employing C++17 this becomes particularly easy. In the following program <code>fizzbuzz_helper<\/code> template classes are defined which carry a string array which contains either the string representation of a number or \u201cFizz\u201d or \u201cBuzz\u201d or \u201cFizzBuzz\u201d, depending on the template parameter. This is pretty standard template programing stuff with C++11 or later. Beauty comes in in the <code>concatenate<\/code> const-expression function, which concatenates two arrays at compile-time. Due to some limitations of the array template class this is not possible in C++14 or earlier. At least not in such a clear and straight-forward way. The <code>main<\/code> routine, finally, just prints out the large string, which has been built by the compiler. You may check that the executable contains just the string, which is printed on the screen, via the\u00a0<code><\/code><a href=\"https:\/\/en.wikipedia.org\/wiki\/Strings_(Unix)\">strings<\/a> utility on unix-like systems. Note that all class variables are declared as <code>static constexpr<\/code> to enforce compile-time calculation of the string value for initialization.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">#include &lt;cstdlib&gt;\n#include &lt;iostream&gt;\n#include &lt;array&gt;\n\n\/\/ concatenate two arrays at compile-time\ntemplate&lt;typename T, std::size_t N1, std::size_t N2&gt;\nconstexpr std::array&lt;T, N1+N2&gt; concatenate(const std::array&lt;T, N1&gt; &amp;lhs,\n                       const std::array&lt;T, N2&gt; &amp;rhs) {\n  std::array&lt;T, N1+N2&gt; result{};\n  std::size_t index{0};\n  for (std::size_t i{0}; i&lt;lhs.size(); ++i, ++index)\n    result[index]=lhs[i];\n  for (std::size_t i{0}; i&lt;rhs.size(); ++i, ++index)\n    result[index]=rhs[i];\n  return result;\n}\n\n\/\/ convert a 4-digit integer to a character string\/array \ntemplate&lt;std::size_t I&gt;\nstruct int_to_str {\n  static_assert(I&lt;=9999);\n  static constexpr char digits[]{\"0123456789\"};\n  static constexpr std::array&lt;char, 5&gt; str{ I&gt;=1000 ? digits[(I\/1000)%10] : ' ',\n      I&gt;=100 ? digits[(I\/100)%10] : ' ',\n      I&gt;=10 ? digits[(I\/10)%10] : ' ',\n      digits[(I\/1)%10], '\\n' };\n};\n\n\/\/ convert integer parameter I to string unless I can be devided by 3 or 5\n\/\/ special cases where I can be divided 3 or 5 are handled via partial\n\/\/ template specialization below\ntemplate&lt;int I, bool div3=I%3==0, bool div5=I%5==0&gt;\nstruct fizzbuzz_helper : int_to_str&lt;I&gt; {\n};\n\ntemplate&lt;int I&gt;\nstruct fizzbuzz_helper&lt;I, true, false&gt; {\n  static constexpr std::array&lt;char, 5&gt; str{ 'F', 'i', 'z', 'z', '\\n' };\n};\n\ntemplate&lt;int I&gt;\nstruct fizzbuzz_helper&lt;I, false, true&gt; {\n  static constexpr std::array&lt;char, 5&gt; str{ 'B', 'u', 'z', 'z', '\\n' };\n};\n\ntemplate&lt;int I&gt;\nstruct fizzbuzz_helper&lt;I, true, true&gt; {\n  static constexpr std::array&lt;char, 9&gt; str{ 'F', 'i', 'z', 'z', 'B', 'u', 'z', 'z', '\\n' };\n};\n\n\/\/ all Fizz-Buzz-integer strings are concatenated for all integers \n\/\/ running from 1 to I via a recursive template definition\ntemplate&lt;int I&gt;\nstruct fizzbuzz {\n  static constexpr auto str{concatenate(fizzbuzz&lt;I-1&gt;::str, fizzbuzz_helper&lt;I&gt;::str)};\n};\n\n\/\/ stop the recursion via template specialization for I=1\ntemplate&lt;&gt;\nstruct fizzbuzz&lt;1&gt; {\n  static constexpr auto str{fizzbuzz_helper&lt;1&gt;::str};\n};\n\nint main() {\n  \/\/ print the compile-time concatenated Fizz-Buzz-integer string\n  \/\/    1\n  \/\/    2\n  \/\/ Fizz\n  \/\/    4\n  \/\/ Buzz\n  \/\/ Fizz\n  \/\/    7\n  \/\/    8\n  \/\/ Fizz\n  \/\/ Buzz\n  \/\/   11\n  \/\/ Fizz\n  \/\/   13\n  \/\/   14\n  \/\/ FizzBuzz\n  \/\/   16\n  \/\/ ...\n  for (auto x: fizzbuzz&lt;100&gt;::str)\n    std::cout &lt;&lt; x;\n  return EXIT_SUCCESS;\n}\n<\/pre>\n<p>\u00a0<\/p>\n\n","protected":false},"excerpt":{"rendered":"<p>FizzBuzz is a popular test that is commonly used in job interviews for software developers. In this test one is asked to write a function that prints the numbers from 1 to 100. But for multiples of three \u201cFizz\u201d has to be printed instead of the number and for the multiples of five the word&hellip; <a href=\"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">FizzBuzz or the beauty of compile-time calculations in C++17<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16,5],"tags":[],"class_list":["post-810","post","type-post","status-publish","format-standard","hentry","category-c","category-software"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>FizzBuzz or the beauty of compile-time calculations in C++17 - Number Crunch<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"FizzBuzz or the beauty of compile-time calculations in C++17 - Number Crunch\" \/>\n<meta property=\"og:description\" content=\"FizzBuzz is a popular test that is commonly used in job interviews for software developers. In this test one is asked to write a function that prints the numbers from 1 to 100. But for multiples of three \u201cFizz\u201d has to be printed instead of the number and for the multiples of five the word&hellip; Continue reading FizzBuzz or the beauty of compile-time calculations in C++17\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/\" \/>\n<meta property=\"og:site_name\" content=\"Number Crunch\" \/>\n<meta property=\"article:published_time\" content=\"2018-02-22T23:02:41+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-01-10T22:27:33+00:00\" \/>\n<meta name=\"author\" content=\"Heiko Bauke\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Heiko Bauke\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/\"},\"author\":{\"name\":\"Heiko Bauke\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413\"},\"headline\":\"FizzBuzz or the beauty of compile-time calculations in C++17\",\"datePublished\":\"2018-02-22T23:02:41+00:00\",\"dateModified\":\"2023-01-10T22:27:33+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/\"},\"wordCount\":354,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413\"},\"articleSection\":[\"C++\",\"Software\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/\",\"url\":\"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/\",\"name\":\"FizzBuzz or the beauty of compile-time calculations in C++17 - Number Crunch\",\"isPartOf\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#website\"},\"datePublished\":\"2018-02-22T23:02:41+00:00\",\"dateModified\":\"2023-01-10T22:27:33+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.numbercrunch.de\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"FizzBuzz or the beauty of compile-time calculations in C++17\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#website\",\"url\":\"https:\/\/www.numbercrunch.de\/blog\/\",\"name\":\"Number Crunch\",\"description\":\"A computational science blog.\",\"publisher\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.numbercrunch.de\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413\",\"name\":\"Heiko Bauke\",\"logo\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"FizzBuzz or the beauty of compile-time calculations in C++17 - Number Crunch","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/","og_locale":"en_US","og_type":"article","og_title":"FizzBuzz or the beauty of compile-time calculations in C++17 - Number Crunch","og_description":"FizzBuzz is a popular test that is commonly used in job interviews for software developers. In this test one is asked to write a function that prints the numbers from 1 to 100. But for multiples of three \u201cFizz\u201d has to be printed instead of the number and for the multiples of five the word&hellip; Continue reading FizzBuzz or the beauty of compile-time calculations in C++17","og_url":"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/","og_site_name":"Number Crunch","article_published_time":"2018-02-22T23:02:41+00:00","article_modified_time":"2023-01-10T22:27:33+00:00","author":"Heiko Bauke","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Heiko Bauke","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/#article","isPartOf":{"@id":"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/"},"author":{"name":"Heiko Bauke","@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413"},"headline":"FizzBuzz or the beauty of compile-time calculations in C++17","datePublished":"2018-02-22T23:02:41+00:00","dateModified":"2023-01-10T22:27:33+00:00","mainEntityOfPage":{"@id":"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/"},"wordCount":354,"commentCount":0,"publisher":{"@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413"},"articleSection":["C++","Software"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/","url":"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/","name":"FizzBuzz or the beauty of compile-time calculations in C++17 - Number Crunch","isPartOf":{"@id":"https:\/\/www.numbercrunch.de\/blog\/#website"},"datePublished":"2018-02-22T23:02:41+00:00","dateModified":"2023-01-10T22:27:33+00:00","breadcrumb":{"@id":"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.numbercrunch.de\/blog\/2018\/02\/fizzbuzz-or-the-beauty-of-compile-time-calculations-in-c17\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.numbercrunch.de\/blog\/"},{"@type":"ListItem","position":2,"name":"FizzBuzz or the beauty of compile-time calculations in C++17"}]},{"@type":"WebSite","@id":"https:\/\/www.numbercrunch.de\/blog\/#website","url":"https:\/\/www.numbercrunch.de\/blog\/","name":"Number Crunch","description":"A computational science blog.","publisher":{"@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.numbercrunch.de\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413","name":"Heiko Bauke","logo":{"@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/posts\/810"}],"collection":[{"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/comments?post=810"}],"version-history":[{"count":23,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/posts\/810\/revisions"}],"predecessor-version":[{"id":947,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/posts\/810\/revisions\/947"}],"wp:attachment":[{"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/media?parent=810"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/categories?post=810"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/tags?post=810"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}