""" The nth term of the sequence of triangle numbers is given by, $t_n = \frac{n(n+1)}{2}$ ; so the first ten triangle numbers are: 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ... By converting each letter in a word to a number corresponding to its alphabetical position and adding these values we form a word value. For example, the word value for SKY is 19+11+25 = 55 = t_10 . If the word value is a triangle number then we shall call the word a triangle word. Using words.txt (right click and 'Save Link/Target As...'), a 16K text file containing nearly two-thousand common English words, how many are triangle words? """ import time from pathlib import Path def timer(func): def wrapper(*args, **kwargs): start_time = time.perf_counter() result = func(*args, **kwargs) end_time = time.perf_counter() print(f"Time taken by {func.__name__}: {end_time - start_time:.8f} seconds") return result return wrapper def word_to_num(txt: str) -> int: """ 将单词转换为数字,每个字母对应其在字母表中的位置(A=1, B=2, ..., Z=26) 参数: txt: 要转换的单词 返回: 单词的数字表示 示例: >>> word_to_num("SKY") 55 """ return sum(ord(c) - ord("A") + 1 for c in txt) def is_triangle_number(n: int) -> bool: """ 判断一个数是否为三角形数 参数: n: 要判断的数 返回: True 如果 n 是三角形数,否则 False 示例: >>> is_triangle_number(10) True >>> is_triangle_number(11) False """ # 使用二次方程求解,如果结果是整数则为三角形数 # 三角形数公式:n = k(k+1)/2 # 解得 k = (-1 + sqrt(1 + 8n)) / 2 k = (-1 + (1 + 8 * n) ** 0.5) / 2 return k.is_integer() @timer def main() -> None: with open(Path(__file__).parent / "0042_words.txt", "r") as file: words = file.read().replace('"', "").split(",") triangle_words = [word for word in words if is_triangle_number(word_to_num(word))] print(f"Number of triangle words: {len(triangle_words)}") if __name__ == "__main__": main()