utils.py

View source code here on GitHub!

Includes

python.src.lib.utils.get_data_file(name: str, mode: 'r' = 'r') str
python.src.lib.utils.get_data_file(name: str, mode: 'rb') bytes

Returns the contents of a file in the top-level _data directory.

python.src.lib.utils.get_answer(n: int) int | str
python.src.lib.utils.is_palindrome(n: ~typing.Any, rep_func: ~typing.Callable[[~typing.Any], str] = <built-in function repr>) bool

Checks if the string representation of an object is a palindrome

python.src.lib.utils.steps_to_palindrome(n: int, depth: int = 0) int

Returns a 0 if the number does not reach a palindrome in 50 or fewer steps, otherwise returns the step count

 1from functools import lru_cache
 2from pathlib import Path
 3from typing import Any, Callable, Union, overload
 4
 5from .iters import digits
 6from .math import from_digits
 7
 8try:
 9    from typing import Literal
10except ImportError:
11    from typing_extensions import Literal  # type: ignore
12
13
14@overload
15def get_data_file(name: str, mode: Literal['r'] = 'r') -> str: ...
16@overload
17def get_data_file(name: str, mode: Literal['rb']) -> bytes: ...
18
19
20@lru_cache(maxsize=None)
21def get_data_file(name: str, mode: str = 'r') -> Any:
22    """Returns the contents of a file in the top-level _data directory."""
23    with Path(__file__).parent.parent.parent.parent.joinpath('_data', name).open(mode) as f:
24        return f.read()
25
26
27def get_answer(n: int) -> Union[int, str]:
28    for line in get_data_file('answers.tsv').splitlines()[1:]:
29        id_, type, size, value = line.split('\t')
30        if int(id_) != n:
31            continue
32        if type == 'str':
33            return value
34        return int(value)
35    raise ValueError()
36
37
38def is_palindrome(n: Any, rep_func: Callable[[Any], str] = repr) -> bool:
39    """Checks if the string representation of an object is a palindrome"""
40    r = rep_func(n)
41    return r == r[::-1]
42
43
44def steps_to_palindrome(n: int, depth: int = 0) -> int:
45    """Returns a 0 if the number does not reach a palindrome in 50 or fewer steps, otherwise returns the step count"""
46    new = n + from_digits(digits(n))
47    if is_palindrome(new):
48        return depth + 1
49    elif depth == 50:
50        return 0
51    return steps_to_palindrome(new, depth=depth + 1)

Tags: file-io