SRT Polyglotting Euler Problems
I was first introduced to the term polyglot when I was in high school.  Our French class did a presentation at a Foreign Language Day.  I have this vague recollection that the theme of the day was "Polyglots Have More Fun". I've always liked the word, so I was thrilled to see Neal Ford using it.

In any case, Bill Wagner started things off at SRT by working the Project Euler problems in C#/LINQ.  Marina Fedner joined in, addressing the problems in Ruby.  Darrell Hawley tackled them with Python, and I (Dianne Marsh) jumped in with Scala.  This article compares the solutions to Problem 1, in each of the languages.  We don’t maintain that these are optimal solutions, in any of these languages, and we’re happy to take and post feedback containing better solutions.

Problem 1:

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.

Here are the SRT “solutions”, in alphabetical order.

C# 3.0/LINQ:

var nums = from n in
           Generators.NumberSequence(0, 1000)
           where ((n % 3 == 0) || (n % 5 == 0))
           select n;
var answer = nums.Sum();

// note: Bill put this in a library for future use

public static IEnumerable<int> NumberSequence(int from, int to)
{
    do
    {
        yield return from++;

    } while (from < to);

}

Python:

print sum([x for x in range(1,1000) if x%5==0 or x%3==0])

Ruby:

answer = (0..999).select {|a| a%3 ==0 || a%5==0}
puts answer.inject {|sum, n| sum+n}

Scala:

  val nums = 3 until 1000
  val somenums = nums.filter(x => (x % 3 == 0 || x % 5 ==0))
  var sum = 0

  somenums.foreach(sum += _)
  println (sum)

The Ruby and Python implementations are really concise! I was left wondering if Bill and I could have done better jobs in our respective languages.

Without rethinking the approach, but just eliminating local variables, I was able to get the Scala version down to a more respectable:

    sum = 0

    (1 to 1000).filter(x => (x %3 == 0 || x % 5 ==0)).foreach( sum += _)

    println (sum)

Then, I looked at the C#.  The only thing bloating the C# implementation is the missing “Range” function, which Bill rightly put into a library for later use as NumberSequence.  The comments in his blog for Problem 1 noted a built-in function

Enumerable.Range(0, 1000)

that could be used to simplify the code and obviate the need for that function.  So, the C# code refactored to:

var nums = from n in
           Enumerable.Range(0, 1000)
           where ((n % 3 == 0) || (n % 5 == 0))
           select n;
var answer = nums.Sum();

So there you have it: 4 implementations, fairly similar in their approach but using different syntax, to Problem 1.   If you wish, add a comment to this blog indicating which you prefer, and why!  And, perhaps also indicate if your preferred implementation is in your typical programming language or if you like what you see in another, better.

 

Published Tuesday, April 08, 2008 3:15 PM by dmarsh
Filed under: , , , , ,

Comments

# re: SRT Polyglotting Euler Problems@ Tuesday, June 03, 2008 12:56 PM

Here's my Groovy sample:

def sum = 0

1.upto(999) {

 sum += (it.mod(5) == 0 || it.mod(3) == 0) ? it : 0

}

println "sum is ${sum}."

I wonder if we can compact it further...

Leave a Comment

(required) 
(required) 
(optional)
(required)