鶏ドリアンさんの情報の講義のC言語の課題
- カテゴリ:パソコン/インターネット
- 2010/07/31 08:10:13
鶏ドリアンさんのブログ
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^)ノ
#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;
}
}
}
あとで、こっちのブログに貼っておきます。
/*
・操作過程で 「2の(0以上の整数)乗×(-1)」の公差の等差数列(便宜上、最上面のカードを初項とする)
が次々と出現するのを利用
・項数が奇数か偶数か、によって次の等差数列の初項、及び項数が異なるので
(偶数→初項、項数は元の半分、
奇数→第3項、項数は自身から1引いたものを半分、ただし整数で処理してるのであまりここでは関係ない)
場合分けが生じる点に注意
*/
人のプログラム読むより自分で最初から考えた方が早いので、私も考えてみました~~。
http://www.nicotto.jp/blog/detail?user_id=288939&aid=16691800
なにがなんだかわからないです・・・(´・ω・`;)
#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;
}
}
}
ボクの考えてたアリゴリズムに、余分な部分があったみたいです^^;
でも、大いにヒントになりました。
どっちにしろ、配列を使う必要はなさそうです。
デバッグが要るのはこっちかもしれんw
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
ですよね?
で、だんだん暗闇にぃ♫
デバクしといてぇ(←ぉぃ)