#!/usr/bin/ruby # Tests for various Number divisor functions. var h = Hash( divisors => 'sigma', prime_divisors => 'prime_sigma', prime_power_divisors => 'prime_power_sigma', square_divisors => 'square_sigma', cube_divisors => 'cube_sigma', squarefree_divisors => 'squarefree_sigma', cubefree_divisors => 'cubefree_sigma', udivisors => 'usigma', prime_udivisors => 'prime_usigma', prime_power_udivisors => 'prime_power_usigma', square_udivisors => 'square_usigma', cube_udivisors => 'cube_usigma', squarefree_udivisors => 'squarefree_usigma', cubefree_udivisors => 'cubefree_usigma', edivisors => 'esigma', idivisors => 'isigma', bdivisors => 'bsigma', ) var h2 = Hash( power_divisors => 'power_sigma', power_udivisors => 'power_usigma', powerfree_divisors => 'powerfree_sigma', powerfree_udivisors => 'powerfree_usigma', ) with([irand(3,10)!, 340282366920938463942989953348216553641, 92971590131496140210160].rand) {|n| h.each {|a,b| var D = n.(a) for k in (0..3) { assert_eq(D.sum {|d| d**k }, n.(b)(k), "#{a} != #{b} for n=#{n} and k=#{k}") } assert_eq(D.len, n.(b+'0'), "#{a}.len != #{b+'0'} for n=#{n}") } h2.each {|a,b| for k in (0..3) { var D = k.(a)(n) for j in (0..3) { assert_eq(D.sum {|d| d**j }, k.(b)(n,j), "#{a} != #{b} for n=#{n}, k=#{k}, j=#{j}") } assert_eq(D.len, k.(b+'0')(n), "#{a}.len != #{b+'0'} for n=#{n}, k=#{k}") } } } with (irand(5, 10)!) {|n| var D = n.divisors assert_eq(n.perfect_power_divisors, D.grep{.is_power}) assert_eq(1.power_divisors(n), D.grep{.is_power(1)}) assert_eq(2.power_divisors(n), D.grep{.is_power(2)}) assert_eq(3.power_divisors(n), D.grep{.is_power(3)}) assert_eq(4.power_divisors(n), D.grep{.is_power(4)}) assert_eq(5.power_divisors(n), D.grep{.is_power(5)}) assert_eq(9.power_divisors(n), D.grep{.is_power(9)}) } with (irand(10, 21)!) {|n| var D = n.udivisors assert_eq(n.pp_udivisors, D.grep{.is_power}) assert_eq(1.power_udivisors(n), D.grep{.is_power(1)}) assert_eq(2.power_udivisors(n), D.grep{.is_power(2)}) assert_eq(3.power_udivisors(n), D.grep{.is_power(3)}) assert_eq(4.power_udivisors(n), D.grep{.is_power(4)}) assert_eq(5.power_udivisors(n), D.grep{.is_power(5)}) assert_eq(9.power_udivisors(n), D.grep{.is_power(9)}) } with (irand(10, 21)!) {|n| var D = n.udivisors assert_eq(1.powerfree_udivisors(n), D.grep{.is_powerfree(1)}) assert_eq(2.powerfree_udivisors(n), D.grep{.is_powerfree(2)}) assert_eq(3.powerfree_udivisors(n), D.grep{.is_powerfree(3)}) assert_eq(4.powerfree_udivisors(n), D.grep{.is_powerfree(4)}) assert_eq(5.powerfree_udivisors(n), D.grep{.is_powerfree(5)}) assert_eq(6.powerfree_udivisors(n), D.grep{.is_powerfree(6)}) assert_eq(7.powerfree_udivisors(n), D.grep{.is_powerfree(7)}) } for n in (0..50) { var D1 = n.divisors var D2 = n.udivisors assert_eq(n.pp_divisors, D1.grep { .is_power }) assert_eq(1.power_divisors(n), D1.grep { .is_power(1) }) assert_eq(2.power_divisors(n), D1.grep { .is_power(2) }) assert_eq(3.power_divisors(n), D1.grep { .is_power(3) }) assert_eq(n.pp_udivisors, D2.grep { .is_power }) assert_eq(1.power_udivisors(n), D2.grep { .is_power(1) }) assert_eq(2.power_udivisors(n), D2.grep { .is_power(2) }) assert_eq(3.power_udivisors(n), D2.grep { .is_power(3) }) assert_eq(0.powerfree_udivisors(n), D2.grep { .is_powerfree(0) }) assert_eq(1.powerfree_udivisors(n), D2.grep { .is_powerfree(1) }) assert_eq(2.powerfree_udivisors(n), D2.grep { .is_powerfree(2) }) assert_eq(3.powerfree_udivisors(n), D2.grep { .is_powerfree(3) }) assert_eq(4.powerfree_udivisors(n), D2.grep { .is_powerfree(4) }) assert_eq(5.powerfree_udivisors(n), D2.grep { .is_powerfree(5) }) } assert_eq(5040.sigma(-1), 5040.divisors.sum {|d| d**(-1) }) assert_eq( 10!.sigma(-2), 10!.divisors.sum {|d| d**(-2) }) do { var n = 5040 var D = n.divisors for k in (0..4) { assert_eq(k.powerfree_divisors(n), D.grep{ .is_powerfree(k) }) } } do { # bi-unitary divisors func biudivs(n) { #return n.bdivisors n.divisors.grep {|x| gcud(x,n/x) == 1 } } func a(n,k=1) { biudivs(n).sum { _**k } } func g(n, k=1) { return 0 if (n == 0) n.factor_prod {|p,e| (p**(k*(e + 1)) - 1)/(p**k - 1) - (e.is_even ? p**(k*(e/2)) : 0) } } assert_eq( 30.of { bsigma(_, 1) }, 30.of { g(_) } ) assert_eq( 30.of { bsigma(_, 2) }, 30.of { g(_, 2) } ) assert_eq( 30.of { bsigma(_, 3) }, 30.of { g(_, 3) } ) assert_eq( 30.of { .bsigma }, 30.of { a(_) }, ) assert_eq( 30.of { .bsigma(2) }, 30.of { a(_, 2) }, ) assert_eq( 30.of { .bsigma(3) }, 30.of { a(_, 3) }, ) assert_eq( 30.of { a(_, 0) } 30.of { .bsigma(0) } ) assert_eq( 30.of { .divisors - biudivs(_) -> sum } 30.of { .nbsigma } ) assert_eq( 30.of { .divisors - biudivs(_) -> sum { _**2 } } 30.of { .nbsigma(2) } ) assert_eq( 30.of { .divisors - biudivs(_) -> len } 30.of { .nbsigma0 } ) } do { # non-unitary divisors assert_eq( 30.of { .nusigma }, 30.of {|n| n.divisors.grep {|d| gcd(d, n/d) != 1 }.sum } ) assert_eq( 10.of { .nusigma(0) }, 10.of { .nusigma0 }, ) assert_eq( 30.of { .nusigma(0) }, 30.of {|n| n.divisors.count {|d| gcd(d, n/d) != 1 } } ) } do { # infinitary divisors func a(n, k=1) { return 0 if (n == 0) n.factor_prod {|p,e| #~ e.digits(2).map_kv {|r,v| #~ (p**(2**r * (v+1) * k) - 1) / (p**(k * 2**r) - 1) #~ }.prod var prod = 1 var r = 0 do { if (e%2 == 1) { #prod *= ((p**(2**(r+1) * k) - 1) / (p**(k * 2**r) - 1)) prod *= (p**(k * 2**r) + 1) } ++r } while (e >>= 1) prod } } assert_eq( 30.of { a(_+1) }, 30.of { idivisors(_+1).sum } ) assert_eq( 30.of { a(_+1, 2) }, 30.of { idivisors(_+1).sum { _**2 } } ) assert_eq( 30.of { a(_+1, 3) }, 30.of { idivisors(_+1).sum { _**3 } } ) assert_eq( 30.of { .isigma0 }, 30.of { idivisors(_).len } ) assert_eq( 30.of { .isigma }, 30.of { a(_) }, ) assert_eq( 30.of { .isigma(2) }, 30.of { a(_, 2) }, ) assert_eq( 30.of { .isigma(3) }, 30.of { a(_, 3) }, ) assert_eq( 30.of { divisors(_) - idivisors(_) -> sum }, 30.of { .nisigma }, ) assert_eq( 30.of { divisors(_) - idivisors(_) -> len }, 30.of { .nisigma0 }, ) assert_eq( 30.of { divisors(_) - idivisors(_) -> sum { _**2 } }, 30.of { .nisigma(2) }, ) assert_eq( 30.of { .antidivisors.sum }, 30.of { .antidivisor_sum }, ) assert_eq( 30.of { .antidivisors.len }, 30.of { .antidivisor_count }, ) } do { # A051377: exponential divisors func ediv(n) { #return n.edivisors return [1] if (n == 1) var f = n.factor_exp var D = f.map{.tail.divisors} var L = [] D.map {|d| @(^d.len) }.cartesian {|*a| L << f.prod_kv {|j,pp| pp[0]**D[j][a[j]] } } L } func f(n, k=1) { return 0 if (n == 0) # Multiplicative with: # a(p^e) = Sum_{d|e} p^d n.factor_map {|p,e| e.divisors.sum {|d| p**(k*d) } }.prod } assert_eq(ediv(7!).sum, f(7!)) assert_eq(ediv(8!).sum { _**2 }, f(8!, 2)) assert_eq(ediv(9!).sum { _**3 }, f(9!, 3)) assert_eq( 30.of { ediv(_).sum }, 30.of { .esigma(1) } ) assert_eq( 30.of { ediv(_).sum { _**3 } }, 30.of { .esigma(3) } ) assert_eq( 30.of { ediv(_).len }, 30.of { .esigma(0) } ) assert_eq( 30.of { ediv(_).len }, 30.of { .esigma0 } ) assert_eq( 30.of { f(_) }, 30.of { .esigma } ) assert_eq( 30.of { f(_, 2) }, 30.of { .esigma(2) }, ) assert_eq( 30.of { f(_, 3) }, 30.of { .esigma(3) }, ) assert_eq( 30.of { divisors(_) - ediv(_) -> sum }, 30.of { .nesigma }, ) assert_eq( 30.of { divisors(_) - ediv(_) -> sum { _**2 } }, 30.of { .nesigma(2) }, ) assert_eq( 30.of { divisors(_) - ediv(_) -> len }, 30.of { .nesigma0 }, ) } assert_eq(divisors(2**128 - 1).grep{ _ <= 5040 }.sum, 16738) assert_eq(divisors(2**128 - 1, 5040).len, 16) assert_eq(divisors(2**128 - 1, 5040).sum, 16738) assert_eq(divisors(2**128 - 1, 2**64 - 1).len, 256) assert_eq(divisors(2**128 - 1, 2**64 + 1).len, 257) assert_eq(divisors(2**128 - 1, 2**64 + 1).sum, 155871713282619791539) assert_eq(divisors(2**128 - 1, 2**32 - 1).sum, 33234996535) assert_eq(divisors(2**128 - 1, 2**32 + 1).sum, 37529963832) assert_eq(3 * (2**127 - 1) -> divisors(2**127 - 1), %n[1, 3, 170141183460469231731687303715884105727]) assert_eq(3 * (2**127 - 1) -> divisors(3*(2**127 - 1)), %n[1, 3, 170141183460469231731687303715884105727, 510423550381407695195061911147652317181]) assert_eq(5040.divisors(120), %n[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 24, 28, 30, 35, 36, 40, 42, 45, 48, 56, 60, 63, 70, 72, 80, 84, 90, 105, 112, 120]) assert_eq(divisors(next_prime(next_prime(2**64) / 3) * 6, 2**64 - 1), %n[1, 2, 3, 6, 6148914691236517223, 12297829382473034446]) assert_eq(divisors(prev_prime(next_prime(2**64) / 3) * 6, 2**64 - 1), %n[1, 2, 3, 6, 6148914691236517199, 12297829382473034398, 18446744073709551597]) assert_eq(divisors(next_prime((2**64) / 2) * 2, 2**64 - 1), %n[1, 2, 9223372036854775837]) assert_eq(divisors(next_prime((2**64) / 3) * 3, 2**64 - 1), %n[1, 3, 6148914691236517223]) assert_eq(divisors(next_prime((2**64) / 5) * 5, 2**64 - 1), %n[1, 5, 3689348814741910379]) say "** Test passed!"