Add tasks for all the new languages

This commit is contained in:
Tina Müller 2016-12-05 23:44:36 +01:00
parent 9dc3c2bb62
commit bba7bfd280
13208 changed files with 134745 additions and 0 deletions

View file

@ -0,0 +1,54 @@
;; implementation of Floyd algorithm to find cycles in a graph
;; see Wikipedia https://en.wikipedia.org/wiki/Cycle_detection
;; returns (cycle-length cycle-starter steps)
;; steps = 0 if no cycle found
;; it's all about a tortoise 🐢 running at speed f(x) after a hare 🐰 at speed f(f (x))
;; when they meet, a cycle is found
(define (floyd f x0 steps maxvalue)
(define lam 1) ; cycle length
(define tortoise (f x0))
(define hare (f (f x0)))
;; cyclic ? yes if steps > 0
(while (and (!= tortoise hare) (> steps 0))
(set!-values (tortoise hare) (values (f tortoise) (f (f hare))))
#:break (and (> hare maxvalue) (set! steps 0))
(set! steps (1- steps)))
;; first repetition = cycle starter
(set! tortoise x0)
(while (and (!= tortoise hare) (> steps 0))
(set!-values (tortoise hare) (values (f tortoise) (f hare))))
;; length of shortest cycle
(set! hare (f tortoise))
(while (and (!= tortoise hare) (> steps 0))
(set! hare (f hare))
(set! lam (1+ lam)))
(values lam tortoise steps))
;; find cycle and classify
(define (taxonomy n (steps 16) (maxvalue 140737488355328))
(define-values (cycle starter steps) (floyd sum-divisors n steps maxvalue))
(write n
(cond
(( = steps 0) 'non-terminating)
(( = starter 0) 'terminating)
((and (= starter n) (= cycle 1)) 'perfect)
((and (= starter n) (= cycle 2)) 'amicable)
((= starter n) 'sociable )
((= cycle 1) 'aspiring )
(else 'cyclic)))
(aliquote n starter)
)
;; print sequence
(define (aliquote x0 (starter -1) (end -1 )(n 8))
(for ((i n))
(write x0)
(set! x0 (sum-divisors x0))
#:break (and (= x0 end) (write x0))
(when (= x0 starter) (set! end starter)))
(writeln ...))

View file

@ -0,0 +1,39 @@
(lib 'math)
(lib 'bigint)
(for-each taxonomy (range 1 13))
1 terminating 1 0 0 ...
2 terminating 2 1 0 0 ...
3 terminating 3 1 0 0 ...
4 terminating 4 3 1 0 0 ...
5 terminating 5 1 0 0 ...
6 perfect 6 6 6 ...
7 terminating 7 1 0 0 ...
8 terminating 8 7 1 0 0 ...
9 terminating 9 4 3 1 0 0 ...
10 terminating 10 8 7 1 0 0 ...
11 terminating 11 1 0 0 ...
12 terminating 12 16 15 9 4 3 1 0 0 ...
(for-each taxonomy '( 28 496 220 1184 12496 1264460 790 909 562 1064 1488 15355717786080))
28 perfect 28 28 28 ...
496 perfect 496 496 496 ...
220 amicable 220 284 220 284 220 ...
1184 amicable 1184 1210 1184 1210 1184 ...
12496 sociable 12496 14288 15472 14536 14264 12496 14288 15472 ...
1264460 sociable 1264460 1547860 1727636 1305184 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 ...
15355717786080 non-terminating 15355717786080 44534663601120 144940087464480 471714103310688 1130798979186912 2688948041357088 6050151708497568 13613157922639968 ...
(taxonomy 1000) ;; 1000 non-terminating after 16 steps
1000 non-terminating 1000 1340 1516 1144 1376 1396 1054 674 ...
(taxonomy 1000 32) ;; but terminating if we increase the number of steps
1000 terminating
1000 1340 1516 1144 1376 1396 1054 674 340 416 466 236 184 176 196 203 37 1 0 0 ...

View file

@ -0,0 +1,27 @@
Integer method: properDivs
| i l |
ListBuffer new dup add(1) ->l
2 self nsqrt tuck for: i [ self i mod ifFalse: [ l add(i) l add(self i / ) ] ]
sq self == ifTrue: [ l removeLast drop ]
l sort ;
: aliquot(n) // ( n -- aList ) : Returns aliquot sequence of n
| end l |
2 47 pow ->end
ListBuffer new dup add(n) dup ->l
while (l size 16 < l last 0 <> and l last end <= and) [ l last properDivs sum l add ] ;
: aliquotClass(n) // ( n -- aList aString ) : Returns aliquot sequence and classification
| l i j |
n aliquot dup ->l
l last 0 == ifTrue: [ "terminate" return ]
l second n == ifTrue: [ "perfect" return ]
l third n == ifTrue: [ "amicable" return ]
l indexOfFrom(n, 2) ifNotNull: [ "sociable" return ]
l size loop: i [
l indexOfFrom(l at(i), i 1 +) -> j
j i 1 + == ifTrue: [ "aspiring" return ]
j ifNotNull: [ "cyclic" return ]
]
"non-terminating" ;

View file

@ -0,0 +1,33 @@
function aliquot(atom n)
sequence s = {n}
integer k
if n=0 then return {"terminating",{0}} end if
while length(s)<16
and n<140737488355328 do
n = sum(factors(n,-1))
k = find(n,s)
if k then
if k=1 then
if length(s)=1 then return {"perfect",s}
elsif length(s)=2 then return {"amicable",s}
end if return {"sociable",s}
elsif k=length(s) then return {"aspiring",s}
end if return {"cyclic",append(s,n)}
elsif n=0 then return {"terminating",s}
end if
s = append(s,n)
end while
return {"non-terminating",s}
end function
function flat_d(sequence s)
for i=1 to length(s) do s[i] = sprintf("%d",s[i]) end for
return join(s,",")
end function
constant n = tagset(12)&{28, 496, 220, 1184, 12496, 1264460, 790, 909, 562, 1064, 1488, 15355717786080}
sequence class, dseq
for i=1 to length(n) do
{class, dseq} = aliquot(n[i])
printf(1,"%14d => %15s, {%s}\n",{n[i],class,flat_d(dseq)})
end for

View file

@ -0,0 +1,59 @@
# "until" is available in more recent versions of jq
# than jq 1.4
def until(cond; next):
def _until:
if cond then . else (next|_until) end;
_until;
# unordered
def proper_divisors:
. as $n
| if $n > 1 then 1,
( range(2; 1 + (sqrt|floor)) as $i
| if ($n % $i) == 0 then $i,
(($n / $i) | if . == $i then empty else . end)
else empty
end)
else empty
end;
# sum of proper divisors, or 0
def pdsum:
[proper_divisors] | add // 0;
# input is n
# maxlen defaults to 16;
# maxterm defaults to 2^47
def aliquot(maxlen; maxterm):
(maxlen // 15) as $maxlen
| (maxterm // 40737488355328) as $maxterm
| if . == 0 then "terminating at 0"
else
# [s, slen, new] = [[n], 1, n]
[ [.], 1, .]
| until( type == "string" or .[1] > $maxlen or .[2] > $maxterm;
.[0] as $s | .[1] as $slen
| ($s | .[length-1] | pdsum) as $new
| if ($s|index($new)) then
if $s[0] == $new then
if $slen == 1 then "perfect \($s)"
elif $slen == 2 then "amicable: \($s)"
else "sociable of length \($slen): \($s)"
end
elif ($s | .[length-1]) == $new then "aspiring: \($s)"
else "cyclic back to \($new): \($s)"
end
elif $new == 0 then "terminating: \($s + [0])"
else [ ($s + [$new]), ($slen + 1), $new ]
end )
| if type == "string" then . else "non-terminating: \(.[0])" end
end;
def task:
def pp: "\(.): \(aliquot(null;null))";
(range(1; 11) | pp),
"",
((11, 12, 28, 496, 220, 1184, 12496, 1264460,
790, 909, 562, 1064, 1488, 15355717786080) | pp);
task

View file

@ -0,0 +1,26 @@
$ jq -n -r -f aliquot.jq
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]
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]
496: perfect [496]
220: amicable: [220,284]
1184: amicable: [1184,1210]
12496: sociable of length 5: [12496,14288,15472,14536,14264]
1264460: sociable of length 4: [1264460,1547860,1727636,1305184]
790: aspiring: [790,650,652,496]
909: aspiring: [909,417,143,25,6]
562: cyclic back to 284: [562,284,220]
1064: cyclic back to 1184: [1064,1336,1184,1210]
1488: non-terminating: [1488,2480,3472,4464,8432,9424,10416,21328,22320,55056,95728,96720,236592,459792,881392,882384]
15355717786080: non-terminating: [15355717786080,44534663601120]