Data update

This commit is contained in:
Ingy döt Net 2026-04-30 12:34:36 -04:00
parent 4bb20c9b71
commit cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions

View file

@ -0,0 +1,96 @@
with Ada.Text_IO;
with Ada.Integer_Text_IO;
procedure Show_Fusc is
generic
Precalculate : Natural;
package Fusc_Sequences is
function Fusc (N : in Natural) return Natural;
end Fusc_Sequences;
package body Fusc_Sequences is
Precalculated_Fusc : array (0 .. Precalculate) of Natural;
function Fusc_Slow (N : in Natural) return Natural is
begin
if N = 0 or N = 1 then
return N;
elsif N mod 2 = 0 then
return Fusc_Slow (N / 2);
else
return Fusc_Slow ((N - 1) / 2) + Fusc_Slow ((N + 1) / 2);
end if;
end Fusc_Slow;
function Fusc (N : in Natural) return Natural is
begin
if N <= Precalculate then
return Precalculated_Fusc (N);
elsif N mod 2 = 0 then
return Fusc (N / 2);
else
return Fusc ((N - 1) / 2) + Fusc ((N + 1) / 2);
end if;
end Fusc;
begin
for N in Precalculated_Fusc'Range loop
Precalculated_Fusc (N) := Fusc_Slow (N);
end loop;
end Fusc_Sequences;
package Fusc_Sequence is
new Fusc_Sequences (Precalculate => 200_000);
function Fusc (N : in Natural) return Natural
renames Fusc_Sequence.Fusc;
procedure Print_Small_Fuscs is
use Ada.Text_IO;
begin
Put_Line ("First 61 numbers in the fusc sequence:");
for N in 0 .. 60 loop
Put (Fusc (N)'Image);
Put (" ");
end loop;
New_Line;
end Print_Small_Fuscs;
procedure Print_Large_Fuscs (High : in Natural) is
use Ada.Text_IO;
use Ada.Integer_Text_IO;
subtype N_Range is Natural range Natural'First .. High;
F : Natural;
Len : Natural;
Max_Len : Natural := 0;
Placeholder : String := " n fusc(n)";
Image_N : String renames Placeholder (1 .. 8);
Image_Fusc : String renames Placeholder (10 .. Placeholder'Last);
begin
New_Line;
Put_Line ("Printing all largest Fusc numbers upto " & High'Image);
Put_Line (Placeholder);
for N in N_Range loop
F := Fusc (N);
Len := F'Image'Length;
if Len > Max_Len then
Max_Len := Len;
Put (Image_N, N);
Put (Image_Fusc, F);
Put (Placeholder);
New_Line;
end if;
end loop;
end Print_Large_Fuscs;
begin
Print_Small_Fuscs;
Print_Large_Fuscs (High => 20_000_000);
end Show_Fusc;

View file

@ -0,0 +1,110 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. FUSC-SEQUENCE.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 FUSC-MAX PIC 9(8) COMP VALUE 2000.
01 FUSC-TABLE.
05 FUSC-VAL OCCURS 2000 TIMES
PIC 9(8) COMP.
01 WS-N PIC 9(8) COMP.
01 WS-I PIC 9(2) COMP.
01 WS-J PIC 9(8) COMP.
01 WS-START PIC 9(8) COMP.
01 WS-VAL PIC S9(8) COMP.
01 WS-HALF PIC 9(8) COMP.
01 WS-HALF-MINUS PIC 9(8) COMP.
01 WS-HALF-PLUS PIC 9(8) COMP.
01 WS-POWER PIC 9(8) COMP.
01 WS-IDX PIC 9(8) COMP.
01 WS-FOUND PIC X VALUE 'N'.
01 WS-DISPLAY-IDX PIC Z(7)9.
01 WS-DISPLAY-VAL PIC Z(7)9.
PROCEDURE DIVISION.
000-MAIN SECTION.
MAIN-PARA.
PERFORM 100-INIT-FUSC
PERFORM 200-DISPLAY-FIRST-61
PERFORM 300-DISPLAY-LENGTH-RECORDS
STOP RUN.
*>----------------------------------------------------------------
*> Initialize the FUSC array
*>----------------------------------------------------------------
100-INIT-FUSC SECTION.
MOVE 0 TO FUSC-VAL(1)
MOVE 1 TO FUSC-VAL(2)
PERFORM VARYING WS-N FROM 3 BY 1
UNTIL WS-N > FUSC-MAX
EVALUATE TRUE
WHEN FUNCTION MOD(WS-N - 1, 2) = 0
COMPUTE WS-HALF = (WS-N - 1) / 2 + 1
MOVE FUSC-VAL(WS-HALF) TO FUSC-VAL(WS-N)
WHEN OTHER
COMPUTE WS-HALF-MINUS =
(WS-N - 2) / 2 + 1
COMPUTE WS-HALF-PLUS =
WS-N / 2 + 1
COMPUTE FUSC-VAL(WS-N) =
FUSC-VAL(WS-HALF-MINUS) +
FUSC-VAL(WS-HALF-PLUS)
END-EVALUATE
END-PERFORM.
*>----------------------------------------------------------------
*> Display first 61 fusc numbers (0-based index 0..60)
*>----------------------------------------------------------------
200-DISPLAY-FIRST-61 SECTION.
DISPLAY "Show the first 61 fusc numbers "
"(starting at zero) in a horizontal format"
PERFORM VARYING WS-N FROM 1 BY 1
UNTIL WS-N > 61
MOVE FUSC-VAL(WS-N) TO WS-DISPLAY-VAL
DISPLAY FUNCTION TRIM(WS-DISPLAY-VAL
LEADING) " " WITH NO ADVANCING
END-PERFORM
DISPLAY " ".
*>----------------------------------------------------------------
*> Display fusc numbers whose value first exceeds 10^i
*>----------------------------------------------------------------
300-DISPLAY-LENGTH-RECORDS SECTION.
DISPLAY " "
DISPLAY "Show the fusc number (and its index) whose "
"length is greater than any previous fusc number length."
MOVE 1 TO WS-START
PERFORM VARYING WS-I FROM 0 BY 1
UNTIL WS-I > 5
EVALUATE WS-I
WHEN 0
MOVE -1 TO WS-VAL
WHEN OTHER
MOVE 1 TO WS-POWER
PERFORM VARYING WS-IDX FROM 1 BY 1
UNTIL WS-IDX > WS-I
MULTIPLY 10 BY WS-POWER
END-PERFORM
MOVE WS-POWER TO WS-VAL
END-EVALUATE
MOVE 'N' TO WS-FOUND
PERFORM VARYING WS-J FROM WS-START BY 1
UNTIL WS-J > FUSC-MAX OR WS-FOUND = 'Y'
IF FUSC-VAL(WS-J) > WS-VAL
COMPUTE WS-N = WS-J - 1
MOVE WS-N TO WS-DISPLAY-IDX
MOVE FUSC-VAL(WS-J) TO WS-DISPLAY-VAL
DISPLAY "fusc["
FUNCTION TRIM(WS-DISPLAY-IDX LEADING)
"] = "
FUNCTION TRIM(WS-DISPLAY-VAL LEADING)
MOVE WS-J TO WS-START
MOVE 'Y' TO WS-FOUND
END-IF
END-PERFORM
END-PERFORM.

View file

@ -0,0 +1,185 @@
!
! Fusc sequence
! tested with Intel ifx (IFX) 2025.2.1 20250806 on Kubuntu 25.04
! GNU Fortran (Ubuntu 14.2.0-19ubuntu2) 14.2.0 on Kubuntu 25.04
! VSI Fortran x86-64 V8.6-001 on OpenVMS x86_64 V9.2-3
! No Non-standard features used, should compile on any fairly recent Fortran.
! U.B., September 2025
program FuscNumbers
implicit none
integer, parameter :: kInt = 4
integer, parameter :: maxdigs = 6
integer, parameter :: strLen = 20
integer (kind=kInt), allocatable :: fuscMem(:)
integer :: capacity, content ! usage of above container
integer (kind=kInt) :: w,c,t
integer (kind=kINt) :: i, f
integer :: d=0, n=61, digs=1
character (len=strLen) :: sNum(2) ! for formatted output of integer numbers
content = 0
capacity = 1024
call resize (fuscMem, capacity)
call push (0)
call push (1)
w = -1
c = 0
n = 61
write ( *, '("First " , i0, " numbers in the fusc sequence:" )') n
i = 0
do while (i .lt. 61)
f = fusc(i)
if (mod (i, 20) .ne. 0) then
write (*, '(i2, x)', advance='no' ) f
else
write (*, '(i2,x)') f
endif
i = i + 1
end do
write (*, '(/"Fusc numbers with more digits than any previous (1 to 6 digits):")')
write (*, '( " Index Value")')
i = 0
do while (digs <= maxdigs)
f = fusc (i)
if (f .ge. d) then
! show all numbers with commas (if appropriate).
snum(1) = GroupedDigits(i, 10)
snum(2) = GroupedDigits(f,10)
if (digs .gt.1) then
write (*,'(i2, " digits: ", A10,x,A )' ) digs, snum(1), snum(2)
else
write (*,'(i2, " digit : ", A10,x,A )' ) digs, snum(1), snum(2)
endif
if (d .eq. 0) then
d = 10
else
d = d * 10
endif
digs = digs + 1
if (digs .gt. 6) exit
end if
i = i + 1
end do
contains
function fusc (n) result (ret)
integer (kind=kint), intent(in) :: n
integer (kind=kInt) ret
if (n .lt. content) then
ret = fuscMem (1+n)
else
if (iand (n,1_kint) .eq. 0) then ! Even n has bit 0 = zero
ret = fuscMem(1+n/2)
call push (ret) ! Store for future use.
else ! Else its odd.
ret = fuscMem(1+(n-1)/2) + fuscMem(1+(n+2)/2)
call push (ret)
end if
end if
end function fusc
! ---------------------
! memoize another value
! ---------------------
subroutine push (k)
integer (kind=kint), intent (in) :: k
content = content+1
! If we would exceed capacity of array 'Words', we need to increment capacity
if (content .gt. capacity) then
capacity = 2*capacity
call resize (fuscMem, capacity)
end if
fuscMem(content) = k
end subroutine push
! ----------------------------------------------
! Increase allocated size of dynamic array 'var'
! ----------------------------------------------
subroutine resize(var, newSize)
integer (kind=kint), allocatable, intent(inout) :: var(:) ! The array to be increased
integer, intent(in) :: newSize ! The new size of var
integer (kind=kint), allocatable :: tmp(:) ! Temporary storage
integer :: oldSize ! Current array size
integer :: ii ! Loop index
! Copy allocated values to temporary, then allocate var with
! new size and copy back saved values.
! Could be done with move_alloc but this would not be portable to OpenVMS Fortran
if (allocated(var)) then
oldSize = size(var)
else
oldSize = 0
end if
if (newSize .gt. oldSize) then ! only increment
if (oldSize .gt.0) then
allocate(tmp (oldSize))
tmp(:oldSize) = var(:oldSize)
deallocate (var)
end if
allocate(var(newSize))
if (allocated(tmp) .and. allocated (var) ) then
oldSize = min(size(tmp, 1), size(var, 1))
var(:oldSize) = tmp(:oldSize)
deallocate (tmp)
end if
end if
end subroutine resize
! ----------------------------------------------------------------
! Fortran does not have a way to use locales for output.
! Manual insert of separating commas such as 1,345,678 for 1345678
! ----------------------------------------------------------------
function GroupedDigits (n, width) result (outStr)
integer(kind=kint), intent (in) :: n
integer :: width
character (len=width) :: outStr
character (len=2*strLen) :: workStr
integer :: ii, jj, cnt, trueLen
! Write n into a string, then copy the digits to a second string,
! inserting separater after every 3 digits.
write (workStr, '(i0)') n
! Adjust left, then cutoff trailing blanks
workstr = adjustl (workstr)
trueLen = len_trim (workStr)
outStr = ' '
jj = width
cnt = 0
do ii=trueLen, 1, -1 ! Copy backwards for correct grouping.
outStr (jj:jj) = workStr (ii:ii)
jj = jj -1
cnt = cnt + 1
! Insert comma after 3 digits, but only if more digits follow.
if (mod (cnt, 3) .eq. 0 .and. ii .gt. 1 .and. workStr(ii-1:ii-1) .ne. ' ') then
outStr (jj:jj) = ','
jj = jj - 1
endif
end do
end function GroupedDigits
end program FuscNumbers

View file

@ -0,0 +1,27 @@
local fmt = require "fmt"
print("The first 61 numbers in the fusc sequence are:")
local fusc = {0, 1}
local fusc2 = {{0, 0}}
local max_len = 1
local n = 2
while n < 20e6 do -- limit to indices under 20 million say
local f = (n % 2 == 0) ? fusc[n/2 + 1] : fusc[(n - 1)/2 + 1] + fusc[(n+1)/2 + 1]
fusc:insert(f)
local len = #tostring(f)
if len > max_len then
max_len = len
if n <= 60 then
fusc2:insert({n, f})
else
fmt.print("%10s %s", fmt.int(n), fmt.int(f))
end
end
if n == 60 then
for fusc as e do io.write($"{e} ") end
print("\n\nFirst terms longer than any previous ones for indices < 20,000,000:")
print(" Index Value")
for fusc2 as iv do fmt.print("%10d %d", iv[1], iv[2]) end
end
n += 1
end