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.
My solution to Problem 5 has been posted here.
Pingback: Project Euler in Clojure – Problem 3 « Proctor It
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??
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.
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])
([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])
(for [x (range 1 5) y (range 1 5) :while (>= x y) ] [x y] )
([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!
Pingback: Project Euler in Clojure – Problem 5 « Proctor It