Project Euler Problem 4 Solution

Question

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 \times 99.

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

Clojure

#!/usr/bin/env clojure
(defn palindrome? [n]
  (= (seq (str n)) (reverse (str n))))

(defn palindromes [limit]
  (filter palindrome? (for [a (range 100 1000) b (range a 1000)] (* a b))))

(println (reduce max (palindromes 1000)))
$ time clojure palindrome.clj
real   0m1.213s
user   0m2.255s
sys    0m0.196s

Go

package main

import "fmt"

func IsPalindrome(number int) bool {
    n := number
    reversed, digit := 0, 0
    for n > 0 {
        digit = n % 10
        reversed = reversed*10 + digit
        n /= 10
    }
    return number == reversed
}

func main() {
    product, max := 0, 0
    for a := 100; a < 1000; a++ {
        for b := a; b < 1000; b++ {
            product = a * b
            if product > max && IsPalindrome(product) {
                max = product
            }
        }
    }
    fmt.Println(max)
}
$ go build -o palindrome palindrome.go
$ time ./palindrome
real   0m0.002s
user   0m0.000s
sys    0m0.002s

Haskell

isPalindrome ::  Integer -> Bool
isPalindrome n = show n == reverse (show n)

main ::  IO ()
main = print $ maximum [prod | a <- [100..999], b <- [a..999], let prod = a * b, isPalindrome prod]
$ ghc -O2 -o palindrome palindrome.hs
$ time ./palindrome
real   0m0.046s
user   0m0.046s
sys    0m0.000s

JavaScript

const isPalindrome = (s) => s === s.split("").reverse().join("")
let max = 0
for (let i = 100; i < 1000; i++) {
  for (let j = 100; j < 1000; j++) {
    const s = (i * j)
    if (s > max && isPalindrome(s.toString())) {
      max = s
    }
  }
}
console.log(max)
$ time node --use-strict palindrome.js
real   0m0.083s
user   0m0.082s
sys    0m0.008s

Python

#!/usr/bin/env python
print(max(a * b for a in range(100, 1000) for b in range(a, 1000) if str(a * b) == str(a * b)[::-1]))
$ time python3 palindrome.py
real   0m0.318s
user   0m0.310s
sys    0m0.008s

Ruby

#!/usr/bin/env ruby

class Integer
  def palindromic?
    digits = self.to_s.split('')
    return digits == digits.reverse
  end
end

max = 0
(100..999).each do |a|
  (a..999).each do |b|
    product = a * b
    if product > max and product.palindromic?
      max = product
    end
  end
end
puts max
$ time ruby palindrome.rb
real   0m0.284s
user   0m0.276s
sys    0m0.008s

Rust

fn is_palindrome(number: u64) -> bool {
    let mut n = number;
    let mut reversed = 0;
    while n > 0 {
        let digit = n % 10;
        reversed = reversed * 10 + digit;
        n /= 10;
    }
    number == reversed
}

fn main() {
    let mut largest = 0;
    for a in 100..1000 {
        for b in 100..1000 {
            let product = a * b;
            if product > largest && is_palindrome(product) {
                largest = product;
            }
        }
    }
    println!("{}", largest);
}
$ rustc -C target-cpu=native -C opt-level=3 -o palindrome palindrome.rs
$ time ./palindrome
real   0m0.002s
user   0m0.000s
sys    0m0.002s