Aliquot sequence classifications: Difference between revisions

Tcl implementation added
(Tcl implementation added)
Line 1,269:
1488 non-term [1488 2480 3472 4464 8432 9424 10416 21328 22320 55056 95728 96720 236592 459792 881392 882384 1474608]
15355717786080 non-term [15355717786080 44534663601120]</pre>
 
 
=={{header|Tcl}}==
 
This solution creates an iterator from a coroutine to generate aliquot sequences. al_classify uses a "RESULT" exception to achieve some unusual control flow.
 
<lang Tcl>proc ProperDivisors {n} {
if {$n == 1} {return 0}
set divs 1
set sum 1
for {set i 2} {$i*$i <= $n} {incr i} {
if {! ($n % $i)} {
lappend divs $i
incr sum $i
if {$i*$i<$n} {
lappend divs [set d [expr {$n / $i}]]
incr sum $d
}
}
}
list $sum $divs
}
 
proc al_iter {n} {
yield [info coroutine]
while {$n} {
yield $n
lassign [ProperDivisors $n] n
}
yield 0
return -code break
}
 
proc al_classify {n} {
coroutine iter al_iter $n
set items {}
try {
set type "non-terminating"
while {[llength $items] < 16} {
set i [iter]
if {$i == 0} {
set type "terminating"
}
set ix [lsearch -exact $items $i]
set items [linsert $items 0 $i]
switch $ix {
-1 { continue }
0 { throw RESULT "perfect" }
1 { throw RESULT "amicable" }
default { throw RESULT "sociable" }
}
}
} trap {RESULT} {type} {
rename iter {}
set map {
perfect aspiring
amicable cyclic
sociable cyclic
}
if {$ix != [llength $items]-2} {
set type [dict get $map $type]
}
}
list $type [lreverse $items]
}
 
for {set i 1} {$i <= 10} {incr i} {
puts [format "%8d -> %-16s : %s" $i {*}[al_classify $i]]
}
 
foreach i {11 12 28 496 220 1184 12496 1264460 790 909 562 1064 1488 } {
puts [format "%8d -> %-16s : %s" $i {*}[al_classify $i]]
}
 
;# stretch goal .. let's time it:
set i 15355717786080
puts [time {
puts [format "%8d -> %-16s : %s" $i {*}[al_classify $i]]
}]</lang>
 
{{out}}
<pre>
1 -> terminating : 1 0
2 -> terminating : 2 1 0
3 -> terminating : 3 1 0
4 -> terminating : 4 3 1 0
5 -> terminating : 5 1 0
6 -> perfect : 6 6
7 -> terminating : 7 1 0
8 -> terminating : 8 7 1 0
9 -> terminating : 9 4 3 1 0
10 -> terminating : 10 8 7 1 0
11 -> terminating : 11 1 0
12 -> terminating : 12 16 15 9 4 3 1 0
28 -> perfect : 28 28
496 -> perfect : 496 496
220 -> amicable : 220 284 220
1184 -> amicable : 1184 1210 1184
12496 -> sociable : 12496 14288 15472 14536 14264 12496
1264460 -> sociable : 1264460 1547860 1727636 1305184 1264460
790 -> aspiring : 790 650 652 496 496
909 -> aspiring : 909 417 143 25 6 6
562 -> cyclic : 562 284 220 284
1064 -> cyclic : 1064 1336 1184 1210 1184
1488 -> non-terminating : 1488 2480 3472 4464 8432 9424 10416 21328 22320 55056 95728 96720 236592 459792 881392 882384
</pre>
The large number is still running ..
 
=={{header|zkl}}==
Anonymous user