Problem 197

completed January 27, 2021

Comments

I implemented the brute force solution, then realized that the solutions become cyclical starting at n = 516. Since the cycle length is just 2, all I needed to do was return the sum of those two numbers.

Use of the decimal module isn’t necessary. I initially used it to ensure that I was getting accurate values. However for the final answer, the only reason why I kept returning a decimal.Decimal was to make sure the tests pass.

Code

import decimal

c = decimal.Decimal('30.403243784')
e = decimal.Decimal('1e-9')

def memoize(fn):
    _cache = {}
    def wrap(n):
        if n in _cache:
            return _cache[n]
        ret = fn(n)
        _cache[n] = ret
        return ret
    return wrap

@memoize
def f(n):
    return int(2**(c-n**2)) * e

@memoize
def u(n):
    if n == 0:
        return -1
    return f(u(n-1))

def solve(n):
    if n > 515:
        return decimal.Decimal('1.029461839') + decimal.Decimal('0.681175878')
    return u(n) + u(n+1)

if __name__ == '__main__':
    import sys
    n = eval(sys.argv[1])
    print(solve(n))

Tests

import pytest, decimal
from problem import solve

_test_solve = (
        (10**0, decimal.Decimal('1.711242148')),
        (10**1, decimal.Decimal('1.710098289')),
        (10**2, decimal.Decimal('1.710575329')),
        (10**3, decimal.Decimal('1.710637717')),
        (10**4, decimal.Decimal('1.710637717')),
        (10**5, decimal.Decimal('1.710637717')),
        (10**6, decimal.Decimal('1.710637717')),
)

@pytest.mark.parametrize('n,expect', _test_solve)
def test_solve(n, expect):
    assert expect == solve(n)