留学・音ゲー・研究備忘録

heine98の音ゲー・研究・留学の記録。PCの知識はちょっとシェルから操作できます、くらいの人間。

AtCoderに手を出してしまった

はっきりいって僕が普段やっているマクロ経済学数値計算は、世間一般で求められているコーディング技術とは少し違う。

  1. 所与の価格のもとで制約付き動的計画法を解いて家計の政策関数を導出。
  2. その政策関数を元に、家計の財需要ないし資本や労働供給を計算。それが市場の需給が一致するかチェック。していれば終了、していなければ価格を変更して再計算。

が定常状態計算。ここから景気循環やら何かしらのショックが起きたときに経済変数がどのように変動するか、また別のコーディングで計算する(DynareやMIT ShockのTransition Pathなど)。

ただ、そういった中でも、例えば行列から条件に当てはまる要素を探し出すことなんかは頻繁に出てくる。(まあJuliaならsearchsortedlastなどのBase関数でやれば一発ではあるが。)

というわけで全然別物というわけでもないことも気付かされた。入出力をほぼ使わないという点を除けば。

AtCoderの問題というか競技プログラミングの問題は、意外とパズルっぽいものも多く、みんながハマる理由がわかった気がする。(Cまで解いた感想です)。

それに経済学のコードだとあまりネットに落ちていない分、どんなアルゴリズムやコードの書き方がいいのかということがわかりにくいが、AtCoderなら解説も存在するし、普通の人はこういうふうに捉えるのかというのが学べてとても面白い。

たとえば、Beginnerコンテスト117回目のB問題

atcoder.jp

これは解くのに必要な定理が示されているので、それ通りにコードを書くだけである。 問題はどうやって最大の長さを調べるか、そしてそれ以外の辺の長さの合計をどう出すか、だと思うのだが、僕自身が何も考えずに書いた結果、はforループを3回も使う書き方しかピンとこなかった。

#include <bits/stdc++.h>
using namespace std;

int main() {
    int N, maxl =0, ind = 0, total = 0;
    cin >> N;
    vector<int> length(N);

    for (int i = 0; i < N; ++i){
        cin >> length.at(i);
    }

    // max
    for (int i = 0; i < N; ++i){
        if (maxl < length.at(i)){
            maxl = length.at(i);
            ind = i;
        }
    }

    // total length except for the max
    for (int i = 0; i < N; ++i){
        if (i != ind ){
            total += length.at(i);
        }
    }

    if (total > maxl){
        cout << "Yes" << endl;
    }
    else{
        cout << "No" << endl;
    }
        
}

しかし、解説を見れば、長さのベクトルを取得したあとにsortでやる、または長さを取得した際にすべての合計sumとmaxを取得し、それ以外の長さはsum-maxとすればよいなど、言われてみればたしかにそのとおりだという解き方が示されていた。 そういった細かいアルゴリズムが、自分の数値計算コードに役立つ日が来るといいと願いながら、今後もやっていきたい。

まあ発表スライド作るのが嫌すぎて現実逃避しているだけなのだが。