Aliquot sequence classifications: Difference between revisions
Content added Content deleted
m (→{{header|REXX}}: adjusted output width to fit Rosetta Code's window width, added whitespace to the REXX section header.) |
|||
Line 2,083: | Line 2,083: | ||
{1488, Non-terminating, {1488, 2480, 3472, 4464, 8432, 9424, 10416, 21328, 22320, 55056, 95728, 96720, 236592, 459792, 881392, 882384, 1474608}} |
{1488, Non-terminating, {1488, 2480, 3472, 4464, 8432, 9424, 10416, 21328, 22320, 55056, 95728, 96720, 236592, 459792, 881392, 882384, 1474608}} |
||
{15355717786080, Non-terminating, {15355717786080, 44534663601120, 144940087464480, 471714103310688, 1130798979186912, 2688948041357088, 6050151708497568, 13613157922639968, 35513546724070632, 74727605255142168, 162658586225561832, 353930992506879768, 642678347124409032, 1125102611548462968, 1977286128289819992, 3415126495450394808, 7156435369823219592}}</pre> |
{15355717786080, Non-terminating, {15355717786080, 44534663601120, 144940087464480, 471714103310688, 1130798979186912, 2688948041357088, 6050151708497568, 13613157922639968, 35513546724070632, 74727605255142168, 162658586225561832, 353930992506879768, 642678347124409032, 1125102611548462968, 1977286128289819992, 3415126495450394808, 7156435369823219592}}</pre> |
||
=={{header|Nim}} |
|||
No special optimizations, but quite efficient. |
|||
<lang Nim> |
|||
import math |
|||
import strformat |
|||
from strutils import addSep |
|||
import times |
|||
type |
|||
# Classification categories. |
|||
Category = enum |
|||
Unknown |
|||
Terminating = "terminating" |
|||
Perfect = "perfect" |
|||
Amicable = "amicable" |
|||
Sociable = "sociable" |
|||
Aspiring = "aspiring" |
|||
Cyclic = "cyclic" |
|||
NonTerminating = "non-terminating" |
|||
# Aliquot sequence. |
|||
AliquotSeq = seq[int] |
|||
const Limit = 2^47 # Limit beyond which the category is considered to be "NonTerminating". |
|||
#--------------------------------------------------------------------------------------------------- |
|||
proc sumProperDivisors(n: int): int = |
|||
## Compute the sum of proper divisors.* |
|||
if n == 1: return 0 |
|||
result = 1 |
|||
for d in 2..sqrt(n.toFloat).int: |
|||
if n mod d == 0: |
|||
inc result, d |
|||
if n div d != d: |
|||
inc result, n div d |
|||
#--------------------------------------------------------------------------------------------------- |
|||
iterator aliquotSeq(n: int): int = |
|||
## Yield the elements of the aliquot sequence of "n". |
|||
## Stopped if the current value is null or equal to "n". |
|||
var k = n |
|||
while true: |
|||
k = sumProperDivisors(k) |
|||
yield k |
|||
#--------------------------------------------------------------------------------------------------- |
|||
proc `$`(a: AliquotSeq): string = |
|||
## Return the representation of an allquot sequence. |
|||
for n in a: |
|||
result.addSep(", ", 0) |
|||
result.addInt(n) |
|||
#--------------------------------------------------------------------------------------------------- |
|||
proc classification(n: int): tuple[cat: Category, values: AliquotSeq] = |
|||
## Return the category of the aliquot sequence of a number "n" and the sequence itself. |
|||
var count = 0 # Number of elements currently generated. |
|||
var prev = n # Previous element in the sequence. |
|||
result.cat = Unknown |
|||
for k in aliquotSeq(n): |
|||
inc count |
|||
if k == 0: |
|||
result.cat = Terminating |
|||
elif k == n: |
|||
result.cat = case count |
|||
of 1: Perfect |
|||
of 2: Amicable |
|||
else: Sociable |
|||
elif k > Limit or count > 16: |
|||
result.cat = NonTerminating |
|||
elif k == prev: |
|||
result.cat = Aspiring |
|||
elif k in result.values: |
|||
result.cat = Cyclic |
|||
prev = k |
|||
result.values.add(k) |
|||
if result.cat != Unknown: |
|||
break |
|||
#--------------------------------------------------------------------------------------------------- |
|||
let t0 = getTime() |
|||
for n in 1..10: |
|||
let (cat, aseq) = classification(n) |
|||
echo fmt"{n:14}: {cat:<20} {aseq}" |
|||
echo "" |
|||
for n in [11, 12, 28, 496, 220, 1184, 12496, 1264460, |
|||
790, 909, 562, 1064, 1488, 15355717786080.int]: |
|||
let (cat, aseq) = classification(n) |
|||
echo fmt"{n:14}: {cat:<20} {aseq}" |
|||
echo "" |
|||
echo fmt"Processed in {(getTime() - t0).inMilliseconds} ms." |
|||
</lang> |
|||
{{out}} |
|||
<pre> |
|||
1: terminating 0 |
|||
2: terminating 1, 0 |
|||
3: terminating 1, 0 |
|||
4: terminating 3, 1, 0 |
|||
5: terminating 1, 0 |
|||
6: perfect 6 |
|||
7: terminating 1, 0 |
|||
8: terminating 7, 1, 0 |
|||
9: terminating 4, 3, 1, 0 |
|||
10: terminating 8, 7, 1, 0 |
|||
11: terminating 1, 0 |
|||
12: terminating 16, 15, 9, 4, 3, 1, 0 |
|||
28: perfect 28 |
|||
496: perfect 496 |
|||
220: amicable 284, 220 |
|||
1184: amicable 1210, 1184 |
|||
12496: sociable 14288, 15472, 14536, 14264, 12496 |
|||
1264460: sociable 1547860, 1727636, 1305184, 1264460 |
|||
790: aspiring 650, 652, 496, 496 |
|||
909: aspiring 417, 143, 25, 6, 6 |
|||
562: cyclic 284, 220, 284 |
|||
1064: cyclic 1336, 1184, 1210, 1184 |
|||
1488: non-terminating 2480, 3472, 4464, 8432, 9424, 10416, 21328, 22320, 55056, 95728, 96720, 236592, 459792, 881392, 882384, 1474608, 2461648 |
|||
15355717786080: non-terminating 44534663601120, 144940087464480 |
|||
Processed in 110 ms. |
|||
</pre> |
|||
=={{header|Oforth}}== |
=={{header|Oforth}}== |