2014年6月18日水曜日

プログラムの難しさの階層の答え

きしだのはてなの記事を見て、
回答を書きたくなったのでそっと書いてみることにしました。

実際に回答してもらう問題じゃないということなので、
こちらもゆるい感じに解いていきます。

動かなかったらゴメンナサイ。

あ、言語はJavaScriptでいきます。

問題で定義されていない部分については、
触れないように書きます。


演算
function(input) { return input + "が入力されました"; }



条件分岐
function(input) {
    if (input == "1") {
        return "ガケに落ちました";
    } else if (input == "2") {
        return "ライオンに食われました";
    }
}



ループ
function(input) {
    for (var i = 0; i < input.length; ++i) {
        if (input.substr(i, 1) != "A") { return false; }
    }
    return true;
}



状態管理(初版)
function(input) {
    if (input.length <= 1) { return false; }
    if (input.substr(0, 1) != "A") { return false; }
    var flag = false;
    for (var i = 1; i < input.length; ++i) {
        if (input.substr(i, 1) == "A") {
            if (flag) { return false; }
        } else {
            flag = true;
        }
    }
    return flag;
}



状態管理(2版)
function(input) {
    var state = "1st";
    for (var i = 0; i < input.length; ++i) {
        var target = input.substr(i, 1);
        switch (state) {
            case "1st": // "A"で始まる
                if (target != "A") { return false; }
                state = "2nd";
                break;
            case "2nd": // "A"が続く
                if (target != "A") { state = "3rd"; }
                break;
            case "3rd": // "A"以外が続く
                if (target == "A") { return false; }
                break;
        }
    }
    return (state == "3rd");
}


スタック
function(input) {
    var state = "1st";
    var nest = 0;
    for (var i = 0; i < input.length; ++i) {
        var target = input.substr(i, 1);
        switch (state) {
            case "1st": // "A"で始まる
                switch (target) {
                    case "A":
                        state = "2nd";
                        break;
                    case "(":
                    case ")":
                    default:
                        return false;
                }
                break;
            case "2nd": // "A"が続く、"("の検知
                switch (target) {
                    case "A":
                        break;
                    case "(":
                        ++nest;
                        state = "1st";
                        break;
                    case ")":
                        return false;
                    default:
                        state = "3rd";
                        break;
                }
                break;
            case "3rd": // "A"以外が続く、")"の検知
                switch (target) {
                    case "A":
                    case "(":
                        return false;
                    case ")":
                        if (nest == 0) { return false; }
                        --nest;
                        state = "4th";
                        break;
                    default:
                        break;
                }
                break;
            case "4th": // ")"の次は"A"、"("、")"、以外
                switch (target) {
                    case "A":
                    case "(":
                    case ")":
                        return false;
                    default:
                        state = "3rd";
                        break;
                }
                break;
        }
    }
    return (state == "3rd" && nest == 0);
}


状態管理に第2版があるのは、
回答の仕方が状態管理じゃなくてフラグ管理でしかなくて、
次のスタックの問題に繋がらなかったからです。

たいしたことは書いてないですし、
これ以上の解説はいらない…ですよね?

あ、ツッコミは歓迎します。

2014/06/19追記:ソースにコメントを追加

0 件のコメント:

コメントを投稿