2016年9月24日土曜日

開発環境

計算機プログラムの構造と解釈[第2版](ハロルド エイブルソン (著)、ジュリー サスマン (著)、ジェラルド・ジェイ サスマン (著)、Harold Abelson (原著)、Julie Sussman (原著)、Gerald Jay Sussman (原著)、和田 英一 (翻訳)、翔泳社、原著: Structure and Interpretation of Computer Programs (MIT Electrical Engineering and Computer Science)(SICP))の第1章(手続きによる抽象の構築)、1.3(高階手続きによる抽象)、1.3.3(一般的方法としての手続き)、問題1.37-a、b.を JavaScript で取り組んでみる。

その他参考書籍

問題1.37-a、b.

コード(Emacs)

HTML5

<div id="graph0"></div>
<input id="num00" type="number" min="1" step="1" value="1"> ≤ n ≤
<input id="num01" type="number" min="1" step="1" value="2">
<br>
<div id="graph1"></div>
<input id="num10" type="number" min="1" step="1" value="1"> ≤ n ≤
<input id="num11" type="number" min="1" step="1" value="2">
<br>

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.2/d3.min.js"></script>
<script src="array.js"></script>
<script src="sample37.js"></script>

JavaScript

(() => {
    'use strict';
    var PHI = (1 + Math.sqrt(5)) / 2,
        input_num00 = document.querySelector('#num00'),
        input_num01 = document.querySelector('#num01'),
        input_num10 = document.querySelector('#num10'),
        input_num11 = document.querySelector('#num11'),
        inputs = [input_num00, input_num01, input_num10, input_num11],
        width = 600,
        height = 600,
        padding = 50,
        contFrac0,
        contFrac1,
        contFracs,
        getPoints,
        draw,
        n = (i) => 1,    
        d = (i) => 1;

    // 再帰関数
    // 再帰的プロセス
    contFrac0 = (n, d, k) => {
        var iter;

        iter = (i) => {
            if (i > k) {
                return 0;
            }
            return n(i) / (d(i) + iter(i + 1));
        };
        return iter(1);
    };
    // 反復的プロセス
    contFrac1 = (n, d, k) => {
        var iter;

        iter = (i, result) => {
            if (i === 0) {
                return result;
            }
            return iter(i - 1, n(i) / (d(i) + result));
        };
        return iter(k, 0);
    };
    contFracs = [contFrac0, contFrac1],

    getPoints = (func, a, b) => {
        var xs = Array.range(a, b + 1),
            ys = xs.map((x) => func(n, d, x)),
            xmin = Math.min.apply(null, xs),
            xmax = Math.max.apply(null, xs),
            ymin = Math.min.apply(null, ys),
            ymax = Math.max.apply(null, ys),
            points;

        points = xs.map((x, i) => [x, ys[i]]);
        return {points:points, xmin:xmin, xmax:xmax, ymin:ymin, ymax:ymax};
    };

    draw = (id_num) => {
        var div_graph = document.querySelector(`#graph${id_num}`),
            input_num0 = document.querySelector(`#num${id_num}${0}`),
            input_num1 = document.querySelector(`#num${id_num}${1}`),
            svg,
            xscale,
            yscale,
            xaxis,
            yaxis,
            a = parseInt(input_num0.value, 10),
            b = parseInt(input_num1.value, 10),
            contFrac = contFracs[id_num],
            point_data = getPoints(contFrac, a, b),
            points = point_data.points,
            xmin = point_data.xmin,
            xmax = point_data.xmax,
            ymin = point_data.ymin,
            ymax = point_data.ymax;

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

        svg = d3.select(`#graph${id_num}`)
            .append('svg')
            .attr('width', width)
            .attr('height', height);

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

        svg.append('line')
            .attr('x1', xscale(xmin))
            .attr('y1', yscale(1 / PHI))
            .attr('x2', xscale(xmax))
            .attr('y2', yscale(1 / PHI))
            .attr('stroke', 'rgba(0, 0, 255, 0.5)');
        
        svg.append('g')
            .attr('transform', `translate(0, ${height - padding})`)
            .call(xaxis);
        svg.append('g')
            .attr('transform', `translate(${padding}, 0)`)
            .call(yaxis);
    };

    inputs.forEach((input, i) => {
        var j = Math.floor(i / 2);
        
        input.onchange = () => draw(j);
        draw(j);
    });
})();
≤ n ≤
≤ n ≤

0 コメント:

コメントを投稿