6 ms·
I agree that Fizzbuzz can be a more interesting example of how to write code without repetition. While the author suggests that languages such as Haskell provid
by absherwin 14y ago
I agree that Fizzbuzz can be a more interesting example of how to write code without repetition. While the author suggests that languages such as Haskell provide a unique advantage, the deciding question seems to be the availability of pre-built abstractions. Consider the following solution in Python:
for i in xrange(1,101): print (('' if i%3 else 'Fizz')+('' if i%5 else 'Buzz')) or i
or the even more general:
mapping={3:'Fizz',5:'Buzz'}
for i in xrange(1,101):
print ''.join(['' if i%x else mapping[x] for x in mapping]) or i
We can even do this in C though to write something as extensible as the second would require writing more helper functions than I can justify for this brief comment:
#include<string.h>
#include<stdio.h>
int main(){
int i;
char s[4];
char n[3];
for (i=1;i<101;i++){
sprintf(n,"%d",i)
s=strcat((i%3)?"":"Fuzz",(i%5)?"":"Buzz")
printf("%s",(strlen(s))?s:n)
}
return 0;
}
- wisty 14y agoJust as you can write FORTRAN or COBOL in any language, you can write functional code in any language.
- innguest 14y agoNo you can't, as you need the language to provide a few basic building blocks, such as lambdas, and the ability to pass functions as arguments.
- KirinDave 14y agoYou can generally approximate higher order functions in almost every OOP language. See C++ before it got lambdas, they have a pattern. See also java's anonymous inner classes, which are often used with the Runnable interface for that rule.
- KirinDave 14y agoIt is still crazy to me that in Python ('' or 10) == 10 # True That's like making the universe crazier one electron at a time. But yes, it's just about having the right abstractions. What's nice about the Haskell solution is that the right abstractions make the code much nicer (to my eye).
- benhoyt 14y agoI honestly don't understand why that's crazy. Empty string evaluates as falsey, so the "or" picks the 10, which is obviously equal to 10. Or am I missing something?
- deleted 14y ago[deleted]
- KirinDave 14y agoIt just seems like a bad choice. The empty string being falsey is... very arbitrary to me. It seems like it's strictly a perl legacy thing that should be (but cannot be) reconsidered. About as far as I am willing to go is nil punning.
- thecoffman 14y agoFWIW - it has been reconsidered in Ruby - all values are truthy except nil and false.
- pdonis 14y ago> The empty string being falsey is... very arbitrary to me. It's extremely useful in a lot of contexts. The basic logic is that an empty string is an empty container, and empty containers are false, so you can test for them more easily.
- daeken 14y agoMy "I'm going to hell, but that's okay" C version: #include <stdio.h> #include <stdbool.h> #define when(mod, msg) do { if((i mod) == 0) { fputs(#msg, stdout); *hit = true; } } while(0) #define through ; i <= #define engine(range) \ void rules(int, bool *);\ int main(void) { for(int i = range; ++i) { bool hit = false; rules(i, &hit); if(!hit) printf("%d", i); putchar('\n'); } } \ void rules(int i, bool *hit) engine(1 through 100) { when(% 3, Fizz); when(% 5, Buzz); } Super extensible!
- KirinDave 14y agoI'm not sure even hell will take you after doing what you just did. There is no metaphysical consequence great enough save to have experienced the writing of that.
- rcsorensen 14y agoMy going to hell version: https://github.com/rcs/fizzbuzz/blob/master/bitwise.c https://github.com/rcs/fizzbuzz/blob/master/bitwise.c Choice excerpts: char fmts[] = "FizzBuzz%u"; and // Default start is 8 unsigned int start = // Shift down 1 if div5 (8 >> DIV5(mask)) // Shift down another 4 if div3 */ >> ( DIV3(mask) << 2);
- LnxPrgr3 14y agoMy "I'm going to hell" C++ version: https://gist.github.com/3838042 https://gist.github.com/3838042 Or, since github's being broken right now: #include <iostream> #include <arpa/inet.h> template <int multiples_of, uint32_t noise> class Noisemaker { private: union { uint32_t noise_as_int; char noise_as_cstr[5]; }; public: Noisemaker() { noise_as_int = htonl(noise); noise_as_cstr[4] = '\0'; } bool operator()(std::ostream &out, int i) { if(i % multiples_of == 0) { out << noise_as_cstr; return true; } return false; } }; template <typename Noise1, typename Noise2> class NoisemakerPair { private: Noise1 noise1; Noise2 noise2; public: bool operator()(std::ostream &out, int i) { bool matched = false; matched |= noise1(out, i); matched |= noise2(out, i); return matched; } }; int main(int argc, char *argv[]) { NoisemakerPair<Noisemaker<3, 'Fizz'>, Noisemaker<5, 'Buzz'> > fizzbuzz; for(int i=1;i<=100;++i) { if(!fizzbuzz(std::cout, i)) std::cout << i; std::cout << std::endl; } } You can nest NoisemakerPairs to add more Noisemakers. But good luck with strings longer than 4 characters… for some absurd reason, string literals can't be template parameters. Go figure.
- gshubert17 14y agoIn the Python example, wouldn't you need to make sure the x values from mapping are sorted, since dictionaries are unordered? Change, for x in mapping to for x in sorted(mapping)
- GeorgeTirebiter 14y agoBreaks the spec: 'Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.' Actually, this spec is ambiguous, too. For multiples of five, do we print the number AND "Buzz" or just "Buzz" ? Similarly for multiples of 15. I thought the OP was a joke, BTW. It had to be, doesn't it? If somebody thought of this problem and solution the way the job candidate did, why on earth would one want to hire somebody who loves complexity for its own sake? To me, the following is the clearest way to express this (in C anyway). I suppose it says a lot about me! lol #include <stdio.h> #define FALSE (0) #define TRUE (!FALSE) int main(){ for(int i=1; i <= 100; i++){ int printed_something_already=FALSE; if(i%3 == 0){ printf("Fizz"); printed_something_already=TRUE; } if(i%5 == 0){ printf("Buzz"); printed_something_already=TRUE; } if(!printed_something_already) printf("%d",i); printf("\n"); } return 0; }
- KirinDave 14y ago> I thought the OP was a joke, BTW. Well balls to you too, I guess? Or not. We're all just trying to have a good time here. And from the look of this thread, people are having fun. I think golfing fizzbuzz into an unreadable mess sorta misses the point, but most people here are software engineers because they love to code and build stuff. So let's enjoy the moment. > why on earth would one want to hire somebody who loves complexity for its own sake? You remind me of: http://wondermark.com/333/ http://wondermark.com/333/ It's not complexity for its own stake. I daresay the functional patterns tend to be simpler. Certainly moreso than things like Visitor or AbstractFactory. > To me, the following is the clearest way to express this (in C anyway). I suppose it says a lot about me! Your version is almost identical to the Ruby version I listed. And it's an appropriate solution for C.
- GeorgeTirebiter 14y agoI don't know what balls to me too means. Yes, if we're all trying to have a good time, we'd shoot heroin and be done with it. ;-) IMHO, we are group sharing to learn better ways to build startups, small businesses, and to better ourselves, co-workers, and companies with best practices - and to do it with fun and a twinkle in our eyes. I did look at that wordmark comic -- I believe I ask a credible question: If complexity buys you nothing, then why make something complex? And, believe me, if you are thinking "Visitor" or "AbstractFactory" then I have already lost you. ;-) Thank you for your comment about my C version. I wanted to make sure it was extensible and quite obvious -- because I write code to be read by humans as my 2nd goal (my first is that it works & meets the spec!). Knuth's Literate Programming taught me that. The other thing about that C solution is that it's simple and many people can understand it. One does not need to know the difference between a monad and a gonad to "get it". My overall comment: Complexity: when required; otherwise, choose simple. Believe me, I have learned this lesson over and over again during my 45 years of programming.