* CeL.run('application.math', function() {
* // ..
* });
*
*/
'use strict';
if (typeof CeL === 'function')
CeL.run(
{
name : 'application.math',
// includes() @ data.code.compatibility.
require : 'data.code.compatibility.|data.math.',
code : function module_code(library_namespace) {
/**
* null module constructor
* @class 出數學題目用的 functions
*/
var _// JSDT:_module_
= function() {
// null module constructor
};
/**
* for JSDT: 有 prototype 才會將之當作 Class
*/
_// JSDT:_module_
.prototype = {
};
//----------------------------------------------------- //
(function() {
runCode.setR = 0;
for (var i = 0, j, t, s, n_e; i < 10;) {
t = 2000 + 8000 * Math.random();
s = get_random_prime.get_different_number_set(3, t, t / 8);
if (s.LCM > 9999)
continue;
n_e = [];
n_e[s.GCD] = 1;
for (j = 0; j < s.length; j++)
if (n_e[s[j]])
continue;
else
n_e[s[j]] = 1;
sl([ s.GCD, s.LCM ] + '; ' + s);
i++;
}
});
//----------------------------------------------------- //
// 中式短除法(Chinese short division)並非 short division.
// https://en.wikipedia.org/wiki/Short_division
function draw_short_division(naturals, layer, GCD_only) {
if (!Array.isArray(naturals))
if (isNaN(layer))
naturals = [ naturals ];
else
naturals = arguments, layer = null;
var i, length = naturals.length | 0, divisor, cell_width_em = 2,
//
natural_Array = [];
for (i = 0; i < length; i++) {
divisor = +naturals[i];
if (0 < divisor && divisor < Number.MAX_SAFE_INTEGER) {
natural_Array.push(divisor);
if (cell_width_em < String(divisor).length * .6)
cell_width_em = Math.ceil(String(divisor).length * .6);
}
}
length = (naturals = Array.prototype.slice.call(natural_Array)).length | 0;
var block = [], count = 0,
//
_GCD = library_namespace.GCD(natural_Array),
//
GCD = library_namespace.factorize(_GCD);
library_namespace.debug(length + ' Naturals: '+natural_Array+'.',2);
if (GCD) {
// assert: _GCD > 1
if (_GCD !== (divisor = GCD.toString(true)))
_GCD += ' = ' + divisor;
// phase 1: 處理 GCD 部分。
for (divisor in GCD) {
divisor |= 0;
for (var j = 0; j < GCD[divisor] | 0; j++)
if (length !== 1 || natural_Array[0] !== divisor) {
block.push(draw_short_division.add_line(natural_Array, cell_width_em, divisor, count++, true));
for (i = 0; i < length; i++)
natural_Array[i] = natural_Array[i] / divisor;
}
}
}
// phase 2: 處理 LCM 部分。
// TODO: 按大小排列。
GCD = 0;
do {
var LCM = natural_Array[0];
for (i = 1; i < length; i++)
if (natural_Array[i] > 1 && (GCD = library_namespace.GCD(LCM, natural_Array[i])) > 1) {
divisor = +library_namespace.first_factor(GCD);
block.push(draw_short_division.add_line(natural_Array, cell_width_em, divisor, count++));
for (i = 0; i < length; i++)
if (natural_Array[i] % divisor === 0)
natural_Array[i] = natural_Array[i] / divisor;
break;
}
} while (GCD > 1);
// 依照各種不同類之輸入,顯示不同備註標示。
if (length === 1) {
// 質因數分解。
block.push(
draw_short_division.add_line(natural_Array, cell_width_em),
{
div: [
_GCD
]
}
);
} else {
i = library_namespace.LCM(naturals);
block.push(
draw_short_division.add_line(natural_Array, cell_width_em),
{
div: [
'GCD',
// '(', naturals.join(', '), ')',
' = ',
_GCD
],
S: draw_short_division.GCD_style
}, {
div: [
'LCM',
// '(', naturals.join(', '), ')',
' = ',
i,
' = ',
library_namespace.factorize(i).toString(true)
]
}
);
}
// 最後收尾。
block = {
div: block,
style: 'width:' + (1 + (length + (1 < length ? 2 : 1)) * cell_width_em | 0) + 'em;background-color:#def',
C: 'short_division'
};
return layer ? new_node(block, layer) : block;
}
draw_short_division.GCD_style = 'color:#f79;';
draw_short_division.add_line = function(naturals, cell_width_em, divisor, count, phase_GCD) {
library_namespace.debug(divisor + ': ' + naturals, 3, 'draw_short_division.add_line');
var line = [];
naturals.forEach(function(natural, index) {
line.push({
span: natural,
S: 'display:inline-block;text-align:right;padding-right:.2em;width:'
+ (cell_width_em + (index ? 0 : .5 - count / 5)).to_fixed(2) + 'em'
}, ' ');
});
line.pop();
if (divisor)
line = [{
span: divisor,
S: 'text-align:right;padding-right:.2em;'
}, {
span: line,
S: 'border-left:1pt solid #88f;border-bottom:1pt solid #88f'
}];
return {
div: line,
S: 'clear:both;text-align:right;' + (phase_GCD ? draw_short_division.GCD_style : '')
};
};
_.draw_short_division = draw_short_division;
/*
CeL.run('application.math', function() {
CeL.draw_short_division([12], [ document.body, 2 ]);
CeL.draw_short_division([12, 18], [ document.body, 2 ]);
CeL.draw_short_division([12, 18, 24], [ document.body, 2 ]);
});
*/
// ---------------------------------------------------------------------------------------------- //
var new_node = function () {
var func = library_namespace.DOM.new_node;
if (func)
return (new_node = func).apply(null, arguments);
},
//
check_MathML = function() {
var math_node = new_node({
div : {
span : 'normal'
},
S : 'line-height:1em;visibility:hidden'
}, document.body);
if (!math_node)
return;
new_node({
math : {
mfrac : [ {
mi : 'test'
}, {
mi : 'MathML'
} ]
}
}, math_node, 'mathml');
// Firefox/37.0 不需要 setTimeout()。
// setTimeout(check_MathML.check.bind(math_node), 0);
// return check_MathML.check.call(math_node, true);
return check_MathML.check.call(math_node);
};
// 2015/1/1: Firefox only. 僅 firefox 回傳 true。
check_MathML.check = function(no_remove) {
// library_namespace.debug(this);
Object.defineProperty(_, 'support_MathML', {
// method 1:
// 分數 2/3 之 2 的 offsetTop 應該比 3 更高一點。
// 但在 ff 中,沒有 .offsetTop。
// var mfrac = this.lastChild.firstChild;
// value : mfrac.firstChild.offsetTop < mfrac.lastChild.offsetTop;
// method 2: 因為插入
//