Problem 4

左右どちらから読んでも同じ値になる数を回文数という。 2桁の数の積で表される回文数のうち、最大のものは 9009 = 91 × 99 である。

では、3桁の数の積で表される回文数のうち最大のものはいくらになるか。

Problem 4 - PukiWiki

まぁあれです、正直に言うとRuby以外はかなり手抜きしたしR版とかめちゃくちゃ実行速度が遅いです。

基本的には、3桁の数2つの組み合わせを全部取ってきて、そこから積が回文数になっているものを探すという戦略で行きました。
Ruby版だけは高速化のため並び替えたりとかしてますが、他の2言語では範囲内の全ての回文数を探してその最大の数を取っています。

Ruby

def palindromic?(n)
  t = n.to_s
  (t.length/2).times do |i|
    unless t[i] == t[-(i+1)] then
      return false
    end
  end
  return true
end


num_pairs = []

(100..999).each do |i|
  (100..i).each do |j|
    num_pairs << [i,j]
  end
end

num_pairs.sort_by{|i| i[0]+i[1]}.reverse_each do |k|
  if palindromic?(k[0]*k[1]) then
    puts "#{k[0]} x #{k[1]} = #{k[0]*k[1]}"
    break
  end
end

R

split.digit = function(n) {
  d <- n%%10
  if(n%/%100 == 0) {
    return(append(d, (n%/%10)))
  } else {
    return(append(d, split.digit(n%/%10)))
  }
}

is.palindromic = function(t) {
  for(i in 1:(length(t)/2)) {
    if(t[i] != t[length(t)-i+1]) {
      return(FALSE)
    }
  }
  return(TRUE)
}


x <- NULL

for(i in 999:100) {
  for(j in i:100) {
    if(is.palindromic(split.digit(i*j))) {
      x <- append(x, i*j)
    }
  }
}

print(max(x))

Haskell

splitDigit n
    | (div n 100)==0 = (mod n 10):[(div n 10)]
    | otherwise = (mod n 10):splitDigit(div n 10)

joinDigit (x:xs)
    | xs == [] = x
    | otherwise = x+10*(joinDigit xs)

isPalindromic [] = True
isPalindromic (x:xs)
    | xs == [] = True
    | x /= (last xs) = False
    | otherwise = isPalindromic $ init xs

main = print $ maximum $ map joinDigit $ filter isPalindromic $ map splitDigit $ map multT pairs
    where
      pairs = [(x,y) | x<-[100..999], y<-[100..999], y <= x]
      multT (a,b) = a * b