1
\$\begingroup\$

Pentagonal numbers are generated by the formula, \$P_n=\frac{n(3n−1)}{2}\$. The first ten pentagonal numbers are:

1, 5, 12, 22, 35, 51, 70, 92, 117, 145

It can be seen that \$P_4 + P_7 = 22 + 70 = 92 = P_8\$. However, their difference, \70ドル − 22 = 48\$, is not pentagonal.

Find the pair of pentagonal numbers, \$P_j\$ and \$P_k\$, for which their sum and difference are pentagonal and \$D = |P_k − P_j|\$ is minimised; what is the value of D?

Awaiting feedback.

from time import time
def generate_pentagons(n):
 """generates next n pentagons"""
 pentagons = (num * (3 * num - 1) // 2 for num in range(1, n))
 for i in range(n - 1):
 yield next(pentagons)
def get_pentagons(n):
 """Assumes n is a range > 0.
 generates pentagons that obey to the + - rules."""
 pentagons = set(generate_pentagons(n))
 for pentagon1 in pentagons:
 for pentagon2 in pentagons:
 if pentagon1 + pentagon2 in pentagons and abs(pentagon1 - pentagon2) in pentagons:
 return pentagon1, pentagon2
if __name__ == '__main__':
 start_time = time()
 pent1, pent2 = get_pentagons(10000)
 print(abs(pent1 - pent2))
 print(f'Time: {time() - start_time} seconds.')
asked Jul 22, 2019 at 4:48
\$\endgroup\$
6
  • 1
    \$\begingroup\$ Why do you ignore the repeated advice (1, 2) to tag Python questions correctly? \$\endgroup\$ Commented Jul 22, 2019 at 5:17
  • \$\begingroup\$ I'm sorry if I seem to be ignoring your advice but in fact, 'python-3.x' as well as 'programming-challenge' are already tagged. I don't know what's wrong here. \$\endgroup\$ Commented Jul 22, 2019 at 5:24
  • \$\begingroup\$ check under the code block, you must see them I guess. \$\endgroup\$ Commented Jul 22, 2019 at 5:25
  • 1
    \$\begingroup\$ From the first referenced comment: "Please tag all Python questions with [python], ..." \$\endgroup\$ Commented Jul 22, 2019 at 5:28
  • 7
    \$\begingroup\$ You're averaging 5 questions a day. Some of the downvotes might be from people who think you should take things a lot slower, waiting for answers to one question so that you can apply the same principles to your next program. \$\endgroup\$ Commented Jul 22, 2019 at 7:18

1 Answer 1

1
\$\begingroup\$

This is an answer focused primarily about styling

  • Your parameter names can be renamed to be more specific, like generate_pentagons(n) can be rewritten to generate_pentagons(number_of_pentagons). This change can also be implemented in the get_pentagons method. While this may seem useless in this program, since n can be easily interpreted as the number of pentagons to generate, it's a good practice to follow when you start writing large programs that require more specific parameter names.
  • Parameter constants should be UPPERCASE.
  • You don't use i in your loop in generate_pentagons method. To avoid generating an unused variable, you can use an underscore. The _ immediately signals the reader that the value is not important.

Final Code

from time import time
def generate_pentagons(number_of_pentagons):
 """generates next n pentagons"""
 pentagons = (num * (3 * num - 1) // 2 for num in range(1, number_of_pentagons))
 for _ in range(number_of_pentagons - 1):
 yield next(pentagons)
def get_pentagons(number_of_pentagons):
 """Assumes n is a range > 0. Generates pentagons that obey to the + - rules."""
 pentagons = set(generate_pentagons(number_of_pentagons))
 for pentagon1 in pentagons:
 for pentagon2 in pentagons:
 if pentagon1 + pentagon2 in pentagons and abs(pentagon1 - pentagon2) in pentagons:
 return pentagon1, pentagon2
if __name__ == '__main__':
 START_TIME = time()
 PENTAGON_1, PENTAGON_2 = get_pentagons(10000)
 print(abs(PENTAGON_1 - PENTAGON_2))
 print(f"Time: {time() - START_TIME} seconds.")
answered Jul 25, 2019 at 5:14
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.