Eban numbers: Difference between revisions
Content added Content deleted
(Added AppleScript.) |
(→{{header|AppleScript}}: Rewritten to generate the numbers itself instead of just testing those thrown at it.) |
||
Line 36: | Line 36: | ||
=={{header|AppleScript}}== |
=={{header|AppleScript}}== |
||
<lang applescript>(* |
<lang applescript>(* |
||
Quickly generate all the (positive) eban numbers up to and including the |
|||
This assumes either positive or negative integer input and treats 0 as "zero" rather than as "nought" or "nil". |
|||
specified end number, then lose those before the start number. |
|||
Because of AppleScript's number precision at the time of writing, the range is limited to between > -10^15 and < 10^15. |
|||
0 is taken as "zero" rather than as "nought" or "nil". |
|||
WARNING: The getEbans() handler returns a potentially very long list of numbers. |
|||
Don't let such a list get assigned to a persistent variable or be the end result displayed in an editor! |
|||
*) |
*) |
||
on isEban(n) |
|||
on getEbans(startNumber, endNumber) |
|||
if (n < 2) then |
|||
script o |
|||
if (n > -2) then return false |
|||
property output : {} |
|||
property listCollector : missing value |
|||
end if |
|||
property temp : missing value |
|||
repeat 5 times -- Change to 7 times for > -10^21 to < 10^21. |
|||
end script |
|||
set x to n mod 1000 |
|||
if ((x > 66) or (x mod 2 is 1) or ((x < 30) and (x > 6)) or (x mod 10 is 8)) then return false |
|||
if (startNumber > endNumber) then set {startNumber, endNumber} to {endNumber, startNumber} |
|||
set n to n div 1000 |
|||
-- The range is limited to between 0 and 10^15 to keep within AppleScript's current number precision. |
|||
if (n is 0) then return true |
|||
-- Even so, some of the numbers may not /look/ right when displayed in a editor. |
|||
set limit to 10 ^ 15 - 1 |
|||
if (endNumber > limit) then set endNumber to limit |
|||
if (startNumber > limit) then set startNumber to limit |
|||
-- Initialise the output list with 0 and the sub-1000 ebans, stopping if the end number's reached. |
|||
-- The 0's needed for rest of the process, but is removed at the end. |
|||
repeat with tens in {0, 30, 40, 50, 60} |
|||
repeat with units in {0, 2, 4, 6} |
|||
set thisEban to tens + units |
|||
if (thisEban ≤ endNumber) then set end of o's output to thisEban |
|||
end repeat |
|||
end repeat |
end repeat |
||
return missing value -- Status unknown. Number out of range. |
|||
-- Repeatedly sweep the output list, adding new ebans formed from the addition of those found previously |
|||
end isEban |
|||
-- to a suitable power of 1000 times each one. Stop when the end number's reached or exceeded. |
|||
-- The output list may become very long and appending items to it individually take forever, so results are |
|||
-- collected in short, 1000-item lists, which are concatenated to the output at the end of each sweep. |
|||
set sweepLength to (count o's output) |
|||
set multiplier to 1000 |
|||
repeat while (thisEban < endNumber) -- Per sweep. |
|||
set o's temp to {} |
|||
set o's listCollector to {o's temp} |
|||
repeat with i from 2 to sweepLength -- Per eban found already. (Not the 0.) |
|||
set baseAmount to (item i of o's output) * multiplier |
|||
repeat with j from 1 to sweepLength by 1000 -- Per 1000-item list. |
|||
set z to j + 999 |
|||
if (z > sweepLength) then set z to sweepLength |
|||
repeat with k from j to z -- Per new eban. |
|||
set thisEban to baseAmount + (item k of o's output) |
|||
if (thisEban ≤ endNumber) then set end of o's temp to thisEban |
|||
if (thisEban ≥ endNumber) then exit repeat |
|||
end repeat |
|||
if (thisEban ≥ endNumber) then exit repeat |
|||
set o's temp to {} |
|||
set end of o's listCollector to o's temp |
|||
end repeat |
|||
if (thisEban ≥ endNumber) then exit repeat |
|||
end repeat |
|||
-- Concatentate this sweep's new lists together |
|||
set listCount to (count o's listCollector) |
|||
repeat until (listCount is 1) |
|||
set o's temp to {} |
|||
repeat with i from 2 to listCount by 2 |
|||
set end of o's temp to (item (i - 1) of o's listCollector) & (item i of o's listCollector) |
|||
end repeat |
|||
if (listCount mod 2 is 1) then set item -1 of o's temp to (end of o's temp) & (end of o's listCollector) |
|||
set o's listCollector to o's temp |
|||
set o's temp to {} |
|||
set listCount to (count o's listCollector) |
|||
end repeat |
|||
-- Concatenate the result to the output list and prepare to go round again. |
|||
set o's output to o's output & (beginning of o's listCollector) |
|||
set sweepLength to sweepLength * sweepLength |
|||
set multiplier to multiplier * multiplier |
|||
end repeat |
|||
-- Lose the initial 0 and any ebans before the specified start number. |
|||
set resultCount to (count o's output) |
|||
if (resultCount is 1) then |
|||
set o's output to {} |
|||
else |
|||
repeat with i from 2 to resultCount |
|||
if (item i of o's output ≥ startNumber) then exit repeat |
|||
end repeat |
|||
set o's output to items i thru resultCount of o's output |
|||
end if |
|||
if (endNumber = limit) then set end of o's output to "(Limit of AppleScript's number precision.)" |
|||
return o's output |
|||
end getEbans |
|||
-- Task code: |
-- Task code: |
||
Line 59: | Line 132: | ||
set AppleScript's text item delimiters to ", " |
set AppleScript's text item delimiters to ", " |
||
set |
set ebans to getEbans(0, 1000) |
||
set end of output to ((count ebans) as text) & " eban numbers between 0 and 1,000:" & (linefeed & " " & ebans) |
|||
repeat with i from 0 to 1000 |
|||
set ebans to getEbans(1000, 4000) |
|||
if (isEban(i) is true) then set end of collector to i |
|||
set end of output to ((count ebans) as text) & " between 1,000 and 4,000:" & (linefeed & " " & ebans) |
|||
end repeat |
|||
set end of output to ((count |
set end of output to ((count getEbans(0, 10000)) as text) & " up to and including 10,000" |
||
set end of output to ((count getEbans(0, 100000)) as text) & " up to and including 100,000" |
|||
set end of output to ((count getEbans(0, 1000000)) as text) & " up to and including 1,000,000" |
|||
set collector to {} |
|||
set end of output to ((count getEbans(0, 10000000)) as text) & " up to and including 10,000,000" |
|||
repeat with i from 1000 to 4000 |
|||
set ebans to getEbans(6.606606602E+10, 1.0E+12) |
|||
if (isEban(i) is true) then set end of collector to i |
|||
set end of output to ((count ebans) as text) & " between 66,066,066,020 and 1,000,000,000,000:" & (linefeed & " " & ebans) |
|||
end repeat |
|||
set end of output to ((count collector) as text) & " eban numbers between 1,000 and 4,000:" & linefeed & " " & collector |
|||
set counter to 0 |
|||
set landmarks to {10000, 100000, 1000000, 10000000} |
|||
repeat with i from 0 to 10000000 |
|||
if (isEban(i) is true) then set counter to counter + 1 |
|||
if (i mod 10000 is 0) then |
|||
repeat with j from 1 to 4 |
|||
if (item j of landmarks is i) then |
|||
set end of output to (counter as text) & " eban numbers up to and including " & ¬ |
|||
item j of {"10,000", "100,000", "1,000,000", "10,000,000"} |
|||
exit repeat |
|||
end if |
|||
end repeat |
|||
end if |
|||
end repeat |
|||
set AppleScript's text item delimiters to linefeed |
set AppleScript's text item delimiters to linefeed |
||
Line 98: | Line 155: | ||
<lang applescript>"19 eban numbers between 0 and 1,000: |
<lang applescript>"19 eban numbers between 0 and 1,000: |
||
2, 4, 6, 30, 32, 34, 36, 40, 42, 44, 46, 50, 52, 54, 56, 60, 62, 64, 66 |
2, 4, 6, 30, 32, 34, 36, 40, 42, 44, 46, 50, 52, 54, 56, 60, 62, 64, 66 |
||
21 |
21 between 1,000 and 4,000: |
||
2000, 2002, 2004, 2006, 2030, 2032, 2034, 2036, 2040, 2042, 2044, 2046, 2050, 2052, 2054, 2056, 2060, 2062, 2064, 2066, 4000 |
2000, 2002, 2004, 2006, 2030, 2032, 2034, 2036, 2040, 2042, 2044, 2046, 2050, 2052, 2054, 2056, 2060, 2062, 2064, 2066, 4000 |
||
79 |
79 up to and including 10,000 |
||
399 |
399 up to and including 100,000 |
||
399 |
399 up to and including 1,000,000 |
||
1599 |
1599 up to and including 10,000,000 |
||
16 between 66,066,066,020 and 1,000,000,000,000: |
|||
6.606606603E+10, 6.6066066032E+10, 6.6066066034E+10, 6.6066066036E+10, 6.606606604E+10, 6.6066066042E+10, 6.6066066044E+10, 6.6066066046E+10, 6.606606605E+10, 6.6066066052E+10, 6.6066066054E+10, 6.6066066056E+10, 6.606606606E+10, 6.6066066062E+10, 6.6066066064E+10, 6.6066066066E+10"</lang> |
|||
=={{header|AWK}}== |
=={{header|AWK}}== |