Skip to content

Instantly share code, notes, and snippets.

@mjtb49
Last active February 28, 2025 22:22
Show Gist options
  • Save mjtb49/07935eb9bbd61ae785f5365b83044079 to your computer and use it in GitHub Desktop.
Save mjtb49/07935eb9bbd61ae785f5365b83044079 to your computer and use it in GitHub Desktop.
Illustrating how to iterate over seeds giving a particular ruined portal without having to think about lattices. To do this in the fastest way takes lattices, but a naive iteration is perfectly possible and not much slower, and this gist is to iterate that point.
# lcg constants. Replace A and B to change indices of targeted call.
A = 25214903917
B = 11
M = 1 << 48
mask = M - 1
# Can mess with this
argument_to_next_int = 28 # must not be a perfect power of 2
known_lower_bits = 17 # must be >= 17
lower_bits = 0 # must be the lower bits of some valid seed
target = (0, 0)
# zero out upper bits.
lower_bits &= (1 << known_lower_bits) - 1
# extract the "true" argument to this nextInt
_n = argument_to_next_int
_v2n = 0
while _n % 2 == 0:
_v2n += 1
_n //= 2
assert known_lower_bits >= 17
assert _n != 1
# Don't mess with these
# How much should we increase the upper bits of the first seed by? Must be a multiple of 2^17
BASE_INCREMENT = argument_to_next_int << (max(known_lower_bits - _v2n, 17))
# Smallest modulus that is a multiple of both the argument to the nextInt and 2^48
BIG_MOD = _n * M
# the effect an increment of BASE_INCREMENT at the first seed has on the second seed.
BASE_SECOND_SEED_INCREMENT = (A * BASE_INCREMENT) % BIG_MOD
def _next(seed):
return (A * seed + B) & mask
def test_seed(target, seed1, seed2=None):
if seed2 is None:
seed2 = _next(seed1)
return ((seed1 >> 17) % argument_to_next_int, (seed2 >> 17) % argument_to_next_int) == target
def print_if_statements():
upper_bound = -1
lower_bound = M
i = 1
prefix = "if"
while lower_bound > upper_bound:
guessed_effect_on_second_seed = ((i * BASE_SECOND_SEED_INCREMENT) // M) % _n
if guessed_effect_on_second_seed == 0:
bound = M - (i * BASE_SECOND_SEED_INCREMENT) % BIG_MOD
if bound > upper_bound:
upper_bound = bound
# print(i, i * second_seed_increment / M % n)
print(f"{prefix} b < {bound}:")
print(f"\t a += {i * BASE_INCREMENT}")
prefix = "elif"
elif guessed_effect_on_second_seed == _n - 1:
bound = BIG_MOD - (i * BASE_SECOND_SEED_INCREMENT) % BIG_MOD
if bound < lower_bound:
lower_bound = bound
# print(i, i * second_seed_increment / M % n)
print(f"{prefix} b >= {bound}:")
print(f"\t a += {i * BASE_INCREMENT}")
prefix = "elif"
i += 1
smallest_solution = lower_bits
print_if_statements()
seeds_found_fast = set()
print("Starting search for seeds")
# find solution with smallest possible upper bits to start our search from
while not test_seed(target, smallest_solution):
smallest_solution += 1 << known_lower_bits
print("Found initial seed")
# Start the main search
a = smallest_solution
while a < M:
b = _next(a)
seeds_found_fast.add(a)
assert test_seed(target, a, b)
# paste here the output from print_if_statements()
if b >= 66166523953152:
a += 3670016
elif b < 31479762518016:
a += 95420416
elif b < 97646286471168:
a += 99090432
# One of these branches is guaranteed to occur, so this last one could be an "else".
else:
assert False
print("Finished search for seeds and beginning test")
for a in range(lower_bits, M, 1 << known_lower_bits):
if test_seed(target, a) and a not in seeds_found_fast:
print(a)
assert False
print("Test complete")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment