不思議ちゃん

不思議ちゃん

みんクロ大好きな不思議ちゃんの日記
みんクロ無くなっちゃって悲しい

鶏ドリアンさんの情報の講義のC言語の課題

パソコン/インターネット

鶏ドリアンさんのブログ
http://www.nicotto.jp/blog/detail?user_id=276870&aid=16610652

にある、「情報の講義のC言語の課題」をCではなくて、「なでしこ」で書いてみました。
所用時間およそ30分。

課題は以下の通り。

自然数nを入力させる。

そのnに対して、「1」、「2」、…「n-1」、「n」の番号が書かれたn枚のカードを仮定する。
このn枚のカードを「n」が最上面になるように番号の順に積む。

その後、「最上面のカードを最下面に移動し、その次に最上面になったカードを捨てる」

という操作を繰り返し、最後にのこったカードの番号を出力せよ。


##################################################
# トリさんの課題
# 2010/07/31

# 自然数 N の入力
「自然数 N を入力してください」で尋ねてNに代入する。

# 入力チェック
もし(Nの整数部分<>N)OR (N<=0)ならば
 「自然数って言ってるだろ、ボケェ!」と言う。
 終わる。

# カードの作成
N回
 カード【回数】=N-回数+1
# カード【1】が一番上(初期値 N)

# 1操作につき1枚減るので、N-1回繰り返せば終り。
# だけれども、一応変数「枚数」を作ってこれで管理してみることに。
枚数=N

枚数>1の間
 最下面移動
 最上面廃棄
 枚数から1を直接引く

カード【1】を言う。
終わる。

# main routine 終了
# 以下のサブルーチンは、メインルーチンの変数を直接使用して変更する
# お作法の悪いサブルーチン(^_^;)
# C なら引数を参照渡し。なでしこではそんな手数はいらない。

●最下面移動
 移動対象=カード【1】
 カードの1を配列削除
 カードの枚数に移動対象を配列挿入

●最上面廃棄
 カードの1を配列削除
##################################################
 なでしこは、実務系プログラミング言語なので、配列操作など簡単ですね。配列から一つ引っこ抜くとか配列に一つ挿入するとか、命令1個で出来ちゃいますから楽ちんですね~♫
 「100」を入れたら「28」でしたぁ(^o^)ノ

  • 鶏ドリアン

    鶏ドリアン

    2010/08/02 22:37:31

    #include <stdio.h>
    #include <math.h>

    main()

    {

    int n, i, j, flag = 0;


    printf("仮定として~中略~を出力する。\n\n自然数nを入力せよ。\n\n");

    while (flag == 0){

    flag = 1;

    printf("n = ");
    scanf("%d", &n);

    j = n;

    if (n >= 1){

    for (i = 0; flag == 1 && j != 1; i++){


    if (j%2 == 1){

    n -= pow(2, i)*2;
    }

    j /= 2;

    /* 全項数が2以下になったら */

    if (j <= 2){

    /* ループ中断 */

    flag = 2;

    }

    }
    n -= pow(2, i)*(j - 1);

    printf("result = %d \n", n);

    }else{

    printf("数値が不正です。\n最初からやり直してください。\n\n");
    flag = 0;

    }

    }

    }

  • 鶏ドリアン

    鶏ドリアン

    2010/08/02 22:14:58

    よく見直したらデバッグがまだ足りませんでした。

    あとで、こっちのブログに貼っておきます。

  • 鶏ドリアン

    鶏ドリアン

    2010/08/02 21:35:21

    要約です

    /*

    ・操作過程で 「2の(0以上の整数)乗×(-1)」の公差の等差数列(便宜上、最上面のカードを初項とする)
     が次々と出現するのを利用

    ・項数が奇数か偶数か、によって次の等差数列の初項、及び項数が異なるので
     (偶数→初項、項数は元の半分、
      奇数→第3項、項数は自身から1引いたものを半分、ただし整数で処理してるのであまりここでは関係ない)
     場合分けが生じる点に注意

    */

  • 不思議ちゃん

    不思議ちゃん

    2010/08/02 21:13:26

     いったん数学的に煮詰めてからコーディングされてますね~~。コメントがないと何やってるのか良く分からないですぅ~~(;_;)
     人のプログラム読むより自分で最初から考えた方が早いので、私も考えてみました~~。

    http://www.nicotto.jp/blog/detail?user_id=288939&aid=16691800

  • Nana

    Nana

    2010/08/01 10:00:09

    うわお・・・・
    なにがなんだかわからないです・・・(´・ω・`;)

  • 鶏ドリアン

    鶏ドリアン

    2010/07/31 14:41:41

    こんなもんでどうでしょう?


    #include <stdio.h>
    #include <math.h>

    main()

    {

    int n, i, j, flag = 0;


    printf("仮定として~中略~を出力する。\n\n自然数nを入力せよ。\n\n");

    while (flag == 0){

    flag = 1;

    printf("n = ");
    scanf("%d", &n);

    j = n;

    if (n >= 1){

    for (i = 0; flag == 1; i++){


    if (j%2 == 1){

    n -= pow(2, i)*2;
    }

    j /= 2;

    if (j <= 3){

    flag = 2;

    }

    }
    n -= pow(2, i)*(j - 1);

    printf("result = %d \n", n);

    }else{

    printf("数値が不正です。\n最初からやり直してください。\n\n");
    flag = 0;

    }

    }

    }

  • 鶏ドリアン

    鶏ドリアン

    2010/07/31 09:08:17

    計算しましたが、100だと28を返しますねw

    ボクの考えてたアリゴリズムに、余分な部分があったみたいです^^;


    でも、大いにヒントになりました。
    どっちにしろ、配列を使う必要はなさそうです。

  • 鶏ドリアン

    鶏ドリアン

    2010/07/31 08:44:21

    ちょっと待てよ・・・

    デバッグが要るのはこっちかもしれんw

  • 不思議ちゃん

    不思議ちゃん

    2010/07/31 08:22:04

    1→1
    2,1→1,2→2
    3,2,1→2,1,3→1,3→3,1→1
    4,3,2,1→3,2,1,4→2,1,4→1,4,2→4,2→2,4→4
    5,4,3,2,1→4,3,2,1,5→3,2,1,5→2,1,5,3→1,5,3→5,3,1→3,1→1,3→3
    ですよね?

  • 不思議ちゃん

    不思議ちゃん

    2010/07/31 08:14:03

    あら~デバグ必要(^◇^;

    で、だんだん暗闇にぃ♫

    デバクしといてぇ(←ぉぃ)

  • 鶏ドリアン

    鶏ドリアン

    2010/07/31 08:12:17

    いや、100だと66を返すはずですw