2017年4月24日月曜日

開発環境

行列プログラマー(Philip N. Klein (著)、 松田 晃一 (翻訳)、 弓林 司 (翻訳)、 脇本 佑紀 (翻訳)、 中田 洋 (翻訳)、 齋藤 大吾 (翻訳)、オライリージャパン)の2章(ベクトル)、2.12(ラボ: ドット積を用いた投票記録の比較)、2.12.5(平均的でない民主党員)、課題 2.12.7、2.12.8 を JavaScript で取り組んでみる。

課題 2.12.7、2.12.8

voting_record_dump109.txt

コード(Emacs)

HTML5

<pre id="output0"></pre>
<input id="file0" type="file">
<br>
<button id="run0">run</button>
<button id="clear0">clear</button>

<script src="sample12_7.js"></script>

JavaScript

let btn0 = document.querySelector('#run0'),
    btn1 = document.querySelector('#clear0'),
    pre0 = document.querySelector('#output0'),
    input0 = document.querySelector('#file0'),
    p = (x) => pre0.textContent += x + '\n';

let createVotingDict = (strArray) => {
    let d = {};
    strArray.forEach((s) => {
        let a = s.split(/\s+/);

        d[a[0]] = a.slice(3).map((n) => parseInt(n, 10));
    });
    return d;
};

let policyCompare = (senA, senB, votingDict) => {
    let a = votingDict[senA],
        b = votingDict[senB];

    return a.reduce((prev, next, i) => prev += next * b[i], 0);
};
let mostSimilar = (sen, votingDict) => {
    let a = votingDict[sen],
        names = Object.keys(votingDict);

    names.splice(names.indexOf(sen), 1);
    
    let result = names[0],
        n = policyCompare(sen, result, votingDict);
    
    names.slice(1).forEach((name) => {
        let t = policyCompare(sen, name, votingDict);
        if (t > n) {
            n = t;
            result = name;
        }
    });
    return result;
};
let leastSimilar = (sen, votingDict) => {
    let a = votingDict[sen],
        names = Object.keys(votingDict);

    names.splice(names.indexOf(sen), 1);
    
    let result = names[0],
        n = policyCompare(sen, result, votingDict);
    
    names.slice(1).forEach((name) => {
        let t = policyCompare(sen, name, votingDict);
        if (t < n) {
            n = t;
            result = name;
        }
    });
    return result;
};

let findAverageSimilarity = (sen, senArray, votingDict) => {
    return senArray
        .reduce((prev, s) => prev + policyCompare(sen, s, votingDict), 0) /
        senArray.length;
};
let findAverageRecord = (senArray, votingDict) => {
    return Object.keys(votingDict)
        .filter((k) => senArray.indexOf(k) !== -1)
        .map((k) => votingDict[k])
        .reduce((x, y) => x.map((a, i) => a + y[i]))
        .map((x) => x / senArray.length);
};

let output = () => {
    let file = input0.files[0],
        reader = new FileReader();

    reader.onload = () => {
        let s = reader.result,
            strArray = s.split('\n'),
            votingDict = createVotingDict(strArray),
            names = Object.keys(votingDict);

        p('2.12.7')
        let rNames = strArray
            .filter((s) => s.split(/\s+/)[1] === 'R')
            .map((s) => s.split(/\s+/)[0]),            
            sen = names[0],
            average = findAverageSimilarity(sen, rNames, votingDict);

        names.slice(1).forEach((name) => {
            let t = findAverageSimilarity(name, rNames, votingDict);
            if (t > average) {
                average = t;
                sen = name;
            }
        });
        p(sen);

        p('2.12.8');
        let averageDemocratRecord = findAverageRecord(rNames, votingDict);
        
        sen = names[0];
        average = averageDemocratRecord.map((x, i) => x * votingDict[sen][i])
            .reduce((x, y) => x + y);
        names.slice(1).forEach((name) => {
            let t = averageDemocratRecord.map((x, i) => x * votingDict[name][i])
                .reduce((x, y) => x + y);
            if (t > average) {
                average = t;
                sen = name;
            }
        });
        p(sen);
    };
    reader.readAsText(file);
};

btn0.onclick = output;
btn1.onclick = () => pre0.textContent = '';



0 コメント:

コメントを投稿