Consider the partial configuration . The configuration after two steps is . We note the following shift rule:
As a result, we get after steps. Advancing two steps produces . A second shift rule is useful here:
This allows us to reach in steps. Moving five more steps gets us to , which is the same configuration as . Accounting for the head movement creates the condition that . In summary:
With we have . As a result, we can apply this rule times (assuming ), which creates two possible scenarios:
If , then in steps we arrive at . The matching complete configuration is . After steps this is , which then leads to in steps. After five more steps, we reach , from which another shift rule must be applied:
Doing so allows us to get the configuration in steps. In six steps we have , so we use the shift rule again, ending at , equal to , steps later. This gives a total of steps.
If , then in steps we arrive at . The matching complete configuration is . After steps this becomes . If then we have reached the undefined F0 transition with a total of steps. Otherwise, continuing for six steps gives us . We conclude with the configuration , equal to , in steps. This gives a total of steps.
The information above can be summarized as
Substituting for the first case and for the other two yields the final result.
In effect, the halting problem for Antihydra is about whether repeatedly applying the function will at some point produce more odd values of than twice the number of even values.
These rules can be modified to use the function , or the Hydra function, which strengthens Antihydra's similarities to Hydra.
Trajectory
Path of parity of repeated applications of Hydra map for Antihydra.
Starting from a blank tape, Antihydra reaches in 11 steps and then the rules are repeatedly applied. So far, Antihydra has been simulated to rule steps,[4] at which point exceeds . Here are the first few:
The trajectory of values resembles a random walk in which the walker can only move in step sizes +2 or -1 with equal probability, starting at position 0. If is the probability that the walker will reach position -1 from position , then it can be seen that . Solutions to this recurrence relation come in the form , which after applying the appropriate boundary conditions reduces to . This means that if the walker were to get to the position of the current value, then the probability of it ever reaching position -1 is less than . This combined with the fact that the expected position of the walker after steps is strongly suggests Antihydra probviously runs indefinitely.
Code
The following Python program implements the abstracted behavior of the Antihydra. Proving whether it halts or not would also solve the Antihydra problem:
# Current value of the iterated Hydra function starting with initial value 8 (the values do not overflow)h=8# (Collatz-like) condition counter that keeps track of how many odd and even numbers have been encounteredc=0# If c equals -1 there have been (strictly) more than twice as many odd as even numbers and the program haltswhilec!=-1:# If h is even, add 2 to c so even numbers count twiceifh%2==0:c+=2else:c-=1# Add the current hydra value divided by two (integer division, rounding down) to itself (Hydra function)# Note that integer division by 2 is equivalent to one bit shift to the right (h >> 1)h+=h//2
The variable values of this iteration have been put into the On-Line Encyclopedia of Integer Sequences (OEIS):
Fast Hydra/Antihydra simulation code by Greg Kuperberg (who said it could be made faster using FLINT):
# Python script to demonstrate almost linear time hydra simulation# using fast multiplication. # by Greg Kuperbergimporttimefromgmpy2importmpz,bit_mask# Straight computation of t steps of hydradefsimple(n,t):forsinrange(t):n+=n>>1returnn# Accelerated computation of 2**e steps of hydradefhydra(n,e):ife<9:returnsimple(n,1<<e)t=1<<(e-1)(p3t,m)=(mpz(3)**t,bit_mask(t))n=p3t*(n>>t)+hydra(n&m,e-1)returnp3t*(n>>t)+hydra(n&m,e-1)defelapsed():(last,elapsed.mark)=(elapsed.mark,time.process_time())returnelapsed.mark-lastelapsed.mark=0(n,e)=(mpz(3),25)elapsed()print('hydra: steps=%d hash=%016x time=%.6fs'%(1<<e,hash(hydra(n,e)),elapsed()))# Quadratic time algorithm for comparison# print('simple: steps=%d hash=%016x time=%.6fs'# % (1<<e,hash(simple(n,1<<e)),elapsed()))