プログラマ志望のネタが多いが、
中にはホントにプログラマになりたいって思ってる奴もいるだろう。
そんな奴等に課題を投げてくれ。
言語はCが基本。K&R2を買え。
守って欲すいルールは
>>2 仕様の不備は皆で補完しろ。
それでは一日一課題。
マターリとした学習の始まりだゴルァ!
 ̄ ̄ ̄ ̄ ̄|/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
∧_∧
( ・∀・)
( ⊃ )
2 :
仕様書無しさん :02/03/06 16:15
1【出題者へ】 出題は初心者が一日で解けるくらいの課題のみだゴルァ! また、1日に2問以上の出題は回答者が散るから禁止する。 初心者用なんでコメント大盛りつゆだくで。 あと前レス完全依存な出題は控えめにな。 2【回答者へ】 取り組んだ結果を報告しろゴルァ! こんなバグが出ましたとか。完成までに何時間かかったとか。 仕様を勘違いして作っちゃいましたとか。この課題、職場で活用しまくってますとか。 とにかく報告だゴルァ! 3【できました!の条件】 完成ってのはこういうことだゴルァ! [ 課題のコピー(仕様書) ] [ 設計をしたメモ(ドキュメント) ] [ バグがない、コメント付きのソース ] [ テストに用いたmain関数 ] [ その他、仕様上要求されたもの ] これらがそろって初めて完成。これ常識。 設計もしないでint main(int argcとか撃つなよゴルァ!
3 :
仕様書無しさん :02/03/06 16:17
___ヽヽ ヽ丶 (´ (´ {-―-/ (´⌒ } /./ l (´⌒(´ / ┼─┼ ===== .(´ l/l ノ} ( }-‐''´レ' / (´⌒´ , く / {\, _,,..::--――――- ''´ `、l ヾ_ツ / (´ / ヽ / } `´ o .,-‐―┐ o .丶 ヽ `、 l ./ l ヽ ヽ ヽ (´⌒(´ (´⌒(´ { ム-―‐-┴ `、. (´⌒´ .〉―‐-〉 (´⌒(´ (´⌒(´ / ._,,=-::.,,_ ∧ ∧ ノ ./ (´⌒(´ {,,__,,....::-‐''"´/l :::::``ヽ. (゚Д゚,,)`/ヾ/、/ ̄`ヽ/ (´⌒´ ああん i ' ....:::::/ l:::...... ,、 :::⊂ ⊂ ヽ / l l i,/``i./ ≡(´ (´⌒(´ (´⌒(´ こすれる. l..::{::::/i::::ハ::/ i::∧:::ハ:::::::/ /~:丶_ `ム-=ッ l (´⌒(´ {/{::/l'ヾノ V リ V ヽ,:∪ ∪::::::::::::ヽ-‐ l | L_ (´⌒(´ ∧∧ ) ____l/.i .;:= =ュ { .{::::::::,、::::lヾ _ ヾ.、 7 ≡(⌒⌒(⌒⌒ ⊂(゚Д゚⊂⌒`つ ̄ ノ l. { ,.,. ,.,. .{ / ト、::::{ \l  ̄ //〈 ≡≡(⌒⌒ `''ーヾ、,,__,,ム,,___,,{ムヽ、 ヾ、 ̄) .〉 ` ヽ| _ノ===::::;;;ム_〉≡(´⌒ ` _ _,,....-ヽ、 ノ~ 3ゲトー  ̄ ''ー''´
/*創意工夫のコメントスキップを求む!*/ 基本的にC言語を用いてC形式(/**/)のコメントスキップ を作成すること。回答者の実力に応じて幾つかのレベルを 設ける。 1)単純なコメントスキップ 2)文字列リテラルの対応 3)コメントのネスト対応 従来のやり方にとらわれず、自由な発想で挑戦したし。参考までに、 前回コルーチンによる実装が投稿され話題を呼んだ。。。
いまら!4げっとぉぉぉなのれす!  ̄ ̄ ̄ ̄ ̄∨ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄(´´ ∋oノハヽo∈ ) (´⌒(´ ⊂(´ⅴ`⊂⌒`つ≡≡≡(´⌒;;;≡≡≡  ̄ ̄ (´⌒(´⌒;; ズザーーーーーッ ・・・・・・・・・・・・・・・・・・  ̄ ̄ ̄ ̄ ̄∨ ̄ ̄ ̄ ∋oノハヽo∈ (´;; ⊂(´ⅴ`⊂⌒`つ (´⌒(´ ろっこいしょれす・・・・・・・・・  ̄ ̄ ̄ ̄ ̄∨ ̄ ̄ ̄ ̄ ̄ ̄ ∋oノハヽo∈ (´ⅴ` )⌒ヽ U‐U^(,,⊃'~... (´⌒;; らにみてるのれす、てれるらないれすか!  ̄ ̄ ̄ ̄ ̄∨ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ポ∋oノハヽo∈ ポ ン (´ⅴ` #) ン (´;) U,U )~ (;;). (´)~(⌒;;UU (´ )...~⌒(`)
とりあえず最初の課題はあれだ。 やらないと確実に殺されるともっぱらうわさのあれだ。 だが、ここは2chだ。 あえて違う文字を表示させるという狂言も一応ありかとおもう。 はろー2ch!と表 (ズぎゅ-ン) おっとあぶねえ。カーニハンの雇われスナイパーか。 一応完成した人から順にバグ報告!
【出題】 長さ最大20バイトの文字列が引数として与えられる。 もし、 引数の文字列中に「sage」という文字列が含まれている場合には 先頭の「s」を除外する。ただし「sage」は文字列中に複数含まれている 場合もある。 引数から上記の条件で「s」を除外した文字列を返却する関数をつくって。
1はコンパイルの仕方とか教えなくていいのか?
他に出題があるようだから
>>7 は無視して逝ってくれ。
10 :
仕様書無しさん :02/03/06 16:36
>>7-9 最初の出題は「へろー2ch」で確定か?
>>10 いいんじゃないっすか。
っつうか、出題管理者必要じゃない?
>>1 よ。
じゃあ、それで逝こう。 改行ありとなし。両方作れば完璧だろうな。
回答者いるのかな・・・
ルールには1日1課題とあるが、 まああれだ。 日付じゃなくて見た感じでいいだろうな。 課題が前レスに見えるときには出題しないという感じで。
>>9 つかその問題はム板にあるぞ
検索くらいせれ
A:先生!関数が長いと答えずらいと思います! B:なんでそんなに長くなるんだ? まさか律儀に一時ずつ putchar('へ'); /* 出力されるか試すこと */ putchar('ろ'); /* 出力されるか試すこと */ … とかやってるのか? A:ほかの方法があるならもったいぶらずに教えてください。
/*模範解答*/ main() { int i=0; while (putchar("hello 2ch.\n"[i++])); }
/*模範解答2*/ main() { int i=0; while (putchar(((char *)i++)[(int)"hello 2ch.\n"])); }
問題はそれなりにネタとなっているのを希望 検索一発でソースが出てくるのはよそうよ
#include <stdio.h> #include <stdlib.h> #include <string.h> #define NumberOf(p) (sizeof(p)/sizeof(p[0])) const char SCANSTR[] = "sage"; bool RemoveSage(const char *s, char *so) { bool bRet = false ; const char* p = s; char* pp; char* sop = so; *so = '\0'; while ( NULL != (pp = strstr(p, SCANSTR))) { strncpy(sop, p, pp - p); sop += (pp - p); ++pp; // sage -> age for ( int i = 0 ; i < NumberOf(SCANSTR)-1 ; i++ ) { *sop++ = *pp++; } *sop = '\0'; p = pp; bRet = true; } strcpy(sop, p); return true; } void main() { char p[256]; char* s = "てすとだゴルァ! sage てかけ!解かったか?sageだ!"; if ( NULL != RemoveSage(s, p)) printf("%s\n%s", s, p); }
22 :
仕様書無しさん :02/03/06 18:36
return bRet ↑; だった。
つまらんにゃ
24 :
仕様書無しさん :02/03/06 18:54
int main() { printf("hello,\ 2ch world"); }
25 :
仕様書無しさん :02/03/06 19:22
つーか、出題時間、問題決定時間、解答時間、模範解答決定時間 に分割したらどうだ? 例えば・・・ 00:00~07:00 出題時間 07:00~09:00 本日の問題決定時間 09:00~21:00 解答時間 21:00~24:00 模範解答&解説時間 ・・・と、いった感じで・・・ 「Hello ~」は基本中の基本なので最初にふさわしいと思うぞ
26 :
仕様書無しさん :02/03/06 19:59
>>25 テレホユーザー無視の
>>25 に激しく萌え。
「中にはホントにプログラマになりたいって思ってる奴もいるだろう。」
こんなやつらは学生とかなんだし、全部3時間ずつ後ろにずらすほうがいいわ
27 :
仕様書無しさん :02/03/06 20:01
>>25 9:00-21:00って仕事や学業の間に書かせるのか?
非常識すぎるぞ
#include <stdio.h> int main() { printf("Good bye," " world\n"); }
> 1)単純なコメントスキップ > 2)文字列リテラルの対応 > 3)コメントのネスト対応 4)トライグラフ対応 > 前回コルーチンによる実装が投稿され話題を呼んだ。。。 ほう、Cでコルーチンができるのか?
30 :
仕様書無しさん :02/03/06 20:45
>>25 は無職かヒッキー、あるいは春厨にケテーイ。
普通の生活を送ってたら今から学ぼうというやつらが
昼間に考えて答えを書くのはつらいだろ…
なぁ、 今日でおれらの関係おわりにしないか?
32 :
仕様書無しさん :02/03/07 01:19
ご期待にこたえて出題します。 【課題1-1】 おいジョン。俺は英語を勉強したいんだ。天才すぎる俺のために使用頻度の少ない難しい単語だけ抽出してくれないか? ジョンってだれだよ? まあとにかく詳しい仕様を教えれ。 英文が一文だけ格納された文字列二つを引数に取るdelete_override_word関数を作れ。 この関数はs1の文字列からs2に含まれる全ての文字列を削除するものとする。戻り値は無い。 なお、効率化のために仕様を変更することも可能である #英文は空白で単語が区切られていて、最後にピリオドがあることもある。 いまから20分くらいで落ちます。
1出現あげ
s2に含まれる全ての「単語」を削除するんですよね?
#include <stdio.h> #include <string.h> void delete_override_word(char* s1, const char* s2) { char* p = s1; char* pp; int l = strlen(s2); while ( NULL != (pp = strstr(p, s2))) { p = pp; while (*pp) { *pp = *(pp+l); ++pp; } } } void main() { char p[256]; char* s = "てすとだゴルァ! sage てかけ!解かったか?sageだ!"; strcpy(p,s); delete_override_word(p, "sage"); printf("%s\n%s", s, p); }
早いな。しかもスレ的には初解答。しかもコメントねえ。 はてさて、ここは2chなので勝手に解説します。 "sage"が取り除かれているので一見課題を満たしているようですね。 ただ、仕様を確認すると、s2って英文だぞゴラァ! 少し改良すると英単語タイピングソフトの問題自動作成とか、 多分実用的な関数になるとは思うんで期待あげ。
39 :
仕様書無しさん :02/03/07 11:17
あがってなかった。 鬱堕し脳
>>38 そのまえにagesageでageになるのがバグ
ボク、ジョンだよ! なんかボクの机で、ボクじゃない人がプログラム作ってるよ! 助けてぇえ!
#include <stdio.h> #include <string.h> void delete_override_word(char* s1, const char* s2) { const char* p = s1; char* pp; char buf[255]; char* pt = buf; strcpy(buf, s2); for (pt = strtok(pt, " ,") ; pt ; pt = strtok(NULL, " ,")) { p = s1; int l = strlen(pt); while ( NULL != (pp = strstr(p, pt))) { p = pp; while (*pp) { *pp = *(pp+l); ++pp; } } } } void main() { char p[256]; char* s = "テストダゴルァ! sage テカケ!解カッタカ?sageダ!"; strcpy(p,s); delete_override_word(p, "sage ゴルァ"); printf("%s\n%s", s, p); }
>>42 空白or.による単語訳なので"テストダゴルァ!","sage","テカケ!解カッタカ?sageダ!"の3単語から
"sage","ゴルァ"と同じ単語を取り除くことになる
つまり"テストダゴルァ!","テカケ!解カッタカ?sageダ!"が残る
さすがにマ板だ。レスが早い。そしてまたコメントねえし(w
>>2 の忠告どおり設計したか?
"テストダゴルァ!"から"ゴルァ"が削除されるとすると、
s1="office 2000 is nise"、s2="of is"とかのときに
"fice 2000 nise"になるのではないかとちょっと思うが、どうか。
>>43 納得。なんか3分も後に変なレスをしてしまった。
鬱だ…
ボク、ジョンだよ。 でも机にいる日本人が自分はジョンだっていうんだよ。 ボク、誰?
47 :
仕様書無しさん :02/03/07 12:01
#include <stdio.h> #include <string.h> void delete_override_word(char* s1, const char* s2) { const char* p ; char* pp; char buf[255]; char* pt = buf; strcpy(buf, s2); for (pt = strtok(pt, " ,") ; pt ; pt = strtok(NULL, " ,")) { p = s1; int l = strlen(pt); while ( NULL != (pp = strstr(p, pt))) { if ( (pp == s1 || (unsigned char)(*(pp-1)) <= ' ') && (unsigned char)*(pp+l) <= ' ') { p = pp; while (*pp) { *pp = *(pp+l); ++pp; } } else p += l; } } } void main() { char p[256]; char* s = "office 2000 is nise"; strcpy(p,s); delete_override_word(p, "of is"); printf("%s\n%s", s, p); }
処理時間について言及されてないが、手元の翻訳ソフトには一般辞書で
30kワードとなっているため、s2は巨大だから仕組みが必要と思われ
つか出題が間違っている
>>34 >s1の文字列からs2に含まれる全ての文字列を削除するものとする
s2に含まれる全ての単語だろう?
出題通りなら
>>37 で正解
49 :
仕様書無しさん :02/03/07 12:59
>>48 >s2は巨大だから仕組み
s2に含まれる単語の最少完全ハッシュ関数が存在するとして出題するべき
>>34
>>49 問題としてなら、ソート済み単語リスト&リスト数を渡し、
バイナリサーチあたりをプログラムさせれ
51 :
仕様書無しさん :02/03/07 13:10
>>50 プログラマを目指すんだったら実情にそった方がいいだろう
その辺の線引きはどうする?
>>1
>なお、効率化のために仕様を変更することも可能である 1がさりげなくこんなことを言ってます。 このスレの効率化のため、仕様を現実的なものに変更しましょう。 とりあえず関数はタイピングソフトとかに流用できるので無駄にはならんですし。
>>52 「問題/設問」と見るか、「業務に使う関数」と見るかはどうする?
54 :
仕様書無しさん :02/03/07 15:02
>>51 34は激しく頭痛がイタイ仕様を貰ったってことで実情を反映(w
1日で解ける問題を作れ。
57 :
仕様書無しさん :02/03/08 05:52
二つのファイルを比較して 違っている最初の行を出力するプログラムを書け。
59 :
仕様書無しさん :02/03/12 11:07
あげ
[レベル2] MMX命令を使いたい。 x86CPUを判別する関数と使い方を載せなさい
おいジョン。俺はアメリカ人だぜ? 漢字なんかわかんねーよ。 だから、漢数字の文字列を数値型に変換する関数を作ってくれよ。 「六九」も「六十九」も「69」として返してくれるようなインテリジェンスな奴を頼むぜ。
>>60 MMXPen(P55C),P2以降,P3以降,K6以降,K7以降,M2,WinChip2,Celeronが該当でいいのか?
バッチファイルでレジストリを読み出すのが安全な回答だな
63 :
仕様書無しさん :02/03/12 13:21
65 :
仕様書無しさん :02/03/12 22:07
ここ見るとデスマーチが発生する一因がある 出題された問題のほとんどが、1日で終らない 出題者も手加減しているはずだから、彼らには3時間くらいの問題なのだろう ここまで見積もりがぶれると、実務でも同様と思われる
>>62 cpuidしろって事じゃねーの?
64の言う通り環境と対象CPUがわからんと。
67 :
仕様書無しさん :02/03/13 00:29
で、1問目の答えは?1さんはどこに行った?
初心者養成に良いスレだと思われるのでage しかしもう課題続いてないのね…(´ロ`)
70 :
仕様書無しさん :02/03/13 02:21
71 :
仕様書無しさん :02/03/13 02:47
>>70 何が模範解答かで荒れるに10000void。
「明日のためのその1」 1から100までの掛け算(階乗)を計算するプログラムを作るべし! for()ループで計算結果を確かめたら 再帰を使って計算するやつを作るべし!べし!
73 :
仕様書無しさん :02/03/13 03:02
[演習] NULLの値を整数として表示するプログラムを書け。
def fact(n) raise ArgumentError unless n.integer? and n >= 0 n == 0 ? 1 : fact(n-1) * n end
ここはなかなかいいスレだな、と思ってるけど 参加する気がさらさらない俺は逝ってよしですか。
76 :
仕様書無しさん :02/03/13 23:08
次の課題をどうぞ
77 :
仕様書無しさん :02/03/13 23:11
const int BIT_MMX = 23; const int BIT_SSE = 25; const int BIT_SSE2 = 26; const int BIT_3DNOW = 31; const int BIT_E3DNOW = 30; bool IsMMX() { DWORD Ans = 0x0000000; _asm { mov eax,1 cpuid mov Ans,edx } return ( (Ans >> BIT_MMX) & 0x01 ); }
78 :
仕様書無しさん :02/03/13 23:18
CPUの周波数を求める関数を作成せよ void GetCpuFaq( double * pOut );
79 :
仕様書無しさん :02/03/13 23:21
>>77 cpuidが使えないときのハンドラくらい最低限実装せい
80 :
仕様書無しさん :02/03/13 23:29
これでどう? const int BIT_MMX = 23; const int BIT_SSE = 25; const int BIT_SSE2 = 26; const int BIT_3DNOW = 31; const int BIT_E3DNOW = 30; bool IsMMX() { DWORD Ans = 0x0000000; __try { _asm { mov eax,1 cpuid mov Ans,edx } } __except( EXCEPTION_EXECUTE_HANDLER ) { return false; } return ( (Ans >> BIT_MMX) & 0x01 ); }
なんかだんだん趣旨が違ってきたな…
83 :
仕様書無しさん :02/03/13 23:41
[問題] 自分の寿命を求める関数lifeを作れ。 戻り値は寿命を年で表した数値。 引数は自由である。 ユニークな回答を求む。
int life(void) { return -1; }
unsigned char life(void) { unsigned char ret; printf("イツ シニマシタ カ ?"); scanf("%d" , &ret); return(ret); }
int life(int year /* 西暦でね! */, int month /* 0 - 11 */) { return (month < 7)? 1999 - year: 1999 - year - 1; }
88 :
仕様書無しさん :02/03/16 00:18
誰かまじめな課題をお願いします
89 :
仕様書無しさん :02/03/16 01:09
先生! 居ないんですか?
90 :
仕様書無しさん :02/03/16 01:34
91 :
仕様書無しさん :02/03/16 01:37
回答の評価と解説は?
つーか、どれがまともな(正式な?)問題で、 まともにこたえた問題なのかわからない。
93 :
仕様書無しさん :02/03/16 13:27
じゃあ、まじめな課題は「まじめ」といれること。
>>78 > void GetCpuFaq( double * pOut );
( ´_ゝ`).。oO(Faq。。。´,_ゝ`プッ Freqじゃないのか?)
[問題] 最終生理日から予定日を求める baby関数をつくれ、ただし生理サイクルは28日から35日迄 自由に変えられるモノを求む。 あ、ついでに危険日も分かるものね
マジに使うヤツがいると困るので、勝手に仕様を砕こう Ogino_basic_method: 過去12回の月経周期を渡し、次の妊娠しやすい期間を返す(型などは自由に決定してよし) 期間を求める式は、下記の通り 最短周期-18 ≦求める期間 ≦ 最長周期-11 Ogino_rhythm_method: 過去1年間の基礎体温を渡し、次の妊娠しやすい期間を返す(型などは自由に決定してよし) 月平均から、体温が1週間程度の期間1、2度高くなる最初の日を排卵日とする 排卵日の前3日、後2日が求める期間である 実際使用する際には、精子の生存期間を加味し、さらに前2日~7日を危険期間として用いる
98 :
仕様書無しさん :02/03/18 13:04
実用的(wなのであげ
99 :
仕様書無しさん :02/03/18 13:42
全然実用的じゃないよ。 家のハムスター、排卵の周期4日なので、 排卵の周期4日に変えれるようにしてくれ。
>>99 その前に、ハム公の頭に電極突っ込んで、セクースさせない仕組みを作らないと
101 :
仕様書無しさん :02/03/18 13:56
>>100 そんなことしたら、ハムスターしんじゃうでしょ?
家に帰ったら、ハムスターしかいないし。
それに、僕の唯一の話し相手なんだから。
ママさんPG ハァハァ
どうしてこういうエロネタだとこうも 取り乱したスレになるんだろうねぇ
結局生理の近くは妊娠するのかしないのか、どうなんだ。
>>104 月経開始の直前が最も妊娠しやすいのだよ。
フッ、白か黒かでしか物事を見ることが出来ないとは、まだまだ青いな...
>>106 フッ。白と黒しか見えないから青いかなんてわかんねーよ
微妙にウマいがスレの趣旨からどんどん外れていっている事に気付きやがれコンチクショウ
110 :
仕様書無しさん :02/03/18 22:53
>>97 の突込みで、ネタがマトモな問題になってるぞ(w
参加者居ないのか>PG脂肪
いっちょ作ってみるか。
112 :
仕様書無しさん :02/03/19 23:28
age
115 :
仕様書無しさん :02/03/23 00:23
誰か作れ!プロなんだろ?
118 :
仕様書無しさん :02/03/23 06:08
120 :
仕様書無しさん :02/03/23 21:18
>>72 >「明日のためのその1」
>1から100までの掛け算(階乗)を計算するプログラムを作るべし!
>for()ループで計算結果を確かめたら
>再帰を使って計算するやつを作るべし!べし!
#include <stdio.h>
long double f_rec( int count )
{
return ( count != 1 ) ? f_rec(--count)*(count+1) : 1;
}
long double f_for( int count )
{
long double result=1;
for( ; count>1; --count ) result *= count;
return result;
}
int main()
{
printf( "recurcion : %Lf\n", f_rec(100) );
printf( "for : %Lf\n", f_for(100) );
return 0;
}
recurcion : 93326215443944150965646704795953882578400970373184098831012889540582227238570431295066113089288327277825849664006524270554535976289719382852181865895959724032.000000
for : 93326215443944150965646704795953882578400970373184098831012889540582227238570431295066113089288327277825849664006524270554535976289719382852181865895959724032.000000
関数電卓値: 9.332621544394415268169923885627e+157
121 :
仕様書無しさん :02/03/23 21:28
>61 名前:仕様書無しさん 投稿日:2002/03/12(火) 11:52 >おいジョン。俺はアメリカ人だぜ? >漢字なんかわかんねーよ。 >だから、漢数字の文字列を数値型に変換する関数を作ってくれよ。 > >「六九」も「六十九」も「69」として返してくれるようなインテリジェンスな奴を頼むぜ。 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> #define NumberOf(p) (sizeof(p)/sizeof(p[0])) int _iskdigit(unsigned char** p) { unsigned char *szJn1 = "0123456789"; unsigned char *szJn2 = "零一二三四五六七八九"; int i; if ( isdigit(**p)) return *(*p)++ & 0x0f; for ( i = 0 ; *(szJn1+i*2) ; ++i ) { if ( *(szJn1+i*2) == **p && *(szJn1+i*2+1) == *(*p+1)) { *p += 2; return i; } } for ( i = 0 ; *(szJn2+i*2) ; ++i ) { if ( *(szJn2+i*2) == **p && *(szJn2+i*2+1) == *(*p+1)) { *p += 2; return i; } } return -1; } int _isktani(char **p) { unsigned char* szKtn[] = { {"十万"},{"百万"},{"千万"},{"十"},{"百"},{"千"},{"万"},{"億"}, }; long lKtn[] = {100000, 1000000, 10000000, 10, 100, 1000, 10000, 100000000 }; int i; for ( i = 0 ; i < NumberOf(szKtn) ; i++ ) { if ( 0 == strncmp(*p, szKtn[i], strlen(szKtn[i]))) { (*p) += strlen(szKtn[i]); return lKtn[i]; } } return -1; }
122 :
仕様書無しさん :02/03/23 21:29
int CountDigit(int v) { int n; for (n = 0;v;++n) v /= 10; return n ? n : 1; } void jn2en(char* pstr, char* presult) { long d, dn; int i, n; d = dn = 0; i = 0; while ( *pstr ) { if (0 <= (n = _isktani(&pstr))) { if (d) d *= n; else d = n; #if 0 /* 2万33千 とかが 53000になる */ if (dn * 10 % n) #else /* 2万33千 とかが 2033000にする */ if ( CountDigit(dn) <= CountDigit(d)) #endif dn *= n; dn += d; d = 0; }else if ( 0 <= (n = _iskdigit(&pstr))) { d = 0; do { d *= 10; d += n; } while (0 <= (n = _iskdigit(&pstr)) ); } else pstr++; } sprintf(presult, "%d", d + dn); } void main(int argc, char** argv) { char buf[256]; while ( --argc ) { jn2en(*++argv, buf); printf("%20s %s\n", buf, *argv); } }
123 :
仕様書無しさん :02/03/23 21:29
/* result... 3256 3256 325600 3256百 102 百2 1000000 百万 1050000 百5万 1000004 百万4 1000012 百万12 1000012 百万十2 1000010 百万十 1000030 百万3十 50003 5万3 53000 5万3千 50300 5万3百 53200 5万3千2百 53270 5万3千2百7十 53278 5万3千2百7十8 53324 5万3324 53300 5万33百 50033000 5万33千 50032 5万3十2 1024 千24 1024 千2十4 1004 千4 5908 千4908 1008 千008 */
124 :
仕様書無しさん :02/03/24 01:12
先生!採点お願いします
125 :
仕様書無しさん :02/03/24 01:44
[問題] Nの階上を「整数」で求め、出力するプログラムを作成せよ。 階上は負の値を考えない。 5!=5*4*3*2*1 (Nの値の範囲を勝手に想像してはいけない) (前のは実数で計算してるから誤差だらけ。) 余裕がある人は 階上を以下のように定義した場合においても計算ができるようにする。 -5!=-5 * -4 * -3 * -2 * -1とする さらに余裕がある人は、高速化するためのアイディアを提案し 余裕があれば実装する。 以上 ある中学校の夏休みの宿題
126 :
仕様書無しさん :02/03/24 02:01
127 :
仕様書無しさん :02/03/24 02:06
(前のは実数で計算してるから誤差だらけ。) と書いてあるが?
100の階乗の正確な答えは以下である。 Perlの標準ライブラリを使ったので間違いない。 気合があるものは自分で多倍長整数演算ライブラリを作ること。 以上 ある中学校の夏休みの宿題 +942689044888324774562618574305724247380969376407895166349423877 7294707070023223798882976159207729119823605850588608460429412647 56736000000000000000000000000
<<128 つーか、間違ってるって
130 :
仕様書無しさん :02/03/24 02:58
933262154439441526816992388562667004907159682643816214 6859296389521759999322991560894146397615651828625369 7920827223758251185210916864000000000000000000000000
>>131 それじゃ問題集買ってきて即解答見るのと同じじゃねぇか...。
それであれば・・・・ 多倍長整数演算ライブラリを自作せよ。 余裕があれば、それで階上を計算せよ。 (以下略)
じゃあ、第二問 ある数式の計算結果を表示するプログラムを作成せよ。 例:5 + 6 * 3 / ( ( 4 + 2 ) * 5 ) 注意:数式の要素の数を勝手に予想してはならない。 以上、とある中学校の冬休みの宿題。
135 :
仕様書無しさん :02/03/24 23:48
>>134 そりは一つの関数にまとめなきゃいけないのかぃ?
136 :
仕様書無しさん :02/03/25 01:07
>>135 そうでしょ?
文字列渡して結果を数値で返せばいんじゃ?
でも、これも、逆ポーランド 電卓 でサーチすれば、
ソース一杯でてくるんだけど・・・
137 :
仕様書無しさん :02/03/25 04:20
>ソース一杯でてくるんだけど・・・ まあ、簡単なのは本を読めば全部載ってるけどさ。 見ないで書けることが重要なんじゃないかと。 漢字のテストをやって、辞書に全部載ってるけど・・・じゃ意味ないよね? まあいいや。 [問題] ある地点を(x,y,z)とあらわせるとする。 x,y,zは符号付整数。 ある地点A,B,C・・・を結ぶためのパイプを設置する事を考える。 パイプのコストはなるべく安くすませたい。 パイプは長さ1に対して、コストL円かかる。 パイプを連結するのにB円かかる。 ひとつの連結パーツで最大9つのパイプを一点で連結する事ができるが、 それぞれのパイプの角度は90*n度でなくてはならない。(nは整数) それから、パイプの方向は(1,0,0),(0,1,0)(0,0,1)のいずれかでなくてはならない。 パイプの配置方法を求めるプログラムを作成せよ。 以上、とある高校の夏休みの宿題。
>最大9つのパイプを一点で どうやったら可能なのか、小一時間問い詰めたい
139 :
仕様書無しさん :02/03/25 17:21
高校生ならわかるんだよ
>>138 青春の一時の幻ってやつ
>>136 再帰下降構文解析とかだと一つの関数にまとまらないがそれでは
駄目なのか?やはり。難しいな。
141 :
仕様書無しさん :02/03/25 17:47
というか俺は1ではない
>135 $str = '5 + 6 * 3 / ( ( 4 + 2 ) * 5 )'; print eval $str
…じゃ座標は (v, w, x, y, z) になるじゃん
継ぎ手を立方体と考えれば、TESSERACT(4次元立方体)で
繋げるパイプは9本を超えます
>>143
146 :
仕様書無しさん :02/03/26 01:34
>最大9つのパイプを一点で
あー、ごめん6本だね。
意味は通じてたからいいか。
誰かできた?
あ、ちなみに俺のオリジナルですよ。
>>142 それは
注意:数式の要素の数を勝手に予想してはならない。
に反してるよ~
>注意:数式の要素の数を勝手に予想してはならない。 >に反してるよ~ 何だ? while(<>){ print eval $_; } とでもやってほしかったのか?
>>133 への「回答」
でも「できましたとはとても言えません」
*注意*
C++です。許して(;;)
コンパイルしてません
テストしてません
デバッグしてません
longのサイズがshortの2倍以上前提(普通大丈夫)
const char MAXLEN = 10; //配列のサイズ
const int NUMLEN = 9999; //配列の1つずつにもてる最大の値
class CLongNumber
{
public:
CLongNumber(long num = 0) { Equal(num); } //手抜きコンストラクタ
void Equal(long num); //代入
bool Plus(long num); //プラス
bool Kakeru(short num); //かける
private:
unsigned long Nums[MAXLEN];
bool PlusFlag //+かーのフラグ
}
void CLongNumber::Equal(long num)
{
//手抜き関数
for(int i=0; i<MAXLEN; i++)
Nums[i] = 0;
PlusFlag = true;
Plus(num);
}
bool CLongNumber::Plus(long num) { if(num < 0) //足す方がマイナスのとき return Mainus(-num); //Mainusは+とあまり変わらないから省略 if(PlusFlag == false) //足される方がマイナスのとき; { PlusFlag = true; bool ok = Mainus(num); PlusFlag = !PlusFlag; return ok; } for(int i=0; num == 0; i++) { if(i >= MAXLEN) return false; //オーバーフロー Nums[i] += num; num = Nums[i] / (NUMLEN+1); //繰り上がり Nums[i] %= (NUMLEN+1); //繰り上がり分を消す } return true; } bool CLongNumber::Kakeru(short num) { if(num < 0) { PlusFlag = !PlusFlag; num = -num; } long temp = 0; //繰り上がりを保持する変数 for(int i=0; i < MAXLEN; i++) { Nums[i] *= num; Nums[i] += temp; //i-1のときの繰り上がりを足す temp = Nums[i] / (NUMLEN+1); //繰り上がり Nums[i] %= (NUMLEN+1); //繰り上がり分を消す } if(Nums[MAXLEN-1] > NUMLEN) //オーバーフロー判定 { Nums[MAXLEN-1] %= (NUMLEN+1); return false; } return true; }
言い訳 1 配列がlongなのは一時変数作るのが面倒だったが 特に問題ないかなと思ったので。 2 配列のサイズが決っているのは可変長が面倒だったから。 STLはよく知らない。自作Vectorは説明が面倒。 3 コンパイルしてない事がむかつく人は ネタと思って見なかったことにして下さい。(全員か・・・) 4 インデントが無い理由。こうなるなんて知らなかったんです。
151 :
仕様書無しさん :02/04/14 06:53
[問題] 文字配列giko_str[]やstringに、例えば、"if( 10<get_hoge() )" や、"if ( 30<get_hoge() && get_hoge()<50 )"とか が格納されるとする。 (上記get_hoge()という関数は、10前後のintegerを返す ようなものである。) ここで、このgiko_strを渡せば、 その中に入っている文字列をC/C++言語の文法で評価する ような関数 eval_giko()を作ることはできますかひ。
[答え] できます。
153 :
仕様書無しさん :02/04/14 19:41
>>152 正解。まあ、でもif文だけでもtrue/falseを評価
してくれる簡単なものでも載せてみようや。
154 :
仕様書無しさん :02/04/14 20:34
「問題文」って、その問題に対する出題者の理解度が はっきり現れるから面白いね。
>153 入力が"if ( 30<get_hoge() && get_hoge()<50 )"だけなら、 true,falseもない。C/C++では、ifは文であり、式ではないため。 "( 30<get_hoge() && get_hoge()<50 )"なら、式であるので その真偽を問うことができる。 よって、 ・文字列をC/C++言語の文法で評価するような関数 eval_giko() なら、つくることはできるが、 ・例えば、"if( 10<get_hoge() )" が格納されている文字列を評価して、 true/falseを返すようなeval_giko はつくることができない。 (そのtrue/falseが文法にエラーが{ない/ある}なら別)
156 :
仕様書無しさん :02/04/16 04:58
>154,155 いっていることは最もなことで、問題の方もとんでもなことは 認める。この場合、"if(10<get_hoge())"という文字列が 入っていたらエラーを投げる。strに"get_hoge()"とか入っていたら if(eval_giko(str))とかint a=eval_giko(str)とか できるような動作。もしくは、153みたい な無理解な人のために、"if(10<get_hoge())"が入ってると、 "if(真)"ならtrue,"if(偽)"ならfalseを返すように曲解する ようなモンをつくれ、ということなのか。しかし後者のモンは 存在してはいかんな。
157 :
仕様書無しさん :02/04/17 17:13
あげ
//ベターCなのは許してください
>>133 >それであれば・・・・
>多倍長整数演算ライブラリを自作せよ。
>余裕があれば、それで階上を計算せよ。
#include <stdio.h>
const int MAXSIZE = 100; //配列のサイズ
const int MAXNUM = 9999; //1つの配列での最大の値
const int MAXLEN = MAXNUM + 1;
struct LongNum //多倍長変数用の構造体
{
bool PlusFlag;
unsigned short Nums[MAXSIZE];
};
bool Plus(LongNum *buffer, long num);
bool Mainus(LongNum *buffer, long num);
bool Kakeru(LongNum *buffer, short num);
int Waru(LongNum *buffer, short num);
void Print(LongNum *buffer); //結果の表示用
int main() { LongNum Buffer; //0クリア Buffer.PlusFlag = true; for(int i=0; i<MAXSIZE; i++) Buffer.Nums[i] = 0; int atai; //足したりかけたりする値 char enzan = '+'; //選択した演算子 while(enzan != 'e') { ::puts("演算子の入力 +-*/"); ::scanf("%c", &enzan); getchar(); //※1 ::puts("数値の入力"); ::scanf("%d", &atai); getchar(); //※1 /* ※1 Enterを押すと演算子や数値の次に'Enter'が邪魔になり 次の入力を受け付けないので'Enter'を取り出す どうすればいいんでしょうか? */ switch(enzan) { case '+': Plus(&Buffer, atai); break; case '-': Mainus(&Buffer, atai); break; case '*': Kakeru(&Buffer, atai); break; case '/': Waru(&Buffer, atai); break; default: enzan = 'e'; //演算子でなければ終了するための値 break; } Print(&Buffer); //結果表示 } return 0; }
bool Plus(LongNum *buffer, long num) { if(buffer->PlusFlag == false && num < 0) // (-A)+(-B) → -(A+B) { buffer->PlusFlag = true; num = -num; bool ok = Plus(buffer, num); buffer->PlusFlag = !buffer->PlusFlag; return ok; } else if(buffer->PlusFlag == false) // (-A)+B → -(A-B) { buffer->PlusFlag = true; bool ok = Mainus(buffer, num); buffer->PlusFlag = !buffer->PlusFlag; return ok; } else if(num < 0) // A+(-B) → A-B { return Mainus(buffer, -num); } //A+B for(int i=0; i<MAXSIZE; i++) { buffer->Nums[i] += num % MAXLEN; //一定範囲の値を足す num = num / MAXLEN + buffer->Nums[i] / MAXLEN; //次に足す値に足した分を消し繰り上がりを加える buffer->Nums[i] %= MAXLEN; //繰り上げた分を戻す if(num == 0) return true; //足す値がなくなったら終了 } //オーバーフロー return false; }
bool Mainus(LongNum *buffer, long num) { bool ok; if(buffer->PlusFlag == false && num < 0) // (-A)-(-B) → -(A-B) { buffer->PlusFlag = true; num = -num; ok = Mainus(buffer, num); buffer->PlusFlag = !buffer->PlusFlag; return ok; } else if(buffer->PlusFlag == false) // (-A)-B → -(A+B) { buffer->PlusFlag = true; ok = Plus(buffer, num); buffer->PlusFlag = !buffer->PlusFlag; return ok; } else if(num < 0) // A-(-B) → A+B { return Plus(buffer, -num); } //A-B int i, temp; for(i=0; i<MAXSIZE; i++) { temp = num % MAXLEN; //tempにこれから計算する分を入れる num /= MAXLEN; //tempに入れた分を消す if(buffer->Nums[i] < temp) //引く方が大きいとき { buffer->Nums[i] += MAXLEN; //筆算のように1つうえの桁から1を持ってくる num++; //引いた分次に1余分に引くようにする } buffer->Nums[i] -= temp; if(num == 0) return true; //引く値がなくなれば終了 } //ここまで処理が来たら値がマイナスになることが確定している //2進数のときみたいな感じで各桁で9から引いた結果に1を足す for(i=0; i<MAXSIZE; i++) buffer->Nums[i] = MAXNUM - buffer->Nums[i]; ok = Plus(buffer, 1); //符号の反転 buffer->PlusFlag = false; return ok; //okがfalseならオーバーフロー }
bool Kakeru(LongNum *buffer, short num) { if(num < 0) //マイナスなら符号の反転 { buffer->PlusFlag = !buffer->PlusFlag; num = -num; //計算用にプラスにしておく } unsigned long temp, up = 0; //tempは計算用の変数、upは繰り上がりよう for(int i=0; i<MAXSIZE; i++) { temp = buffer->Nums[i] * num + up; //値をかけて繰り上がりを足す up = temp / MAXLEN; //繰り上がりを変数に入れる buffer->Nums[i] = (unsigned short)(temp % MAXLEN); //結果を入れる } return temp == 0; //tempにまだあればオーバーフロー }
int Waru(LongNum *buffer, short num) { if(num == 0) return -1; //0除算はエラー if(num < 0) //マイナスなら符号の反転 { buffer->PlusFlag = !buffer->PlusFlag; num = -num; //計算用にプラスにしておく } unsigned long temp, amari = 0; //tempは計算用の変数 for(int i=MAXSIZE-1; i>=0; i--) //上の桁から計算 { temp = buffer->Nums[i] + amari * MAXLEN; //計算用変数に前のあまり分を加えて代入 amari = temp % num; //次に加えるあまりの計算 buffer->Nums[i] = (unsigned short)(temp / num); //結果を代入 } return amari; //あまりを返す }
void Print(LongNum *buffer) { if(!buffer->PlusFlag) putchar('-'); //マイナスなら符号を表示 bool ok = false; for(int i=MAXSIZE-1; i>=0; i--) { if(buffer->Nums[i] == 0 && ok == false) //上位の0をスキップ continue; if(ok) { for(int j=MAXLEN/10; j>1; j/=10) //0があれば表示 { if(!(buffer->Nums[i] / j == 0)) break; putchar('0'); } } printf("%u", (unsigned int)buffer->Nums[i]); //表示 ok = true; //これから0も表示するフラグ } if(!ok) putchar('0'); //あたいが0なら0を表示 putchar('\n'); //改行 }
2進数ではなく10進数で計算している理由は効率よく2進数を10進数に直す 方法を思いつかなかったからです。なんかいい方法を教えてください。 指定した桁の値が何なのかが分からないと不便なので。 困ったバグ mainに書いてある※1の'Enter'の所。 あとプロの人たちはこの課題でどれほどのプログラムを どのくらいの時間で完成するか教えてください。 スペースに変換してもインデントが消えてしまいました。 読みずらくてすいません。
>>165 >効率よく2進数を10進数に直す
10で割った余りを文字にして右からならべればいいんでは。
割り算ルーチンと一緒にあまりを求めるルーチン(%)も作っておくのがポイントか。
>>158 私もプロではないですが、貴方のコードになんかギクシャクしたものを感じたので
今回のような課題には、以下のような手順でプログラムを作る事をお勧めします。
絶対にそれに従わなければならないという訳ではないですが、
まあ普通に経験を積んだ人は、暗黙のうちに従っている指針だと思います
1.どのような形でデータを保存するかを決定する。
・以下の 2-4 の各機能が実現できるか、おおよその見当をつけながら決定する。
・そのデータが表現できる範囲(整数という集合)と、
決定する "データ(構造)" が表現できる範囲(その構造体(とは限らないが・・・)が
"取り得る全て" の値)に出来るだけ "食い違い" が無い様にする事が重要。
2.データ(構造)を画面に表示する関数を作成。
・作成が済んだら、テストプログラムを作成し、テストする。
3.データをキーボードから入力し、データ(構造)に変換する関数を作成。
・上記 2 で作成した関数を使いながらテストする。
・一般に "入力関数" は "表示する関数" より作るのが難しい。
・得体の知れない組み込み関数は使わないほうがいい場合もある(w
4.データ(構造)"同士" で演算をする方法を作成。
・全ての演算に対する処理を考える(課題自体が "ライブラリの作成" なので)。
・個々の関数は出来るだけ "還元" した処理のみを行うようにする。
ただし、「掛け算は足し算の複数回の処理に還元できる」とも考えられるが、
演算速度の点から不合理と考えられるならば、個別の処理として関数を
作成した方がよい、と言う場合もある。
・"データ(構造)" と "データ(構造)" を演算した結果は
"データ(構造)" になる事に注意。
・エラー(オーバーフロー、0除算等)が出た場合の方針を決める。
・上記 2-3 で作成した関数を使いながらテストする。
5.最終的なインタプリタの作成。
・出来るだけ上記で作成した機能を組み合わせるだけで作成するように心がける。
>>166 多分僕の書き方が悪かったみたいです。
配列の1つずつに 1101 1011みたいに2のX乗進数で管理してると、
9132 4913みたいに十進数で管理するよりメモリ、
速度の点(シフト演算が使える)で計算では効率いいですけど、
実際の値を習得するとき何桁目がどんな数字になるかとか、
そもそも何桁あるのかが計算するのが大変な気がしたんです。
でも僕がバカなだけで簡単な方法にも気づかず、
>>166 で言っていることも分からないだけのような気もします。
お暇ならもう少し詳しく話してください。お願いします。
>>167 構造体同士の演算は初めC++の癖でオーバーライドで作ろうと思ってました。
構造体にプリミティブ型を入れてから計算するより高速かなと思ったので。
まぁプログラムはとても見にくくなると思ったんですけど。
構造体での演算の方が
>>158 に似た処理で、より高速なので、
まぁいいかと思って。自分用にC++に書き直したときには、
>>167 で言ってくれたように代入して計算で実装しようかと思います。
”還元”の話は僕も考えましたが、速度をとってやめました。
最初やろうと思ったんですが、「10000*10000だと10000回ループじゃん」
とか考えるとなんかアレだと思ったので。
>一般に "入力関数" は "表示する関数" より作るのが難しい。
本当に難しかったです。かかった時間の2割はたった4行程度の入力関数で使いました。
>>166 ,167
助言ありがとうございました。
再帰での階乗の計算も数式を入れた文字列の解析もどっかのスレで出てたぞ。
170 :
仕様書無しさん :02/04/21 01:02
質の高いお題がホスィ
171 :
仕様書無しさん :02/04/21 05:36
>>170 数列の予測プログラムを書け。
条件:
(1) A0 = C = const.
(2) An+1 = f(An)
つまり、数列の各項は前項の値によってのみ定まるということです。
A0, A1, ..., An-1 が与えられた時に、Anを予測するプログラムを書いてください。
これは、20年程前に僕がお遊びでFORTRANで組んでみたのですが、予測率は70%~90%程度でした。
質が高いかどうかはわかりませんが...(藁
条件漏れがありますた。 f(n)は、四則演算のみからなる関数で、かつ有限級数とします。スマソ。
173 :
仕様書無しさん :02/04/21 17:26
ある地点を(x,y,z)とあらわせるとする。 x,y,zは符号付整数。 ある地点A,B,C・・・を結ぶためのパイプを設置する事を考える。 パイプのコストはなるべく安くすませたい。 パイプは長さ1に対して、コストL円かかる。 パイプを連結するのにB円かかる。 ひとつの連結パーツで最大6つのパイプを一点で連結する事ができるが、 それぞれのパイプの角度は90*n度でなくてはならない。(nは整数) それから、パイプの方向は(1,0,0),(0,1,0)(0,0,1)のいずれかでなくてはならない。 パイプの配置方法を求めるプログラムを作成せよ。 以上、とある高校の夏休みの宿題。
175 :
仕様書無しさん :02/05/18 23:27
保守
176 :
仕様書無しさん :02/05/18 23:46
[対象言語] C言語 [難易度] 初心者向 [所要時間] 1時間以下 [内容] 年,月をパラメータとして渡すと、その月の日数を返す関数を作れ。 [仕様&備考] ・うるう年を考慮する。 ・年,月はint型で渡す。年は西暦。 ・戻り値もint型。
>>176 ううう、むつかしい。本見たらだめですか?
178 :
仕様書無しさん :02/05/19 05:41
int GetDays( int nYear, int nMonth) { static int aanDay[2][12] = { {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; int nResult; if (nYear < 1 || nMonth < 1 || nMonth > 12) nResult = -1; else nResult = aanDay[nYear % 4 == 0 && nYear % 100 != 0 || nYear % 400 == 0 ? 1 : 0][nMonth - 1]; return nResult; } エラーの時は -1 を返すのだ!
所要時間 3分ですた。
180 :
仕様書無しさん :02/05/19 05:45
>>180 コピペじゃねーよ、俺Cは10年やってんだよ(藁
>>178 > {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
> {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
なんでこんな無駄なことするの?
次のお題は俺も挑戦する予定
185 :
難易度上がっちゃいました :02/05/20 23:31
[対象言語] C言語 [難易度] 中級者向け [所要時間] 1時間~2時間 [内容] 「"aDb"形式でパラメータを渡すと、b面ダイスをa回振る」関数を作れ。 パラメータの例:1D6、2D10、3D4など。 [仕様&備考] ・a/bは1桁or2桁、どちらかは不明。 ・渡されるパラメータはchar型、戻り値はint型。 [ポイント] ・Dを利用して、char型パラメータからaとbを分ける。 ・char型の"文字型の数値"をint型に変換する。 [初心者向け] パラメータを、char型のパラメータ1つから、 int型のパラメータ2つに変えてやってみてください。
186 :
仕様書無しさん :02/05/20 23:38
>>185 ついでだから簡単な数式解析もつけるようにキボンヌ
5D10+8
みたいの。
187 :
仕様書無しさん :02/05/21 08:10
age
188 :
仕様書無しさん :02/05/21 09:18
>>178 10年やって
> static int aanDay[2][12] = {
> {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
> {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
この定義はないだろうプププ
あきらかにわざとだろそこは(笑) 気付けよおい
#include <stdio.h> #include <ctype.h> int dice(const char *str) { int a=0, b=0; if (!str) return 0; /* a 抽出 */ while (isdigit(*str)) { a = 10 * a + *str - '0'; ++str; } /* D がなければエラー */ if (*str++ != 'D') return 0; /* b 抽出 */ while (isdigit(*str)) { b = 10 * b + *str - '0'; ++str; } printf ("%d面ダイスを%d回振りました.", b, a); return 1; } int main(int argc, char *argv[]){ if (2 <= argc) dice(argv[1]); return 0; } すんません。問題の意図がよくわかんなかったんで。
>>190 たぶん合計値を返すことを期待してると思うぞ(w
>>191 おお,なるほどっ。。。って,そんなワケあるかーいっ。
ていうかアレですか,あとは 1~b までの乱数を
a 回出力するだけだという落ち。
んじゃ,便乗してお題。
[対象言語] C 言語
[難 易 度] 初級者向け
[所要時間] 1 時間
上記の関数は,指定された仕様とは合致していません。
("D4" だと 4 面ダイスが 0 回振られたり
3 ケタ以上の数でも普通に処理できたり)
そこらへんの判定関数が欲しいと思いました。
>>185 をよく読み,仕様に合致している文字列なら 0 以外 (1 でも何でも)
合致していなければ 0 を返す関数 int isValid(const char *str); を
実装してください。
# 実際は,上の関数の最後のあたりで
# if (a<=0 || a>=100 || b<=0 || b>=100) return 0; // エラー
# とやればよいという罠。笑い
って,答えを言っちゃダメじゃん。。。 残業中で頭がクルクルパーなのです。。。
194 :
仕様書無しさん :02/05/23 22:46
>>192 暇つぶしに考えてみた。
致命的なバグがありそでなさそ。
int isValid(const char *str)
{
char b[1+5+1], t[1+99*99*6+1], *p=t;
int i, j;
if(5<strlen(str))
return 0;
for(i=1;i<=99;i++)
for(j=1;j<=99;j++)
p+=sprintf(p,"\n%dD%d",i,j);
sprintf(p,"\n");
sprintf(b,"\n%s\n",str);
return (strstr(t,b)!=NULL);
}
195 :
仕様書無しさん :
02/05/24 00:31 int isValid(const炭*str){炭b[1つの+5+1]、 t[1つの+99*99*6+1]、*p=t;int i、 j;場合(5<strlen(str))0を返す;のために(i=1;)i<=99;i++、 のために(j=1;)j<=99;j++p+=sprintf(p、「¥n%dD%d」、i、j); sprintf(p、「¥n」);sprintf(b、「¥n%s¥n」(str)); リターン(strstr! =NULL(t、b));}