2016年9月28日水曜日

開発環境

アルゴリズムパズル(Anany Levitin (著)、Maria Levitin (著)、黒川 洋 (翻訳)、松崎 公紀 (翻訳)、オライリージャパン)の中級パズル、57.(フィボナッチのウサギ問題(Fibonacci's Rabbits Problem))をJavaScriptで。

コード(Emacs)

HTML5

<div id="graph0"></div>
<label for="months0">
  月数:
</label>
<input id="months0" type="number" min="0" step="1" value="12">ヶ月後, <span id="nums0"></span><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="array.js"></script>
<script src="sample57.js"></script>

JavaScript

{
    'use strict';
    let width = 600,
        height = 600,
        padding = 50,
        div_graph = document.querySelector('#graph0'),
        input_months = document.querySelector('#months0'),
        span_nums = document.querySelector('#nums0'),
        memo = [2, 2];

    let calc = (n) => {
        if (memo[n]) {
            return memo[n];
        }
        let a = memo[0],
            b = memo[1];
        for (let i = 2; i <= n; i += 1) {
            memo[i] = a + b;
            let t = a;
            a = b;
            b = t + b;
        }
        return b;
    };
    let getNums = (n) => {
        return Array.range(n + 1).map(calc);
    };
    let draw = function () {
        let months = parseInt(input_months.value, 10),
            ys = getNums(months),
            xmin = 0,
            xmax = months,
            ymin = 0,
            ymax = Math.max.apply(null, ys);

        let xscale = d3.scaleLinear()
            .domain([xmin, xmax])
            .range([padding, width - padding]);
        let yscale = d3.scaleLinear()
            .domain([ymin, ymax])
            .range([height - padding, padding]);
        let xaxis = d3.axisBottom().scale(xscale);
        let yaxis = d3.axisLeft().scale(yscale);

        div_graph.innerHTML = '';
        let svg = d3.select('#graph0')
            .append('svg')
            .attr('width', width)
            .attr('height', height);

        svg.selectAll('line')
            .data(ys.slice(0, -1))
            .enter()
            .append('line')
            .attr('x1', (d, i) => xscale(i))
            .attr('y1', (d) => yscale(d))
            .attr('x2', (d, i) => xscale(i + 1))
            .attr('y2', (d, i) => yscale(ys[i + 1]))
            .attr('stroke', 'blue');

        svg.append('g')
            .attr('transform', `translate(0, ${height - padding})`)
            .call(xaxis);
        svg.append('g')
            .attr('transform', `translate(${padding}, 0)`)
            .call(yaxis);
        span_nums.innerText = ys.pop();
    };

    input_months.onchange = draw;

    draw();
}
ヶ月後,

0 コメント:

コメントを投稿