Sudoku solver in CoffeeScript

Posted by Jonas Elfström Tue, 19 Apr 2011 13:46:00 GMT

CoffeeScript is inspired by Ruby and Python but what's most peculiar with it is that it compiles to JavaScript. The generated JavaScript isn't all that bad and it even passes JavaScript lint without warnings.

"Underneath all of those embarrassing braces and semicolons, JavaScript has always had a gorgeous object model at its heart." - Jeremy Ashkenas

About a week ago I stumbled on the very clever Sudoku solver by Peter Norvig. I have nothing (or at least not much) against Python but I pretty soon checked out the Ruby translations of the solver. I then refactored one of the solutions to get a chance to get to know the algorithm better.

Now that I finally installed CoffeeScript the Sudoku solver came to mind. I dived in head first and got in trouble pretty soon. It turns out that Array Comprehensions in CoffeeScript differs some from the List Comprehensions in Python.

1
2
3
def cross(A, B):
       "Cross product of elements in A and elements in B."
       return [a+b for a in A for b in B]

returns an one-dimensional array if you call it with two arrays (or strings).

But in CoffeeScript

cross = (A, B) -> (a+b for a in A for b in B)

returns a two-dimensional array.

The jury is still out on if this is intended or not but either way the array comprehensions in CoffeeScript are still very useful.

EDIT 2011-06-02
It's been decided that this is by design. The issue has been closed.


For the cross-function I ended up with

1
2
3
4
5
6
cross = (A, B) ->
  results = []
  for a in A
    for b in B
      results.push a + b
  results


EDIT 2011-06-02
Using `map` I could have got much closer to the Ruby version.
1
2
cross = (cols, rows) ->
  [].concat (cols.map (x) -> rows.map (y) -> y+x)...
I'm still more of a map/reduce guy than a list comprehension ninja.



You can find the CoffeScript Sudoku solver as a Gist. Compile it with
coffee -c sudoku.coffee
and then run it with
node sudoku.js

I don't know how I missed it but as Trevor pointed out below all you have to do is
coffee sudoku.coffee

    1 2 3 4 5 6 7 8 9
  |------+-----+-----|
A | 4 8 3|9 2 1|6 5 7|
B | 9 6 7|3 4 5|8 2 1|
C | 2 5 1|8 7 6|4 9 3|
  |------+-----+-----|
D | 5 4 8|1 3 2|9 7 6|
E | 7 2 9|5 6 4|1 3 8|
F | 1 3 6|7 9 8|2 4 5|
  |------+-----+-----|
G | 3 7 2|6 8 9|5 1 4|
H | 8 1 4|2 5 3|7 6 9|
I | 6 9 5|4 1 7|3 8 2|
  |------+-----+-----|

Here's the generated sudoku.js.

This is the only CoffeeScript I've ever written but I already like it (more than JavaScript). Please correct me if I strayed from the CoffeeScript way.

Posted in Ruby, JavaScript | 6 comments

Comments

    1. Avatar
      Trevor Burnham Wed, 20 Apr 2011 19:01:01 GMT

      Nice post. By the way, you can just do coffee sudoku.coffee instead of coffee -c sudoku.coffee; node sudoku.js.

    2. Avatar
      Jonas Elfström Wed, 20 Apr 2011 19:35:18 GMT

      Didn’t know that. Thanks!

    3. Avatar
      Jonas Elfström Wed, 04 May 2011 19:32:59 GMT

      I didn’t write nearly enough about why I like CoffeeScript. Fortunately Trevor sums it up very good at http://www.pragprog.com/magazines/2011-05/a-coffeescript-intervention

    4. Avatar
      Jonas Elfström Thu, 19 May 2011 18:49:27 GMT

      “CoffeeScript is well done and more convenient to use than JS, provided you buy into the Python-esque significant space and the costs of generating JS from another source language. But semantically it’s still JS.” - Brendan Eich http://brendaneich.com/2011/01/harmony-of-my-dreams/

    5. Avatar
      Jakob Eriksson Wed, 25 May 2011 06:59:39 GMT

      I also think your blog is so wonderful to keep sight of! :-P

      Spambottarna smickrar, trevligt.

    6. Avatar
      Jonas Elfström Tue, 13 Sep 2011 14:02:21 GMT

      The list comprehension issue has been reopened because of this post CoffeeScript Comprehensions Are Broken

      A reply from Trevor Burnham

      The issue

Comments are closed