Introduction
This series explores CoffeeScript, a new programming language that is built on top of JavaScript and offers a clean syntax. CoffeeScript compiles into efficient JavaScript. In addition to running the JavaScript in a web browser, you can use it with technologies such as Node.js for server applications. In Part 1, you learned to set up the CoffeeScript compiler and use it to create code that's ready to run in a browser or server.
In this article, explore the CoffeeScript language by solving several programming problems from Project Euler (see Resources for more information about Project Euler). The examples walk you through the use of functions, ranges, comprehensions, block statements, arrays, and some objectoriented aspects of CoffeeScript.
Download the source code used in this article.
Functions, ranges, and comprehensions
The first Project Euler problem you'll tackle is Problem 6 (see Resources), which asks you to calculate the sum of the squares of the first natural numbers, the square of the sum of those same numbers, and then give the difference. For this problem you will use the CoffeeScript ReadEvaluatePrintLoop (REPL). Listing 1 shows the code and corresponding output from the REPL session.
Listing 1. Problem 6 from the REPL
coffee> square = (x) > x*x [Function] coffee> sum = (nums) > nums.reduce (a,b) > a+b [Function] coffee> diff = (nums) > (square sum nums)  (sum nums.map square) [Function] coffee> diff [1..100] 25164150
Breakdown:
 In the REPL, define a function. (As mentioned in Part 1, CoffeeScript celebrates the functional programming
nature of JavaScript, discarding much of JavaScript's Clike syntax
that makes it cumbersome to do elegant functional programming.)
The example in Listing 1 defines a function called
square
and states that it takes a single parameter and returns the product of multiplying that parameter by itself (squaring it). The REPL then tells you that you've defined a function.  Define another function called
sum
that takes a single parameter: an array.Sum
then invokes thereduce
method on the array.The
reduce
method is not added by CoffeeScript but is part of JavaScript proper (added in JavaScript 1.8). Thereduce
method is similar to the reduce function in Python or the fold function in Haskell or Scala. It takes a function and goes from left to right on the array, applying the function to the previous value returned by the fold and the next value in the array. CoffeeScript's compact function syntax makesreduce
easy to use. In this case, the function passed to reduce is specified by(a,b) > a + b
. This is a function that takes two values and adds them together, thus causing all of the elements of the array to be added together.  Create a function called
diff
, which takes an array of numbers, calculates two subexpressions, then subtracts them. The first passes the array to the sum function and then takes the result and passes it to thesquare
function.CoffeeScript allows you to omit parentheses in many cases so there can be no confusion. For example,
square sum nums
is equivalent tosquare(sum(nums))
. The second subexpression invokes themap
method of the array, which is another JavaScript 1.8 method that takes another function as its input. It then applies that function to each member of the array, creating a new array from the results. The example in Listing 1 uses the square function as the input parameter to map, giving you an array whose elements are the squares of the input array. Then, you simply pass this to the sum function to get the sum of the squares.  Pass the appropriate array of numbers into the
diff
function to solve Problem 6, using a range[1..100]
.This range is equivalent to an array of all of the numbers from 1 to 100, inclusive. If you had wanted it to be exclusive you would have written
[1...100]
, using three periods instead of two. Passing this todiff
gives you the solution to Problem 6.
Let's back up a little and look at Project Euler Problem 1 (see Resources), which asks you to sum up all of the integers less than 1000 that are divisible by either 3 or 5. You might think this would be the easiest of the Project Euler problems. You could easily solve it just using functions and ranges, as in Problem 6. With the CoffeeScript comprehensions feature, however, you can create the elegant solution in Listing 2.
Listing 2. Solving Problem 1 using comprehensions
coffee> (n for n in [1..999] when n % 3 == 0 or n % 5 == 0).reduce (x,y) > x+y 233168
It's always nice to solve a problem with a single line of code, and
CoffeeScript's concise syntax lends itself to oneliners. The solution in
Listing 2 creates a list of all of the integers that are
multiples of 3 or 5 by using a comprehension. It is generated by starting
with the range [1..999]
but using only the
values that are divisible by 3 or 5. Another
reduce
is then used to sum the values up. The
REPL evaluates this one line of code and prints the solution to the
problem.
The next section tackles slightly more difficult problems and explores CoffeeScript further.
Block statements, arrays, and files
Project Euler Problem 4 (see Resources) asks you to find the largest palindrome that is the product of two threedigit numbers. There are many ways to solve this problem; Listing 3 shows one way.
Listing 3. Testing for palindromes
isPal = (n) > digits = [] while n > 0 digits.push(n % 10) n = Math.floor(n / 10) len = digits.length comps = [0..len/2].map (i) > digits[i] == digits[leni1] comps.reduce (a,b)> a && b vals = [] vals.push(x*y) for x in [100..999] for y in [100..999] pals = vals.filter (n) > isPal(n) biggest = pals.reduce (a,b) > Math.max(a,b) console.log biggest
 Define a function called
isPal
, which will test if a number is a palindrome. This function is a little more complicated than those defined so far. It has seven lines of code in its body.You probably noticed that CoffeeScript does not use curly brackets ({ }) or any other explicit mechanism to denote the beginning and ending of the function. It uses whitespace (indentation), much like Python, and starts with the same notation to denote a function: the parameter list followed by the greater than arrow (>). Then you create an empty array for the digits of the numbers and begin a while loop. This loop is similar to the while loop from JavaScript (or C, Java, and so on). The predicate (
n > 0
) does not require parentheses around it. The body of the loop is indented further to indicate that it is part of the loop. Inside the loop you chop off the last digit of the number, push it to the front of the array, and then divide the number by 10, discarding the remainder. This results in an array of the digits of the original number. You could also replace the loop simply withdigits = new String n
, convertingn
to a string. The rest of the code works asis.  After you have the array of digits, create an array that is half the
length of this array. Use the
map
function to turn each element of this array into a Boolean value corresponding to whether the digits equidistant from the beginning and ending of the array are equal.If all of these come out true, then you have a palindrome. To test the work, simply use another reduce function, this time 'anding' together the Booleans.
 Now that you have the
isPal
function defined, use it to test for palindromes. Test all of the numbers that are the product of two threedigit numbers. Create two comprehensions, each ranging from the smallest threedigit number (100) to the largest (999).
 For each of these, take the product and put it into an array.
 Use another
reduce
function to find the largest element in the array. Finally, this element is printed out using console.log.  Save this to a file.
Listing 4 shows how to execute and time the solution.
Listing 4. Executing the solution for Problem 4
$ time coffee p4.coffee 906609 real 0m2.132s user 0m2.106s sys 0m0.022s
The script in Listing 4 takes over two seconds to execute on a fast computer, largely due to the compound comprehension that generates 899*899 = 808,201 values to test (many of them duplicates). As an additional exercise, you can optimize the Listing 3 code. (Hint: Converting the number to a string is actually much faster.)
Project Euler Problem 22 (see Resources) requires you to perform a complex calculation on a list of strings. You will read the list from a file, parse the contents into a list, sort it and convert each string to a number, and then sum the products of each number and its position in the list. Problem 22 lets you see how files work in CoffeeScript. There's also some string manipulation and more array magic. Listing 5 shows the solution.
Listing 5. Working with files in CoffeeScript
path = "/path/on/your/computer/names.txt" fs = require "fs" contents = fs.readFileSync path, "utf8" strs = contents.split(",") names = strs.map (str) > str[1 .. str.length  2] names = names.sort() vals = names.map (name) > name.split("") vals = vals.map (list) > list.map (ch) > 1 + ch.charCodeAt(0)  'A'.charCodeAt(0) vals = vals.map (list) > list.reduce (a,b) > a+b vals = ((i+1)*vals[i] for i in [0...vals.length]) total = vals.reduce (a,b) > a+b console.log total
 Save the file. There's a link in the problem description, or you can
use the source code included with this
article. Change the value of the path variable to the absolute path to
the file on your computer.
CoffeeScript does not include any special libraries for working with files. Instead, it leverages node.js and its
fs
module. Load thefs
module using therequire
function.  Read the contents of the file using
fs.readFileSync
. The file looks like "MARY", "PATRICIA", and so on. It starts out as a single string, so use thesplit
method to break it apart at the commas.Each string still has double quotes (") at the beginning and end of the string. To get rid of them, use the
map
function and replace each string with a slice. Ifstr
is a string, thenstr[1 .. str.length 2]
is a substring starting with the second character and ending with the next to last character. The code will precisely remove the first and last characters—those pesky double quotes. Slicing strings can be very convenient.  After you have a list of strings without double quotes, you're ready
to sort. Use array's
sort
method. You need to convert the strings to a number where each character becomes its place in the alphabet (A > 1, B > 2, C > 3, and so on). Turn each string into an array of characters using the
split
method again.  Map each character to a numeric value using the
charCodeAt
method.  Add up these numeric values using another
reduce
operation.
 Turn each string into an array of characters using the
 Multiply each number by its position in the list and sum these
together using another comprehension. Create a new array where each
element is generated by multiplying an element from the previous array
along by its position. Sum up the elements of this array by using one
more
reduce
operation, and print out the total.
Once again, you can save the work to a file, and then execute and time it, as shown in Listing 6:
Listing 6. Timing the execution of Problem 22
$ time coffee p22.coffee 871198282 real 0m0.133s user 0m0.115s sys 0m0.013s
It takes less than 0.2 seconds to execute the solution to Problem 22. It took almost as many lines of English to describe what was to be calculated as it did lines of code to perform the calculation. This is a great example of CoffeeScript's succinct syntax. You can imagine the example taking many more lines of code in other programming languages.
In this section, you have solved more difficult problems using some of the important features of CoffeeScript. The next section examines a crucial feature in CoffeeScript: objectoriented programming.
Objectoriented CoffeeScript
As mentioned in Part 1, a major pain point of JavaScript is its "unusual" style of objectoriented programming (OOP). It is unusual simply because classbased OOP is so overwhelmingly common. CoffeeScript makes classbased OOP.
Your next challenge is to use CoffeeScript's OOP to solve Project Euler Problem 35 (see Resources). In Problem 35, you're told that a circular prime is a special kind of prime number with the property that you can perform any rotation of its digits and still have a prime number. The code in Listing 7 uses OOP to calculate the number of circular primes less than one million.
Listing 7. Counting circular primes
class PrimeSieve constructor: (@max) > @nums = [2..@max] for p in @nums d = 2*p while p != 0 and d <= @max @nums[d2] = 0 d += p isPrime: (n) > @nums[n2] != 0 thePrimes: > @nums.filter (n) > n != 0 class CircularPrimeGenerator extends PrimeSieve genPerms = (num) > s = new String num x = (for i in [0 ... s.length] s[i+1 ... s.length].concat s[0..i]) x.map (a) > parseInt(a) isCircularPrime : (n) > perms = genPerms(n) len = perms.length primePerms = perms.filter (p) => @isPrime(p) len == primePerms.length theCircularPrimes: > (p for p in @thePrimes() when @isCircularPrime(p)) max = process.argv[2] generator = new CircularPrimeGenerator max console.log "Number of circular primes less than #{max} is #{generator.theCircularPrimes().length}"
 Create a class called
PrimeSieve
, which implements the classic Sieve of Erasthones algorithm for calculating all of the primes less than a particular value.The
@
sign denotes a property of a class and is also shorthand for'this.'
. Therefore,@nums = [2..@max]
is equivalent tothis.nums = [2 .. this.max]
.Class methods are indicated by their name followed by a semicolon and the function definition. The first method, called
constructor
, is a constructor for the class. For example, newPrimeSieve(100)
would cause the constructor to be invoked with 100 passed in asmax
and assigned tothis.max
. Our constructor builds the sieve and stores the primes in the@nums
member variable. It then declares two more methods:isPrime
andthePrimes
. ThethePrimes
method uses an array filter to remove the composite numbers from@nums
.  Declare a subclass of
PrimeSieve
, calledCircularPrimeGenerator
. CoffeeScript usesclass ... extends
syntax, like many popular OOP languages. This class will inherit the constructor, member variables, and methods ofPrimeSieve
. It has the:genPerms
method for generating all of the permutations of a given number by rotating the digits of the number.isCircularPrime
method that generates all of the permutations of a given number and removes any numbers in the list of permutation that are not a prime. If the filtered list has all of the same elements as the unfiltered list, then the number must be a circular prime.theCircularPrimes
method that generates a list of all of the circular primes using a comprehension.
@thePrimes
method defined in the superclass and then simply filter out the primes that are not circular.After you have two classes defined, you're ready to use them to solve the problem.
 Listing 7 was written to
take a commandline argument that is the max value to be used for
calculating the primes and the circular primes. All commandline
arguments can be accessed using
process.argv
. The first two values in this array are the command and the script, so it isprocess.argv[2]
that contains the first parameter to be used by the script.Create an instance of
CircularPrimeGenerator
using the max value passed in to the script.Print out the number of circular primes that were found using console.log.
In this example, you used another convenient feature of CoffeeScript: stringinterpolation to create the string that is passed to console.log.
Conclusion
In this article, you explored many of the features of CoffeeScript. Its concise syntax and functional programming features let you elegantly implement many common algorithms. At the same time, CoffeeScript also provides simplified objectoriented programming. For whatever kind of problem you need to solve, you'll find that CoffeeScript's syntax simplifies your task.
Stay tuned for the next part of this series, which will get more pragmatic and use CoffeeScript for clientside scripting in a web application.
Download
Description  Name  Size 

Article source code  cs2.zip  19KB 
Resources
Learn
 "Your first cup of CoffeeScript" series (developerWorks): Explore
the popular CoffeeScript programming language, which is built on top of
JavaScript.
 "Your first cup of CoffeeScript, Part 1: Getting started" (developerWorks, December 2011): Learn about the perks of CoffeeScript for developers, set up the CoffeeScript compiler, and use it to create code that is ready to run in a browser or server.
 Project Euler: Explore challenging
mathematical and computer programming problems that will require more than
just mathematical insights to solve.
 Project Euler Problem 1: Add all the natural numbers below one thousand that are multiples of 3 or 5.
 Project Euler Problem 4: Find the largest palindrome made from the product of two threedigit numbers.
 Project Euler Problem 6: What is the difference between the sum of the squares and the square of the sums?
 Project Euler Problem 22: What is the total of all the name scores in the file of first names?
 "Just what is Node.js?" (developerWorks, May 2011): Understand how Node is a serverside JavaScript interpreter that changes the notion of how a server should work.
 Node.js: Use this launching point to learn more about the application.
 "Use Node.js as a full cloud environment development stack" (developerWorks, April 2011): See how Node.js can be combined with cloud technologies.
 "Highperformance Web development with Google Web Toolkit and Eclipse" (developerWorks, October 2009): Compiling into JavaScript is not a new idea. So if you are a fan of the Java programming language, you should read this article.
 "All aboard! An introduction to Rails 3" (developerWorks, March 2010): CoffeeScript is now part of Ruby on Rails. Check out the other new features in Rails in this article.
 CoffeeScript project on Github: Start here to learn about CoffeeScript.
 "Create Ajax applications for the mobile Web" (developerWorks, March 2010): Get more information about using Ajax in mobile web applications.
 developerWorks Web development zone: Find articles covering various webbased solutions. See the Web development technical library for a wide range of technical articles and tips, tutorials, standards, and IBM Redbooks.
 developerWorks podcasts: Listen to interesting interviews and discussions for software developers.
 developerWorks technical events and webcasts: Stay current with developerWorks technical events and webcasts.
 developerWorks on Twitter: Join today to follow developerWorks tweets.
 developerWorks ondemand demos: Watch demos ranging from product installation and setup for beginners to advanced functionality for experienced developers.
Get products and technologies
 Node.js: Download Node.js and start easily building scalable network programs.
 IBM product evaluation versions: Download or explore the online trials in the IBM SOA Sandbox and get your hands on application development tools and middleware products from DB2, Lotus, Rational, Tivoli, and WebSphere.
Discuss
 The developerWorks community: Connect with other developerWorks users while exploring the developerdriven blogs, forums, groups, and wikis.
 Find other developerWorks members interested in web development.
Comments
Dig deeper into Web development on developerWorks
 Overview
 New to Web development
 Technical library (tutorials and more)
 Forums
 Open source projects
 Events

developerWorks Premium
Exclusive tools to build your next great app. Learn more.

dW Answers
Ask a technical question

Explore more technical topics
Tutorials & training to grow your development skills