Advertisement
Semper_Idem

Branchless FizzBuz

May 5th, 2020
263
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.22 KB | None | 0 0
  1. #include <limits.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. // 0 or 1
  6. unsigned is_divisible(unsigned x, unsigned d) {
  7.   unsigned rem = x % d;
  8.   rem--;
  9.   return ((rem & (1 << sizeof(rem) * CHAR_BIT - 1)) >>
  10.           (sizeof(rem) * CHAR_BIT - 1));
  11. }
  12.  
  13. typedef void (*do_num_f)(unsigned i);
  14.  
  15. void do_last(unsigned i) {
  16.   (void)(i);
  17.   printf("Good bye!\n");
  18.   exit(0);
  19. }
  20. void do_3_and_5(unsigned i) {
  21.   (void)(i);
  22.   printf("FizzBuzz!\n");
  23. }
  24. void do_3(unsigned i) {
  25.   (void)(i);
  26.   printf("Fizz!\n");
  27. }
  28. void do_5(unsigned i) {
  29.   (void)(i);
  30.   printf("Buzz!\n");
  31. }
  32. void do_other(unsigned i) { printf("%u\n", i); }
  33.  
  34. do_num_f do_num[5] = {do_other, do_3, do_5, do_3_and_5, do_last};
  35.  
  36. // 0 - others
  37. // 1 - 3
  38. // 2 - 5
  39. // 3 - 15
  40. // 4 - last
  41. unsigned get_do_index(unsigned i, unsigned last) {
  42.   unsigned is_divisible_last = is_divisible(i, last);
  43.   unsigned is_divisible_5 = is_divisible(i, 5);
  44.   unsigned is_divisible_3 = is_divisible(i, 3);
  45.   return is_divisible_last * 4 +
  46.          (is_divisible_5 * 2 + is_divisible_3 * 1) * (is_divisible_last ^ 1);
  47. }
  48.  
  49. int main(int argc, char *argv[]) {
  50.   printf("Branchless FizzBuzz!\n");
  51.   for (unsigned i = 1;; i++)
  52.     do_num[get_do_index(i, 101)](i);
  53.  
  54.   return -1;
  55. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement