Shoelace formula for polygonal area: Difference between revisions

→‎{{header|JavaScript}}: Updated primitives, tidied.
(→‎{{header|Haskell}}: Tidied in terms of bimap)
(→‎{{header|JavaScript}}: Updated primitives, tidied.)
Line 836:
=={{header|JavaScript}}==
<lang javascript>(() => {
'"use strict'";
 
// ------- SHOELACE FORMULA FOR POLYGONAL AREA -------
 
// shoelaceArea :: [(Float, Float)] -> Float
const shoeLaceArea = vertices => abs(
uncurry(subtract)(
foldlap(zip)(compose(tail, cycle))(
a => x => map(vertices
);
b => a[int(b)] + x[0][int(b)] * x[1][int(!b)]
).reduce([0, 1])
) (a, x) => [0, 01]).map(
ap(zip)(compose(tail, cycle))( b => {
vertices const n = Number(b);
 
)
args return a[0n] + (
b => a[int(b)] + x[0][int(b)n] * x[1][intNumber(!b)]
);
}
),
xs[0, 0]
)
)
Line 863 ⟶ 871:
[5, 6]
];
 
return unlines([
'Polygonal area by shoelace formula:',
JSON.stringify(ps) + ' -> '"Polygonal +area shoeLaceArea(ps)by shoelace formula:",
`${JSON.stringify(ps)} -> ${shoeLaceArea(ps)}`
]);
1]
) .mapjoin(f"\n");
};
 
Line 873 ⟶ 883:
 
// abs :: Num -> Num
const abs = x =>
// Absolute value of a given number - without the sign.
Math// without the sign.abs;
)0 > x ? -x : 0x;
 
 
// ap :: (a -> b -> c) -> (a -> b) -> (a -> c)
const ap = f =>
// Applicative instance for functions.
Line 889 ⟶ 900:
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
const compose = (...fs) =>
// A function defined by the right-to-left
// composition of all the functions in fs.
fs.reduce(
(f, g) => x => f(g(x)),
Line 896 ⟶ 909:
 
// cycle :: [a] -> Generator [a]
const cycle = function* cycle(xs) {
// toAn eachinfinite elementrepetition of xs.,
// from which an arbitrary prefix
// may be consttaken.
const lng = xs.length;
let i = 0;
 
while (true) {
yield( xs[i]);
i = (1 + i) % lng;
}
};
 
// foldl :: (a -> b -> a) -> a -> [b] -> a
const foldl = f =>
a => xs => xs.reduce((x, y) => f(x)(y), a);
 
 
// int :: Bool -> Int
const int = bln =>
bln ? (
1
) : 0;
 
// length :: [a] -> Int
Line 922 ⟶ 929:
// the shorter argument when one is non-finite,
// like cycle, repeat etc
(Array.isArray(xs) || 'string'"GeneratorFunction" =!== typeof xs) ? (.constructor
bln.constructor.name ? (
xs.length
) : Infinity;
 
 
// map :: (a -> b) -> [a] -> [b]
const map = f =>
// The list obtained by applying f
// to each element of xs.
// (The image of xs under f).
xs => (
Array.isArray(xs) ? (
xs
) : xs.split('')
).map(f);
 
 
Line 948 ⟶ 944:
// A new list consisting of all
// items of xs except the first.
'"GeneratorFunction'" !== xs.constructor.constructor.name ? (
0 < xs.lengthconstructor.name ? xs.slice(1) : []
Array.isArrayBoolean(xs.length) ? (
) : xs.splitslice(''1)
) : undefined
) : (take(1)(xs), xs);
 
Line 958 ⟶ 957:
// The first n elements of a list,
// string of characters, or stream.
xs => '"GeneratorFunction'" !== xs
.constructor.constructor.name ? (
xs.slice(0, n)
) : [].concat.apply([], Array.from({
length: n
}, () => {
const x = xs.next();
 
return x.done ? [] : [x.value];
}).flat();
 
 
Line 973:
// A function over a pair, derived
// from a curried function.
function(...args) => {
const [x, y] = Boolean(args.length % 2) ? (
args = arguments,[0]
) : xy = Boolean(args.length % 2) ? (;
 
args[0]
return f(x)(y) : args;
return f(xy[0])(xy[1]);
};
 
 
// unlineszip :: [Stringa] -> String[b] -> [(a, b)]
const unlineszip = xs => ys => {
]);const
// A single string formed by the intercalation
lngn = Math.min(length(xs), length(ys)),
// of a list of strings with the newline character.
xs.join vs = take('\n')(ys);
 
return ftake(xy[0]n)(xy[1]xs);
a => xs => xs.reducemap((x, yi) => f([x)(y), avs[i]]);
};
 
// zip :: [a] -> [b] -> [(a, b)]
const zip = xs =>
// Use of `take` and `length` here allows for zipping with non-finite
// lists - i.e. generators like cycle, repeat, iterate.
ys => {
const
lng = Math.min(length(xs), length(ys)),
vs = take(lng)(ys);
return take(lng)(xs).map(
(x, i) => [x, vs[i]]
);
};
 
// MAIN ---
9,655

edits