2008-10-28

http://anond.hatelabo.jp/20081026132547

FizzBuzz続き

Cにもlambdaがあればいいのに

#include <stdio.h>
#include <unistd.h>
#define FALSE 0
#define TRUE !FALSE

typedef struct state_t {
    int state;
    int num;
    int max;
    int outputted;
} state_t;

typedef struct fsm_t {
    state_t *(*func)(struct fsm_t *, state_t *);
    int divider;
    char *str;
} fsm_t;

static state_t *fizzbuzz(fsm_t *, state_t *);
static state_t *end_of_line(fsm_t *, state_t *);
static state_t *cond(fsm_t *, state_t *);
static state_t *succ(fsm_t *, state_t *);

static fsm_t fsm[] = {
    { fizzbuzz, 3, "Fizz" },
    { fizzbuzz, 5, "Buzz" },
    { end_of_line, 0, NULL },
    { cond, 0, NULL },
    { NULL, 0, NULL },
};

static state_t *fizzbuzz(fsm_t *fsm, state_t *cur) {
    if ((cur->num % fsm[cur->state].divider) == 0) {
        printf("%s", fsm[cur->state].str);
        cur->outputted = TRUE;
    }
    return succ(fsm, cur);
}

static state_t *end_of_line(fsm_t *fsm, state_t *cur) {
    if (!cur->outputted)
        printf("%d", cur->num);
    puts("");
    cur->outputted = FALSE;
    return succ(fsm, cur);
}

static state_t *cond(fsm_t *fsm, state_t *cur) {
    if (++cur->num > cur->max)
        return NULL;
    return succ(fsm, cur);
}

static state_t *succ(fsm_t *fsm, state_t *cur) {
    if (fsm[++cur->state].func == NULL)
        cur->state = 0;
    return cur;
}

int main(void) {
    state_t state = { 0, 1, 100, FALSE };
    state_t *cur = &state;

    while ((cur = (*fsm[cur->state].func)(fsm, cur)) != NULL)
        ;

    return 0;
}
記事への反応 -
  • じゃぁ再帰で。 int fizz_buzz(int i, int j) { if(i % 3 == 0 &amp;amp;&amp;amp; j % 3 != 0) { printf(&quot;Fizz&quot;); return 1+ fizz_buzz(i / 3, j * 3); } if(i % 5 == 0 &amp;amp;&amp;amp; j % 5 != 0) { printf(&quot;Buzz&quot;); r...

    • さっきのはあまりに汚かったのでちゃんと書いたよ!! static int do_fizz_buzz(int num, int rem, const char* str, int print) { if (num % rem == 0) { return do_fizz_buzz(num / rem, rem, str, 1); } if (print) printf(&quot;%...

      • printf("%s", str); printf(str);又はputs(str); "%s"をパースする時間がもったいない とかどうでしょうか?

        • Thanks. 確かにそうなんだけど、putsだと勝手に改行が出力されてしまうので一ヶ所しか使えなかった。DRY、forなし、ifなし(:?使ってるのでインチキだけど)、main以外に関数なし風味。これで...

          • http://anond.hatelabo.jp/20081026002746 ステートマシン大好きっ子としては書かずにいられない もう少しがんばればforも無くせるな fsmの中身ってDRYなの?的な話もあるだろうが,こんなもの他の...

            • FizzBuzz続き Cにもlambdaがあればいいのに #include &lt;stdio.h&gt;#include &lt;unistd.h&gt;#define FALSE 0#define TRUE !FALSEtypedef struct state_t { int state; int num; int max; int outputted;} state_t;typedef struct fsm_t { ...

              • なんでここまで簡単な要求を、ここまで複雑に書く必要があるのか、サッパリ理解できません。 それがプログラマというもの? だったら僕はプログラマになんかならなくてもいいや。

              • じゃ、少しだけ本気出してみたよ。要求仕様にかなうといいんだけど。 #include &lt;stdio.h&gt;int main(void) { puts(&quot;1&quot;); puts(&quot;2&quot;); puts(&quot;Fizz&quot;); puts(&quot;4&quot;); puts(&quot;...

          • for を再帰で代替するなんて、どういうメリットがあるの?

            • for を再帰で代替するなんて、どういうメリットがあるの? 逆だよ。ループ構文が再帰の一種なの。 だから代替するってのはちょっと違う。

              • ループが再帰処理の一種・・・? 再帰処理って処理を停止して新しい処理を行い、終了後に停止していた処理に戻ることじゃない? 処理A -&gt; 処理B -&gt; 処理A が再帰処理の名前の由来で...

                • 元増田じゃないけど、LISPとかの話じゃないかな。 ループは再帰で実現できるけど、再帰はループで実現できない。だから論理的には、再帰の方がより一般的。(再帰さえあればOK) ただ...

                • 「俺にとってはループの方が判りやすい」という主張は否定しないが。 再帰処理って処理を停止して新しい処理を行い、終了後に停止していた処理に戻ることじゃない? 処理A -&gt; 処...

                  • 「末尾再起のある処理系なら」と付け加える必要があるのでは?

                  • よくわかってないならマジレスしなくていいよ。ネタじゃないし。 それは「関数呼び出し」じゃないかな? 言語によるのかも知れないが、私が触ってきた言語では全部自分自身を関数...

                    • 元増田と違う人かもしれないが、 言語によるのかも知れないが、私が触ってきた言語では全部自分自身を関数呼び出しすることを再帰と言っていた。 これには同意します。しかしな...

                      • プログラム構造のレベルでも、個人的な感覚の問題かもしれないが、再帰処理よりもループのほうがわかりやすい。 それで、元々のプログラムがループで記述されていた場合、わざわざ...

                    • 元エントリについている『大はずれだろ。どこが「名前の由来」やねん。』云々は別増田です 口調が違うのでわかります。 ちなみにそのエントリについてるエントリも私とは別増田で...

        • 後者がいいんじゃないかな。前者だと一部コンパイラだとセキュリティ警告が出ると突っ込まれるかもしれない。 この流れだとw

記事への反応(ブックマークコメント)

ログイン ユーザー登録
ようこそ ゲスト さん