FizzbuzzΒΆ

The fizzbuzz test is a pretty good determinate of ability to code.

It has a low false negative rate - that is if you can code, its pretty hard to fail. It also has a low false positive rate - if you cannot code, you simply wont pass. As such it is apparently depressing why it is still a necessary evil - I can attest to sitting slackjawed as candidates could not understand a SELECT

query let alone attempt a for loop.

I am not a big fan of programming puzzles like codility. I think they certainly have their place - I suspect as ongoing development for coders. Having an hour or two a week just to work on Project Euler problems would sharpen anyone’s saw.

It must be admitted that I have only seen early candidates fail so amazingly. In general there is a pool of people who apply for every programming gig going, and will have CVs tuned to get through the doors. But there is a reason they don’t get hired and so are available to interview the first day you post the ad.

This is why recruitment is an ongoing investment.

I however have flamed out over the more complex puzzles. I remember happily designing a scalable architecture for some pretend web app, discussing the benefits and costs of Rabbit MQ, and then being asked to write a routine to calculate prime numbers, whilst the director of Engineering harangued looking like the dog with the bone if he saw a missed optimisation. I have never yet turned round in an interview and said shut the fuck up and let me write on the board. But it was touch and go.

As such, lets look at fizzbuzz, and Python and Tail Call Recursion.

Todo

show to AST for this and how elimating tail call could elimnate the stack.

def fb(i, n, result):
    if i == n:
        return result
    elif i % 15 == 0:
       result.append("FizzBuzz")
    elif i % 3 == 0:
       result.append("Fizz")
    elif i % 5 == 0:
       result.append("Buzz")
    else:
       result.append(i)
    return fb(i+1, n, result)

#print fb(1,999,[])

def fb2(i, n, result):
    if i == n:
        return result
    elif i % 15 == 0:
       result.append("FizzBuzz")
    elif i % 3 == 0:
       result.append("Fizz")
    elif i % 5 == 0:
       result.append("Buzz")
    else:
       result.append(i)
    return (lambda: fb2(i+1, n, result))

#this now returns a function that when called ( a() )
# returns the next recursion
    
    
# http://paulbutler.org/archives/tail-recursion-in-python/
# basicakky turning the recursion into a whle loop
# I have expanded out the params 
def tail_rec(fun):
   def tail(fun):
      a = fun
      while callable(a):
         a = a()         # here a is a function that returns a function
                         # that returns the next recursive step
                         # essentially we convert the recursion into a while
                         # loop of each step in the recusrion.
                         # instead of the recursive function calling itself
                         # we make a while loop call it.
      return a
   return (lambda *x: tail(fun(*x)))

fbr = tail_rec(fb2)
print fbr(1,2000,[])


"""
if we use fb in tail_rec it still recurses.
SO what is going on?

the inner part of tail_rec takes any callable and calls it in a while loop
till it returns its halt condition.

This block is then returned as an anonymous function.
So we convert any recursive function into a lambda function that
returns a function that unwinds the recursive function

Now we make that recursive function at its tail, not call itself,
but return a lambda that returns its "call myself"

so...

fbr is now a lambda function that given <params> will
repeatedly set a = a() for the 



"""

But if I exceed pythons recursion depth limit

1001