Monday, March 31, 2008

Finger Exercises

I've been working on a bunch of little projects recently that individually don't amount to much, yet. I should have something to post about that soon.

In the mean time, here is a cute little problem (via Uri to the fun with Perl list):

What is an easy way to get all possible combinations of Y/N of length 5? (i.e., "YYYYY", "YYYYN", etc.)

Coming up with a solution to this exact problem seemed to cry out for a list comprehension:

[[a,b,c,d,e] | let l a

but as soon as I wrote that, I saw how unsatisfactory it was. A better solution would produce all possible combinations of Y and N for a list of any integer n > 0:

yn i = (iterate f [""]) !! i where f l = map ('Y':) l ++ map ('N':) l

This problem itself isn't very interesting, but it's good to have little diversions like this when you want to take a break while the coffee is steeping, waiting for the Guinness to settle, or whatnot. (Something that's more than a function from the Prelude, but less involved than something from Project Euler.)

Do you have any cute little "finger exercise" problems like these? I'd love to hear about them!

Which is about as good as I can see in "Haskell golf" (which is like Perl golf except you're going for the least inelegance). That's a bad solution though, because the tails vary faster than the heads, and thus there is no sharing (watch "length (yn 500)" eat up all your memory!). This is better:

Here is a fun relatively simple problem that actually appeared in a real program for me a few years ago:Generate all unique lists of N positive integers whose sum is equal to M or equivalently Generate all unique ways to place M identical balls in N different buckets as I like to think about it. For example with M = 3 and N = 3 it should give (in any order): [[0,0,3], [0,1,2], [0,2,1], [0,3,0], [1,0,2], [1,1,1], [1,2,0], [2,0,1], [2,1,0], [3,0,0]] Writing a recursive function that solved this was pretty easy, but I suspect it can be written as a oneliner by someone with better Haskell-Fu than me. :) Happy hacking.