15
\$\begingroup\$

As a follow up to Shortest terminating program whose output size exceeds Graham's number and Golf a number bigger than TREE(3), I present a new challenge.

Loader's number is a very large number, that is kind of hard to explain (since it was itself the result of a code golfing exercise with a flexible goal). There is a definition and explanation here, but for the purposes of self-containment, I will attempt to explain it later in this post as well.

The algorithm Ralph Loader used produces one of the largest numbers of any (computable) algorithm ever written! Indeed, Loader's number is the largest "computable" number on the Googology Wiki. (By "computable" number, they mean a number defined in terms of a computation.) That means that if answer produces a number larger than Loader's number in an interesting way (i.e. not just Loader's number+1), you could go down in Googology history! That being said, programs that produce something like Loader's number+1 are definitely valid answers and contenders to this question; just don't expect any fame.

Your job is to create a terminating program that produces a number larger than Loader's number. This is , so the shortest program wins!

  • You aren't allowed to take input.
  • Your program must eventually terminate deterministically but you can assume the machine has infinite memory.
  • You may assume your language's number type can hold any finite value but need to explain how this exactly works in your language (ex: does a float have infinite precision?)
    • Infinities are not allowed as output.
    • Underflow of a number type throws an exception. It does not wrap around.
  • You need to provide an explanation of why your number is so big and an ungolfed version of your code to check if your solution is valid (since there is no computer with enough memory to store Loader's number).

So here is an explanation of Loader's number. See http://googology.wikia.com/wiki/Loader%27s_number and the links therein for more precise details. In particular, it contains a program that produces Loader's number exactly (by definition).

The calculus of constructions is essentially a programming language with very particular properties.

First of all, every syntactically valid program terminates. There are no infinite loops. This will be very useful, because it means that if we run an arbitrary calculus of constructions program, our program will not get stuck. The problem is that this implies the calculus of constructions is not Turing complete.

Second of all, among non-Turing complete languages, it is one of the most powerful. Essentially, if you can prove that a Turing machine will halt on every input, you can program a function in the calculus of constructions that will simulate it. (This does not make it turing complete, because there are halting turing machines that you can not prove are halting.)

Loader's number is essentially a busy beaver number for the calculus of constructions, which is possible to compute since all coc programs terminate.

In particular, loader.c defines a function called D. Approximately, D(x) iterates over all bit-strings less than x, interprets them as a coc programs, runs the syntactically valid ones, and concatenates the results (which will also be bitstrings). It returns this concatenation.

Loader's number is D(D(D(D(D(99))))).

A more readable copy of the code from the googolology wiki

int r, a;

P(y,x){return y- ~y<<x;}

Z(x){return r = x % 2 ? 0 : 1 + Z (x / 2 );}

L(x){return x/2 >> Z(x);}

S(v,y,c,t){
   int f = L(t);         
   int x = r;
   return f-2 ? f>2 ? f-v ? t-(f>v)*c : y : P(f,P(S(v,y,c,L(x)), S(v+2,t=S(4,13,-4,y),c,Z(x)))) : A(S(v,y,c,L(x)),S(v,y,c,Z(x)));
}

A(y,x){return L(y)-1 ? 5<<P(y,x) : S(4,x,4,Z(r));}

D(x) 
{
   int f;
   int d;
   int c=0;
   int t=7;
   int u=14;
   while(x&&D(x-1),(x/=2)%2&&(1)){
      d = L(L(D(x))),
      f = L(r),
      x = L(r),
      c - r||(L(u)||L(r)-f||(x/=2)%2&&(u=S(4,d,4, r),t=A(t,d)),f/2&(x/=2)%2&&(c=P(d,c),t=S(4,13,-4,t),u=S(4,13,-4,u))),
      c&&(x/=2)%2&&(t=P(~u&2|(x/=2)%2&&(u=1<<P(L(c),u)),P(L(c),t)),c=r)
      u/2&(x/=2)%2&&(c=P(t,c),u=S(4,13,-4,t),t=9);
    }
    return a = P( P( t, P( u, P( x, c)) ),a);
}

main(){return D(D(D(D(D(99)))));}
\$\endgroup\$
  • 5
    \$\begingroup\$ I would advise against downvoting this for similarity to the TREE(3) question: Loader's number is so much larger than TREE(3) that new and interesting approaches are required. \$\endgroup\$ – lirtosiast Dec 4 '18 at 1:00
  • 1
    \$\begingroup\$ @fəˈnɛtɪk Well, printing Loader's number + 1 is still interesting from a code golf perspective (for example, can you beat the original 512 bytes?) There are also some natural generalizations of loader's number that might be easier to implement (for example, using ZFC instead of CoC). Also, Greedy clique sequences or finite promise games could be used. \$\endgroup\$ – PyRulez Dec 4 '18 at 3:24
  • 1
    \$\begingroup\$ Unfortunately, as I don't understand the construction of Loader's number and there does not seem to be known upper bounds in terms of the fast growing hierarchy, I cannot give any good answers here. I believe that most answers will be either extensions of Loader's number or things such as the greedy clique sequences and finite promise games... \$\endgroup\$ – Simply Beautiful Art Dec 4 '18 at 12:33
  • 1
    \$\begingroup\$ @SimplyBeautifulArt Oh boy, if you don't understand it, that doesn't bode well for this challenge. :P I could try explaining it in more detail to you in chat, but I also do not know any hierarchy upper bounds. \$\endgroup\$ – PyRulez Dec 4 '18 at 16:36
  • 1
    \$\begingroup\$ @SimplyBeautifulArt In particular, since Loader's constant was specifically chosen to try to be the biggest number generated by a certain amount of code (where as Graham's number and TREE(3) at just mathematically interesting numbers that just so happen to be large), I think most answers will just be Loader's number + 1. \$\endgroup\$ – PyRulez Dec 4 '18 at 16:38
2
\$\begingroup\$

JavaScript, D^6(9)(Untested) (508 501 495 492 487B)

_='r=a=0,PM,yEx-~x<<y,ZMEr=x%2?0:1+ZC>>1@LMEx/2>>ZC@S=Bt,f=Ht@x=rEf-2?f>2?f-v?t-(f>v)*c:y:Ff,FSN(v+2,t8y@c,ZCKK:A(ANBZC)GAM,yELC)-1?5<<PC,y):S(4,y,4,Z(rGDM,f,d,c=0,t=7,u=14E{whileC&&DC-1@61Kd=HHDC)Gf=Hr@x=Hr@c-r||(Hu)||Hr)-f||6u=S(4,d,4,r@t=A(t,dGfId,c@t8t@u8u)Gc&&6t=F~u&2|6u=1<<FHc@uGFHc@tGc=r@uIt,c@u8t@t=9);return a=FFt,Fu,PC,c)Ga)},JJJ9KKK6C>>=1)%2&&(8=S(4,13,-4,G)@@),B(v,y,c,M=CNBLCGSC(xE)=>I/2&6c=FFP(HL(JD(D(K))';for(Y of $='KJHFIECNMB@G86')with(_.split(Y))_=join(pop());eval(_)

This is an encoded code.

_='r=a=0,PM,yEx-~x<<y,ZMEr=x%2?0:1+ZC>>1@LMEx/2>>ZC@S=Bt,f=Ht@x=rEf-2?f>2?f-v?t-(f>v)*c:y:Ff,FSN(v+2,t8y@c,ZCKK:A(ANBZC)GAM,yELC)-1?5<<PC,y):S(4,y,4,Z(rGDM,f,d,c=0,t=7,u=14E{whileC&&DC-1@61Kd=HHDC)Gf=Hr@x=Hr@c-r||(Hu)||Hr)-f||6u=S(4,d,4,r@t=A(t,dGfId,c@t8t@u8u)Gc&&6t=F~u&2|6u=1<<FHc@uGFHc@tGc=r@uIt,c@u8t@t=9);return a=FFt,Fu,PC,c)Ga)},JJJ9KKK6C>>=1)%2&&(8=S(4,13,-4,G)@@),B(v,y,c,M=CNBLCGSC(xE)=>I/2&6c=FFP(HL(JD(D(K))'; //encoded code
for(Y of $='KJHFIECNMB@G86')with(_.split(Y))_=join(pop()); //decoding algorithm
eval(_) //Evaluation of the string

Decoded code:

r=a=0,P=(x,y)=>x-~x<<y,Z=(x)=>r=x%2?0:1+Z(x>>1),L=(x)=>x/2>>Z(x),S=(v,y,c,t,f=L(t),x=r)=>f-2?f>2?f-v?t-(f>v)*c:y:P(f,P(S(v,y,c,L(x)),S(v+2,t=S(4,13,-4,y),c,Z(x)))):A(A(v,y,c,L(x)),S(v,y,c,Z(x))),A=(x,y)=>L(x)-1?5<<P(x,y):S(4,y,4,Z(r)),D=(x,f,d,c=0,t=7,u=14)=>{while(x&&D(x-1),(x>>=1)%2&&(1))d=L(L(D(x))),f=L(r),x=L(r),c-r||(L(u)||L(r)-f||(x>>=1)%2&&(u=S(4,d,4,r),t=A(t,d)),f/2&(x>>=1)%2&&(c=P(d,c),t=S(4,13,-4,t),u=S(4,13,-4,u))),c&&(x>>=1)%2&&(t=P(~u&2|(x>>=1)%2&&(u=1<<P(L(c),u)),P(L(c),t)),c=r),u/2&(x>>=1)%2&&(c=P(t,c),u=S(4,13,-4,t),t=9);return a=P(P(t,P(u,P(x,c))),a)},D(D(D(D(D(D(9))))))

Decoded, ungolfed code(conditions and stuff are kept from loader.c):

var r=a=0;
function P(y,x){
  return y-~y<<x;
}
function Z(x){
  return r=x%2?0:1+Z(x>>1);
}
function L(x){
  return x/2>>Z(x);
}
function S(v,y,c,t){
  var f=L(t),x=r;
  return f-2?
           f>2?
             f-v?
               t-(f>v)*c
               :y
             :P(f,P(S(v,y,c,L(x)),S(v+2,t=S(4,13,-4,y),c,Z(x))))
           :A(S(v,y,c,L(x)),S(v,y,c,Z(x)))
}
function A(y,x){
  return L(y)-1?
         5<<P(y,x):
         S(4,x,4,Z(r));
}
function D(x){
  var f,
      d,
      c=0,
      t=7,
      u=14;
  while(x&&D(x-1),(x>>=1)%2&&(1))
    d=L(L(D(x))),
    f=L(r),
    x=L(r),
    c-r||(
      L(u)||L(r)-f||
      (x>>=1)%2&&(
        u=S(4,d,4,r),t=A(t,d)
      ),
      f/2&(x>>=1)%2&&(
        c=P(d,c),
        t=S(4,13,-4,t),
        u=S(4,13,-4,u)
      )
    ),
    c&&(x>>=1)%2&&(
      t=P(
        ~u&2|(x>>=1)%2&&(
          u=1<<P(L(c),u)
        ),
        P(L(c),t)
      ),
      c=r
    ),
    u/2&(x>>=1)%2&&(
      c=P(t,c),
      u=S(4,13,-4,t),
      t=9
    );
  return a=P(P(t,P(u,P(x,c))),a)
};
D(D(D(D(D(D(9))))))

This is actually(modified) one of attempts of similar stuff, and right now ~460 byte is listed, however I discovered that the code is malformed... And this one was one that I was able to run without syntax error, so that's cool.

I rebuilt it.

Encoding/Decoding algorithm:

The encoding is done as follows:

  • Take a repeated string, call it S.
  • Replace all S in the code to a key K.
  • Put K and S at the end.
  • Make a list of keys, and also put decoding algorithm so the code actually runs.

The decoding algorithm:

  • Take list of keys.
  • Take the earliest key K.
  • Split the string for each K.
  • Since last of the array is what to replace K S, pop it, and replace all K by joining the array with the popped value S.

The compression was done with this code, check only the last box. Since this will encode the largest save first, it is not the most efficient compression, but I don't know how to make it smaller either so meh.

JavaScript(more), (341 chars)

for(i=(a=")⡟慬敶⤻⠩潰⡰楮橯弽⤩⡙楴灬⹳⡟瑨睩✩㠶䁇䵂䍎䥅䡆䭊㴧․潦夠爨景✻⤩⡋⡄䩄䰨⡈䙐㵆㙣㈦䤯㴾䔩⡸千䍇䉌䍎䴽挬礬瘬䈨⤬䁀䜩㐬Ⱝㄳ㐬匨㠽☨㈦⤥㴱㸾㙃䭋㥋䩊ⱊ⥽䝡挩䌬ⱐ䙵琬䙆愽渠畲整㭲㤩琽瑀甸捀琬畉牀挽瑇捀䙈畇捀䙈㰼㴱㙵㉼甦䙾琽☶挦⥇㡵䁵㡴䁴Ᵽ䥤䝦Ɽ⡴㵁䁴ⱲⰴⱤ⠴㵓㙵籼ⵦ爩籈⥼䡵簨牼挭牀㵈䁸䡲昽⥇䑃䡈搽ㅋ䀶ⴱ䑃☦敃楬睨䕻ㄴ甽㜬琽〬挽搬昬䴬䝄⡲ⱚⰴⱹ⠴㩓礩䌬㱐㔼ㄿ⤭䱃祅䴬䝁䌩䉚䅎䄨䬺䍋ⱚ䁣㡹ⱴ⬲⡶华ⱆ䙦示挺⤪㹶⡦琭瘿昭㈿显㈿昭牅砽瑀㵈ⱦ䉴匽䍀㹚㈾砯䵅䁌㸱䌾⭚㨱㼰┲㵸䕲婍礬㰼繸砭祅䴬ⱐ㴰㵡❲弽").length,b="";i;b+=(d=String.fromCharCode)((c=a.charCodeAt(--i))>>8)+d(c&255));eval(b)

This code will take the 16bit string as a, reverse it, converts it to 8bit string with same binary(BE), and eval it.

The decoded code is the encoded code above.

Proof that D^6(9)>D^5(99)

For this, we would compare D(9) and 99.

After some code running, D(9) turns out to be (15*2^14849+1)*2^((15*2^14849+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^929+1)*2^((15*2^929+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^((15*2^59+1)*2^(15*2^59+1)))))))))))))))))))))))))))))))), and even D(0) is equal to 8646911284551352321.

So, D(9)>>>99, therefore D^6(9)>D^5(99).

  • 508B->501B, -7B
    • -1B for... I don't know why. I did change D(D(D(D(D(99))))) to D(D(D(D(D(D(9)))))). Also that shuffled the letters.
    • -6B for re-adding &&(1) for D(x)'s loop condition.
  • 501B->495B, -6B
    • Fixed most /2s to >>1s because Number
    • 6 byte save from somewhere
    • You can see my attempt in this update here
  • 495->492B, -3B
    • By changing the decoder from for...in to for...of.
  • 492->487B, -5B
    • Removing unnecessary assignments
    • Changing argument names
\$\endgroup\$
  • \$\begingroup\$ Or easily pass it with equal length by replaceing 99 with M9, which makes the value D^6(9). \$\endgroup\$ – Naruyoko Apr 26 at 13:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.