from itertools import islice
from sys import setrecursionlimit
from typing import Generator, Iterator
from hypothesis import given, settings
from hypothesis import strategies as st
setrecursionlimit(10**6)
# Solución del ejercicio 1
def esCapicua(x: int) -> bool:
return x == int(str(x)[::-1])
# Solución del ejercicio 2
def inverso(x: int) -> int:
return int(str(x)[::-1])
# Solución del ejercicio 3
def siguiente(x: int) -> int:
return x + inverso(x)
# Solución del ejercicio 4
def busquedaDeCapicua(x: int) -> list[int]:
if esCapicua(x):
return [x]
return [x] + busquedaDeCapicua(siguiente(x))
# Solución del ejercicio 5
def capicuaFinal(x: int) -> int:
return busquedaDeCapicua(x)[-1]
# Solución del ejercicio 6
def orden(x: int) -> int:
if esCapicua(x):
return 0
return 1 + orden(siguiente(x))
# Solución del ejercicio 7
def ordenMayor(x: int, n: int) -> bool:
if esCapicua(x):
return n == 0
if n <= 0:
return True
return ordenMayor(siguiente(x), n - 1)
# Solución del ejercicio 8
# ========================
# naturales es el generador de los números naturales positivos, Por
# ejemplo,
# >>> list(islice(naturales(), 5))
# [1, 2, 3, 4, 5]
def naturales() -> Iterator[int]:
i = 1
while True:
yield i
i += 1
def ordenEntre(m: int, n: int) -> Generator[int, None, None]:
return (x for x in naturales()
if ordenMayor(x, m) and not ordenMayor(x, n))
# Solución del ejercicio 9
def menorDeOrdenMayor(n: int) -> int:
return list(islice((x for x in naturales() if ordenMayor(x, n)), 1))[0]
# Solución del ejercicio 10
def menoresdDeOrdenMayor(m: int) -> list[tuple[int, int]]:
return [(n, menorDeOrdenMayor(n)) for n in range(1, m + 1)]
# Solución del ejercicio 11
# La conjetura es que para n mayor que 1, la última cifra de
# menorDeOrdenMayor(n) es 9.
# Solución del ejercicio 12
# =========================
# La conjetura es
# @given(st.integers(min_value=2, max_value=200))
# def test_menorDeOrdenMayor(n: int) -> None:
# assert menorDeOrdenMayor(n) % 10 == 9
# La comprobación es
# src> poetry run pytest -q numeros_de_Lychrel.py
# E assert (196 % 10) == 9
# E + where 196 = menorDeOrdenMayor(25)
# E Falsifying example: test_menorDeOrdenMayor(
# E n=25,
# E )
# Se puede comprobar que 25 es un contraejemplo,
# >>> menorDeOrdenMayor(25)
# 196
# Solución del ejercicio 13
# El cálculo es
# λ> menoresdDeOrdenMayor 50
# [(1,10),(2,19),(3,59),(4,69),(5,79),(6,79),(7,89),(8,89),(9,89),
# (10,89),(11,89),(12,89),(13,89),(14,89),(15,89),(16,89),(17,89),
# (18,89),(19,89),(20,89),(21,89),(22,89),(23,89),(24,89),(25,196),
# (26,196),(27,196),(28,196),(29,196),(30,196),(31,196),(32,196),
# (33,196),(34,196),(35,196),(36,196),(37,196),(38,196),(39,196),
# (40,196),(41,196),(42,196),(43,196),(44,196),(45,196),(46,196),
# (47,196),(48,196),(49,196),(50,196)]
# Solución del ejercicio 14
# El orden de 196 es infinito y, por tanto, 196 es un número
# de Lychrel.
# Solución del ejercicio 15
# =========================
# La propiedad es
@settings(deadline=None)
@given(st.integers(min_value=2, max_value=5000))
def test_ordenDe196(n: int) -> None:
assert ordenMayor(196, n)
# La comprobación es
# src> poetry run pytest -q numeros_de_Lychrel.py
# 1 passed in 7.74s