開発環境
- macOS Sierra - Apple (OS)
- Emacs (Text Editor)
- JavaScript (プログラミング言語)
- Learning JavaScript [邦訳](参考書籍)
レンガを重ねて(前編)金曜日は『数学ガールの秘密ノート』の日。最新回は一週間無料で読めます。公式RTしてから読みにいってね!
— 結城浩 (@hyuki) 2017年5月4日
やさしく始まる新シーズン「整数に誘われて」第2章 レンガを重ねて(前編)https://t.co/5TjsPhorbG
- 《最小公倍数》は、長方形を積み重ねた最小の正方形の一辺。
- 《最大公約数》は、長方形を埋め尽くす最大の正方形の一辺。
「m = 6, n = 9の場合」以外の他の正の整数での最小公倍数と最大公約数の長方形、正方形を気軽に確認できるようにしてみて、より実感してみる。
コード(Emacs)
HTML5
<div id="graph0"></div> <pre id="output0"></pre> <label for="m0">m = </label> <input id="m0" min="1" step="1" type="number" value="6"> <label for="n0">n = </label> <input id="n0" min="1" step="1" type="number" value="9"> <button id="draw0">draw</button> <button id="clear0">clear</button> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.6/d3.min.js" integrity="sha256-5idA201uSwHAROtCops7codXJ0vja+6wbBrZdQ6ETQc=" crossorigin="anonymous"></script> <script src="sample8.js"></script>
JavaScript
let div0 = document.querySelector('#graph0'),
input_m = document.querySelector('#m0'),
input_n = document.querySelector('#n0'),
inputs = [input_m, input_n],
pre0 = document.querySelector('#output0'),
width = 600,
height = 600,
padding = 50,
btn0 = document.querySelector('#draw0'),
btn1 = document.querySelector('#clear0'),
p = (x) => pre0.textContent += x + '\n',
range = (start, end, step=1) => {
let result = [];
for (let i = start; i < end; i += step) {
result.push(i);
}
return result;
};
let draw = () => {
pre0.textContent = '';
let m = parseInt(input_m.value, 10),
n = parseInt(input_n.value, 10),
lm = m,
ln = n;
for (; lm !== ln;) {
if (lm < ln) {
lm += m;
} else {
ln += n;
}
}
p(`lcm(${m}, ${n}) = ${lm}`);
let g = m > n ? m : n;
for (; m % g !== 0 || n % g !== 0; g -= 1) {
;
}
p(`gcd(${m}, ${n}) = ${g}`);
let lines =
range(0, ln + 1)
.map((i) => [[i, 0], [i, lm],
i === 0 || i === ln ? ['green', 4] :
i % n === 0 ? ['blue', 2] : ['lightgray', 1]])
.concat(range(0, lm + 1)
.map((i) => [[0, i], [ln, i],
i === 0 || i === lm ? ['green', 4] :
i % m === 0 ? ['greenyellow', 2] : ['lightgray', 1]]))
.concat([[[0, 0], [0, g], ['red', 4]], [[g, 0], [g, g], ['red', 4]],
[[0, 0], [g, 0], ['red', 4]], [[0, g], [g, g], ['red', 4]]]);
let xscale = d3.scaleLinear()
.domain([0, ln])
.range([padding, width - padding]);
let yscale = d3.scaleLinear()
.domain([0, lm])
.range([height - padding, padding]);
let xaxis = d3.axisBottom().scale(xscale);
let yaxis = d3.axisLeft().scale(yscale);
div0.innerHTML = '';
let svg = d3.select('#graph0')
.append('svg')
.attr('width', width)
.attr('height', height);
svg.selectAll('line')
.data(lines)
.enter()
.append('line')
.attr('x1', (d) => xscale(d[0][0]))
.attr('y1', (d) => yscale(d[0][1]))
.attr('x2', (d) => xscale(d[1][0]))
.attr('y2', (d) => yscale(d[1][1]))
.attr('stroke', (d) => d[2][0])
.attr('stroke-width', (d) => d[2][1]);
svg.append('g')
.attr('transform', `translate(0, ${height - padding})`)
.call(xaxis);
svg.append('g')
.attr('transform', `translate(${padding}, 0)`)
.call(yaxis);
}
inputs.forEach((input) => input.onchange = draw);
btn0.onclick = draw;
btn1.onclick = () => pre0.textContent = '';
draw();
0 コメント:
コメントを投稿