d라이브러리









[오일러 프로젝트] 세 자릿수를 곱해 만들 수 있는 가장 큰 대칭수는? 조커

 

영화 ‘조커’의 주인공 아서 플렉은 광대 일을 하며 코미디언을 꿈꿉니다. 
하지만 모두가 미쳐가는 코미디같은 세상에서 점점 악당의 모습으로 변해가죠. 
그런데 그 일이 실제로 일어났습니다. 한 오일러 프로젝트 문제 때문이었죠. 
이 기사를 읽고 있는 독자 여러분, 앞으로 저를 ‘홍커’라고 불러줄래요?

 

 

일요일, 토마토, 오디오, 기러기, 구로구, 이 낱말들의 공통점은 무엇일까요? 바로 순서대로 읽거나 거꾸로 읽어도 같은 단어입니다. 수학에서도 같은 성질을 가진 수가 있습니다. 121이나 43234같이 왼쪽 또는 오른쪽에서 읽어도 같은 수를 대칭수 또는 ‘팰린드롬 수’라고 합니다.


대칭수는 앞뒤가 똑같은 성질 때문에 유희 수학에서 많이 다뤄졌습니다. 1984년 미국의 컴퓨터과학자 프레드 그루엔버거는 미국의 잡지 ‘사이언티픽 아메리칸’에 어떤 자연수로도 대칭수를 만들 수 있는 알고리듬을 발표했습니다.

 


예를 들어 13은 알고리듬을 따르면 13+31=44이므로 대칭수가 됩니다. 64는 어떨까요?

64+46=110으로 대칭수를 만들지 못하지만, 한 번 더 과정을 반복하면 110+11=121로 대칭수가 됩니다. 89는 과정을 24번이나 반복해야 대칭수가 되죠.


하지만 이 과정을 계속 반복해도 대칭수가 나오지 않는 수가 있었으니, 바로 196입니다. 대칭수를 만들지 못하는 수를 ‘라이크렐 수’라 부르는데, 196을 가장 작은 라이크렐 수라고 추정하고 있죠. 일부 수학자들은 196이 정말 대칭수를 못 만드는지 알아보기 위해 알고리듬을 만들어 살펴보고 있는데요, 2015년 로맹 돌보가 알고리듬을 이용해 10억 자릿수까지 만들어봤지만 대칭수를 만들지 못했습니다. 


이렇듯 사람들의 흥미를 불러일으킨 대칭수를 이번 오일러 프로젝트 4번에서 다룹니다. 세 자릿수를 곱해 만든 수 중 가장 큰 대칭수는 얼마인지 찾아야 하죠. 먼저 세 자릿수 2개를 곱하는 반복문은 ‘for’ 명령어와 ‘range’ 함수를 이용해 만들 수 있습니다. 하지만 어떤 수가 대칭수인지 판별하려면 원래 수와 뒤집은 수가 같은지 일일이 확인해봐야 합니다. 


이걸 어떻게 풀지 고민하다 묘수를 떠올렸어요. 수학 없이 수학 문제를 푸는 방법을 말이죠! 이번 한 번만 조커처럼 삐뚤어져 보렵니다! 하하!

 

※ 편집자 주
코딩의 ‘코’자도 모르는 코.알.못. 홍 기자가 수학 문제를 코딩으로 푸는 오일러 프로젝트 문제를 하나하나 해결해 나갈 예정입니다. 오일러 프로젝트는 수학과 프로그래밍 실력을 모두 키울 수 있도록 2001년에 만든 수학 문제 웹사이트로, 수학 문제를 프로그래밍으로 해결하는 게 목적이지요. 홍 기자와 함께 한다면 수학과 파이썬 모두 정복할 수도…?

 

 

1. 숫자를 문자열로 바꾸기


파이썬에서는 눈에 보이진 않지만, 변수에 따라 자료의 유형이 정의됩니다. 예를 들어 a=1이면 숫자, a=‘math donga X’ 면 문자열로 정의하죠. 4번 문제에서는 숫자를 문자열로 바꾼 다음 뒤집어 대칭수인지 확인할 거예요. 같은 123이라도 문자열로 정의하면 뒤집기가 더 쉽거든요. 이때 문자열은 수와 다르게 작은따옴표를 사용해 나타냅니다. 
숫자를 문자열로 바꾸는 함수는 ‘str’입니다. 예를 들어 숫자 123을 문자열 ‘123’으로 바꾸는 명령어는 아래와 같이 씁니다.

 

 

2. 문자열을 마음대로 자르고 뒤집기


‘잘라낸다’라는 의미가 있는 ‘슬라이싱(slicing)’ 표기법을 이용해 문자를 뒤집을 수 있습니다. 슬라이싱 표기법은 (문자열 변수의 이름)[시작 번호:끝 번호:step]으로 나타냅니다. 만약 시작 또는 끝 번호를 따로 지정하지 않으면 각각 처음과 마지막 문자로 정해지죠. 이때 문자를 뒤집기 위해서 제일 마지막에 있는 ‘step’을 이용해야 합니다. 


step은 숫자의 간격을 의미하는데요, 예를 들어 왼쪽 첫 번째 문자를 기준으로 5, 10, 15번째 문자를 출력하고 싶다면 step을 5로 정하면 됩니다. 여기서 step을 -1로 지정하면 방향을 오른쪽에서 왼쪽 방향으로 읽어 출력하라는 뜻이 됩니다. 즉, 문자열을 뒤집을 수 있죠.
 

 

 

①②③ 앞의 명령어를 이용해 대칭수인지 판별하는 is_palindrome(n) 함수를 만듭니다.
④ 조건문을 만들어 원래와 뒤집은 문자열이 같다면 참을 돌려줍니다.
⑤ 만약 문자열이 같지 않아 대칭수 조건을 만족하지 않으면 거짓을 돌려줍니다.
⑥ 구해야 할 답을 0으로 두고 시작합니다.
⑦⑧ 곱해야 할 세 자릿수 a, b의 범위를 지정합니다.
⑨ 대칭수인지 판별해야 할 세 자릿수 두 개의 곱을 p로 정합니다.
⑩ 세 자릿수의 곱으로 만든 가장 큰 대칭수를 찾아야 하므로, 기존에 나온 곱셈 결과 이상의 
수만 나오도록 조건문을 작성합니다.
⑪ ⑩번의 조건을 만족하는 대칭수 p의 값을 변수 ans에 대입합니다.
⑫ 가장 큰 대칭수를 출력합니다.

 


 

수학 문제를 푸는 데 문자열을 이용하다니, 역시 파이썬의 세계는 무궁무진하죠? 저는 문자열로 바꿔 풀었지만 숫자 상태에서 대칭수인지 판별하는 코드를 짜 볼 수도 있지 않을까요? 폴리매스 홈페이지에서 숨은 파이썬 고수 독자분들의 ‘가취’ 있는 제보를 기다릴게요! 

 

 

이 기사의 내용이 궁금하신가요?

기사 전문을 보시려면500(500원)이 필요합니다.

2020년 03월 수학동아 정보

  • 홍아름 기자 기자
  • 도움

    중빈(사이냅소프트 상무)
  • 참고자료

    박응용 ‘점프 투 파이썬’

🎓️ 진로 추천

  • 컴퓨터공학
  • 수학
  • 정보·통신공학
이 기사를 읽은 분이 본
다른 인기기사는?