42 lines
956 B
Plaintext
42 lines
956 B
Plaintext
!YS-v0
|
|
|
|
# Use *' (vs. *) to allow arbitrary length arithmetic:
|
|
mul =: value("*'")
|
|
|
|
# Number of random times to test each n:
|
|
TIMES =: 1000000
|
|
|
|
defn main(max=20):
|
|
say: "\tAvg\tExp\tDiff"
|
|
|
|
doseq n (1 .. max):
|
|
anal =: analytical(n):F
|
|
avg =: avg-cycle-length(n TIMES):F
|
|
diff =: abs(100 * (1 - (avg / anal)))
|
|
say:
|
|
format "%3d\t%.4f\t%.4f\t%.2f%%": n avg anal diff
|
|
|
|
defn factorial(n):
|
|
:: n!
|
|
range(1 n.++): .mul(*)
|
|
|
|
defn analytical(n):
|
|
:: Analytical computation
|
|
1 .. n:
|
|
.map(\(factorial(n) / pow(n _) / factorial(n - _)))
|
|
.sum()
|
|
|
|
defn single-test-cycle-length(n):
|
|
:: Single random test of cycle length
|
|
loop count 0, bits 0, x 1:
|
|
if bit-and(x bits) == 0:
|
|
recur: count.++ bit-or(bits x) bit-shift-left(1 rand-int(n))
|
|
else: count
|
|
|
|
defn avg-cycle-length(n times):
|
|
:: Average results of single tests of cycle lengths
|
|
div _ times:
|
|
sum:
|
|
for i (range times):
|
|
single-test-cycle-length: n
|