pull down to refresh

Find an integer such that the base expansion of begins "happy.newyear".
Caveat: I haven't written the code yet to do this myself, but I'm confident an answer exists. Actually, there should be infinitely many. I'll give it a try myself in the morning.
Previous iteration: #826121 (solution in #826313).
The base36 part is probably the easiest, all you need is
We can try various in to find something close enough to an integer .
But this seems to require arbitrary precision floating points, and with a naive search (m=1, 2, 3, ...) I haven't found anything yet.
reply
1000 sats \ 6 replies \ @Scroogey 1 Jan
must be .
reply
Yeah brute forcing isn't working out just yet for me either. I think there must be some smarter way to do it, but don't have time now to think about it.
Here already a few sats for your CPU time, this looks good enough if we rephrase the question to allow for floats that are nearly integer~~
Edit: I'm curious though how you found this float. I'm just iterating over integers...
reply
I think one may be able to approach this using continued fractions. Should give a more targeted way to focus on the more promising angle candidates.
Actually, maybe that's what you did above to find your near integer?
reply
I ended up playing with the continued fractions. I used ChatGPT to help me write out the logic. In this process, ChatGPT came up with the idea of the Levenshtein distance to check for near misses.
No answer yet on "happy.newyear" case, testing on a simpler string now.
This is taking me more time than expected~~
import math from difflib import SequenceMatcher # === User Adjustable Variables === MIN_N = 72523715257 # Minimum value of n to search SEARCH_RANGE = 100000 # The range of offsets around each approximation to search PRECISION_SCALE = 1e15 # Scale factor for capturing decimal precision in base-36 MAX_TERMS = 200 # Number of terms in the continued fraction expansion SIMILARITY_THRESHOLD = 0.8 # Minimum similarity (0-1) to report a near miss # ================================= # Function to convert a number to a base-36 string def to_base36(num): chars = "0123456789abcdefghijklmnopqrstuvwxyz" if num < 0: return "-" + to_base36(-num) if num == 0: return "0" base36 = [] while num > 0: base36.append(chars[num % 36]) num //= 36 return "".join(reversed(base36)) # Function to compute the continued fraction expansion of a number def continued_fraction_expansion(x, max_terms): terms = [] for _ in range(max_terms): int_part = int(x) terms.append(int_part) frac_part = x - int_part if frac_part == 0: break x = 1 / frac_part return terms # Function to compute rational approximations from continued fraction terms def rational_approximations(cf_terms): approximations = [] p0, p1 = 1, cf_terms[0] q0, q1 = 0, 1 approximations.append((p1, q1)) for term in cf_terms[1:]: p2 = term * p1 + p0 q2 = term * q1 + q0 approximations.append((p2, q2)) p0, p1 = p1, p2 q0, q1 = q1, q2 return approximations # Base-36 target string target_prefix = "merry.christmas" # Convert target base-36 string to decimal value def base36_to_decimal(base36_str): chars = "0123456789abcdefghijklmnopqrstuvwxyz" int_part, _, frac_part = base36_str.partition(".") # Integer part conversion int_value = sum(chars.index(c) * (36 ** i) for i, c in enumerate(reversed(int_part))) # Fractional part conversion frac_value = sum(chars.index(c) * (36 ** -(i + 1)) for i, c in enumerate(frac_part)) return int_value + frac_value # Decimal value of "merry.christmas" base36_value = base36_to_decimal(target_prefix) # Compute continued fraction expansion and rational approximations cf_terms = continued_fraction_expansion(base36_value, max_terms=MAX_TERMS) rational_approximations_list = rational_approximations(cf_terms) # Function to compute similarity between two strings def similarity(a, b): return SequenceMatcher(None, a, b).ratio() # Function to check if the base-36 representation of tan(n) starts with target prefix def check_prefix_of_tan(n, target_prefix): try: tan_value = math.tan(n) base36_tan = to_base36(int(abs(tan_value) * PRECISION_SCALE)) # Scale for precision exact_match = base36_tan.startswith(target_prefix.replace(".", "")) return exact_match, base36_tan except ValueError: return False, None # Extended search for a solution found_n = None near_misses = [] # Store near misses for analysis for p, q in rational_approximations_list: # Compute n from arctan(p/q) angle_radians = math.atan(p / q) angle_degrees = math.degrees(angle_radians) # Convert to degrees n = round(angle_degrees) # Round to nearest integer # Adjust for large minimum n n = max(n, MIN_N) # Test a range of values around n for periodicity for offset in range(-SEARCH_RANGE, SEARCH_RANGE + 1): # Search within range test_n = n + offset is_match, base36_tan = check_prefix_of_tan(test_n, target_prefix) if is_match: found_n = test_n break elif base36_tan: # Check for near misses sim_score = similarity(base36_tan, target_prefix.replace(".", "")) if sim_score >= SIMILARITY_THRESHOLD: near_misses.append((test_n, base36_tan, sim_score)) if found_n: break # Output results if found_n: print("Found n:", found_n) else: print("No exact match found.") print("Near misses:") for miss in sorted(near_misses, key=lambda x: -x[2]): # Sort by similarity score print(f"n={miss[0]}, base-36={miss[1]}, similarity={miss[2]:.2f}")
reply
I got strange results with Python's built-in floats, as if the precision wasn't good enough.
Closest match so far:
u=97366344686.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 z=305885393174.00000000000140601378546118371359432952443993406280164926158704474801197648048400878906250000000000000000000000000000 r=305885393174.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 y=29052179.885292215619356553510385828347735846057466489994871801023624482995165949265643254134563120164232130092252951481137523825 haosz.vvc6yx5pfugb5u1knqd1
reply
I got strange results with Python's built-in floats, as if the precision wasn't good enough.
Oh that's a good point. Will test using mpmath.tan(n) instead of math.tan(n) and setting the number of decimals using mpmath.mp.dps = 100.
Tnx for your code.
From my end, I could probably speed up things by switching to Fortran, but I guess I'll be content for now knowing there is a likely way and a likely solution. Learned a few things in the process :)
reply
No, I did just brute force using LibBF. Reading up continued fractions now, like this?
reply