Another update from ingydotnet^djgoku

This commit is contained in:
Ingy döt Net 2015-11-18 06:14:39 +00:00
parent 91df62d461
commit 948b86eafa
7604 changed files with 108452 additions and 22726 deletions

View file

@ -1,37 +1,47 @@
class
APPLICATION
inherit
ARGUMENTS
create
make
feature
make
do
Perimeter:= 100
from
until
Perimeter>1000000
loop
pyt_tri(3,4,5)
io.put_string ("There are " +total.out + " triples, below " + Perimeter.out + ". Of which " + prim.out+ " are primitives.%N")
Perimeter:= Perimeter*10
end
end
pyt_tri(a, b, c: INTEGER)
local
p: INTEGER
do
p:= a+b+c
if p<= Perimeter then
prim:= prim+1
total := total + Perimeter // p
pyt_tri (a+2*(-b+c), 2*(a+c)-b, 2*(a-b+c)+c)
pyt_tri (a+2*(b+c), 2*(a+c)+b, 2*(a+b+c)+c)
pyt_tri (-a+2*(b+c), 2*(-a+c)+b, 2*(-a+b+c)+c)
create
make
feature
make
local
perimeter: INTEGER
do
perimeter := 100
from
until
perimeter > 1000000
loop
total := 0
primitive_triples := 0
count_pythagorean_triples (3, 4, 5, perimeter)
io.put_string ("There are " + total.out + " triples, below " + perimeter.out + ". Of which " + primitive_triples.out + " are primitives.%N")
perimeter := perimeter * 10
end
end
end
Perimeter:INTEGER
prim: INTEGER
total: INTEGER
count_pythagorean_triples (a, b, c, perimeter: INTEGER)
-- Total count of pythagorean triples and total count of primitve triples below perimeter.
local
p: INTEGER
do
p := a + b + c
if p <= perimeter then
primitive_triples := primitive_triples + 1
total := total + perimeter // p
count_pythagorean_triples (a + 2 * (- b + c), 2 * (a + c) - b, 2 * (a - b + c) + c, perimeter)
count_pythagorean_triples (a + 2 * (b + c), 2 * (a + c) + b, 2 * (a + b + c) + c, perimeter)
count_pythagorean_triples (- a + 2 * (b + c), 2 * (- a + c) + b, 2 * (- a + b + c) + c, perimeter)
end
end
feature {NONE}
primitive_triples: INTEGER
total: INTEGER
end

View file

@ -0,0 +1,14 @@
defmodule RC do
def count_triples(limit), do: count_triples(limit,3,4,5)
defp count_triples(limit, a, b, c) when limit<(a+b+c), do: {0,0}
defp count_triples(limit, a, b, c) do
{p1, t1} = count_triples(limit, a-2*b+2*c, 2*a-b+2*c, 2*a-2*b+3*c)
{p2, t2} = count_triples(limit, a+2*b+2*c, 2*a+b+2*c, 2*a+2*b+3*c)
{p3, t3} = count_triples(limit,-a+2*b+2*c,-2*a+b+2*c,-2*a+2*b+3*c)
{1+p1+p2+p3, div(limit, a+b+c)+t1+t2+t3}
end
end
list = for n <- 1..8, do: Enum.reduce(1..n, 1, fn(_,acc)->10*acc end)
Enum.each(list, fn n -> IO.inspect {n, RC.count_triples(n)} end)

View file

@ -0,0 +1,37 @@
function primitiven{T<:Integer}(m::T)
1 < m || return T[]
m != 2 || return T[1]
!isprime(m) || return T[2:2:m-1]
rp = trues(m-1)
if isodd(m)
rp[1:2:m-1] = false
end
for p in keys(factor(m))
rp[p:p:m-1] = false
end
T[1:m-1][rp]
end
function pythagoreantripcount{T<:Integer}(plim::T)
primcnt = 0
fullcnt = 0
11 < plim || return (primcnt, fullcnt)
for m in 2:plim
p = 2m^2
p+2m <= plim || break
for n in primitiven(m)
q = p + 2m*n
q <= plim || break
primcnt += 1
fullcnt += div(plim, q)
end
end
return (primcnt, fullcnt)
end
println("Counting Pythagorian Triplets within perimeter limits:")
println(" Limit All Primitive")
for om in 1:10
(pcnt, fcnt) = pythagoreantripcount(10^om)
println(@sprintf " 10^%02d %11d %9d" om fcnt pcnt)
end

View file

@ -1,5 +1,5 @@
constant limit = 20;
constant limit = 100;
for [X] [^limit] xx 3 -> \a, \b, \c {
for [X] [^limit] xx 3 -> (\a, \b, \c) {
say [a, b, c] if a < b < c and a**2 + b**2 == c**2
}

View file

@ -1,5 +1,5 @@
my %triples;
my $limit = 100;
my $limit = 10000;
for 3 .. $limit/2 -> $c {
for 1 .. $c -> $a {

View file

@ -0,0 +1,50 @@
function triples($p) {
if($p -gt 4) {
# ai + bi + ci = pi <= p
# ai < bi < ci --> 3ai < pi <= p and ai + 2bi < pi <= p
$pa = [Math]::Floor($p/3)
1..$pa | foreach {
$ai = $_
$pb = [Math]::Floor(($p-$ai)/2)
($ai+1)..$pb | foreach {
$bi = $_
$pc = $p-$ai-$bi
($bi+1)..$pc | where {
$ci = $_
$pi = $ai + $bi + $ci
$ci*$ci -eq $ai*$ai + $bi*$bi
} |
foreach {
[pscustomobject]@{
a = "$ai"
b = "$bi"
c = "$ci"
p = "$pi"
}
}
}
}
}
else {
Write-Error "$p is not greater than 4"
}
}
function gcd ($a, $b) {
function pgcd ($n, $m) {
if($n -le $m) {
if($n -eq 0) {$m}
else{pgcd $n ($m%$n)}
}
else {pgcd $m $n}
}
$n = [Math]::Abs($a)
$m = [Math]::Abs($b)
(pgcd $n $m)
}
$triples = (triples 100)
$coprime = $triples |
where {((gcd $_.a $_.b) -eq 1) -and ((gcd $_.a $_.c) -eq 1) -and ((gcd $_.b $_.c) -eq 1)}
"There are $(($triples).Count) Pythagorean triples with perimeter no larger than 100
and $(($coprime).Count) of them are coprime."

View file

@ -1,30 +1,28 @@
/*REXX pgm counts number of Pythagorean triples that exist given a max */
/* perimeter of N, and also counts how many of them are primitives.*/
trips=0; prims=0 /*zero # of triples, primatives. */
parse arg N .; if N=='' then n=100 /*get "N". If none, then assume.*/
/*REXX program counts number of Pythagorean triples that exist given a max */
/*────────── perimeter of N, and also counts how many of them are primitives.*/
trips=0; prims=0 /*set the number of triples, primitives*/
parse arg N .; if N=='' then n=100 /*N specified? No, then use default. */
do a=3 to N%3; aa=a*a /*limit side to 1/3 of perimeter.*/
do a=3 to N%3; aa=a*a /*limit side to 1/3 of the perimeter.*/
do b=a+1 /*triangle can't be isosceles. */
ab=a+b /*compute partial perimeter. */
if ab>=N then iterate a /*a+b≥perimeter? Try different A*/
aabb=aa+b*b /*compute sum of a² + b² (cheat)*/
do b=a+1 /*the triangle can't be isosceles. */
ab=a+b /*compute a partial perimeter (2 sides)*/
if ab>=N then iterate a /*is a+b ≥ perimeter? Try different A*/
aabb=aa+b*b /*compute the sum of a²+b² (shortcut)*/
do c=b+1 /*3rd side: also compute c² */
if ab+c>N then iterate a /*a+b+c > perimeter? Try diff A.*/
cc=c*c /*compute C². */
if cc > aabb then iterate b /*c² > a²+b² ? Try different B.*/
if cc\==aabb then iterate /*c² ¬= a²+b² ? Try different C.*/
trips=trips+1 /*eureka. We found a prim triple*/
prims=prims+(gcd(a,b)==1) /*is this triple a primitive? */
end /*a*/
do c=b+1 /*compute the value of the third side. */
if ab+c>N then iterate a /*is a+b+c > perimeter? Try diff. A.*/
cc=c*c /*compute the value of C². */
if cc > aabb then iterate b /*is c² > a²+b² ? Try a different B.*/
if cc\==aabb then iterate /*is c² ¬= a²+b² ? Try a different C.*/
trips=trips+1 /*eureka. We found a Pythagorean triple*/
prims=prims+(gcd(a,b)==1) /*is this triple a primitive triple? */
end /*c*/
end /*b*/
end /*c*/
end /*a*/
say 'max perimeter =' N, /*show a single line of output. */
left('',7) "Pythagorean triples =" trips, /*left('',7)≡7 blanks.*/
left('',7) 'primitives =' prims
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────GCD subroutine──────────────────────*/
gcd: procedure; parse arg x,y
do until y==0; parse value x//y y with y x; end; return x
_=left('',7) /*for padding the output with 7 blanks.*/
say 'max perimeter =' N _ "Pythagorean triples =" trips _ 'primitives =' prims
exit /*stick a fork in it, we're all done. */
/*────────────────────────────────────────────────────────────────────────────────────*/
gcd: procedure; parse arg x,y; do until y==0; parse value x//y y with y x; end; return x

View file

@ -1,36 +1,36 @@
/*REXX pgm counts number of Pythagorean triples that exist given a max */
/* perimeter of N, and also counts how many of them are primitives.*/
@.=0; trips=0; prims=0 /*zero some REXX variables. */
parse arg N .; if N=='' then N=100 /*get "N". If none, then assume.*/
/*REXX program counts number of Pythagorean triples that exist given a max */
/*REXX program counts number of Pythagorean triples that exist given a max */
/*────────── perimeter of N, and also counts how many of them are primitives.*/
@.=0; trips=0; prims=0 /*define some REXX variables to zero. */
parse arg N .; if N=='' then n=100 /*N specified? No, then use default. */
do a=3 to N%3; aa=a*a /*limit side to 1/3 of perimeter.*/
aEven= a//2==0 /*set var to 1 if A is even.*/
do a=3 to N%3; aa=a*a /*limit side to 1/3 of the perimeter.*/
aEven= a//2==0 /*set variable to 1 if A is even. */
do b=a+1 by 1+aEven /*triangle can't be isosceles. */
ab=a+b /*compute partial perimeter. */
if ab>=N then iterate a /*a+b≥perimeter? Try different A*/
aabb=aa+b*b /*compute sum of a² + b² (cheat)*/
do b=a+1 by 1+aEven /*the triangle can't be isosceles. */
ab=a+b /*compute a partial perimeter (2 sides)*/
if ab>=N then iterate a /*is a+b ≥ perimeter? Try different A*/
aabb=aa+b*b /*compute the sum of a²+b² (shortcut)*/
do c=b+1 /*C is the third side of triangle*/
if aEven then if c//2==0 then iterate
if ab+c>n then iterate a /*a+b+c > perimeter? Try diff A.*/
cc=c*c /*compute C². */
if cc > aabb then iterate b /*c² > a²+b² ? Try different B.*/
if cc\==aabb then iterate /*c² ¬= a²+b² ? Try different C.*/
if @.a.b.c then iterate /*Is this a duplicate? Try again*/
trips=trips+1 /*eureka. We found a prim triple*/
prims=prims+1 /*count this primitive triple. */
do c=b+1 /*compute the value of the third side. */
if aEven then if c//2==0 then iterate
if ab+c>n then iterate a /*a+b+c > perimeter? Try different A.*/
cc=c*c /*compute the value of C². */
if cc > aabb then iterate b /*is c² > a²+b² ? Try a different B.*/
if cc\==aabb then iterate /*is c² ¬= a²+b² ? Try a different C.*/
if @.a.b.c then iterate /*Is this a duplicate? Then try again.*/
trips=trips+1 /*Eureka! We found a Pythagorean triple*/
prims=prims+1 /*count this also as a primitive triple*/
do m=2; am=a*m; bm=b*m; cm=c*m /*gen non-primitives.*/
if am+bm+cm>N then leave /*is this multiple a triple ? */
trips=trips+1 /*yuppers, then we found another.*/
if m//2 then @.am.bm.cm=1 /*don't mark if an even multiple.*/
end /*m*/
end /*d*/
end /*b*/
end /*a*/
do m=2; am=a*m; bm=b*m; cm=c*m /*generate non-primitives.*/
if am+bm+cm>N then leave /*is this multiple Pythagorean triple? */
trips=trips+1 /*Eureka! We found a Pythagorean triple*/
@.am.bm.cm=1 /*mark Pythagorean triangle as a triple*/
end /*m*/
end /*c*/
end /*b*/
end /*a*/
say 'max perimeter =' N, /*show a single line of output. */
left('',7) "Pythagorean triples =" trips, /*left('',7)≡7 blanks.*/
left('',7) 'primitives =' prims
/*stick a fork in it, we're done.*/
_=left('',7) /*for padding the output with 7 blanks.*/
say 'max perimeter =' N _ "Pythagorean triples =" trips _ 'primitives =' prims
/*stick a fork in it, we're all done. */

View file

@ -2,17 +2,17 @@ class PythagoranTriplesCounter
def initialize(limit)
@limit = limit
@total = 0
@primatives = 0
@primitives = 0
generate_triples(3, 4, 5)
end
attr_reader :total, :primatives
attr_reader :total, :primitives
private
def generate_triples(a, b, c)
perim = a + b + c
return if perim > @limit
@primatives += 1
@primitives += 1
@total += @limit / perim
generate_triples( a-2*b+2*c, 2*a-b+2*c, 2*a-2*b+3*c)
@ -24,6 +24,6 @@ end
perim = 10
while perim <= 100_000_000
c = PythagoranTriplesCounter.new perim
p [perim, c.total, c.primatives]
p [perim, c.total, c.primitives]
perim *= 10
end

View file

@ -0,0 +1,36 @@
For i=1 To 8
WScript.StdOut.WriteLine triples(10^i)
Next
Function triples(pmax)
prim=0 : count=0 : nmax=Sqr(pmax)/2 : n=1
Do While n <= nmax
m=n+1 : p=2*m*(m+n)
Do While p <= pmax
If gcd(m,n)=1 Then
prim=prim+1
count=count+Int(pmax/p)
End If
m=m+2
p=2*m*(m+n)
Loop
n=n+1
Loop
triples = "Max Perimeter: " & pmax &_
", Total: " & count &_
", Primitive: " & prim
End Function
Function gcd(a,b)
c = a : d = b
Do
If c Mod d > 0 Then
e = c Mod d
c = d
d = e
Else
gcd = d
Exit Do
End If
Loop
End Function