Law of cosines - triples: Difference between revisions

→‎{{header|Javascript}}: Added a Javascript draft ( returns 18394 - not sure why this differs from the Python draft)
(→‎{{header|Haskell}}: corrected label order, updated type signature)
(→‎{{header|Javascript}}: Added a Javascript draft ( returns 18394 - not sure why this differs from the Python draft))
Line 303:
15 solutions for 60 degrees:
[[1,1,1],[2,2,2],[3,3,3],[3,7,8],[4,4,4],[5,5,5],[5,7,8],[6,6,6],[7,7,7],[8,8,8],[9,9,9],[10,10,10],[11,11,11],[12,12,12],[13,13,13]]</pre>
 
=={{header|JavaScript}}==
<lang JavaScript>(() => {
'use strict';
 
// main :: IO ()
const main = () => {
 
const
f90 = dct => x2 => dct[x2],
f60 = dct => (x2, ab) => dct[x2 - ab],
f120 = dct => (x2, ab) => dct[x2 + ab],
f60unequal = dct => (x2, ab, a, b) =>
(a !== b) ? (
dct[x2 - ab]
) : undefined;
 
// triangles :: Dict -> (Int -> Int -> Int -> Int -> Maybe Int)
// -> [String]
const triangles = (f, n) => {
const
xs = enumFromTo(1, n),
dctSquares = foldl(
(a, x) => (a[x] = x * x, a), {},
xs
),
dctRoots = foldl(
(a, x) => (a[x * x] = x, a), {},
xs
),
fr = f(dctRoots),
dct = {};
return (
concatMap(
a => {
const a2 = dctSquares[a];
return concatMap(
b => {
const
suma2b2 = a2 + dctSquares[b],
ab = a * b,
c = fr(suma2b2, ab, a, b);
return undefined !== c ? (
dct[[a, b, c].sort()] = 1,
[1]
) : [];
},
enumFromTo(1, 1 + a)
);
},
xs
),
Object.keys(dct)
);
};
 
const result = 'Triangles of maximum side 13:\n\n' +
unlines(
zipWith(
(s, f) => {
const ks = triangles(f, 13);
return ks.length.toString() + ' solutions for ' + s +
' degrees:\n' + unlines(ks) + '\n';
},
['120', '90', '60'],
[f120, f90, f60]
)
) + '\nUneven triangles of maximum side 10000. Total:\n' +
triangles(f60unequal, 10000).length
 
return (
console.log(result),
result
);
};
 
 
// GENERIC FUNCTIONS ----------------------------
 
// concatMap :: (a -> [b]) -> [a] -> [b]
const concatMap = (f, xs) =>
xs.reduce((a, x) => a.concat(f(x)), []);
 
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = (m, n) =>
m <= n ? iterateUntil(
x => n <= x,
x => 1 + x,
m
) : [];
 
// foldl :: (a -> b -> a) -> a -> [b] -> a
const foldl = (f, a, xs) => xs.reduce(f, a);
 
// iterateUntil :: (a -> Bool) -> (a -> a) -> a -> [a]
const iterateUntil = (p, f, x) => {
const vs = [x];
let h = x;
while (!p(h))(h = f(h), vs.push(h));
return vs;
};
 
// Returns Infinity over objects without finite length
// this enables zip and zipWith to choose the shorter
// argument when one non-finite like cycle, repeat etc
 
// length :: [a] -> Int
const length = xs => xs.length || Infinity;
 
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = (n, xs) =>
xs.constructor.constructor.name !== 'GeneratorFunction' ? (
xs.slice(0, n)
) : [].concat.apply([], Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
 
// unlines :: [String] -> String
const unlines = xs => xs.join('\n');
 
// Use of `take` and `length` here allows zipping with non-finite lists
// i.e. generators like cycle, repeat, iterate.
 
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
const zipWith = (f, xs, ys) => {
const
lng = Math.min(length(xs), length(ys)),
as = take(lng, xs),
bs = take(lng, ys);
return Array.from({
length: lng
}, (_, i) => f(as[i], bs[i], i));
};
 
// MAIN ---
return main();
})();</lang>
{{Out}}
<pre>Triangles of maximum side 13:
 
2 solutions for 120 degrees:
3,5,7
13,7,8
 
3 solutions for 90 degrees:
3,4,5
10,6,8
12,13,5
 
15 solutions for 60 degrees:
1,1,1
2,2,2
3,3,3
4,4,4
5,5,5
6,6,6
7,7,7
3,7,8
5,7,8
8,8,8
9,9,9
10,10,10
11,11,11
12,12,12
13,13,13
 
Uneven triangles of maximum side 10000. Total:
18394
Triangles of maximum side 13:
 
2 solutions for 120 degrees:
3,5,7
13,7,8
 
3 solutions for 90 degrees:
3,4,5
10,6,8
12,13,5
 
15 solutions for 60 degrees:
1,1,1
2,2,2
3,3,3
4,4,4
5,5,5
6,6,6
7,7,7
3,7,8
5,7,8
8,8,8
9,9,9
10,10,10
11,11,11
12,12,12
13,13,13
 
Uneven triangles of maximum side 10000. Total:
18394
[Finished in 11.303s]</pre>
 
 
=={{header|Perl 6}}==
9,655

edits