Project Euler
프로젝트 오일러 008
1,000 개 숫자 중에서 연속된 숫자들의 곱의 최대값 찾기 feat. 고차함수
1분
##wordpress
##Import 2024-10-22 00:39
1000개의 숫자에서 순서대로 나열된 13개의 곱이 가장 큰 경우를 찾는 문제입니다. 주어진 값을 정수의 리스트로 변환하고, 슬라이스 문법을 사용하여 xs[i:i+13]으로 손쉽게 길이가 13인 부분열을 구할 수 있습니다.
앞서, 공통최소공배수를 구하는 문제에서 reduce를 사용해본 바가 있습니다. 합계나 누적곱을 구할 때에도 유용하게 사용할 수 있다고 했죠.
풀이
from functools import reduce
# 누적곱을 구하는 함수
product = lambda xs: reduce(lambda x, y: x * y, xs)
# 각 마디의 길이
chunk_size = 13
s = """
73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450
"""
def solve():
ns = [int(x) for x in s if s.isdigit()]
return max(product(ns[i:i+chunk_size]) for i in range(len(ns) - chunk_size))
print(solve())
문자열은 개별 글자의 연속열(sequence)이기 때문에 for .. in에 사용할 수 있습니다. 여기서는 개행문자와 같이 숫자로 변환할 수 없는 문자를 걸러내기 위해서 isdigit()을 사용했습니다. 어떤 문자 혹은 문자열이 숫자인지를 알아내는 방법은 파이썬에서 세 가지가 존재합니다.
s.isdigit(): 숫자와 관련된 유니코드 문자이면 참입니다."四".isdigit() == Trues.isnumeric(): 숫자가 들어간 문자면 참입니다. 윗첨자나, 분수표현문자도 인정합니다.s.isdecimal(): 십진수 숫자만 인정합니다.
그러니 정말 임의의 문자열에서 정수로 전환할 수 있는 숫자를 확인하려면 정확히는 isdecimal()을 써야한다는 점은 알아두세요.