Post Reply 
Tupper's 'Self-referencing' Formula
05-19-2022, 02:31 PM (This post was last modified: 05-19-2022 07:50 PM by matalog.)
Post: #1
Tupper's 'Self-referencing' Formula
I have been trying to get Tupper's 'Self Referencing' Formula to plot on the Prime, just out of interest initially, and after I found out you can't, I wanted to do it even more.

This is a plot of Tupper's Formula, it has of course lost all meaning, as the Formula it plots isn't the Formula used to plot it. It was never self referencing anyway, as the main part of the Formula k, was never plotted in the result, but is the key to the 'bitmap' being plotted.

This contains a routine to divide an arbitrarily large integer by a given number that the calculator can handle, and with division by 2, binary numbers extracted. It is the latter that takes so much time here.

This isn't fast, and I have made it in faster ways, but it's shorter code, and for the time saving, not really a big difference.

Code:
EXPORT T2UP()
BEGIN
LOCAL k:="96093937991895888497167296212785275471500433966012930665150551927170280239526642​46896428421743507181212671537827706233559932372808741443078913259639413377234878​57735749823926629715517173716995165232890538221612403238855866184013235585136048​82869333790249145422928866708109618449609170518345406782773155170540538162738096​76025656250169814820834187831638491155902256100036523513703438744618483787372381​98224849863465033159410054974700593138339226497249461751545728366702369745461014​655997933798537483143786841806593422227898388722980000748404719";
       //   Divide long number by 17 and store by using lsd(k)
LOCAL A:=0;LOCAL B:=lsd(k,17);LOCAL C:=0;LOCAL D:=0;LOCAL E:=0;LOCAL B1:=B;LOCAL B2:="";LOCAL B3:=0;LOCAL NA:="";LOCAL DONE:=0;LOCAL CO:=0;LOCAL li:={};LOCAL pos:=1;LOCAL count:=0;
rect();
  REPEAT 
  B3:=EXPR(RIGHT(B,1));
IF CO<1799 THEN
    //  Divide long number by 2 and plot if it was odd.
  B:=lsd(B,2);
ELSE DONE:=1;
END;
    //  Plot each pixel 3x3 as it is extracted.
    IF B3 MOD 2 THEN
           FOR W FROM 0 TO 2 DO
            FOR H FROM 1 TO 3 DO
              PIXON_P(316-3*FLOOR(CO/17)+W,3*(CO MOD 17)+H,0);
            END;
           END;
    END;
    CO:=CO+1;
    UNTIL DONE OR ISKEYDOWN(4);
WAIT(-1);
END;

lsd(number,divisor)
 //  LongStringDivision will Divide a long string integer of ANY length by a  
 //  Number that the calcualator can handle, integer result only.
BEGIN
LOCAL ans:="";
LOCAL idx:=1;
LOCAL temp:=1;
temp:=number(idx)-48;
  WHILE temp<divisor DO
      temp:=temp*10+(number(idx+1)-48);
      idx:=idx+1;
  END;
  idx:=idx+1;
  WHILE size(number)>idx-1 DO
     ans:=ans+STRING(FLOOR(temp/divisor));
     temp:=(temp MOD divisor)*10+(number(idx)-48);
     idx:=idx+1;
  END;
  idx:=idx+1;
  ans:=ans+STRING(FLOOR(temp/divisor));
  IF size(ans)==0 THEN
    RETURN 0;
  ELSE
    RETURN ans;
  END;

END;
Find all posts by this user
Quote this message in a reply
05-19-2022, 08:15 PM (This post was last modified: 06-01-2022 08:02 PM by OlidaBel.)
Post: #2
RE: Tupper's 'Self-referencing' Formula
Interesting concept, thanks. again a mathematical curiosity.

How did you type , test and build this program ? Directly on the Prime screen or on a pc simulator ?
I find the Prime not very comfortable to program because of the ugly coloured keyboard (G2), the small screen. Working on a PC is maybe the only way to program it comfortably … what do you think ?

---
HP 48GX, Prime G2, 50G, 28S, 15c CE. SwissMicros DM42, DM15L
A long time ago : 11C, 15C, 28C.
Find all posts by this user
Quote this message in a reply
05-19-2022, 10:43 PM
Post: #3
RE: Tupper's 'Self-referencing' Formula
(05-19-2022 02:31 PM)matalog Wrote:  
This is a plot of Tupper’s Formula, it has of course lost all meaning, as the Formula it plots isn’t the Formula used to plot it. It was never self referencing anyway, as the main part of the Formula k, was never plotted in the result, but is the key to the ‘bitmap’ being plotted.

Making adjustments to the formula to “white out” portions that are not of interest is fairly straightforward. The Wikipedia page used to mention some of the adjusted / derived formulas (that remove most of the solutions, leaving just a sliver), but doesn’t seem to currently. There is still a link to

http://www.peda.com/selfplot/

which gives some examples. … but the precision required for the calculations is even higher…
Find all posts by this user
Quote this message in a reply
05-20-2022, 08:43 AM
Post: #4
RE: Tupper's 'Self-referencing' Formula
(05-19-2022 08:15 PM)OlidaBel Wrote:  Interesting concept, thanks. again a mathematical curiosity.

How did you type , test and build this program ? Directly on the Prime screen or on a pc simulator ?
I find the Prime not very comfortable to program because of the ugly coloured keyboard (G2), the small screen. Working on a PC is maybe the only way to program it comfortably … what do you think ?

I actually programmed the first long integer division part of this, lying on my bed, which isn't a comfortable place to code, but I wanted to get it done, and used the calculator itself.

I prefer to sit at a desk, with a standard keyboard and decent screen obviously.

I don't mind the keyboard much on the Prime, but yes, the orange colour for text on keys was a bad idea, they need a lot of light to be seen correctly.
Find all posts by this user
Quote this message in a reply
05-20-2022, 03:04 PM
Post: #5
RE: Tupper's 'Self-referencing' Formula
Hi, matalog

Instead of removing leading zeroes of quotient up-front, it may be simpler to fix afterwards.
Getting a quotient automatically generated remainder (for free), we might as well return both.

Code:
function divmod(num, den)           -- NOTE: num = string of digits
    local q, r, k = '0', 0, 2
    for i = 1, #num do
        local r2 = 10*r + (num:byte(i)-48)
        local q2 = floor(r2/den)
        q = q .. q2
        r = r2 - q2*den              -- num:sub(1,i) = q*den + r
    end
    while q:byte(k)==48 do k=k+1 end -- skip leading zeroes
    return q:sub(min(k,#q)), r       -- but, if all zeroes, keep 1 zero
end

Note that r2 does not involve mod function, thus more efficient.
If we don't care about quotient leading zeroes, after for-end loop, we can simply return q, r

lua> divmod('12345678901234567890', 111)
111222332443554665 75
Find all posts by this user
Quote this message in a reply
05-20-2022, 08:46 PM
Post: #6
RE: Tupper's 'Self-referencing' Formula
(05-20-2022 03:04 PM)Albert Chan Wrote:  Hi, matalog

Instead of removing leading zeroes of quotient up-front, it may be simpler to fix afterwards.
Getting a quotient automatically generated remainder (for free), we might as well return both.

Code:
function divmod(num, den)           -- NOTE: num = string of digits
    local q, r, k = '0', 0, 2
    for i = 1, #num do
        local r2 = 10*r + (num:byte(i)-48)
        local q2 = floor(r2/den)
        q = q .. q2
        r = r2 - q2*den              -- num:sub(1,i) = q*den + r
    end
    while q:byte(k)==48 do k=k+1 end -- skip leading zeroes
    return q:sub(min(k,#q)), r       -- but, if all zeroes, keep 1 zero
end

Note that r2 does not involve mod function, thus more efficient.
If we don't care about quotient leading zeroes, after for-end loop, we can simply return q, r

lua> divmod('12345678901234567890', 111)
111222332443554665 75

You refer to q2 as a string when you use
Code:
q = q .. q2
but you refer to it as a number when you use
Code:
local q2 = floor(r2/den)
. Is it a string or a number?
Find all posts by this user
Quote this message in a reply
05-20-2022, 08:55 PM
Post: #7
RE: Tupper's 'Self-referencing' Formula
(05-20-2022 08:46 PM)matalog Wrote:  You refer to q2 as a string when you use
Code:
q = q .. q2
but you refer to it as a number when you use
Code:
local q2 = floor(r2/den)
. Is it a string or a number?

q2 is a number, 0 to 9

For string concatenation, lua has implicit number/string conversion.
To write code explicitly, it is q = q .. tostring(q2)
Find all posts by this user
Quote this message in a reply
05-20-2022, 10:12 PM
Post: #8
RE: Tupper's 'Self-referencing' Formula
Okay, I think that translates as:

lsd(number,divisor)
BEGIN
LOCAL Q:="0";LOCAL R:=0;LOCAL R2:=0;LOCAL Q2:=0;LOCAL K=0;
FOR I FROM 1 TO size(number) DO
R2:=10*R+(number(I)-48);
Q2:=FLOOR(R2/divisor);
Q:=Q+STRING(Q2);
R:=R2-Q2*divisor;
END;
WHILE Q(1)==48 DO
Q:=RIGHT(Q,size(Q)-1);
END;
RETURN Q;
END;
That is 10 seconds faster for the purposes of this program, which is better.

My other version that uses a general division routine for the string integer division by 17 and then uses a special only divide by 2 routine for all of the binary divisions, is 50 seconds faster than your method in the same program.

Thanks for the info.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 2 Guest(s)