simplify-fractions/index.html

288 lines
9.6 KiB
HTML
Raw Normal View History

2019-06-09 22:13:46 +02:00
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
2019-06-09 22:48:31 +02:00
<meta name="author" content="Felix W. Dekker" />
<meta name="application-name" content="Dice probabilities" />
<meta name="description" content="Calculates the probability of throwing a value given a combination of dice." />
<meta name="theme-color" content="#0033cc" />
2019-06-09 22:13:46 +02:00
2019-06-09 22:48:31 +02:00
<title>Simplify fractions | FWDekker</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css"
integrity="sha256-l85OmPOjvil/SOvVt3HnSSjzF1TUMyT9eV0c2BzEGzU=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/milligram/1.3.0/milligram.min.css"
integrity="sha256-Ro/wP8uUi8LR71kwIdilf78atpu8bTEwrK5ZotZo+Zc=" crossorigin="anonymous" />
2019-06-09 22:13:46 +02:00
<style>
body {
2019-06-09 22:48:31 +02:00
margin-top: 50px;
margin-bottom: 50px;
2019-06-09 22:13:46 +02:00
}
</style>
</head>
<body>
<div class="container">
2019-06-09 22:48:31 +02:00
<h1>Simplify fractions</h1>
<blockquote>
<p><em>Simplify a fraction to eliminate common factors.</em></p>
</blockquote>
2019-06-09 22:13:46 +02:00
2019-06-09 22:48:31 +02:00
<form>
<fieldset>
<label for="numerator">Numerator</label>
<input type="number" id="numerator" min="-2147483647" max="2147483647" autofocus />
2019-06-09 22:13:46 +02:00
2019-06-09 22:48:31 +02:00
<label for="denominator">Denominator</label>
<input type="number" id="denominator" min="-2147483647" max="2147483647" />
2019-06-09 22:13:46 +02:00
2019-06-09 22:48:31 +02:00
<input type="submit" value="Calculate" id="submit" />
</fieldset>
</form>
2019-06-09 22:13:46 +02:00
2019-06-09 22:48:31 +02:00
<span id="out"></span>
</div>
2019-06-09 22:13:46 +02:00
2019-06-09 22:48:31 +02:00
<!-- Scripts -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"
integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script>
2019-06-09 22:28:16 +02:00
<script>
"use strict";
2019-06-09 22:48:31 +02:00
const xor = (a, b) => (a || b) && !(a && b);
2019-06-09 22:28:16 +02:00
/**
* Determines whether something is an integer.
*
* @method isInt
* @param {Object} any Object.
* @return {boolean} true iff given Object is an integer.
*/
var isInt = function (n) {
if (isNaN(n)) {
return false;
}
var x = parseFloat(n);
return (x | 0) === x;
};
/**
* Returns array of given integer's prime factors.
*
* @method primeFactors
* @param {number} n an integer.
* @return {Array} an array of integers which are the given integer's prime
* factors, or undefined if the input is not an integer;
* an empty array is returned for inputs below 2.
*/
var primeFactors = function (n) {
// Cast to integer
n = +n;
if (!isInt(n)) {
return undefined;
}
// Integers < 2 have no prime factors
if (n < 2) {
return [];
}
// Determine factors
var factors = [];
while (n % 2 === 0) {
factors.push(2);
n /= 2;
}
while (n % 3 === 0) {
factors.push(3);
n /= 3;
}
for (var i = 5; i <= n; i += ((i - 1) % 6 === 0) ? 4 : 2) {
while (n % i === 0) {
factors.push(i);
n /= i;
}
}
return factors;
};
/**
* Minimises a fraction and returns an array of integers
* [numerator, denominator].
*
* @method minimise
* @param {number} numer the numerator.
* @param {number} denom the denominator.
* @return {Array} an array of integers [numerator, denominator]
* representing a minimal fraction.
*/
var minimise = function (numer, denom) {
// Cast to integer
numer = +numer;
denom = +denom;
if (!isInt(numer) || !isInt(denom) || denom === 0) {
return undefined;
}
// Short-circuit
if (numer === 0) {
return [0, 1];
}
// Minimise
var sign = (xor(numer < 0, denom < 0) ? -1 : 1);
var factor, factors = primeFactors(numer);
if (factors === undefined) {
return undefined;
}
for (var len = factors.length, i = 0; i < len; i++) {
factor = factors[i];
if (denom % factor === 0) {
numer /= factor;
denom /= factor;
}
}
// Return minimised values
return [sign * Math.abs(numer), Math.abs(denom)];
};
/**
* Formats a fraction.
*
* @method formatFraction
* @param {Array} fraction the fraction as an array of integers
* [numerator, denominator].
* @param {boolean} check false iff the denominator should always be
* displayed.
* @param {string} prefix the prefix to be put in front of the
* formatted fraction, is formatting is
* applicable.
* @return {string} the formatted fraction.
*/
var formatFraction = function (fraction, check, prefix) {
check = (check === undefined ? true : check);
prefix = (prefix === undefined ? "" : prefix);
var numer = +fraction[0],
denom = +fraction[1];
if (!check || !(numer == denom || numer == "0" || numer == "-0" || denom == "1")) {
return prefix + "\\frac{" + numer + "}{" + denom + "}";
} else {
return prefix + numer;
}
};
/**
* Formats a fraction in another way.
*
* @method formatFraction2
* @param {Array} fraction the fraction as an array of integers
* [numerator, denominator].
* @param {string} prefix the prefix to be put in front of the
* formatted fraction, is formatting is
* applicable.
* @return {number} { description_of_the_return_value }
*/
var formatFraction2 = function (fraction, prefix) {
// Default parameter values
prefix = (prefix === undefined ? "" : prefix);
// Cast to integers
var numer = +fraction[0],
denom = +fraction[1];
// No formatting needed
if (numer <= denom || numer == "0" || numer == "-0" || denom == "1") {
return "";
}
// Format
var sign = (xor(numer < 0, denom < 0) ? -1 : 1);
var base = sign * Math.floor(Math.abs(numer) / Math.abs(denom));
var mod = Math.abs(numer) % Math.abs(denom);
return prefix + base + " + " + formatFraction([Math.abs(mod), Math.abs(denom)]);
};
// Handles input
var calculateMinimalFraction = function () {
// Cast inputs to integers
var numer = +(document.getElementById("numerator").value),
denom = +(document.getElementById("denominator").value);
var out = document.getElementById("out");
// Check if both are integers
if (!isInt(numer) || !isInt(denom)) {
out.innerHTML = "The numerator and denominator must be integers.";
}
// Minimise fraction
var fraction = minimise(numer, denom);
out.innerHTML = "" +
"$$" +
/*formatFraction([numer, denom], false) + */
formatFraction(fraction, true, " = ") +
formatFraction2(fraction, " = ") +
"$$";
2019-06-09 22:48:31 +02:00
console.log("DO IT");
2019-06-09 22:28:16 +02:00
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
};
// Event listeners
document.addEventListener('DOMContentLoaded', function () {
var submit = document.getElementById("submit");
submit.addEventListener(
"click",
function (e) {
e.preventDefault();
calculateMinimalFraction();
},
false
);
}, false);
document.onkeypress = function (e) {
if (!e) {
e = window.event;
}
var keyCode = +(e.keyCode || e.which);
switch (keyCode) {
case 13:
// Calculate
document.getElementById("numerator").focus();
document.getElementById("numerator").select();
calculateMinimalFraction();
e.preventDefault();
break;
case 47:
// Select denominator
document.getElementById("denominator").focus();
document.getElementById("denominator").select();
e.preventDefault();
break;
}
};
</script>
2019-06-09 22:13:46 +02:00
</body>
</html>