Self numbers: Difference between revisions

Added AppleScript.
No edit summary
(Added AppleScript.)
Line 12:
;*[[oeis:A003052|OEIS: A003052 - Self numbers or Colombian numbers]]
;*[[wp:Self_number|Wikipedia: Self numbers]]
 
=={{header|AppleScript}}==
 
I couldn't follow the math in the Wikipedia entry, nor the discussion and code here so far. But an initial expedient of generating a list of all the integers from 1 to just over ten times the required number of results and then deleting those that ''could'' be derived using the described method revealed the sequencing pattern on which the code below is based. The results match those from the "expedience" code as far as that can sensibly be pushed and the hundred millionth self number is reported as the hoped-for figure, so the intervening results are presumed to be correct too. The code would need modification (and a faster computer!) if self numbers with more than about 11 or 12 digits were required.
 
<lang applescript>(*
Base-10 self numbers by index (single or range).
After the initial single-digit numbers, the sequence follows an observed pattern whereby self numbers occur in groups,
the interval between consecutive numbers in a group being 11 and that between groups 2.
Groups occur in blocks of ten: eight ten-number groups sandwiched between two shorter groups.
The intervals between blocks and the lengths of the shorter groups
depend the most signficant digit to have changed at the time they're set.
*)
on selfNumbers(indexRange)
-- Subscript to monitor progress, store required results, and indicate when finished.
set indexRange to indexRange as list
script storer
property startIndex : beginning of indexRange
property endIndex : end of indexRange
property counter : 0
property output : {}
on doneAfter(thisSelf)
set counter to counter + 1
if (counter < startIndex) then return false
set end of my output to thisSelf
return (counter = endIndex)
end doneAfter
end script
-- Start with the single-digit odds.
set thisSelf to -1
repeat 4 times
set thisSelf to thisSelf + 2
if (storer's doneAfter(thisSelf)) then return storer's output
end repeat
-- Main loop.
set sentinel to thisSelf
set shortGroupLength to 10
repeat -- Per block.
-- First short group.
-- Its length is initially 10, then the same as that of the second short group of the preceding block.
-- The interval before it depends on the most significant digit to have
-- ticked over since the first (sentinel) number of the preding block.
set interval to 2
set temp1 to sentinel div 1000
set temp2 to thisSelf div 1000
repeat until (temp1 = temp2)
set interval to interval + 13
set temp1 to temp1 div 10
set temp2 to temp2 div 10
end repeat
set thisSelf to thisSelf + interval
set sentinel to thisSelf
if (storer's doneAfter(thisSelf)) then return storer's output
-- Groups' internal intervals are all 11.
repeat (shortGroupLength - 1) times
set thisSelf to thisSelf + 11
if (storer's doneAfter(thisSelf)) then return storer's output
end repeat
-- Eight ten-number groups, each preceded by an interval of 2.
repeat 8 times
set thisSelf to thisSelf + 2
if (storer's doneAfter(thisSelf)) then return storer's output
repeat 9 times
set thisSelf to thisSelf + 11
if (storer's doneAfter(thisSelf)) then return storer's output
end repeat
end repeat
-- Second short group.
-- Its length depends on the most significant digit to tick over at the thousands boundary within it.
-- The interval before it is 2.
set thisSelf to thisSelf + 2
if (storer's doneAfter(thisSelf)) then return storer's output
set i to 2
set shortGroupLength to 9
repeat until (i > shortGroupLength)
set thisSelf to thisSelf + 11
if (storer's doneAfter(thisSelf)) then return storer's output
if (thisSelf mod 1000 < 11) then
set temp to thisSelf div 1000
repeat while (temp mod 10 is 0)
set shortGroupLength to shortGroupLength - 1
set temp to temp div 10
end repeat
end if
set i to i + 1
end repeat
end repeat
return storer's output
end selfNumbers
 
-- Demo calls:
-- First to fiftieth self numbers.
selfNumbers({1, 50})
--> {1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, 97, 108, 110, 121, 132, 143, 154, 165, 176, 187, 198, 209, 211, 222, 233, 244, 255, 266, 277, 288, 299, 310, 312, 323, 334, 345, 356, 367, 378, 389, 400, 411, 413, 424, 435, 446, 457, 468}
 
-- One hundred millionth:
selfNumbers(100000000)
--> {1022727208}</lang>
 
=={{header|C}}==
557

edits