Here was my first, simple C fizzbuzz:
#include <stdio.h>
void main() {
for (int n = 1; n <= 100; ++n) {
if (n % 3 == 0) printf("%s", "fizz");
if (n % 5 == 0) printf("%s", "buzz");
if ((n % 3 != 0) && (n % 5 != 0)) printf("%d", n);
printf("\n");
}
}
I was messing around, trying to separate the transformation logic from the looping logic. As a whole, I don't think that my second Buffer
-based solution is necessarily "better" as a FizzBuzz solution, but I did like the way that I dealt with a limited-purpose character buffer.
Thoughts on the second solution?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#define BUFF_SZ 9
typedef unsigned int u32;
typedef int i32;
/// A string buffer with a notion of its own size.
typedef struct Buffer {
char *s;
u32 sz;
char *ins_ptr;
} Buffer;
/// Returns the content of the buffer.
const char *Buffer_content(Buffer *);
/// Clears contents of the buffer.
void Buffer_clear(Buffer *);
/// Appends a string S to the end of the buffer.
void Buffer_append_str(Buffer *, char *);
/// Appends the string representation of an integer to the end of the buffer.
void Buffer_append_i32(Buffer *, i32);
/// Returns 1 if the buffer has space for a certain number of chars, else 0.
u32 Buffer_has_space(Buffer *, u32);
/* HIGH LEVEL CODE */
/// Writes a number's fizzbuzz transformation into a Buffer.
void write_fizzbuzz_transformation(i32 n, Buffer *buff) {
Buffer_clear(buff);
if (n % 3 == 0) Buffer_append_str(buff, "fizz");
if (n % 5 == 0) Buffer_append_str(buff, "buzz");
if (*Buffer_content(buff) == '\0') Buffer_append_i32(buff, n);
}
void main() {
// setup the string buffer (stack allocated)
char internal_buff[BUFF_SZ];
Buffer buff;
buff.s = internal_buff;
buff.sz = BUFF_SZ;
for (i32 i = 1; i <= 100; ++i) {
write_fizzbuzz_transformation(i, &buff);
printf("%d -> %s\n", i, Buffer_content(&buff));
}
}
/* DETAILS -- IMPLEMENTATION CODE */
u32 Buffer_has_space(Buffer *buff, u32 requested_sz) {
u32 available_sz = buff->sz - (buff->ins_ptr - buff->s) - 1;
return (available_sz >= requested_sz);
}
void Buffer_append_str(Buffer *buff, char* s) {
u32 needed_sz = strlen(s);
assert(Buffer_has_space(buff, needed_sz));
strcpy(buff->ins_ptr, s);
buff->ins_ptr += needed_sz;
}
void Buffer_append_i32(Buffer *buff, i32 n) {
i32 original = n;
u32 needed_sz = 0;
if (n < 1) ++needed_sz;
while (n) {
n /= 10;
++needed_sz;
}
assert(Buffer_has_space(buff, needed_sz));
sprintf(buff->ins_ptr, "%d", original);
buff->ins_ptr += needed_sz;
}
void Buffer_clear(Buffer *buff) {
buff->ins_ptr = buff->s;
*(buff->ins_ptr) = '\0';
}
const char *Buffer_content(Buffer *buff) {
return buff->s;
}