September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -19,4 +19,9 @@ Note: the extra credit is not for you to demonstrate how fast your language is c
;Cf:
* [[List comprehensions]]
;Related tasks:
*   [[Euler's sum of powers conjecture]].
*   [[Pythagorean quadruples]].
<br><br>

View file

@ -1,5 +1,22 @@
pytr n = filter (\(_, a, b, c) -> a+b+c <= n) [(prim a b c, a, b, c) | a <- [1..n], b <- [1..n], c <- [1..n], a < b && b < c, a^2 + b^2 == c^2]
where prim a b _ = gcd a b == 1
pytr :: Int -> [(Bool, Int, Int, Int)]
pytr n =
filter
(\(_, a, b, c) -> a + b + c <= n)
[ (prim a b c, a, b, c)
| a <- xs
, b <- drop a xs
, c <- drop b xs
, a ^ 2 + b ^ 2 == c ^ 2 ]
where
xs = [1 .. n]
prim a b _ = gcd a b == 1
main = putStrLn $ "Up to 100 there are " ++ (show $ length xs) ++ " triples, of which " ++ (show $ length $ filter (\(x,_,_,_) -> x == True) xs) ++ " are primitive."
where xs = pytr 100
main :: IO ()
main =
putStrLn $
"Up to 100 there are " ++
show (length xs) ++
" triples, of which " ++
show (length $ filter (\(x, _, _, _) -> x) xs) ++ " are primitive."
where
xs = pytr 100

View file

@ -1,15 +1,22 @@
triangles :: Int -> [[Int]]
triangles max_peri | max_peri < 12 = []
| otherwise = concat tiers where
tiers = takeWhile (not.null) $ iterate tier [[3,4,5]]
tier = concatMap (filter ((<=max_peri).sum).tmul)
tmul t = map (map (sum . zipWith (*) t))
[[[ 1,-2,2],[ 2,-1,2],[ 2,-2,3]],
[[ 1, 2,2],[ 2, 1,2],[ 2, 2,3]],
[[-1, 2,2],[-2, 1,2],[-2, 2,3]]]
pythagoreanTriplesBelow :: Int -> [[Int]]
pythagoreanTriplesBelow n =
let m = quot n 2
in concatMap
(\x ->
concatMap
(\y ->
concatMap
(\z ->
if x + y + z <= n && x ^ 2 + y ^ 2 == z ^ 2
then [[x, y, z]]
else [])
[y + 1 .. m])
[x + 1 .. m])
[1 .. m]
triangle_count max_p = (length t, sum $ map ((max_p `div`).sum) t)
where t = triangles max_p
main = mapM_ putStrLn $
map (\n -> show n ++ " " ++ show (triangle_count n)) $ map (10^) [1..]
-- TEST -------------------------------------------------------------------------
main :: IO ()
main =
mapM_
(print . length)
([id, filter (\[x, y, _] -> gcd x y == 1)] <*> [pythagoreanTriplesBelow 100])

View file

@ -0,0 +1,24 @@
triangles :: Int -> [[Int]]
triangles max_peri
| max_peri < 12 = []
| otherwise = concat tiers
where
tiers = takeWhile (not . null) $ iterate tier [[3, 4, 5]]
tier = concatMap (filter ((<= max_peri) . sum) . tmul)
tmul t =
map
(map (sum . zipWith (*) t))
[ [[1, -2, 2], [2, -1, 2], [2, -2, 3]]
, [[1, 2, 2], [2, 1, 2], [2, 2, 3]]
, [[-1, 2, 2], [-2, 1, 2], [-2, 2, 3]]
]
triangleCount max_p = (length t, sum $ map ((max_p `div`) . sum) t)
where
t = triangles max_p
main :: IO ()
main =
mapM_
((putStrLn . (\n -> show n ++ " " ++ show (triangleCount n))) . (10 ^))
[1 .. 7]

View file

@ -0,0 +1,43 @@
(() => {
// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = (f, xs) => [].concat.apply([], xs.map(f));
// range :: Int -> Int -> [Int]
const range = (m, n) =>
Array.from({
length: Math.floor(n - m) + 1
}, (_, i) => m + i);
// gcd :: Integral a => a -> a -> a
const gcd = (x, y) => {
const _gcd = (a, b) => (b === 0 ? a : _gcd(b, a % b)),
abs = Math.abs;
return _gcd(abs(x), abs(y));
}
// Arguments: predicate, maximum perimeter
// pythTripleCount :: ((Int, Int, Int) -> Bool) -> Int -> Int
const pythTripleCount = (p, maxPerim) => {
const xs = range(1, Math.floor(maxPerim / 2));
return concatMap(x =>
concatMap(y =>
concatMap(z =>
( (x + y + z <= maxPerim ) &&
(x * x + y * y === z * z ) &&
p(x, y, z) ) ? [
[x, y, z]
] : [ ], // concatMap eliminates empty lists
xs.slice(y)), xs.slice(x)), xs
)
.length;
};
return [10, 100, 1000]
.map(n => ({
maxPerimeter: n,
triples: pythTripleCount(x => true, n),
primitives: pythTripleCount((x, y, _) => gcd(x, y) === 1, n)
}));
})();

View file

@ -0,0 +1,3 @@
[{"maxPerimeter":10, "triples":0, "primitives":0},
{"maxPerimeter":100, "triples":17, "primitives":7},
{"maxPerimeter":1000, "triples":325, "primitives":70}]

View file

@ -0,0 +1,27 @@
// version 1.1.2
var total = 0L
var prim = 0L
var maxPeri = 0L
fun newTri(s0: Long, s1: Long, s2: Long) {
val p = s0 + s1 + s2
if (p <= maxPeri) {
prim++
total += maxPeri / p
newTri( s0 - 2 * s1 + 2 * s2, 2 * s0 - s1 + 2 * s2, 2 * s0 - 2 * s1 + 3 * s2)
newTri( s0 + 2 * s1 + 2 * s2, 2 * s0 + s1 + 2 * s2, 2 * s0 + 2 * s1 + 3 * s2)
newTri(-s0 + 2 * s1 + 2 * s2, -2 * s0 + s1 + 2 * s2, -2 * s0 + 2 * s1 + 3 * s2)
}
}
fun main(args: Array<String>) {
maxPeri = 100
while (maxPeri <= 10_000_000_000L) {
prim = 0
total = 0
newTri(3, 4, 5)
println("Up to $maxPeri: $total triples, $prim primatives")
maxPeri *= 10
}
}

View file

@ -1,29 +1,25 @@
/*REXX program counts the number of Pythagorean triples that exist given a maximum */
/*──────────────────── 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 . /*obtain optional argument from the CL.*/
if N=='' | N=="," then n=100 /*Not specified? Then use the default.*/
do a=3 to N%3; aa=a*a /*limit side to 1/3 of the perimeter.*/
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 /*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 /*a*/
T=0; P=0 /*set the number of Triples, Primitives*/
do a=3 to N%3; aa=a*a /*limit side to 1/3 of the perimeter.*/
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 /*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.*/
T=T + 1 /*eureka. We found a Pythagorean triple*/
P=P + (gcd(a, b)==1) /*is this triple a primitive triple? */
end /*c*/
end /*b*/
end /*a*/
_=left('', 7) /*for padding the output with 7 blanks.*/
say 'max perimeter =' N _ "Pythagorean triples =" trips _ 'primitives =' prims
say 'max perimeter =' N _ "Pythagorean triples =" T _ 'primitives =' P
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,31 @@
/*REXX program counts the number of Pythagorean triples that exist given a maximum */
/*──────────────────── 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 . /*obtain optional argument from the CL.*/
if N=='' | N=="," then n=100 /*Not specified? Then use the default.*/
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 /*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 /*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 /*generate non-primitives Pythagoreans.*/
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*/
T=0; P=0 /*set the number of Triples, Primitives*/
@.=0; 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 /*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 /*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.*/
T=T + 1 /*Eureka! We found a Pythagorean triple*/
P=P + 1 /*count this also as a primitive triple*/
do m=2 while a*m+b*m+c*m<=N /*generate non-primitives Pythagoreans.*/
T=T + 1 /*Eureka! We found a Pythagorean triple*/
am=a*m; bm=b*m; cm=c*m /*create some short-cut variable names.*/
@.am.bm.cm=1 /*mark Pythagorean triangle as a triple*/
end /*m*/
end /*c*/
end /*b*/
end /*a*/
_=left('', 7) /*for padding the output with 7 blanks.*/
say 'max perimeter =' N _ "Pythagorean triples =" trips _ 'primitives =' prims
say 'max perimeter =' N _ "Pythagorean triples =" T _ 'primitives =' P
/*stick a fork in it, we're all done. */

View file

@ -1,21 +1,21 @@
func triples(limit) {
var primitive = 0;
var civilized = 0;
var primitive = 0
var civilized = 0
func oyako(a, b, c) {
(var perim = a+b+c) > limit || (
primitive++;
civilized += int(limit / perim);
oyako( a - 2*b + 2*c, 2*a - b + 2*c, 2*a - 2*b + 3*c);
oyako( a + 2*b + 2*c, 2*a + b + 2*c, 2*a + 2*b + 3*c);
oyako(-a + 2*b + 2*c, -2*a + b + 2*c, -2*a + 2*b + 3*c);
);
primitive++
civilized += int(limit / perim)
oyako( a - 2*b + 2*c, 2*a - b + 2*c, 2*a - 2*b + 3*c)
oyako( a + 2*b + 2*c, 2*a + b + 2*c, 2*a + 2*b + 3*c)
oyako(-a + 2*b + 2*c, -2*a + b + 2*c, -2*a + 2*b + 3*c)
)
}
oyako(3,4,5);
"#{limit} => (#{primitive} #{civilized})";
oyako(3,4,5)
"#{limit} => (#{primitive} #{civilized})"
}
Inf.times { |n|
say triples(10**n);
 
for n (1..Inf) {
say triples(10**n)
}

View file

@ -0,0 +1,9 @@
fcn tri(lim,a=3,b=4,c=5){
p:=a + b + c;
if(p>lim) return(0,0);
T(1,lim/p).zipWith('+,
tri(lim, a - 2*b + 2*c, 2*a - b + 2*c, 2*a - 2*b + 3*c),
tri(lim, a + 2*b + 2*c, 2*a + b + 2*c, 2*a + 2*b + 3*c),
tri(lim, -a + 2*b + 2*c, -2*a + b + 2*c, -2*a + 2*b + 3*c)
);
}

View file

@ -0,0 +1 @@
n:=10; do(10){ println("%,d: %s".fmt(n,tri(n).reverse())); n*=10; }