Skip to content

Commit 2c7f9c9

Browse files
committed
new file: Math/achilles_numbers.sf
new file: Math/square_form_factorization_method.sf
1 parent 847849a commit 2c7f9c9

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed

Math/achilles_numbers.sf

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/ruby
2+
3+
# Generate Achilles and strong Achilles numbers.
4+
5+
# See also:
6+
# https://rosettacode.org/wiki/Achilles_numbers
7+
8+
var P = 2.powerful(1e6)
9+
var achilles = Set(P.grep{ !.is_power }...)
10+
var strong_achilles = achilles.grep { achilles.has(.phi) }
11+
12+
say "First 50 Achilles numbers:"
13+
achilles.sort.first(50).slices(10).each { .map{'%4s'%_}.join(' ').say }
14+
15+
say "\nFirst 30 strong Achilles numbers:"
16+
strong_achilles.sort.first(30).slices(10).each { .map{'%5s'%_}.join(' ').say }
17+
18+
say "\nNumber of Achilles numbers with:"
19+
achilles.to_a.group_by{.len}.sort_by{|k| k.to_i }.each_2d{|a,b|
20+
say "#{a} digits: #{b.len}"
21+
}
22+
23+
__END__
24+
First 50 Achilles numbers:
25+
72 108 200 288 392 432 500 648 675 800
26+
864 968 972 1125 1152 1323 1352 1372 1568 1800
27+
1944 2000 2312 2592 2700 2888 3087 3200 3267 3456
28+
3528 3872 3888 4000 4232 4500 4563 4608 5000 5292
29+
5324 5400 5408 5488 6075 6125 6272 6728 6912 7200
30+
31+
First 30 strong Achilles numbers:
32+
500 864 1944 2000 2592 3456 5000 10125 10368 12348
33+
12500 16875 19652 19773 30375 31104 32000 33275 37044 40500
34+
49392 50000 52488 55296 61731 64827 67500 69984 78608 80000
35+
36+
Number of Achilles numbers with:
37+
2 digits: 1
38+
3 digits: 12
39+
4 digits: 47
40+
5 digits: 192
41+
6 digits: 664
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#!/usr/bin/ruby
2+
3+
# Daniel Shanks's Square Form Factorization (SquFoF).
4+
5+
# See also:
6+
# https://rosettacode.org/wiki/Square_form_factorization
7+
8+
const multipliers = divisors(3*5*7*11).grep { _ > 1 }
9+
10+
func sff(N) {
11+
12+
N.is_prime && return 1 # n is prime
13+
N.is_square && return N.isqrt # n is square
14+
15+
multipliers.each {|k|
16+
17+
var P0 = isqrt(k*N) # P[0]=floor(sqrt(N)
18+
var Q0 = 1 # Q[0]=1
19+
var Q = (k*N - P0*P0) # Q[1]=N-P[0]^2 & Q[i]
20+
var P1 = P0 # P[i-1] = P[0]
21+
var Q1 = Q0 # Q[i-1] = Q[0]
22+
var P = 0 # P[i]
23+
var Qn = 0 # P[i+1]
24+
var b = 0 # b[i]
25+
26+
while (!Q.is_square) { # until Q[i] is a perfect square
27+
b = idiv(isqrt(k*N) + P1, Q) # floor(floor(sqrt(N+P[i-1])/Q[i])
28+
P = (b*Q - P1) # P[i]=b*Q[i]-P[i-1]
29+
Qn = (Q1 + b*(P1 - P)) # Q[i+1]=Q[i-1]+b(P[i-1]-P[i])
30+
(Q1, Q, P1) = (Q, Qn, P)
31+
}
32+
33+
b = idiv(isqrt(k*N) + P, Q) # b=floor((floor(sqrt(N)+P[i])/Q[0])
34+
P1 = (b*Q0 - P) # P[i-1]=b*Q[0]-P[i]
35+
Q = (k*N - P1*P1)/Q0 # Q[1]=(N-P[0]^2)/Q[0] & Q[i]
36+
Q1 = Q0 # Q[i-1] = Q[0]
37+
38+
loop {
39+
b = idiv(isqrt(k*N) + P1, Q) # b=floor(floor(sqrt(N)+P[i-1])/Q[i])
40+
P = (b*Q - P1) # P[i]=b*Q[i]-P[i-1]
41+
Qn = (Q1 + b*(P1 - P)) # Q[i+1]=Q[i-1]+b(P[i-1]-P[i])
42+
break if (P == P1) # until P[i+1]=P[i]
43+
(Q1, Q, P1) = (Q, Qn, P)
44+
}
45+
with (gcd(N,P)) {|g|
46+
return g if g.is_ntf(N)
47+
}
48+
}
49+
50+
return 0
51+
}
52+
53+
[ 11111, 2501, 12851, 13289, 75301, 120787, 967009, 997417, 4558849,
54+
7091569, 13290059, 42854447, 223553581, 2027651281,
55+
].each {|n|
56+
var v = sff(n)
57+
if (v == 0) { say "The number #{n} is not factored." }
58+
elsif (v == 1) { say "The number #{n} is a prime." }
59+
else { say "#{n} = #{[n/v, v].sort.join(' * ')}" }
60+
}
61+
62+
__END__
63+
11111 = 41 * 271
64+
2501 = 41 * 61
65+
12851 = 71 * 181
66+
13289 = 97 * 137
67+
75301 = 257 * 293
68+
120787 = 43 * 2809
69+
967009 = 601 * 1609
70+
997417 = 257 * 3881
71+
4558849 = 383 * 11903
72+
7091569 = 2663 * 2663
73+
13290059 = 3119 * 4261
74+
42854447 = 4423 * 9689
75+
223553581 = 11213 * 19937
76+
2027651281 = 44021 * 46061

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ A nice collection of day-to-day Sidef scripts.
124124
* [Sierpinski triangle](./Image/sierpinski_triangle.sf)
125125
* [Voronoi diagram](./Image/voronoi_diagram.sf)
126126
* Math
127+
* [Achilles numbers](./Math/achilles_numbers.sf)
127128
* [AGM calculate pi](./Math/AGM_calculate_pi.sf)
128129
* [Aitken's array](./Math/aitken_s_array.sf)
129130
* [Akiyama-tanigawa numerators](./Math/akiyama-tanigawa_numerators.sf)
@@ -666,6 +667,7 @@ A nice collection of day-to-day Sidef scripts.
666667
* [Sqrt convergents](./Math/sqrt_convergents.sf)
667668
* [Square-full numbers](./Math/square-full_numbers.sf)
668669
* [Square congruence lookup factorization](./Math/square_congruence_lookup_factorization.sf)
670+
* [Square form factorization method](./Math/square_form_factorization_method.sf)
669671
* [Square product subsets](./Math/square_product_subsets.sf)
670672
* [Square root arithmetic-harmonic mean](./Math/square_root_arithmetic-harmonic_mean.sf)
671673
* [Square root good rational approximations](./Math/square_root_good_rational_approximations.sf)

0 commit comments

Comments
 (0)