Monday, January 23, 2012

Functional Programming, Scala, LWJGL, Space Invader (note the lack of plural) and Programmers Exchange...

I've been mulling on the problem of how one might go about writing a simple video game, like Space Invaders, in Scala (using LWJGL) in as pure a functional programming design approach as possible. I'd planned to write my post shortly after Thanksgiving. However, I let the merrymaking of the holidays get the better of me and postponed writing the post.

Finally, on the way home this evening, I decided to spend at least 5 minutes writing up a question to post on Stack Overflow. Then, when I went to go about generating the post, I realized that Stack Exchange (the parent site of Stack Overflow and many other sites analogous to Stack Overflow) had a site more suited to my general question, Programmers Exchange. I then spent the five minutes writing the start of a post. And now, +2 hours later, I finally hit the submit button.

You can find the resulting post here. I'm looking forward to all the learnin' headed my way. I have the uncomfortable feeling I am going to feel a whole lot stupider around functional programming and Scala before I begin to grow the feeling of confidence emerging from nurturing my growing competence confidence. Or something like that, anyway. {smirk}

Tuesday, November 22, 2011

LWJGL, full screen and Win7 issue...

Summary:
I couldn't get full screen mode to work. The spaceinvaders demo app (provided right in the LWJGL download) would just silently crash straight back to Eclipse. There was no error output at all. It turns out Direct3D doesn't work well with Vista/Win7. And there's a simple VM argument to turn it off, "-Dsun.java2d.d3d=false". 


Details:
Ah, the joys of computer configuration complexity. It ensures I spend lots of time on damn near useless tangents. After a nice time burn like this, I so can see why developing for only one specific platform can be quite desirable. Anywho...

So, in my quest towards writing a space invaders clone in Scala, I decided to first get the space invaders Java application supplied as a demo in the main LWJGL download's demo folder. I was able to get all the .java files copied into the proper path. And then was happy when it worked first time with almost no editing. I did go and clean up several warnings that were shown by the compiler.

And then I decided to try and turn on full screen mode (as opposed to the windowed mode that was the default). The application would clearly start, appear to get close to running (full screen of black would appear) and then it just sat there until I clicked with the mouse. Then it would crash right back to Eclipse with no error output whatsoever. Quite frustrating.

After spending several hours slowly going through the code placing copious amounts of System.out.println() statements and lots of try{...} catch (Throwable t) {t.printStackTrace()}, I finally narrowed the intermittent failures down to a line in LWJGL itself, Display.sync(60). I have the LWJGL source attached so I can examine the related source code easily.

After examining the code for sync() and then evaluating whether I wanted to go to the trouble of making the LWJGL source editable, I decided to stop and see if I could Google and see if anyone else was having the issue. It only took 5 minutes using the starting search terms of "LWJGL full screen crash" to discover a possible answer on a forum message thread (related StackOverflow topic). For Vista/Win7, I must pass a VM argument of "-Dsun.java2d.d3d=false" to turn off Direct3D. Of course, as soon as I did that, everything sprang up and worked like a charm.

Lesson Learned:
Google with simplest set of key words as soon as possible. It might save a whole bunch of time attempting to isolate an intermittent issue.

Sunday, November 6, 2011

I'm back from my gaming hiatus...

I've been away enjoying my personal time. I have not done anything related to coding other than my standard JavaEE stuff at work. I've kept studying all the Scala blogs and have been following the Scala tag on StackOverflow and CodeReview sites. I've continued to want to dive right in and just start coding. It is so obvious to me that I would find designing and writing code very enjoyable in Scala. And I am slowly finding it more and more laborious to produce all the boilerplate necessary when I coding in Java, even with the assistance of code completion and code generation tools in Eclipse.

As I am returning to creating time to play directly with Scala again, I am not finding myself all that motivated to continue on the Life project. I don't want to code a little and then blog alot. It just feels too much like doing Java boilerplate; a huge amount of writing with a very small portion that actually does the interesting work. So, for now I am postponing my Scala Life project. I will very likely return to it.

I am finding myself interested in playing around with Scala and creating a simple retro style video game (from the early 80s); Asteroids, Space Invaders, PacMan Missile Command, Defender, etc. These are the games I initially reproduced when I started learning to program on the TI99/4a 30 years ago. And I don't care that there are hundreds of variations of these games. I am not writing it to be consumed by anyone else. I am writing it to feel the delight of achievement, the thrill of viceral learning, the joy of being playful yet inquisitive while minimize the occurrences of and duration of breakdowns, frustrations (configuration challenges, deployment errors, etc.) and technical challenges.

I have spent about 8 hours researching how to go about writing an OpenGL game using Scala. I looked at a number of possible game engines. And it turns out there is an interesting project called LWJGL (LightWeight Java Game Library) which ties together all sorts of C++/C libraries and APIs such that Java programs can utilize them. And anything Java can utilize, Scala can also. So, I am going to do a Scala + LWJGL project. And for now, I am planning to write a very simple version of Space Invaders. Whoohoo!

Wednesday, July 27, 2011

Odersky talk (16 minutes) at OSCON...

Typesafe and Martin Odersky are working very hard on the parallel and concurrency problems. And all in Scala. This talk is so exciting as it shows how wide and deep they are approaching the problem. And how Scala's unique OO + FP approach to software engineering is ideal for this problem domain.

Sunday, July 24, 2011

Project Euler - Problem 002 - Learning to think the Scala way...

This post continues my journey to learn Scala by using the problems off of the web-site projecteuler.com (descriped in my original post here: http://fromjavatoscala.blogspot.com/2011/05/project-euler-problem-001-learning-to.html)

Problem Statement - 002:


Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.



Visualization/Examples:
  1. Natural numbers in Fibonacci series not exceeding 100 with a multiple of 2
    1. Numbers not exceeding 100 = 1 2 3 ... 98 99 100
    2. Fibonacci Series = 1 2 3 5 8 13 21 34 55 89
    3. Multiples of 2 = 1 2 3 5 8 13 21 34 55 89
    4. Sum = 2 + 8 + 34 = 44


Mathematical Notation:
TBD

Test Cases:

  1. floor = (0 and 1 as 1), ceiling = 100, multiple = 2 , answer = 2 + 8 + 34 = 44 (produced by hand)
  2. floor = (0 and 1 as 1), ceiling = 4000000, multiple = 2, answer = ? (produce from code)

Code Implementation Approaches:
The first and most intuitive approach for me at this time is to go one by one for each two-number sum starting from floor (0 and 1) to ceiling (100) and test a number for whether it is divisible by 2. If so, add it to a total I am keeping. And when the loop is finished, I will have my answer. Here's the small Scala Object class I created to perform the work:

object Problem002 extends App {
  //http://projecteuler.net/index.php?section=problems&id=2
  override def main(args : Array[String]) : Unit = {
    javaWithoutSemicolons
  }
  def javaWithoutSemicolons : Unit = {
    var first = 0   //floor
    var second = 1  //floor
    val ceiling = 100
    val multiple = 2
    var sum = 0
    var next = 0
    while (second <= ceiling) {
      next = first + second
      first = second
      second = next
      if (first % multiple == 0)
        sum = sum + first
    }
    Console.println("javaWithoutSemicolons.sum=" + sum)
  }
}

Just like for problem 1, this code looks almost identical to the Java code I would write, essentially Java without semicolons. Note the presence of the "var"s which is a strong indication I am using the "imperative" approach again (as contrasted with the "functional" approach) to composing a solution.

The next step, again like last time, is to "refactor" this code to move towards the functional paradigm. Let's start by creating a function which returns a list of Fibonacci numbers less than a passed in value. And then use our now familiar filter and sum to obtain our value.

def headedTowardsFunctional : Unit = {
  def fibList (ceiling: Int, floor: Int = -1): List[Int] = {
    var values = List[Int]()
    var first = 0
    if (first > floor)
      values = first :: values
    var second = 1
    var next = 0
    while (second <= ceiling) {
      next = first + second
      first = second
      if (first > floor)
        values = first :: values
      second = next
    }
    values.reverse
  }
  val ceiling = 100
  val multiple = 2
  val fibs = fibList(ceiling)
  val fibsFilter = fibs.filter(n => (n % multiple == 0))
  val sum = fibsFilter.sum
  Console.println("headedTowardsFunctional.sum=" + sum)
}

I have successfully removed all the vars from the main method. However, there are still several in my fibList function. There are a number of approaches possible here. The first that comes to mind is to collect a list of all the numbers in the series which fit in an Int. While it sounds huge, it isn't. There are less than a fifty (47 to be precise). Because the series is exponential in nature, not linear, the entire thing fits in a tiny list.

So, here's a version which separates the production of the whole series up to the highest value an Int can hold. And then that list is easily handled with a for comprehension.

def functional1 : Unit = {
  val fibsAll = {
    var fibs = 0 :: List()
    var current = fibs.head
    var next = 1
    var continue = true
    while (continue) {
      current = fibs.head
      fibs = next :: fibs
      continue = ((0.0 + next + current) <= Int.MaxValue)
      if (continue)
        next = next + current
    }
    fibs.reverse
  }
  def fibList (ceiling: Int, floor: Int = -1): List[Int] = {
    val values =
      for (i <- fibsAll if ((i > floor) && (i < ceiling))) yield i
    values.reverse
  }
  val ceiling = 100
  val multiple = 2
  val fibs = fibList(ceiling)
  val fibsFilter = fibs.filter(n => (n % multiple == 0))
  val sum = fibsFilter.sum
  Console.println("functional1.sum=" + sum)
}

And it is just a very simple step from there to take this fully functional (excluding the function used by fibAll). And while we're at it, let's move the ceiling and multiple constants into being root method parameters:

def functional2(ceiling: Int, multiple: Int) : Unit = {
  val fibsAll = {
    //generate all 47 for an Int
    var fibs = 0 :: List()
    var current = fibs.head
    var next = 1
    var continue = true
    while (continue) {
      current = fibs.head
      fibs = next :: fibs
      continue = ((0.0 + next + current) <= Int.MaxValue)
      if (continue)
        next = next + current
    }
    fibs.reverse
  }
  def fibList (ceiling: Int, floor: Int = -1): List[Int] = {
    val values =
      for (i <- fibsAll if ((i > floor) && (i < ceiling))) yield i
    values.reverse
  }
  val sum = fibList(ceiling).filter(n => (n % multiple == 0)).sum
  Console.println("functional2.sum=" + sum)
}

I don't particularly like the function I have created for fibsAll. It "smells" imperative with it's ample var-ness. How might I go about making it better, more in the Scala style? I've googled other implementations of Fibonacci in Scala, but all are fixated on producing the sum for n elements (and several are incorrect in that they seem to skip the first two root elements (0, 1) starting with (1, 2) instead. The correct sequence starts as [0, 1, 1, 2, 3, 5...] and not [1, 2, 3, 5...]. Even the projecteuler.com Problem 2 states the beginning of the sequence incorrectly at [1, 2, 3...].

After posting my current implementation of fibAll to CodeReview (like StackOverflow, but more specifically for code reviews) and going several comment cycles with Leonardo Lucena there, I finally have a much better solution for for implementing fibsAll. Here it is:

def functional3(ceiling: Int, multiple: Int) : Unit = {
  def fibs(a: Int = 0, b: Int = 1): Stream[Int] = Stream.cons(a, fibs(b, a + b))
  val fibsAll = fibs().takeWhile(n => (n > -1)).toList
  def fibsList (ceiling: Int, floor: Int = -1): List[Int] = {
    for (i <- fibsAll if ((i > floor) && (i < ceiling))) yield i
  }
  val sum = fibsList(ceiling).filter(n => (n % multiple == 0)).sum
  Console.println("functional3.sum=" + sum)
}

So what is the fibs function doing? And what is Stream.cons? And while it's recursive, it's not able to be optimized using the @tailrec annotation. The fibs function is simulating an infinite series, in this case based on Fibonacci. Stream is an object that enables temporary state (via recursion) for a function. It behaves similar to a List, but waits to evaluate the passed function until it is required to do so which in this case does not happen until the takeWhile call when assigning the val fibsAll. As to the inability to do the @tailrec optimization; the actual depth required by this series is relatively shallow at 47. However, if the takeWhile had been replaced with a take(1000) or the like, the function would likely abort with a stack overflow. At this time, I don't exactly know how to approach refactoring the function so as to remain consistent with the functional/recursive approach and enable the @tailrec annotation.

So, this we are at the most functional we can be at this time. Now, for the inevitable - change...

Requirements change (keeping it real):
Or said a slightly different way, slightly changing and expanding the original problem so as to explore code design, refactoring and performance. Using the same basic model in the original problem, find the answer for the following set of problems:

  1. floor = 0, ceiling = 100, multiple 2
  2. floor = 0, ceiling = 4000000, multiple 2
  3. floor = 0, ceiling = 4000000, multiple 3
  4. floor = 0, ceiling = 4000000, multiples 2, 3, 5, 7
  5. floor = 100, ceiling = 4000000, multiple 2


Code Refactoring (fancy way of saying "adapting"):
While I was developing the solution pathway above, I did so with an eye towards the likelyhood that the requirements might change (or in this case, expand). Hence, my placing the floor in the fibsList function. Given this new set of problems, we are most of the way there. We just need to adjust for a set of multiples, as opposed to a single one. And since we already solved that in Problem 1, we just have to graft the solution there into this code. Here's what it looks like:

def functional4(ceiling: Int, multiples: List[Int]) : Unit = {
  def fibs(a: Int = 0, b: Int = 1): Stream[Int] = Stream.cons(a, fibs(b, a + b))
  val fibsAll = fibs().takeWhile(n => (n > -1)).toList
  def fibsList (ceiling: Int, floor: Int = -1): List[Int] = {
    for (i <- fibsAll if ((i > floor) && (i < ceiling))) yield i
  }
  val sum = fibsList(ceiling).filter(n => {multiples.exists(x => (n % x) == 0)}).sum
  Console.println("functional4.sum=" + sum)
}

It's very pleasing to be able to pluck out and reuse part of what we learned from Problem 1. And, we're done! On to Problem 3...soon. {smirk}

Sunday, May 22, 2011

Project Euler - Problem 001 - Learning to think the Scala way...

I stumbled across an interesting web-site called ProjectEuler. The Wiki page gives a very good overview of the site.

I realized it would be a very interesting way for me to learn Scala syntax in a low risk and fun environment, small puzzles. Additionally, my son has expressed an interest in learning how to program. I figured this might be a great way to get him started, too. I will get back to the Scala-life series again, I promise.

My intention is to show the exact text of the problem from the web-site. Then, I would go through the process of taking the word problem and "visualizing" it; draw and possibly even animate it. Once the problem is visual, then I would then talk about possible solution approaches centering on declarative, imperative and functional. And then finally, I will transform it into both mathematical notation and Scala code.

So, let's jump right in. This post may be subjected to some frequent edit/update cycles after being published as I find my way to the right balance in working through designing this.

Problem Statement - 001:


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.



Visualization/Examples:
  1. numbers below 10 with multiples of 3 or 5
    1. Natural numbers below 10 = 1 2 3 4 5 6 7 8 9
    2. Multiples of 3 = 1 2 3 4 5 6 7 8 9
    3. Multiples of 5 = 1 2 3 4 5 6 7 8 9
    4. Multiples only = 3 5 6 9
    5. Sum = 3 + 5 + 6 + 9 = 23
  2. numbers below 20 with multiples of 3 or 5
    1. Natural numbers below 20 = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
    2. Multiples of 3 = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
    3. Multiples of 5 = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
    4. Multiples only = 3 5 6 9 10 12 15 18
    5. Sum = 3 + 5 + 6 + 9 + 10 + 12 + 15 + 18= 78


Mathematical Notation:
TBD

Test Cases:

  1. floor = 1, ceiling = 10, multiples = 3 and 5, answer = 3 + 5 + 6 + 9 = 23 (provided in problem statement)
  2. floor = 1, ceiling = 20, multiples = 3 and 5, answer = 3 + 5 + 6 + 9 + 10 + 12 + 15 + 18 = 78 (produced by hand)
  3. floor = 1, ceiling = 1000, multiples = 3 and 5, answer = ? (produce from code)

Code Implementation Approaches:
The first and most intuitive approach for me at this time is to go one by one for each number from floor (1) to ceiling (10) and test a number for whether it is divisible by 3 or divisible by 5. If so, add it to a total I am keeping. And when the loop is finished, I will have my answer. Here's the small Scala Object class I created to perform the work:

object Problem001 extends App {
  //http://projecteuler.net/index.php?section=problems&id=1
  override def main(args : Array[String]) : Unit = {
    javaWithoutSemicolons
  }
  def javaWithoutSemicolons : Unit = {
    val floor = 1
    val ceiling = 10
    val multiple3 = 3
    val multiple5 = 5
    var sum = 0
    for (i <- floor until ceiling)
      if ((i % multiple3 == 0) || (i % multiple5 == 0))
        sum = sum + i
    Console.println("javaWithoutSemicolons.sum=" + sum);
  }
}

This code looks almost identical to the Java code I would write, essentially Java without semicolons. Note the presence of the "var" for "sum". This is referred to as the "imperative" approach (as contrasted with the "functional" approach) to composing a solution. So, how might one go about moving this towards the more functional approach which is gently promoted by advanced Scala developers (and not so gently by functional programmers who have recently, if not reluctantly, adopted Scala)? We find a way to ensure everything remains "immutable"; i.e. there are no "var" entities defined. Additionally, we don't explicitly loop, but leave that to the internal implementations of appropriate classes and functions. Here's an updated version of a Scala class Problem001 with the new method "headedTowardsFunctional" demonstrating a version of the code moved substantially closer towards the functional goal:

object Problem001 extends App {
  //http://projecteuler.net/index.php?section=problems&id=1
  override def main(args : Array[String]) : Unit = {
    javaWithoutSemicolons
    headedTowardsFunctional
  }
  def javaWithoutSemicolons : Unit = {
    val floor = 1
    val ceiling = 10
    val multiple3 = 3
    val multiple5 = 5
    var sum = 0
    for (i <- floor until ceiling)
      if ((i % multiple3 == 0) || (i % multiple5 == 0))
        sum = sum + i
    Console.println("javaWithoutSemicolons.sum=" + sum);
  }
  def headedTowardsFunctional : Unit = {
    val floor = 1
    val ceiling = 10
    val multiple3 = 3
    val multiple5 = 5
    val numberRange = floor until ceiling
    val validMembers = numberRange.filter(n => {(n % multiple3 == 0) || (n % multiple5 == 0)})
    val sum = validMembers.sum
    Console.println("headedTowardsFunctional.sum=" + sum);
  }
}

In this new method, everything from "numberRange" down is actually a function. As such, we can can use function chaining to reduce the last four lines of code down to one. Here's a new method "mostlyFunctional" with this simplification:

def mostlyFunctional : Unit = {
    val floor = 1
    val ceiling = 10
    val multiple3 = 3
    val multiple5 = 5
    Console.println("mostlyFunctional.sum=" + (floor until ceiling).filter(n => {(n % multiple3 == 0) || (n % multiple5 == 0)}).sum)
  }

Now, to find out the answer to the ProjectEuler problem, I will leave you to figure out how to run this code in either Scala's REPL and/or in your favorite IDE with a Scala plug-in. For those of you who are brand new to programming period, here's a link to a separate page where I take you step-by-step through the process of getting set up so you can get started. And now for a "real world" surprise, a requirements change...

Requirements change (keeping it real):
Or said a slightly different way, slightly changing and expanding the original problem so as to explore code design, refactoring and performance. Using the same basic model in the original problem, find the answer for the following set of problems:

  1. floor = 1, ceiling = 1000, multiples 2 and 5
  2. floor = 1, ceiling = 10000, multiples 3, 7 and 10
  3. floor = 100, ceiling = 1100, multiples 3 and 5
  4. floor = 1, ceiling = 1000, multiples 2 through 10
  5. floor = 1, ceiling = 1000000, multiples 2, 3, 5, 7 and 11


Code Refactoring (fancy way of saying "adapting"):
So, how might we go about arranging the code so as to more optimally handle these problems while exploiting other features of Scala. And maybe even adding some more function programming?

The very first and most obvious refactoring is to move the variable definitions out of the body of the function and into the method definition. Luckily, Scala makes this both simple to do and even simpler to use. Here's the first pass at doing so.

mostlyFunctionalWithParameters(1, 10, 3, 5)
...
  def mostlyFunctionalWithParameters(floor: Int, ceiling: Int, multiple3: Int, multiple5: Int) : Unit = {
    Console.println("mostlyFunctionalWithParameters.sum=" + (floor until ceiling).filter(n => {(n % multiple3 == 0) || (n % multiple5 == 0)}).sum)
  }

And it is more functional design to remove the side-effects, of which Console.println() is in this case. The result of this change looks like this:

Console.println("functionalWithParameters.sum=" + functionalWithParameters(1, 10, 3, 5))
...
  def functionalWithParameters(floor: Int, ceiling: Int, multiple3: Int, multiple5: Int) : Int = {
    (floor until ceiling).filter(n => {(n % multiple3 == 0) || (n % multiple5 == 0)}).sum
  }

Most of the time, the value for floor is going to 1. So, wouldn't it be nice to be able to provide a default so it doesn't have to be supplied unless it's different. Here's how that looks:

Console.println("functionalWithParametersDefaultFloor.sum=" + functionalWithParametersDefaultFloor(10, 3, 5))
...
  def functionalWithParametersDefaultFloor(ceiling: Int, multiple3: Int, multiple5: Int, floor: Int = 1) : Int = {
    (floor until ceiling).filter(n => {(n % multiple3 == 0) || (n % multiple5 == 0)}).sum
  }

Optional parameters (any for which a default is provided) must appear at the end of the method's list of parameters. This enables the client to specify by name or position all the required parameters and then selectively specify the optional parameters by name.

So, we now have a pure functional method. However, we are still only allowing for two multiples to be specified. And two of our new problems identify more than two multiples. So, we must re-arrange things so as to enable any number of multiples to be passed in. Scala's simplest and most preferred way to do this is with a List. Rather than try to explain it, here's the code that initially implements it.

Console.println("functionalWithParameters2Multiples.sum=" + functionalWithParameters2Multiples(10, List(3, 5)))
...
    def functionalWithParameters2Multiples(ceiling: Int, multiples: List[Int], floor: Int = 1) : Int = {
    (floor until ceiling).filter(n => {(n % multiples.head == 0) || (n % multiples.tail.head == 0)}).sum
  }

So, the method's signature (parameter specification) is now allowing n multiples. We must now figure out how to check against all of the entries in "multiples" to see if the modulo is 0. The first number that returns a modulo of 0 means we need to indicate the number is valid to be added to the sum. The most obvious way to change this is to create a function which takes the current number as a parameter and then returns true if any entry in the multiples list can be evenly divided by it. That looks something like this.

Console.println("functionalWithParametersNMultiples.sum=" + functionalWithParametersNMultiples(10, List(3, 5)))
...
  def functionalWithParametersNMultiples(ceiling: Int, multiples: List[Int], floor: Int = 1) : Int = {
    def isMultiple(n: Int) : Boolean = {
      var result = false
      var list = multiples
      while (!result && (list != Nil)) {
        result = (n % list.head == 0)
        list = list.tail
      }
      result
    }
    (floor until ceiling).filter(n => {isMultiple(n)}).sum
  }

I like the fact that Scala allowed me to create a helper function within the method that needed it. And notice how the helper function had access to the method's parameters. I didn't have to pass it the "multiples" parameter. It was already in scope for my function.

Now, the "isMultiple" function is still of the imperative style (note there are two variables defined as var). So, what's required to convert this function to be much more of the "functional style"? Not relying upon the vars. And from what I can tell, not being an experienced functional programmer myself, it will tend in the direction of being recursive, i.e. a method that calls itself. If that confuses you, don't worry, it does me too. And for me, it's also an ingrained big NO-NO! For stack based languages (which Java is), it's problematic to use recursion as a stack overflow is so easy to bumble into. However, Scala is not Java and so one is encouraged to find the functional recursive way to resolve a method like "isMultiple". Here's my first bash at it:

Console.println("functional.sum=" + functional(10, List(3, 5)))
...
  def functional(ceiling: Int, multiples: List[Int], floor: Int = 1) : Int = {
    def isMultiple(n: Int) : Boolean = {
      def isMultipleA(list: List[Int]) : Boolean = {
        if (list == Nil)
          false
        else
          if (n % list.head == 0)
            true
          else
            isMultipleA(list.tail)
      }
      isMultipleA(multiples)
    }
    (floor until ceiling).filter(n => {isMultiple(n)}).sum
  }

And there you have it. Moving all the way from the original hard coded "Java without Semicolons" original to the fully functional conclusion. A full version of the final Scala Object class is just beyond the "Extra Bonus Thinking Credit" section.

UPDATE 2011/Jul/16 - 14:21 CDT:
While I was happy with being able to write the recursive loop above when implementing isMultiple(), I was annoyed as it still had a imperative feel to it. The Scala collection library offers numerous ways to solve this kind of problem. And I am just new enough to Scala, it seemed a better way to solve it was just outside my reach of understanding (partly my intuition has not developed around the collections and partly because the Scala syntax is still pretty distracting to me with all the "optional" aspects). However, my mind kept drifting back to this particular aspect of this solution and I continued to be irritated by it.

So, today I decided to try and scratch the itch. I wanted to see if there was some way to write a Scala one-liner for this. There is for the original problem (you can see it above in the mostlyFunctional() implementation - instead of defining the constants above, just place the literals into the 5th line which does all the processing). However, I wanted a one-liner for my "extended requirements" version.

I quickly stumbled upon the "exists()" method in the collections library on List. That seemed to be the right method to use. Now, how to get the two collection library methods, "filter" and "exists" to work together in a single line. I got the right solution the first time. However, I had to take a couple stabs at it as I kept getting the syntax incorrect. Man, am I looking forward to having all the syntax occur as automatic and intuitive to me. It's SO distracting right now.

Anyway, here's the solution where the recursive isMultiple() has been replaced with the exists() method:

Console.println("functional.sum=" + functional(10, List(3, 5)))
...
  def functional2(ceiling: Int, multiples: List[Int], floor: Int = 1) : Int = {
    (floor until ceiling).filter(n => {multiples.exists(x => (n % x) == 0)}).sum
  }

I am very excited about Scala and leveraging it's collections library. It's freaking AWESOME!


Extra Bonus Thinking Credit:
For extra bonus credit, there is a solution that is O(1) for this particular problem. Care to see if you can figure it out?

All Code Collected in Once Place (from above):

object Problem001 extends App {
  //http://projecteuler.net/index.php?section=problems&id=1
  override def main(args : Array[String]) : Unit = {
    javaWithoutSemicolons
    headedTowardsFunctional
    mostlyFunctional
    mostlyFunctionalWithParameters(1, 10, 3, 5)
    Console.println("functionalWithParameters.sum=" + functionalWithParameters(1, 10, 3, 5))
    Console.println("functionalWithParametersDefaultFloor.sum=" + functionalWithParametersDefaultFloor(10, 3, 5))
    Console.println("functionalWithParameters2Multiples.sum=" + functionalWithParameters2Multiples(10, List(3, 5)))
    Console.println("functionalWithParametersNMultiples.sum=" + functionalWithParametersNMultiples(10, List(3, 5)))
    Console.println("functional.sum=" + functional(10, List(3, 5)))
  }
  def javaWithoutSemicolons : Unit = {
    val floor = 1
    val ceiling = 10
    val multiple3 = 3
    val multiple5 = 5
    var sum = 0
    for (i <- floor until ceiling)
      if ((i % multiple3 == 0) || (i % multiple5 == 0))
        sum = sum + i
    Console.println("javaWithoutSemicolons.sum=" + sum)
  }
  def headedTowardsFunctional : Unit = {
    val floor = 1
    val ceiling = 10
    val multiple3 = 3
    val multiple5 = 5
    val numberRange = floor until ceiling
    val validMembers = numberRange.filter(n => {(n % multiple3 == 0) || (n % multiple5 == 0)})
    val sum = validMembers.sum
    Console.println("headedTowardsFunctional.sum=" + sum)
  }
  def mostlyFunctional : Unit = {
    val floor = 1
    val ceiling = 10
    val multiple3 = 3
    val multiple5 = 5
    Console.println("mostlyFunctional.sum=" + (floor until ceiling).filter(n => {(n % multiple3 == 0) || (n % multiple5 == 0)}).sum)
  }
  def mostlyFunctionalWithParameters(floor: Int, ceiling: Int, multiple3: Int, multiple5: Int) : Unit = {
    Console.println("mostlyFunctional.sum=" + (floor until ceiling).filter(n => {(n % multiple3 == 0) || (n % multiple5 == 0)}).sum)
  }
  def functionalWithParameters(floor: Int, ceiling: Int, multiple3: Int, multiple5: Int) : Int = {
    (floor until ceiling).filter(n => {(n % multiple3 == 0) || (n % multiple5 == 0)}).sum
  }
  def functionalWithParametersDefaultFloor(ceiling: Int, multiple3: Int, multiple5: Int, floor: Int = 1) : Int = {
    (floor until ceiling).filter(n => {(n % multiple3 == 0) || (n % multiple5 == 0)}).sum
  }
  def functionalWithParameters2Multiples(ceiling: Int, multiples: List[Int], floor: Int = 1) : Int = {
    (floor until ceiling).filter(n => {(n % multiples.head == 0) || (n % multiples.tail.head == 0)}).sum
  }
  def functionalWithParametersNMultiples(ceiling: Int, multiples: List[Int], floor: Int = 1) : Int = {
    def isMultiple(n: Int) : Boolean = {
      var result = false
      var list = multiples
      while (!result && (list != Nil)) {
        result = (n % list.head == 0)
        list = list.tail
      }
      result
    }
    (floor until ceiling).filter(n => {isMultiple(n)}).sum
  }
  def functional(ceiling: Int, multiples: List[Int], floor: Int = 1) : Int = {
    def isMultiple(n: Int) : Boolean = {
      def isMultipleA(list: List[Int]) : Boolean = {
        if (list == Nil)
          false
        else
          if (n % list.head == 0)
            true
          else
            isMultipleA(list.tail)
      }
      isMultipleA(multiples)
    }
    (floor until ceiling).filter(n => {isMultiple(n)}).sum
  }
  def functional2(ceiling: Int, multiples: List[Int], floor: Int = 1) : Int = {
    (floor until ceiling).filter(n => {multiples.exists(x => (n % x) == 0)}).sum
  }
}

Wednesday, May 4, 2011

Portal 2 distraction (and other excuses for no posts here in awhile)...

I have yet to write the first pass of the Scala version of Life modeled on the Java version from the previous post. Partly it's because work has become quite overwhelming recently. Partly it's because I know once I start writing Scala, I am going to dread and resist writing much more Java. And then finally, it's because Portal 2 came out and I am spending tons of time playing it.

I will return to the Scala Life thread and continue. In the meantime, I found a link which I thought might be very useful to those who do Java and want to see practical uses for Scala. This Wiki is great at presenting some code in Java and then presenting the Scala code pointing out why it's a desirable improvement. Enjoy!