LoginSignup
1
1

More than 5 years have passed since last update.

[checkio]Weak point

Last updated at Posted at 2017-06-22

問題は引数に数字のみを要素として持つ二次元配列が与えられ、一定のルールに則って弱点を探す。
一定のルールとは、縦横の列それぞれの合計の、もっとも低い列の重なる位置となる。
これで宇宙船のメンテナンスをする・・・だと・・・
なんと今回は一発でテストが通る。嬉しい(´ー`)

自分の回答

function weakPoint(matrix){
    //variables
    let sumCol = [];
    let lenRow = matrix[0].length;
    let lenCol = matrix.length;

    //calculate sum
    let sumRow = matrix.map(function(x) {
        let sum = 0;
        for (let i of x) {
            sum += i;
        }
        return sum
    });
    for (let i = 0; i < lenCol; i++) {
        let sum = 0;
        for (let j = 0; j < lenRow; j++) {
            sum += matrix[j][i];
        }
        sumCol.push(sum);
    }

    //find weakest and obtain index
    let minRow = Math.min.apply(null, sumRow);
    let minCol = Math.min.apply(null, sumCol);
    let minRowIdx = sumRow.indexOf(minRow);
    let minColIdx = sumCol.indexOf(minCol);

    return [minRowIdx, minColIdx]
}

相変わらず正攻法でしか解けない。前回学んだmapメソッドを使ってみた。sumColの方も頑張れば使えたのか。

すごいかいとう

function weakPoint(matrix){
    function minRow(matrix) {
        let sum = matrix.map(row => row.reduce((p, c) => p + c))
        return sum.reduce((p,v,i) => sum[i] < sum[p] ? i : p, 0)
    }
    return [minRow(matrix), minRow(_.unzip(matrix))]
}

もはや何が起こってるのかわからない。
3行目ではmapメソッドでrowを一つずつ取り出しつつreduceを使って合計を求めて、sum array objectに格納。アロー関数すごい。
4行目のreduceの引数を3つ定義してiとpをなんでインデックスに使ってるのかがわからない・・・
pはreduceに第二引数として渡されてる0がまず入って、iも一回目の処理は最初の要素だからこれは同じ要素の比較をしているのではないのか・・・?
あ、pとiにはインデックスの値しか入らないようにあえて指定してるのかな。で、左から順に比べていって一番小さいものが最後に残ると。
最後にunzipで縦横を入れ替えて、同じ関数で縦バージョンを処理。

む、.unzipのアンダースコアってなんだ・・・
stack overflowにあった。
javascript - What does "_" means here? - Stack Overflow
backbone.jsのunderscore.jsというところのオブジェクトらしい。ドットインストールで扱われてるらしいのでチェックする。

学び

Math.min()
 ー与えられた複数の数字からもっとも低い数値を返す。配列は受け取れない。
function.apply(thisArg[, argsArray])
 ーargsArrayに渡した配列に対してfunctionの関数を呼び出す。thisArgには関数に渡すthisの値を指定できる。nullで省略も可能。

reduce(function(previous value, current value, idx, array){return })
 ーなにがしかの指定した動作で配列を一つの値にする。第二引数、つまり初期値を指定した時は、callbackの回数が一回増えることになる。
MDCによると・・・

配列の(左から右へ) 2 つの値に対して同時に関数を適用し、単一の値にします。

便利そう(参考:reduce関数は結構有用っていうお話 - あと味)

concat(value)
 ー配列オブジェクトに呼び出して、引数の配列と連結させる。

unzip(array)
 ー縦横を入れ替えた2次元配列を作り出すのに使える。

反省

アロー関数を確認しつつ、今度使ってみる。
あとドットインストールをチェック。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1