Self numbers: Difference between revisions

m
→‎{{header|Phix}}: spotted another unnecessary test (counter!=startIndex), hoisted some loops into doneAfterAdding
m (→‎first 50 self numbers: added a feature to the program.)
m (→‎{{header|Phix}}: spotted another unnecessary test (counter!=startIndex), hoisted some loops into doneAfterAdding)
Line 900:
sequence output
 
function doneAfterAdding(integer interval, n)
-- Advance to the next self number in the sequence, append it to the output if required, indicate if finished.
currentSelffor +i=1 intervalto n do
counter currentSelf += 1interval
counter += test1
if counter < startIndex then return false end if
if (testcounter >= startIndex) then
output &= currentSelf
return (counter = endIndex)
end if
if counter <= startIndexendIndex then return falsetrue end if
end for
return false
end function
 
function selfNumbers(sequence indexRange)
startIndex = indexRange[1]
Line 917 ⟶ 921:
-- Main process. Start with the single-digit odd numbers and first run.
if doneAfterAdding(112,5) then return output end if
for i=1 to 5 do
if doneAfterAdding(211,9) then return output end if
end for
-- Fast forward to the last self number before the lowest-order block containing the first number required.
for i=1 to 9 do
-- The highest-order blocks whose ends this is thought to handle correctly contain 97,777,777,778 self numbers.
if doneAfterAdding(11) then return output end if
-- The difference between equivalently positioned numbers in these blocks is 1,000,000,000,001.
end for
-- The figures for successively lower-order blocks are obtained by successively removing 7s and 0s!
 
atom indexDiff = 97777777778,
-- If necessary, fast forward to the last self number before the
numericDiff = floor(numericDiff/10) + 11000000000001
-- lowest-order block containing the first number required.
ifwhile indexDiff>=98 and counter!=startIndex thendo
if counter+indexDiff > startIndex then
-- The highest-order blocks whose ends this is thought to handle correctly contain 97,777,777,778 self numbers.
indexDiff = floor(indexDiff/10) + 1
-- The difference between equivalently positioned numbers in these blocks is 1,000,000,000,001.
numericDiff = floor(numericDiff/10) + 1
-- The figures for successively lower-order blocks are obtained by successively removing 7s and 0s!
atom indexDiff = 97777777778,else
counter numericDiff += 1000000000001indexDiff
while indexDiff >= 98 andcurrentSelf counter !+= startIndex donumericDiff
end if
atom test = counter + indexDiff
end forwhile
if (test > startIndex) then
indexDiff = floor(indexDiff/10) + 1
numericDiff = floor(numericDiff/10) + 1
else
counter = test
currentSelf += numericDiff
end if
end while
end if
-- Sequencing loop, per lowest-order block.
Line 948 ⟶ 944:
-- Eight ten-number runs, each at a numeric interval of 2 from the end of the previous one.
for i=1 to 8 do
if doneAfterAdding(2,1) then return output end if
forif j=1doneAfterAdding(11,9) tothen 9return output end doif
if doneAfterAdding(11) then return output end if
end for
end for
-- Two shorter runs, the second at an interval inversely related to their length.
integer intervalshorterRunLength = 28,
shorterRunLength = 9,
temp = floor(currentSelf/1000)
-- Work out a shorter run length based on the most significant digit change about to happen.
Line 962 ⟶ 955:
temp = floor(temp/10)
end while
 
integer interval = 2
for i=1 to 2 do
if doneAfterAdding(interval,1) then return output end if
forif j=1doneAfterAdding(11,shorterRunLength) tothen shorterRunLength-1return output end doif
interval += (109-shorterRunLength)*13
if doneAfterAdding(11) then return output end if
end for
interval += (10-shorterRunLength)*13
end for
end while
7,794

edits