본문 바로가기

Julia

오일러 프로젝트 4번(Julia)

문제

앞에서부터 읽을 때나 뒤에서 부터 읽을 때나 모양이 같은 수를 대칭수(palindrome)라고 부릅니다. 두 자리 수를 곱해 만들 수 있는 대칭수 중 가장 큰 수는 9009(= 91 x 99) 입니다. 세 자리 수를 곱해 만들 수 있는 가장 큰 대칭수는 얼마입니까?

풀이

세 자리수 (100 ~ 999) 중에서 두 개를 골라 곱해서 대칭수가 되는지 판별하고, 그렇게 필터링된 결과 중에서 최대값을 고르면 된다.

대칭수를 판별하기에 가장 간편한 방법은 문자열로 변환하여 reverse() 함수를 통해서 뒤집은 결과와 원래 문자열이 같은지를 보면 된다.

ispal(n) = let s = "$n"; s == reverse(s); end

전체 풀이는 다음과 같다. ispal() 함수 사용하여 대칭수를 판별할 수 있으므로 filter() 함수로 대칭수의 목록을 만들고, maximum() 함수를 통해서 최대값을 고르면 된다.

filter(ispal, [x*y for x=100:999, y=100:999]) |> maximum |> println

참고로 max() 함수는 여러 개 인자 중에서 가장 큰 값을 고르는 것이며, maximum() 함수는 배열에서 가장 큰 값을 고르며, 다차원 배열에 대해서는 특정 차원을 선택할 수 있다.)

개선된 풀이

정수를 문자열로 변환하고 다시 정수로 파싱하는 과정이 제법 비용이 크기 때문에 조금 돌아가더라도 회문수 여부를 체크하는 함수를 따로 작성하자.

test(n) = begin
  m, r = n, 0
  while n > 0
    r = r * 10 + n % 10
    n = div(n, 10)
  end
  m == r
end

@time let xs = [x * y for x=100:999, y=100:999]
  filter(test, xs) |> maximum |> println
end

이전 코드의 수행시간이 약 1.6964초이고 개선한 코드는 0.0055초로 개선됐다.