Project Euler in Clojure – Problem 4

In trying to learn Clojure and wrap my head around good functional programming, and hoping to learn more idiomatic Clojure, I have started working through the Project Euler problems. In doing this, I have also setup a repository on github.com to keep track of my progress, which can be found at https://github.com/stevenproctor/project-euler-clojure.  My approach to Problem 3 can be found here.

Problem 4 of Project Euler is described as:

Find the largest palindrome made from the product of two 3-digit numbers.

The solution I came up with is:

(ns project-euler.core
  (:require [clojure.string :as string]))

(defn is-palindrome? [s]
 (= (str s) (string/join (reverse (str s)))))

(defn problem4 []
 (apply max (filter is-palindrome? (for [x (range 100 1000) y (range 100 1000)] (* x y)))))

As I want to use the join function in the clojure.string namespace, I added the :require keyword and aliased clojure.string as string using the :as keyword from the namespace macro.

The function is-palindrome? converts the value into a string, reverses the stream of characters in the string and then joins them back together and then compares it with the value as a string.

As defined problem4 does the meat of the work, by using a for loop over the set of of values from 100 to 999 for the binding of x and y, and multiplies x and y for each combination. This set is then filtered against the is-palindrome function, and the filtered sequence is then passed to the max function via apply.

Again, I would love comments and suggestions on my solution to this problem, and if there are tweaks to make it more Clojure-ish.

**Update**
My solution to Problem 5 has been posted here.

–Proctor

, ,

  1. #1 by Sonia Hamilton on May 30, 2012 - 23:36

    Hi Proctor – a nice solution. I’m doing a similar thing (deliberate practice, katas), but working through the 4clojure.com exercises first.

    A possible performance improvement – in the *for* you’re calculating each number twice (eg x = 100 y = 101 then x = 101 y =100). Can you think of a better way of doing this?

    PS which WordPress plugin are you using to nicely format your code??

    • #2 by Proctor on May 31, 2012 - 16:09

      Sonia,

      I have done some of the exercises on 4clojure.com as well, as well as the Clojure Koans. I had also been hearing off and on about Project Euler, so I decided I might try some of these problems as well. I figured I might as well blog about my solutions so that I could get feedback, so this is where I started.

      I thought about the fact that I would likely be doing extra multiplication as you pointed out, but was unsure if there was a way to do something along the lines of (for [x (range 100 1000) y [x 1000] …..). Now that you bring that up, I will have to try it out and report back on my findings.

      As far as the WordPress plugin, I am simply using the put a sourcecode wordpress tag feature that one gets with a blog at wordpress.com which can be found here.

      I would be curious to see your solutions 4clojure.com if you decide to post them as you progress on your journey of learning Clojure as well.

      –Proctor

      • #3 by Sonia Hamilton on June 1, 2012 - 06:51

        Hi Proctor, to reduce the number of loops you could use a :while in your list comprehension. For example:

        (for [x (range 1 5) y (range 1 5)] [x y])
        gives:
        ([1 1] [1 2] [1 3] [1 4] [2 1] [2 2] [2 3] [2 4] [3 1] [3 2] [3 3] [3 4] [4 1] [4 2] [4 3] [4 4])

        whereas:
        (for [x (range 1 5) y (range 1 5) :while (>= x y) ] [x y] )
        gives:
        ([1 1] [2 1] [2 2] [3 1] [3 2] [3 3] [4 1] [4 2] [4 3] [4 4])

        In your case the extra multiplications aren’t a worry, but this may come in handy for more expensive calculations.

        I’ll probably start posting my 4clojure problems once I get into the more interesting ones. I’ve done the first 70 problems so far, but these early ones are more focussed on learning the mechanics of the language. I had a look at Clojure Koans and Euler too – I’ll get on to them later 🙂

        Thanks for the pointer on code formatting, I’ve setup SyntaxHighlighter on my blog!

        Sonia.

  1. Project Euler in Clojure – Problem 3 « Proctor It
  2. Project Euler in Clojure – Problem 5 « Proctor It

Leave a comment