[HN Gopher] Solving Fizz Buzz with Cosines
___________________________________________________________________
Solving Fizz Buzz with Cosines
Author : hprotagonist
Score : 188 points
Date : 2025-11-21 17:28 UTC (1 days ago)
(HTM) web link (susam.net)
(TXT) w3m dump (susam.net)
| thomasjudge wrote:
| https://joelgrus.com/2016/05/23/fizz-buzz-in-tensorflow/
| arealaccount wrote:
| This would be an offer on the spot from me
| stronglikedan wrote:
| > me: It's more of a "I can't believe you're asking me that."
|
| > interviewer: Great, we find that candidates who can't get
| this right don't do well here.
|
| > me: ...
|
| Shit attitude from that candidate, considering the
| interviewer is completely correct. I wouldn't hire them since
| they are obviously a problem employee.
|
| For those that don't know, Fizz Buzz is less an aptitude test
| and more of an attitude test. That's why this candidate
| failed and didn't get the job.
| darth_aardvark wrote:
| For those that don't know even more, this interview never
| happened and this interviewer doesn't exist. It's a funny
| joke on the internet.
| toast0 wrote:
| If the candidate didn't even show up to an interview,
| they're definitely not worth hiring. :p
| NitpickLawyer wrote:
| > Fizz Buzz is less an aptitude test and more of an
| attitude test
|
| The amount of (highly credentialed) interviewees that can't
| 0-shot a correct and fully functional fizzbuzz is also way
| higher than a lot of people would think. That's where the
| attitude part also comes in.
| cyphar wrote:
| _> For those that don 't know, Fizz Buzz is less an
| aptitude test and more of an attitude test._
|
| The articles which popularised FizzBuzz as an interview
| question stated as a categorical fact that most computer
| science graduates or programmer candidates (one article
| even said 199/200!![2]) cannot do FizzBuzz[1,2,3] and were
| _absolutely_ recommending it as an _aptitude_ test.
|
| I personally think this whole thing was simply untrue back
| in 2007 (or at the very least incredibly overstated) and we
| are paying the price for it with ridiculous 15-stage
| interviews as a paranoid response to some urban legend from
| ~20 years ago.
|
| [1]: https://imranontech.com/2007/01/24/using-fizzbuzz-to-
| find-de... [2]: http://weblog.raganwald.com/2007/01/dont-
| overthink-fizzbuzz.... [3]:
| https://blog.codinghorror.com/why-cant-programmers-program/
| n4r9 wrote:
| A massively over-engineered, incorrect solution?
| jiveturkey wrote:
| A candidate that appreciates the value of the question, yet
| won't subject themselves to the absurdity of demonstrating
| compliance.
|
| Yes, very much yes.
| gregsadetsky wrote:
| There was another great satirical take on FizzBuzz which had
| something to do with runes and incantation and magical
| spells...? I sort of remember that the same author maybe even
| wrote a follow up? to this extremely experienced developer
| solving FizzBuzz in the most arcane way possible.
|
| Does this ring a bell for anyone?
|
| ---
|
| Found it!
|
| https://aphyr.com/posts/340-reversing-the-technical-intervie...
|
| https://aphyr.com/posts/341-hexing-the-technical-interview
|
| https://aphyr.com/posts/342-typing-the-technical-interview
|
| https://aphyr.com/posts/353-rewriting-the-technical-intervie...
| (the FizzBuzz one)
|
| https://aphyr.com/posts/354-unifying-the-technical-interview
|
| wow.
| ntonozzi wrote:
| One of my favorite blog posts of all time:
| https://aphyr.com/posts/342-typing-the-technical-interview
| flir wrote:
| "Unavailable Due to the UK Online Safety Act"
|
| Does aphyr even have comments, or is it a pure political
| protest?
|
| That's the first thing that's tempted to break out an ssh
| tunnel - I can live without the occasional NSFW reddit group.
| toast0 wrote:
| They do show comments at the bottom of the posts.
| AstroJetson wrote:
| Thanks for the memory reminder, I read them when they first
| came out. They are still highly amusing today!
| taolson wrote:
| Along that line, an over-engineered fizzBuzz using lazy list
| operations:
|
| https://github.com/taolson/Admiran/blob/main/examples/fizzBu...
| ivan_ah wrote:
| This is very nice.
| tantalor wrote:
| There are several mentions of "closed-form expression" without
| precisely defining what that means, only "finite combinations of
| basic operations".
|
| TFA implies that branches (if statements and piecewise
| statements) are not allowed, but I don't see why not. Seems like
| a basic operation to me.
|
| Nevermind that `s[i]` is essentially a piecewise statement.
| susam wrote:
| > There are several mentions of "closed-form expression"
| without precisely defining what that means, only "finite
| combinations of basic operations".
|
| There is no universal definition of 'closed-form expression'.
| But there are some basic operations and functions that are
| broadly accepted, and they are spelled out directly after the
| 'finite combinations' phrase you quoted from the post. Quoting
| the remainder of that sentence here:
|
| _' [...] finite combinations of basic operations such as
| addition, subtraction, multiplication, division, integer
| exponents and roots with integer index as well as functions
| such as exponentials, logarithms and trigonometric functions.'_
| bmacho wrote:
| https://en.wikipedia.org/wiki/Closed-
| form_expression#Compari...
| siegelzero wrote:
| Very cool! There's definitely some similarity to Ramanujan Sums,
| though the approach here sort of packages the fizz-buzz
| divisibility properties into one function.
| https://en.wikipedia.org/wiki/Ramanujan%27s_sum
| layer8 wrote:
| I think that implementation will break down around 2^50 or so.
| nine_k wrote:
| Well, there must be an obvious solution where the fizzbuzz
| sequence is seen as a spectrum of two frequencies (1/3 and 1/5),
| and a Fourier transform gives us a periodic signal with peaks of
| one amplitude at fizz spots, another amplitude at buzz spots, and
| their sum at fizzbuzz spots. I mean. that would be approximately
| the same solution as the article offers, just through a more
| straightforward mechanism.
| atemerev wrote:
| Yes. Exactly. This is how it _should_ have been done.
|
| Also probably easy enough to encode as quantum superpositions.
| HPsquared wrote:
| How would someone do FizzBuzz on a quantum computer? It seems
| like a nice toy example problem.
| susam wrote:
| That is precisely how I began writing this post. I thought I'd
| demonstrate how to apply the discrete Fourier transform (DFT)
| but to do so for each of the 15 coefficients turned out to be a
| lot of tedious work. That's when I began noticing shortcuts for
| calculating each coefficient c_k based on the divisibility
| properties of k. One shortcut led to another and this post is
| the end result. It turns out it was far less tedious (and more
| interesting as well) to use the shortcuts than to perform a
| full-blown DFT calculation for each coefficient.
|
| Of course, we could calculate the DFT using a tool, and from
| there work out the coefficients for the cosine terms. For
| example, we could get the coefficients for the exponential form
| like this:
|
| https://www.wolframalpha.com/input?i=Fourier%5B%7B3%2C+0%2C+...
|
| And then convert them to the coefficients for the cosine form
| like this:
|
| https://www.wolframalpha.com/input?i=%7B11%2F15%2C+2*0%2C+2*...
|
| That's certainly one way to avoid the tedious work but I
| decided to use the shortcuts as the basis for my post because I
| found this approach more interesting. The straightforward DFT
| method is perfectly valid as well and it would make an
| interesting post by itself.
| susam wrote:
| Update: I went ahead and added the method of obtaining the
| coefficients using DFT anyway. Like I mentioned above, this
| approach is quite tedious by hand, so I only work out the
| first few coefficients explicitly. In practice, these are
| almost always computed using numerical software. But for some
| people it may still be interesting to see a direct
| calculation rather than relying on shortcuts.
|
| Here is the direct link to the new section on DFT:
| https://susam.net/fizz-buzz-with-cosines.html#dft
| xbar wrote:
| This is a joy.
| mr_wiglaf wrote:
| Ah so taking the Fourier transform of this function[0]? The
| summation of the fizz and buzz frequencies don't lead to
| perfect peaks for the fizz and buzz locations. I need to
| revisit Fourier cause I would have thought the transform would
| have just recovered the two fizz and buzz peaks not the
| fizzbuzz spot.
|
| [0]: https://www.desmos.com/calculator/wgr3zvhazp
| isoprophlex wrote:
| What a neat trick. I'm thinking you can abuse polynomials
| similarly. If the goal is to print the first, say, 100 elements,
| a 99-degree polynomial would do just fine :^)
|
| EDIT: the llm gods do recreational mathematics as well. claude
| actually thinks it was able to come up with and verify a
| solution...
|
| https://claude.ai/share/5664fb69-78cf-4723-94c9-7a381f947633
| jiggawatts wrote:
| That's the most expletive-laden LLM output I've ever seen.
| ChatGPT would have aborted half way through to protect its pure
| and unsullied silicon mind from the filthy impure thoughts.
| theendisney wrote:
| It would find a therapist contact your employer, your wife
| and your dad.
| flir wrote:
| > LMAOOOOO OKAY SO THE POLYNOMIAL IS LITERALLY SHITTING
| ITSELF
|
| That was a fun read, but I can see that persona quickly
| becoming wearing. I had a "talk like a wiki article" persona
| for a while that worked better (for me) than any attempt to
| inject personality. The greyer the better, when it comes to
| tools.
|
| (Being a child of the internet rather than the classroom my
| abusive solution would be to look up the sequence in OEIS,
| but I think fizzbuzz could be encoded into an L-system quite
| neatly).
| isoprophlex wrote:
| Yes, it's indeed very over the top and one-dimensional.
| However, I've been iterating on this system prompt since
| the early early days of chatgpt.com, and I find that I
| can't really chat with AI systems in their "grey", dry mode
| anymore.
|
| On their default behavior they try too hard to make me like
| them, which I find intolerable. "You're absolutely right!"
| for some reason drives me insane; getting "lmaaoooo my bad
| fam i dun goofed" twenty times a day is equally annoying in
| terms of models being confidently wrong, but somehow the
| lazy shitbag attitude pisses me off less than the goody two
| shoes energy.
|
| And if they're low on crazyness and you force them to be
| crisp and emotionless like a wikipedia article, I notice
| that I tend to trust them more... even though again the
| tendency to bullshit is unchanged, still there.
|
| Somehow this really works for me.
|
| Also when coding it makes it very clear which bits I
| haven't inspected yet because the comments and variable
| names will be super nsfw, thus keeping me on my toes as to
| not accidentally submit PRs filled with "unfuck_json()"
| functions.
| flir wrote:
| > On their default behavior they try too hard to make me
| like them, which I find intolerable. "You're absolutely
| right!"
|
| Yeah, that's what I was trying to avoid, too. Why do we
| have such strong negative reactions to sycophancy? I went
| for something like: "You are a maximally terse assistant
| with minimal affect. Be detailed and complete, but
| brief."
| mikestaas wrote:
| absolute madlad
| drob518 wrote:
| I laughed so hard. Really curious what the pre-prompt was.
| isoprophlex wrote:
| https://claude.ai/share/d855dbf4-6553-4909-ad3e-375b6385e720
|
| "there ya go homie, copy paste ready for whoever needs their
| ai to have some goddamn personality"
| ok123456 wrote:
| I once had a coworker who used the FFT to determine whether
| coordinates formed a regular 2D grid. It didn't really work
| because of the interior points.
| throwaway81523 wrote:
| Where the madness leads:
| https://cspages.ucalgary.ca/~robin/class/449/Evolution.htm
| jmclnx wrote:
| I wonder where this is coming from. I saw on USENET in
| comp.os.linux.misc a conversation about fizzbuzz too. That was on
| Nov 12.
|
| Anyway an interesting read.
| acheron wrote:
| You saw a Usenet post on Nov 12? 2025?
| jmclnx wrote:
| Yes, it was about fizzbuz
| jmclnx wrote:
| Forgot to mention, the subject was "Simple Programming
| Challenge"
| anthk wrote:
| IT and some music/literature niche newsgroups and some
| Paleonthology ones plus a few more are still alive.
| burnt-resistor wrote:
| While it's cute use of mathematics, it's extremely inefficient in
| the real world because it introduces floating point
| multiplications and cos() which are very expensive. The only
| thing it lacks is branching which reduces the chances of a
| pipeline stall due to branch prediction miss.
|
| (The divisions will get optimized away.)
| pbsd wrote:
| This can be translated to the discrete domain pretty easily,
| just like the NTT. Pick a sufficiently large prime with order
| 15k, say, p = 2^61-1. 37 generates the whole multiplicative
| group, and 37^((2^61-2)/3) and 37^((2^61-2)/5) are appropriate
| roots of unity. Putting it all together yields
| f(n) = 5226577487551039623 +
| 1537228672809129301*(1669582390241348315^n +
| 636260618972345635^n) +
| 3689348814741910322*(725554454131936870^n +
| 194643636704778390^n + 1781303817082419751^n +
| 1910184110508252890^n) mod (2^61-1).
|
| This involves 6 exponentiations by n with constant bases.
| Because in fizzbuzz the inputs are sequential, one can further
| precompute c^(2^i) and c^(-2^i) and, having c^n, one can go to
| c^(n+1) in average 2 modular multiplications by multiplying the
| appropriate powers c^(+-2^i) corresponding to the flipped bits.
| burnt-resistor wrote:
| Integer exponentiation is still really, really expensive. 3-4
| modulus operations and a few branches is a lot cheaper.
| Terretta wrote:
| The article conceit is fantastic. That said, is the going-in algo
| wrong?
|
| I see a case for 3 * 5 in here: for n in range(1,
| 101): if n % 15 == 0: print('FizzBuzz')
| elif n % 3 == 0: print('Fizz') elif n % 5
| == 0: print('Buzz') else:
| print(n)
|
| Why?
|
| If we add 'Bazz' for mod 7, are we going to hardcode:
| for n in range(1, 105): if n % 105 == 0: # 3 *
| 5 * 7 print('FizzBuzzBazz') elif n % 15
| == 0: # 3 * 5 print('FizzBuzz')
| elif n % 21 == 0: # 3 * 7 print('FizzBazz')
| elif n % 35 == 0: # 5 * 7 print('BuzzBazz')
| elif n % 3 == 0: print('Fizz') elif n % 5
| == 0: print('Buzz') elif n % 7 == 0:
| print('Bazz') else: print(n)
|
| Or should we have done something like: for n in
| range(1, 105): out = '' if n % 3 == 0:
| out += 'Fizz' if n % 5 == 0: out +=
| 'Buzz' if n % 7 == 0: out += 'Bazz'
| print(out or n)
|
| I've been told sure, but that's a premature optimization, 3
| factors wasn't in the spec. OK, but if we changed our minds on
| even one of the two factors, we're having to find and change 2
| lines of code ... still seems off.
|
| Sort of fun to muse whether almost all FizzBuzz implementations
| are a bit wrong.
| michaelcampbell wrote:
| > Sort of fun to muse whether almost all FizzBuzz
| implementations are a bit wrong.
|
| They're only wrong if they provide output that isn't in the
| spec. Adding "bazz" isn't in the spec, and assuming that
| something indeterminate MIGHT come later is also not part.
| Terretta wrote:
| Yep, that's how people answer.
|
| Folks really _really_ don 't like thinking that "FizzBuzz"
| case maybe shouldn't be there, future extension or factor
| edit or no.
|
| // And as long as we're just manually computing factor times
| factor and typing out the results for it like "FizzBuzz" we
| might as well just hardcode the whole series...
| theendisney wrote:
| I think the reqirement should be to n digits. Then at least
| we can benchmark it.
| theendisney wrote:
| If we are going to be like that we should just increment a var
| by 3,5 or 7 and compare it rather than %3 as the later seems
| expensive.
| econ wrote:
| Made me envision this terrible idea.
|
| arr = [];
|
| y = 0;
|
| setInterval(()=>{arr[y]=x},10)
|
| setInterval(()=>{x=y++},1000)
|
| setInterval(()=>{x="fizz"},3000)
|
| setInterval(()=>{x="buzz"},5000)
|
| setInterval(()=>{x="fizzbuzz"},15000)
| seattle_spring wrote:
| That is beautifully heinous! Nice work.
| pillars001 wrote:
| HN is a great place to learn non-trivial things about trivial
| things, and that's why I like it. My comment won't add much to
| the discussion, but I just wanted to say that I learned something
| new today about a trivial topic I thought I already understood.
| Thank you, HN, for the great discussion thread.
| Someone wrote:
| So, there's a similar way to do it with a function that produces
| one of the characters in "FizBu\nx" and a _while true_ loop that
|
| - increases _i_ on every _\n_ ,
|
| - prints _i_ when that produces _x_ , otherwise prints the
| character
|
| (Disregarding rounding errors)
|
| That would be fairly obfuscated, I think.
| raffael_de wrote:
| This seems like a great benchmark task for LLMs.
| user070223 wrote:
| Inspired by this post & TF comment I tried symbollic regression
| [0] Basically it uses genetic algorithm to find a formula that
| matches known input and output vectors with minimal loss I tried
| to force it to use pi constant but was unable I don't have much
| expreience with this library but I'm sure with more tweaks you'll
| get the right result from pysr import
| PySRRegressor def f(n): if n % 15 == 0:
| return 3 elif n%5 == 0: return 2
| elif n%3 == 0: return 1 return 0
| n = 500 X = np.array(range(1,n)).reshape(-1,1) Y =
| np.array([f(n) for n in range(1,n)]).reshape(-1,1) model =
| PySRRegressor( maxsize=25,
| niterations=200, # < Increase me for better results
| binary_operators=["+", "*"],
| unary_operators=["cos", "sin", "exp"],
| elementwise_loss="loss(prediction, target) = (prediction -
| target)^2",
|
| ) model.fit(X,Y)
|
| Result I got is this:
|
| ((cos((x0 + x0) * 1.0471969) * 0.66784626) + ((cos(sin(x0 *
| 0.628323) * -4.0887628) + 0.06374673) * 1.1508249)) + 1.1086457
|
| with compleixty 22 loss: 0.000015800686 The first term is close
| to 2/3 * cos(2pi*n/3) which is featured in the actual formula in
| the article. the constant doesn't compare to 11/15 though
|
| [0] https://github.com/MilesCranmer/PySR
| Quarrel wrote:
| Great work, I really liked Susam's setup in the article:
|
| > Can we make the program more complicated? The words 'Fizz',
| 'Buzz' and
|
| > 'FizzBuzz' repeat in a periodic manner throughout the
| sequence. What else is
|
| > periodic?
|
| and then I'm thinking ..
|
| > Trigonometric functions!
|
| is a good start, but there are so many places to go!
| makerofthings wrote:
| There are a surprising number of ways to generate the fizzbuzz
| sequence. I always liked this one: fizzbuzz n =
| case (n^4 `mod` 15) of 1 -> show n 6 -> "fizz"
| 10 -> "buzz" 0 -> "fizzbuzz" fb :: IO ()
| fb = print $ map fizzbuzz [1..30]
___________________________________________________________________
(page generated 2025-11-22 23:02 UTC)