■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■■■■■応用プログラミング演習問題集(応用編)■■■■ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ■■■■■■■■■■■■■■■■■■■■■■■■■■■■ ●●●●●●●●●●●●第7章●●●●●●●●●●●● (Pythonではサブルーチンのことを関数とよび,def で定義する.ここでは,関数の使い方を学ぶ.) ● 問題 7-1(これを例題として説明します) 整数nを受け取り,print "#"; を n回繰り返し,長さnの#でできた棒を表示し,その後改行をする関数を作りなさい.例えば,10 を渡すと ########## が表示され,25を渡すと, ######################### が表示されるような関数を作る,ということです. (サンプルコード) 関数部分は以下の通り. def sub(n): print("#"*n) これを呼び出すメイン部分は,以下の通り. n=input("n=") sub(n) 実行すると,以下の結果を得る. >>> n=100 #################################################################################################### ●問題 7-2 問題7-1の関数を,入力した3つの数を引数として3回呼び出しなさい.例えば8,13,4と入力したら, ######## ############# #### と,棒グラフのような表示をする,ということです. ●問題 7-3 問題7-1の関数を使って,#でできた三角形を表示するプログラムを作りなさい.例えば,このようなものを表示するプログラムです. # ## ### #### ##### ###### ●問題7-4 数aを渡すと,aが正なら1を,負なら?1を,0ならば0を返す関数を作りなさい. ●問題7-5 数aを受け取り,数bをキーボードから入力し,a+bの値を返す関数を作りなさい.次に,この関数を使って,数を10個入力してその合計を表示するプログラムを作りなさい. ●●●●●●●●●●●●第8章●●●●●●●●●●●● 8章のグローバル変数は推奨されないので省略. ●●●●●●●●●●●●第9章●●●●●●●●●●●● (Pythonでは配列ではなく,リストを用いる.リストは配列より柔軟性が有り,便利な代物であるが,配列のかわりとして用いることができる.) ●例題9-1 大きさが100の変数のリストaを用意し,0番目に0,1番目に10,2番目に20,...と代入し,最後にそれらを表示する,というプログラムを作りましょう.aの0番目から99番目までに代入するには,iが0から99まで1ずつ大きくなるfor ループを作り,a[i]に順々に数値を代入すればよいですね.a[0]には0,a[1]には10,a[2]には20,...と代入したいので,a[i]にi*10を代入します. (サンプルコード) たとえば,以下のプログラムは,最初に0を入れたリストを100倍することによって,準備をし,次のforループで数字の代入を行う. a=[0]*100 for i in range(100): a[i]=i*10 最初の行は, a=[0 for i in range(100)] と同じ意味であるが,どうせやるなら, a=[i*10 for i in range(100)] と書けば1行で済む.もしくは,最初に空のリストを準備して,1つずつ数字をappendメソッドで追加していっても良い. a=[] for i in range(100): a.append(i*10) いずれの方法でも,実行後にShellでaと入力すると,以下の結果が表示されるはずである. >>> a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99] ●問題9-1 キーボードから10個の数を入力し,それらを入力された順番と逆の順番で表示するプログラムを作りなさい. ●問題 9-2 randomモジュールをインポートしてから,r = randint(0,4) とすると,r に 0 から 4 までの乱数が代入されます.この操作を 100回行って,0から4までのそれぞれの数が何回ずつ代入されたかを調べるプログラムを作りなさい.(ヒント:長さ4のリストx に0を代入した後,100回繰り返すループを書き,ループの中は,rに乱数を代入しxのr番目を1大きくするようにします.) ●問題 9-3 問題9-2の実行結果の表示を,問題7-1,7-2の棒グラフを表示するプログラムを使って,棒グラフで表示するようにしなさい. ●問題9-4 0以上100以下の数を10個入力し,0から9,10から19,…,90から99がそれぞれ何個ずつ入力されたか表示するプログラムを作りなさい.(ヒント:0から99までの整数aを10で割ると,0から9になります.そこで,長さ10のリスト xのa/10番目を1大きくするようにしましょう.) ●問題9-5 整数 a1,a2を入力し,リストxのa1番目からa2番目までを1大きくする,という作業を繰り返すプログラムを作りなさい.リストの大きさは10とし,毎回リストの0番目から9番目までを表示するようにしなさい.(ヒント: iをa1からa2までの1ずつ大きくするforループを使い,リストのi番目を1大きくするようにしましょう.) ●問題9-6 リストと整数iを受け取り,リストのi番目の値を1大きくする関数を作りなさい. ●問題9-7 例題9-1のプログラムの最初のforループの部分を「aの各変数に値を代入する関数」に,2番目のforループの部分を「aの各変数の値を表示する関数」にして,プログラムを書き換えなさい.ただし,両関数はリストを引数として受け取ることとします. Pythonのリストでは,配列ではできないことが容易にできるようになっている.以下では,その練習をする. ●追加問題1(例題) “Taro”, “Jiro”,”Saburo”,”Shiro”,”Goro” がこの順番で座っている.この4人を名前を入れたリスト L を作成せよ.(講義では,自分の座っている列にいる友人の名前のリストを作らせると良い.) (サンプルコード) L=[“Taro”, “Jiro”,”Saburo”, ”Shiro”, ”Goro”] ●追加問題2 上で作成したリストに対して,最初に座っている人と最後に座っている人を表示せよ. ●追加問題3 リストに含まれている人数を表示せよ. ●追加問題4(例題) 10から100までで,3ずつ増えていく数字のリストを作成せよ. (サンプルコード) range(10,100,3) ●追加問題5 100から10まで,2ずつ減っていく数字のリストを作成せよ. ●追加問題6(例題) 5人の学生の身長がリストとして与えられているとき,小さい順に並べ替えよ. (サンプルコード) height=[165,180,155,170,171] print sorted(height) もしくは height=[165,180,155,170,171] height.sort() print height ●追加問題7 5人の学生の身長が与えられている.学生の番号を0から4としたとき,身長順に並べたときの番号のリストを計算するプログラムを作成せよ. ●追加問題8(最大,最小,合計:例題) 100個の[1,10000]の一様整数乱数のリストを作成し,その中の最大の数字を求めよ. (サンプルコード) import random rnd_list=[random.randint(1,10000) for i in range(100)] print max(rnd_list) ●追加問題9 最小の数字が,何番目の数字(最初の数字を0番目とする)なのかを計算するプログラムを作成せよ. ●追加問題10 100個の[1,10000]の一様整数乱数のリストを作成し,次にそれらの和と平均を求めよ. また,平均に最も近い数を求め,それが何番目の数字(最初の数字を0番目とする)なのかを計算するプログラムを作成せよ. ●追加問題11(例題) n行n列のランダムな行列で,各要素が[1,10]の一様整数乱数の行列を,リストを用いて作成せよ. (サンプルコード) import random n=10 Matrix=[ [ [] for i in range(n) ] for j in range(n)] for i in range(10): for j in range(10): Matrix[i][j]=random.randint(1,10) print Matrix ●追加問題12 上で作成した2つのランダムな行列の掛け算を行うプログラムを作成せよ. ●追加問題13 グラフをリストとして表現する方法について考えよ. ●●●●●●●●●●●●第10章●●●●●●●●●●●● (再帰) ●例題10-1  「1円玉1枚,10円玉1枚,100円玉1枚の組合せでできる8通りの金額を全て表示する」というプログラムを,再帰呼び出しを使って作りましょう. まず第1ステップとして,1円,10円,100円,全て使った組合せの金額を,再帰呼び出しを使ったループで計算するプログラムを作りましょう.リストaの各変数にa[0]=1,a[1]=10,a[2]=100を代入して,再帰呼び出しを使ったループで,a[0]からa[2]までの合計を計算します。そして,合計を記録する補助変数(sという名前にしました)を使ってプログラムを作ると,以下のようになります.リストa,硬貨のインデックスを入れた変数i,補助変数sは再帰呼び出しをするときは,引数としてサブルーチンに渡すようにします. (サンプルコード) def sub(a,i,s): if i==3: print("sum=",s) else: sub(a,i+1,s+a[i]) a=[1,10,100] sub(a,0,0) 実行すると,以下のように合計金額が表示されるはずです. sum= 111 ●例題10-2 次に,全ての組合せを使うプログラムを作ります.全ての組合せの金額を表示するには,各硬貨について,「その硬貨を使う場合」と「その硬貨を使わない場合」の場合分けが必要です.そこで,それぞれの再帰呼び出しが,その硬貨を使う組合せ,使わない組合せに対応します. (サンプルコード) def sub(a,i,s): if i==3: print("sum=",s) else: sub(a,i+1,s+a[i]) sub(a,i+1,s) a=[1,10,100] sub(a,0,0) 結果は次のようになります. sum= 111 sum= 11 sum= 101 sum= 1 sum= 110 sum= 10 sum= 100 sum= 0 ●問題 10-1 入力した数の階乗を計算するプログラムを,再帰呼び出しを使って作りなさい. ●問題 10-2 2つの数mとn(ただし,m>n )が与えられたとき,mとnの最大公約数は,nとm%n (mをnで割った余り)の最大公約数になります.これを利用して,入力した2つの整数の最大公約数を求めるプログラムを,再帰呼び出しを使って作りなさい. ●問題 10-3 5つの数a[0],...,a[4]とbを入力して,a[0],...,a[4]の,合計がちょうどbになる組合せがいくつあるかを表示するプログラムを再帰呼び出しを用いて作りなさい. ●●●●●●●●●●●●第11章●●●●●●●●●●●● (文字列は,Pythonだと簡単なので,省略) ●●●●●●●●●●●●第12章●●●●●●●●●●●● (ファイルの入出力) ●問題12-1(例題) 1から100までの整数をファイルに書き出すプログラムを作りなさい. (サンプルコード) f=open("temp.txt","w") for i in range(1,100): f.write(str(i)+"\n") f.close() 最初の行でファイルを書き出すためのオブジェクトfを生成し(第2引数 “w”は書き出すを表す.読み込みのときには,この部分を “r”とする),3行目で数字を文字列に変換したものの後に改行コードの文字列 “\n” を追加して書き出す.最後にcloseメソッドでファイルを閉じる.結果として,temp.txtと名付けたファイルに,1から100までの数字が書き込まれる. ●問題12-2 入力した数を1行に1つずつファイルに書き込む,という作業を繰り返すプログラムを作りなさい.ただし,0が入力されたら終了するようにしなさい. ●問題12-3 1行に1つずつ数が書いてあるファイルを読み込んで,書かれている数の合計を表示するプログラムを作りなさい. ●問題12-4 ファイル名を入力し,そのファイルの内容を表示するプログラムを作りなさい. ●●●●●●●●●●●●追加問題●●●●●●●●●●●● (Pythonでは,リストの他に辞書,タプル,集合を使うことができる.) (辞書) ●追加問題1 名前をキー,体重を値とした辞書 D を作成せよ.ただし,友人は3人以上記入し,名前には友人の名前を文字列として,体重には友人の理想体重を整数値として入力せよ. ●追加問題2 起動すると,友人の名前の入力を求め,上で作成した辞書Dから体重を調べて画面上に表示するプログラムを作成せよ. ●追加問題3 上のプログラムを,何度も友人の名前の入力を求めるように変更せよ.ただし,辞書にない名前を入力すると終了するものとする. 注意:辞書Dにキーkeyがあるかどうかを調べるには,D.has_key( key)とhas_keyメソッドを用いる.has_key()がTrueを返せばkeyは辞書内にあり,Falseを返せば辞書の中にない. 注意の注意:他の方法としてgetメソッドを用いる方法もある.D.get(key,default)とすると,keyがある場合には対応する値を返し,ない場合には規定値defaultを返す.たとえば,体重を値とした辞書の場合には,D.get(名前,-1)とdefaultに体重としてあり得ない値を入れ,返値が-1のときにはif文で判定してループを抜ければ良い. ●追加問題4 空の辞書Dを準備し,その後で名前と体重の入力を何度もユーザーに要求して,名前をキー,体重を値としてDに保管していくプログラムを作成せよ.ただし,ユーザー名に空白 ”” を入力すると,画面に作成した辞書Dを表示してから,終了するものとする. ●追加問題5 友人の名前と体重を保管した辞書Dを準備し,その後で,友人の名前と体重の入力を求め,名前が一致する友人がいたならば,体重を新しい値に変更し,いなければ辞書に追加するプログラムを作成せよ.ただし,ユーザー名に空白 ”” を入力すると,画面に作成した辞書Dを表示してから,終了するものとする. ●追加問題6 問題1で作成した友人の名前と体重を保管した辞書Dに対して,友人の名前を1行ずつすべて画面に印刷するプログラムを作成せよ. 注意:辞書からキーのリストを取り出すメソッドはkeys()である.ただし,forループで反復を行う際には,for key in D.keys(): と書くかわりに,for key in D: と書いても良い.これは,辞書には要素を順に取り出すための仕組み(イテレータ)が準備されているからである. ●追加問題7 問題1で作成した友人の名前と体重を保管した辞書Dに対して,保管されている体重を1行ずつすべて画面に印刷するプログラムを作成せよ. 注意:辞書から値のリストを取り出すメソッドはvalues()である.もちろん,このメソッドを使わなくても書ける.両方のプログラムを書いてみよ. ●追加問題8 問題1で作成した友人の名前と体重を保管した辞書Dの名前を体重を名前のアルファベット順に画面に印刷するプログラムを作成せよ. 注意:辞書からキーと値のタプル(組)をリストとして抽出するメソッドはitems()である.ヒント:並べ替えにはリストのsortメソッドを用いると良い. ●追加問題9 問題1で作成した友人の名前と体重を保管した辞書Dの名前を体重を体重の軽い順に画面に印刷するプログラムを作成せよ. ヒント:itemsメソッドは,キーを第1要素,値を第2要素としたタプルのリストを返す.この問題では,体重をタプルの第1要素にする必要がある. ●追加問題10 都道府県名をキーとし,その名産品(1つ以上入力する)をリストとした辞書Dを作成せよ. ●追加問題11 上で作成した辞書に対して,名産品の多い順に並べるプログラムを作成せよ. (タプル) タプルは変更できないという一点を除いてリストと同じように扱うことができる.タプルは不変(中身の変更が不可である)オブジェクトなので,辞書のキーとして使うことができる. ●追加問題12(例題) n行n列のランダムな行列で,各要素が[1,10]の一様整数乱数の行列を,行と列のタプルをキーとし,要素を値とした辞書を用いて作成せよ. (サンプルコード) import random n=10 Matrix={} for i in range(10): for j in range(10): Matrix[i,j]=random.randint(1,10) print Matrix ●追加問題13 上で作成した2つのランダムな行列の掛け算を行うプログラムを作成せよ. (集合) ●追加問題14 “banana”の各文字なら成る集合と,”apple”の各文字から成る集合の和集合と共通部分を計算するプログラムを示せ. 以下の問題はオプション問題である.余力のある人は挑戦して欲しい. (スケジューリングモデル) ●追加問題15(例題) n個のジョブに対して,処理時間を[1,10]の一様整数乱数とした問題例を作成するプログラムを作成せよ. (サンプルコード) import random n=10 ProcTime=[random.randint(1,10) for i in range(n)] ●追加問題16 これらのジョブを番号の小さい順に並べた順に1台の機械にかけるものとする.このとき,ジョブの完了時刻の和を計算するプログラムを作成せよ. ●追加問題17 これらのジョブを処理時間の小さい順に並べた順に1台の機械にかけるものとする.このとき,ジョブの完了時刻の和を計算するプログラムを作成せよ.(オプション:この順が最適であることを証明せよ.) ●追加問題18 処理時間と納期をもつn個のジョブを,納期の早い順に並べたスケジュールを求め,納期遅れを評価せよ. (生産在庫モデル) ●追加問題19(例題) 各期の需要が平均100,標準偏差10の切断正規分布(負の場合には0とした正規分布)のとき,100期分のシミュレーションを行い,需要が110を超える期数を調べるプログラムを作成せよ. (サンプルコード) import random T=100 count=0 for i in range(T): demand=max(random.normalvariate(100,10) ,0) if demand>110: count+=1 print count ●追加問題20 各期の需要が平均100,標準偏差10の切断正規分布(負の場合には0とした正規分布)のとき,各期の最初に在庫量を調べて,発注量を決める方策のプログラムを作成せよ. また,100期のシミュレーションの後で,発注費用,在庫費用,品切れ費用の合計を計算するプログラムを作成せよ. ・ 発注固定費用が0円,在庫費用が10円,品切れ費用が100円の場合 ・ 発注の固定費用が1000円の場合 ヒント:方策としては,基在庫方策,(s,S)方策,(Q,R)方策が候補となる.