Sam ([info]l33tminion) wrote,
@ 2008-02-26 21:54:00
Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Current mood: quixotic
Entry tags:programming, random

Overthinking and Stupid Programmer Tricks
Fizzbuzz is a simple game. Players take turns counting up in sequence from 1, except all multiples of 3 are replaced with "fizz", all multiples of 5 are replaced with "buzz", and all multiples of both are replaced by "fizzbuzz". So players count:
1, 2, fizz, 4, buzz, fizz, 7, 8, fizz, buzz, 11, fizz, 13, 14, fizzbuzz...

This game has become a popular interview question for programmers; it's simple but many self-identified "programmers" don't have the basic problem-solving skills to tackle it. Of course, programmers sense of humor being what it is, all sorts of odd solutions to the problem have popped up in response. My favorite definition of fizzbuzz(n) is:

['fizzbuzz', 'fizz', 'buzz', n][[n%15,n%3,n%5,0].index(0)]
Aside from being a very weird way of implementing a conditional, this is valid Python and valid Ruby. Nifty!

Dougal Stanton also provided this dramatic solution in Haskall (modified a little for brevity):
import Data.Maybe

fizz = concat $ repeat $ replicate 2 Nothing ++ [Just "Fizz"]
buzz = concat $ repeat $ replicate 4 Nothing ++ [Just "Buzz"]
fizzbuzz = zipWith (maybeWith (++)) fizz buzz
numbers = map (Just . show) [1..]

maybeWith f (Just a) (Just b) = Just (a `f` b) 
maybeWith _ (Just a) Nothing  = Just a
maybeWith _  Nothing (Just b) = Just b
maybeWith _  Nothing Nothing  = Nothing

main = map fromJust $ zipWith (maybeWith const) fizzbuzz numbers
This sort of stuff reminds me of another thing I encountered recently, a regular expresion to "check for primes". The expression in question is:
/^1?$|^(11+?)\1+$/
The first part of this expression matches "" or "1", the vertical bar is a logical or, and the latter part of the expression matches a sequence of two or more ones repeated two or more times. Much less cool than I originally thought it would be, given the title! But it is a regular expression that detects sequences of ones of non-prime length, so you can do the following:
import re
non_prime_length = re.compile(r'^.?$|^(..+?)\1+$',re.DOTALL)
def is_prime(n):
    not non_prime_length.match('X' * n)
That creates a sequence of characters of length n, then checks if the length is prime. This is the sort of thing I'd classify as a "stupid programmer trick", a sort-of clever, not-necessarily-practical, totally silly way of solving a simple problem.

So, to all the programmers out there, what's your favorite stupid programmer trick?

P.S. Incidentally, if you can provide a regular expression such that it actually matches the string representation of only prime (or only non-prime) integers, that would be pretty sweet. A proof that such a thing could not be created would be equally impressive.


(Post a new comment)

Some FizzBuzzes
[info]nertzy
2008-02-27 06:31 am UTC (link)
I did it a few ways in Ruby.

Here's my shortest: 1.upto(?d){|i|m='';[3,5].map{|j|m<<(i%j<1?j<4?'Fizz':'Buzz':'')};puts m>''?m:i}

Tricks:
?d instead of 100 - save one character (the ASCII representation of "d" is 100)
map instead of each - save one character by not caring about the return value of the block
j<1 - save one character for testing if j==0
puts m>''?m:i - check to see if m is empty or not, if it's empty, display the digit

Here's another favorite: puts (1..?d).map{|i|m='';[3,5].map{|j|m<<(i%j<1?'FizzBuzz'[2*j-6,4]:'')};m>''?m:i}

Tricks:
"FizzBuzz" is a single string: this was my arbitrary challenge for this one
(2*j-6): passing in 3 or 5 as j actually gives you a proper string offset
puts: if you call puts on an array it does puts on each entry on its own line

Also, a request. I never use LiveJournal. Could you turn on OpenID posting?

(Reply to this)(Thread)

Re: Some FizzBuzzes
[info]l33tminion
2008-02-27 05:19 pm UTC (link)
Could you turn on OpenID posting

Okay, that should work now.

(Reply to this)(Parent)(Thread)

Re: Some FizzBuzzes
[info]grant@nertzy.com
2008-02-27 10:40 pm UTC (link)
Thanks! Looks like it works.

(Reply to this)(Parent)


[info]kihou
2008-02-27 06:33 am UTC (link)
I think that's going to have to go with balanced parentheses as something regular expressions just can't do. You can do at least some forms of divisibility testing, but you'd need an infinite state machine to handle arbitrary large primes. For a (theoretical computer science) regular expression, you need to take characters one at a time and can't look back, so you'd need an infinite amount of state to keep enough info about previous digits to test divisibility of all (prime) numbers. Of course, this also proves your expression impossible, since TCS regular expressions don't get backrefs.

It is possible to test a decimal string for a number for divisibility by any finite constant set of integers, though.

(Reply to this)

Less cool? I am not too sure...
[info]avinashmeetoo.myopenid.com
2008-03-01 07:56 pm UTC (link)
Hi,

I wrote the blog entry you referred in your article (about the regular expression to check for primes). You wrote that the regular expression is less cool that you thought because it requires as input 1111111111111 (i.e. 13 ones) to check whether 13 is prime or not (and not 13 itself).

I've given a thought to this and I believe you are wrong in your interpretation. 13 and 1111111111111 are strictly equivalent and they are just two different representations of the "concept" that we normally represent with the two symbols 1 and 3. Other perfectly valid representations are XIII (Roman), 1101 (binary) and OFOFO (where F represents five and O one - why not?). A regular expression that takes as input a number in any one of those representations and say whether the concept it represents is prime or not is extremely cool. And this is what /^1?$|^(11+?)\1+$/ is.

Avinash Meetoo - http://www.noulakaz.net/

(Reply to this)(Thread)


[info]l33tminion
2008-03-02 06:17 am UTC (link)
I'll agree that the example you provided is probably not significantly less useful than the one I proposed, although your version probably has higher memory overhead (in storing the string, anyways) for large numbers.

However, I would not agree that there is no significant qualitative difference between those representations. The '1'*n form is a very simple representation. Its language contains strings of arbitrary length, but with only one possible character. There is also a very direct relationship between a property of the string (its length) and the properties of the number. A decimal (or any base system) representation has a higher level of compression and a higher level of complexity.

I would be equally interested to see a regular expression that determined whether a number in binary was prime. Or in Roman numerals, for that matter. Not because it's practical, but because it's interesting.

P.S. I hope you don't take offense at my post. Calling that sort of thing a "stupid programmer trick" doesn't mean that it's not very clever indeed, and I thought your explanation was very well written.

(Reply to this)(Parent)(Thread)


[info]avinashmeetoo.myopenid.com
2008-03-02 06:08 pm UTC (link)
Hi,

Just to clarify something. I am not the one who discovered this regular expression. I just wrote a relatively detailed explanation of what it does.

I don't think it's possible to write a regular expression that determines whether a decimal number is prime or not. The only easy way to do that is to check all divisors from 2 to N-1. Maybe someone has an idea?

(Reply to this)(Parent)(Thread)


[info]l33tminion
2008-03-03 01:13 am UTC (link)
You could divide the problem in two parts:
1. Match all the numbers between 2 and N-1
2. Match only if the string is divisible by a given number

The first seems like it might be doable, but I have no idea how I'd get the second part.

(Reply to this)(Parent)


Create an Account
Forgot your login?
Login w/ OpenID
English • Español • Deutsch • Русский…