Over the holidays I created a new game, Peg Solitaire. Click on the link to go play!
Everybody loves palindromes, right? I do, at least. That's why I was excited when I learned that every number can be a palindrome when it's written in the appropriate base. There is a trivial proof for this property: any number N > 3 is a palindrome in base N-1 because it may be written "11". So here is my solution, in Haskell, to this CodeChef problem, that finds the smallest base that makes any given number a palindrome.
isPalindromeInBase :: Integer -> Integer -> Bool isPalindromeInBase value base = step leftmost 1 where leftmost = base ^ floor(log(fromInteger value) / log(fromInteger base)) step left right | left <= right = True | digit left == digit right = step (left `div` base) (right * base) | otherwise = False digit position = (value `div` position) `mod` base smallestPalindromeBase :: Integer -> Integer smallestPalindromeBase 1 = 2 smallestPalindromeBase 2 = 3 smallestPalindromeBase value = step 2 where step base | base >= value || isPalindromeInBase value base = base | otherwise = step (base + 1) main = interact (unlines . map (show . smallestPalindromeBase . read) . tail . lines)
This is certainly not the fastest solution possible. Indeed it is downright naive. But hopefully the logic is clear.
I released Fishing Girl just under a month ago and yesterday I broke 5000 sales. Thank you, everyone, for your support! For me, knowing so many people are having fun with my game is the ultimate reward.
I'm also very happy that Fishing Girl was so well received by the gaming press. I've been collecting reviews of the game and I've linked them all below, in vaguely chronolgical order.
Fishing Girl has also appeared elsewhere on the web and I've collected some of those links, too. This certainly isn't an exhaustive collection but it highlights some of the more interesting references I've stumbled on.
Any more Fishing Girl sightings you'd like to point out? Let me know in the comments!
I put together a trailer for my new game, Fishing Girl.
I recently made the transition from running my web server on Apache to running it on Nginx. Well, I made the switch at the start of the summer, but only now is my Nginx configuration stable. One of the biggest obstacles I encountered trying to get Nginx to do what I want was a lack of documentation. The official documentation is anemic and I found examples hard to come by. So now I'd like to share parts of my nginx.conf file that cover some common use cases that I found frustrating to implement.
I would like all of the URLs for ericw.ca to be without the "www." prefix. Indeed, that is their canonical form. This configuration snippet uses the 301 Moved Permanently status to redirect users arriving at "www.ericw.ca" to "ericw.ca".
server { server_name www.ericw.ca; rewrite ^(.*) http://ericw.ca$1 permanent; } server { server_name ericw.ca; # The rest of the configuration... }
You can see this in action if you go to www.ericw.ca.
SpinFour now has a free lite version available so you can give the game a spin before you buy it. The lite version restricts you to the easiest difficulty level while upgrading to the full game lets you take on a real challenge.
SpinFour, my new game for iPhone and iPod Touch, is now available for sale on the iTunes App Store for only $1.99. SpinFour is a new spin on Connect Four that lets you rotate the board by rotating your device. It's a fun twist on a classic game, if you trust my opinion about my own game!
As you can see, ericw.ca has a new look. I decided I wanted a simplified layout with everything relevant available directly from the home page. I also wanted a more minimalist aesthetic to match. I'm really happy with the new design, but let me know in the comments what you think.
I've made even more changes under the hood. I switched to VPS hosting by Linode. I upgraded to Pylons 0.9.7 which now sits behind nginx instead of Apache. I use Mercurial for version control instead of Subversion. You can browse my public repositories. Very soon I'll document my epic struggle to configure nginx and hg!
With another new design of ericw.ca I wanted to look back at the designs that have come and gone. I put together a history in screenshots of the four major revisions. I still have a copy of all my old designs, so those pictures were taken in Chrome just this morning. Hopefully you enjoy poking through the history as much as I enjoyed unearthing it.
So tonight I was helping a friend with a CS 134 assignment that involved a recursive solution to the Knight's Tour problem. The assignment included a rather ugly solution in Java and I wondered what a comparable solution in Haskell might look like. I spent the past few minutes hacking together such a function.
tourTo :: Int -> (Int,Int) -> [[(Int,Int)]] tourTo n finish = [pos:path | (pos,path) <- tour (n*n)] where tour 1 = [(finish, [])] tour k = [(pos', pos:path) | (pos, path) <- tour (k-1), pos' <- (filter (`notElem` path) (jumps n pos))] jumps n (r, c) = filter onBoard [(r+2, c+1), (r+1, c+2), (r-2, c+1), (r+1, c-2), (r+2, c-1), (r-1, c+2), (r-2, c-1), (r-1, c-2)] where onBoard (r, c) = r >= 1 && c >= 1 && r <= n && c <= n
It works (as far as I can tell) but it's unbearably slow. Two optimizations come to mind: using a map rather than a list to store the visited squares and using a heuristic to select the next move location. The latter is implemented in the Java version; if motivation strikes I'll post a better/faster(/harder/stronger) version.
Recently my DVD drive, an LG GSA H22N, stopped functioning in Vista. Why? I'm not entirely sure. At some point between reboots the drive disappeared from Windows Explorer and started reporting a Code 39 error (i.e., a corrupt or missing driver) in the Device Manager. I tried both uninstalling/reinstalling the driver and physically disconnecting/reconnecting the device unsuccessfully.
The solution I discovered, via Google and the Comment Ça Marche forums, was a registry hack in an INF file. I have made the fix available on my site in the hopes of saving some future person the vast amounts of agony I suffered in finding a fix. To apply the fix, download the file then right-click it and select "install".