課題1001
コンソールから正の整数 n を入力させ、1からnまでの逆数の和を計算して表示するプログラム HarmonicSeries.java をパッケージ j1.lesson10 に作成しなさい。
以下の擬似コードが表すメソッド harmonic を作成すること。このharmonicは一つの引数 (int n) を持つ。引数で与えられた n を元に1/1+1/2+1/3+...+1/nを計算して、結果をdouble型で返すこと。
sum = 0 kの値を1からnまで1ずつ増やしながら以下の計算を繰り返す sum に 1/k を加える sum を返す
このプログラムではまずmainメソッド内でコンソールの入力から1つの整数を取得し、それを用いて harmonic メソッド内で逆数の和の計算を行い、最後にmainメソッド内で結果を表示する。
mainメソッドの動作を表す擬似コードは以下の通りである。出力する文字列などは以下の擬似コードに従うこと。
print "正の整数を入力:" n = コンソール入力 (整数) nが0以下だったら print "正の整数を入力してください。" そうでなかったら print "nまでの調和級数の部分和はharmonic(n)"
ただし、最後の行にある"nまでの調和級数の部分和はharmonic(n)" のうち、n はコンソールから入力された値、harmonic(n) は harmonicメソッドの戻り値とする。
結果の例
入力に10 を指定した場合、プログラムを終了まで実行した際のコンソールは以下のようになっている。
正の整数を入力: 10 10までの調和級数の部分和は2.9289682539682538
手順
指定した箇所で必ずテストを行うこと。
- powerメソッドに対する詳細な擬似コードを作成する
- パッケージ j1.lesson10 にクラス HarmonicSeries を作成 (ファイル名は HarmonicSeries.javaとなる)
- クラス内に throws IOException の指定をした mainメソッド (public static void main(String[] args) throws IOException { }) を作成
- 必ず throws IOException の記述を付加しておくこと (つまり、import java.io.*;も必要となる)
- クラス内に必要なメソッド (harmonic) の骨格を作成 (こちらには throws IOException は必要ない)
- テスト項目「HarmonicSeries に対する骨格テスト」をパス
- 擬似コードを各メソッドにコメントとして貼り付ける
- 擬似コードに対するプログラムを書く
- 実際に実行して動作を確認する
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メソッド名), existence | 指定されたメソッドが存在しない |
(メソッド名), public | メソッドを作る際に public が抜けている |
(メソッド名), static | メソッドを作る際に static が抜けている |
(メソッド名), type void | メソッドを作る際に void 以外を指定している |
(メソッド名), throws ... | メソッドを作る際に throws... の指定がない |
課題1002
コンソールから1より大きい実数xを入力させ、1/1+1/2+...+1/n > x となる最小の整数nの値を計算して表示するプログラム HarmonicUntil.java をパッケージ j1.lesson10 に作成しなさい。
以下の擬似コードが表すメソッド harmonicUntil を作成すること。このharmonicUntilは一つの引数 (double x) を持つ。引数で与えられた x を元に 1/1+1/2+...+1/n > x となる最小の整数nを計算して、結果をint型で返すこと。
sum = 0 n = 0 sum < x の間以下の計算を繰り返す nに1を加える sum に 1/n を加える n を返す
このプログラムではまずmainメソッド内でコンソールの入力から1つの実数を取得し、それを用いて harmonicUntil メソッド内で調和級数の部分和がxを超えるための最小の項数の計算を行い、最後にmainメソッド内で結果を表示する。
mainメソッドの動作を表す擬似コードは以下の通りである。出力する文字列などは以下の擬似コードに従うこと。
print "1より大きい実数を入力:" x = コンソール入力 (実数) xが1以下だったら print "1より大きい実数を入力してください。" そうでなかったら print "nの値はharmonicUntil(x)"
ただし、最後の行にある"nの値はharmonicUntil(x)" のうち、x はコンソールから入力された値、harmonicUntil(x) は harmonicUntilメソッドの戻り値とする。
結果の例
入力に10 を指定した場合、プログラムを終了まで実行した際のコンソールは以下のようになっている。
1より大きい実数を入力: 10 nの値は12367
確認してみよう。課題1001のプログラムHarmonicSeriesの入力に12367を指定した場合、プログラムを終了まで実行した際のコンソールは以下のようになっている。
正の整数を入力: 12367 12367までの調和級数の部分和は10.000043008275778
同じくHarmonicSeriesの入力に12366を指定した場合、プログラムを終了まで実行した際のコンソールは以下のようになっている。
正の整数を入力: 12366 12366までの調和級数の部分和は9.99996214792161
手順
指定した箇所で必ずテストを行うこと。
- harmonicUntilメソッドに対する詳細な擬似コードを作成する
- パッケージ j1.lesson10 にクラス HarmonicUntil を作成 (ファイル名は HarmonicUntil.javaとなる)
- クラス内に throws IOException の指定をした mainメソッド (public static void main(String[] args) throws IOException { }) を作成
- 必ず throws IOException の記述を付加しておくこと (つまり、import java.io.*;も必要となる)
- クラス内に必要なメソッド (harmonic) の骨格を作成 (こちらには throws IOException は必要ない)
- テスト項目「HarmonicUntil に対する骨格テスト」をパス
- 擬似コードを各メソッドにコメントとして貼り付ける
- 擬似コードに対するプログラムを書く
- 実際に実行して動作を確認する
課題1003 (optional)
コンソールから実数 m と整数 n を入力させ、mnを計算して表示するプログラム BinaryPowerOpt.java をパッケージ j1.lesson10 に作成しなさい。このnは2のべき乗つまり2*2*...*2と素因数分解できる整数に限るものとする。この課題は次の課題1004への準備体操の意味がある。
ただし、以下の概略レベルの擬似コードを元に、プログラムを作成すること。
mのn乗 if n=1 結果は: m そうでなければ sub = mのn/2乗 結果は: sub*sub
上記の擬似コードが表すメソッドの名前は binaryPower とし、二つの引数 (double m, int n) を持つ。引数で与えられた m, n を元に mn を計算し、結果をdouble型の値として返すこと。
このbinaryPowerの考え方は単純である。例えば3.0の16乗を計算したければ、3.0の8乗を計算してそれを平方すればよい。3.0の8乗は3.0の4乗を計算してそれを平方すればよい。これを0乗まで再帰すれば掛け算は4回で済む。真正直にやれば15回である。
入力された整数nが2のべき乗であるか判定したい。そこで以下の擬似コードがあらわすメソッドisPowerOf2を用意する。このメソッドは正の整数(int n)を引数に持つ。nが2のべき乗であればtrueを返し、そうでなければfalseを返す。
nが2で割り切れる間以下を繰り返す nにnを2で割った値を代入する nが1なら trueを返す そうでなければ falseを返す
このプログラムではまずmainメソッド内でコンソールの入力から1つの実数と1つの整数を順に取得し、それらを用いて binaryPower メソッド内でべき乗の計算を行い、最後にmainメソッド内で結果を表示する。本プログラムでは、Math.pow(double,double) の使用を禁止する。
mainメソッドの動作を表す擬似コードは以下の通りである。出力する文字列などは以下の擬似コードに従うこと。
print "mの値を入力:" m = コンソール入力 (実数) print "nの値を入力:" n = コンソール入力 (整数) もしnが正で2のべき乗なら print "mのn乗はbinaryPower(m,n)" そうでないなら print "nには2のべき乗となる正の整数を入力してください。"
ただし、printの引数にある "mのn乗はbinaryPower(m,n)" のうち、m はコンソールから1番目に入力された値、n はコンソールから2番目に入力された値、binaryPower(m,n) は mn を計算して求めた結果とする。
結果の例
入力に順に 2.0, 8 を指定した場合、プログラムを終了まで実行した際のコンソールは以下のようになっている。
mの値を入力: 2.0 nの値を入力: 8 2.0の8乗は256.0
手順
指定した箇所で必ずテストを行うこと。
- powerメソッドに対する詳細な擬似コードを作成する
- パッケージ j1.lesson10 にクラス BinaryPowerOpt を作成 (ファイル名は BinaryPowerOpt.javaとなる)
- クラス内に throws IOException の指定をした mainメソッド (public static void main(String[] args) throws IOException { }) を作成
- 必ず throws IOException の記述を付加しておくこと (つまり、import java.io.*;も必要となる)
- クラス内に必要なメソッド (power) の骨格を作成 (こちらには throws IOException は必要ない)
- テスト項目「BinaryPowerOpt に対する骨格テスト」をパス
- 擬似コードを各メソッドにコメントとして貼り付ける
- 擬似コードに対するプログラムを書く
- 実際に実行して動作を確認する
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メソッド名), existence | 指定されたメソッドが存在しない |
(メソッド名), public | メソッドを作る際に public が抜けている |
(メソッド名), static | メソッドを作る際に static が抜けている |
(メソッド名), type void | メソッドを作る際に void 以外を指定している |
(メソッド名), throws ... | メソッドを作る際に throws... の指定がない |
課題1004 (optional)
コンソールから実数 m と整数 n を入力させ、mnを計算して表示するプログラム PowerOpt.java をパッケージ j1.lesson10 に作成しなさい。
ただし、以下の概略レベルの擬似コードを元に、プログラムを作成すること。
上記の擬似コードが表すメソッドの名前は power とし、二つの引数 (double m, int n) を持つ。引数で与えられた m, n を元に mn を計算し、結果をdouble型の値として返すこと。また、このメソッドでは 1.0000000012000000000 を演習環境で 5 秒以内に計算できること。
このプログラムではまずmainメソッド内でコンソールの入力から1つの実数と1つの整数を順に取得し、それらを用いて power メソッド内でべき乗の計算を行い、最後にmainメソッド内で結果を表示する。本プログラムでは、Math.pow(double,double) の使用を禁止する。
mainメソッドの動作を表す擬似コードは以下の通りである。出力する文字列などは以下の擬似コードに従うこと。
print "mの値を入力:" m = コンソール入力 (実数) print "nの値を入力:" n = コンソール入力 (整数) print "mのn乗はpower(m,n)"
ただし、最後の行にある "mのn乗はpower(m,n)" のうち、m はコンソールから1番目に入力された値、n はコンソールから2番目に入力された値、power(m,n) は mn を計算して求めた結果とする。
結果の例
入力に順に 1.3, -2 を指定した場合、プログラムを終了まで実行した際のコンソールは以下のようになっている。
mの値を入力:1.3 nの値を入力:-2 1.3の-2乗は0.5917159763313609
手順
指定した箇所で必ずテストを行うこと。
- powerメソッドに対する詳細な擬似コードを作成する
- パッケージ j1.lesson10 にクラス PowerOpt を作成 (ファイル名は PowerOpt.javaとなる)
- クラス内に throws IOException の指定をした mainメソッド (public static void main(String[] args) throws IOException { }) を作成
- 必ず throws IOException の記述を付加しておくこと (つまり、import java.io.*;も必要となる)
- クラス内に必要なメソッド (power) の骨格を作成 (こちらには throws IOException は必要ない)
- テスト項目「PowerOpt に対する骨格テスト」をパス
- 擬似コードを各メソッドにコメントとして貼り付ける
- 擬似コードに対するプログラムを書く
- 実際に実行して動作を確認する
ヒント
この課題では、mnを計算する際にmn/2を計算し、それを2回掛け合わせることによってmnを計算している。
ただし、nが奇数のときは mn = m * m(n-1)/2 * m(n-1)/2 を計算している。これによって、nが2のべき乗でなくても問題なく動作する。
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メソッド名), existence | 指定されたメソッドが存在しない |
(メソッド名), public | メソッドを作る際に public が抜けている |
(メソッド名), static | メソッドを作る際に static が抜けている |
(メソッド名), type void | メソッドを作る際に void 以外を指定している |
(メソッド名), throws ... | メソッドを作る際に throws... の指定がない |
課題1005 (optional)
課題1001で作成したプログラムに対する単体テストプログラム PowerOptTest.java をパッケージ j1.lesson10 に作成しなさい。
このテストプログラムは、演習で行った際と同様にJUnitを用いて作成すること。また、テストを行うためのメソッドとして、testPower() メソッドを作成すること。
テストケースは以下の通りとする (期待値は各自で計算すること)。
テスト対象 | 引数 | 許容誤差 |
---|---|---|
power(double,int) | (-2.0, -5) | 0.0001 |
power(double,int) | (-2.0, -1) | 0.0001 |
power(double,int) | (-2.0, 0) | 0.0001 |
power(double,int) | (-2.0, 1) | 0.0001 |
power(double,int) | (-2.0, 2) | 0.0001 |
power(double,int) | (-2.0, 3) | 0.0001 |
power(double,int) | (2.0, -5) | 0.0001 |
power(double,int) | (2.0, -1) | 0.0001 |
power(double,int) | (2.0, 0) | 0.0001 |
power(double,int) | (2.0, 1) | 0.0001 |
power(double,int) | (2.0, 2) | 0.0001 |
power(double,int) | (2.0, 3) | 0.0001 |
power(double,int) | (0.0, 1) | 0.0001 |
double 型の値をテストする場合、assertEqualsに許容誤差を書かなくてはならない。例えばPowerOpt.power(3.0, 2)をassertEqualsで表現したとすると
assertEquals(9.0, PowerOpt.power(3.0, 2), 0.0001);
のように書けばよい。
手順
指定した箇所で必ずテストを行うこと。
- パッケージ j1.lesson10 にクラス PowerOptTest を JUnit・テストケース として作成
- power(double,int) に対するメソッド・スタブを作成する
- testPower() メソッドにテストケースを記述
- 作成したテストケースを実行して動作を確認
- 「PowerOpt に対するテスト一式」 をパス
テストの失敗メッセージ
こちら側で用意したテストの失敗時のメッセージを掲載する。
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メソッド名), existence | 指定されたメソッドが存在しない |
(メソッド名), public | メソッドを作る際に public が抜けている |
(メソッド名), static | メソッドを作る際に static が抜けている |
(メソッド名), type <T> | メソッドを作る際に戻り値の型が違う。正しくは <T> |
(メソッド名), throws ... | メソッドを作る際に throws... の指定がない |
単体テストの項目
テスト失敗時に「Results」の欄の左側に出る「test~」は、テストの項目名を表している。
項目名 | 詳細 |
---|---|
Power_huge | power(1.000000001, 2000000000) を実行 |
他にもあるが割愛する。
機能テスト
メッセージ | 詳細 |
---|---|
余計な入力を待っていると考えられます | コンソール入力を取得する命令を必要以上に行っていないか確認 |
次の入力を変換できませんでした (???) | ??? を取得しようとして失敗している。コンソール入力を取得する命令を確認 |
期待された結果と異なります | 出力された結果が期待された値と異なる。「期待された値」と「実際の値」を比較 (エラーメッセージが出力されているエリアの下のほうにあるバーをスクロールさせれば見ることができる) し確認。他にも直接プログラムを実行して結果を調べたり、エラーメッセージの2行目にあるat以下を参考にプログラムを見直す |
無限ループの可能性 | 一定時間内にプログラムが終了しなかった。ループが無限に続いていないか確認 |
メタテスト
メッセージ | 詳細 |
---|---|
(クラス名) | テストが失敗している |
testcase (メソッド名).(引数) | 指定されたメソッドを指定された引数でテストしていない |
課題1005 (optional)
コンソールから 0 以外の実数値 c を入力させ、c の立方根をニュートン法によって計算して結果を表示するプログラム Newton.java をパッケージ j1.lesson10 に作成しなさい。
ニュートン法で c の立方根を求める場合、以下のようなアルゴリズムになる。
- f(x) - c = 0 とおく
- f(x) = x3
- x0 = c とおく
- y = f(x) - c の x = x0 における接線を引き、x軸と交わったところを x1 とし、以下同様な手順で x2, x3, .. ,xn と求めていく
- | xn - xn-1 | / | xn | < 0.0001 となったときの xn が f(x) = c となる x の 近似値
- 手順 3 へ戻る
ただし、xn を求めるには、以下の計算式を使う。
本課題は、以下の概略レベルの擬似コードを元に、プログラムを作成すること。
上記の擬似コードが表すメソッドの名前は newton とし、一つの引数 (double c) を持つ。この引数で与えられた c と後ほど用意する f(x), g(x) を用いてニュートン法を適用し、c の立方根を計算し、結果を double 型の値として返すこと。
上記の擬似コードに出てくる f(x), g(x) は以下のような関数である。
これらをそれぞれJavaのメソッド f(double x), g(double x) として Newton クラス内に作成し、newtonメソッドから呼び出せるようにすること。それぞれの戻り値型は double 型とする。
このプログラムではまずmainメソッド内でコンソールの入力から1つの実数を取得し、それを用いて newton メソッド内で入力された値の立方根を計算し、最後にmainメソッド内で結果を表示する。
mainメソッドの動作を表す擬似コードは以下の通りである。出力する文字列などは以下の擬似コードに従うこと。
print "実数を入力:" c = コンソール入力 (実数) print "cの立方根はnewton(c)"
ただし、最後の行にある "cの立方根はnewton(c)" のうち、c はコンソールから入力された値、newton(c) は newtonメソッドを実引数としてコンソールから入力された値を与えて呼び出した結果とする。
結果の例
入力に64.0を指定した場合、プログラムを終了まで実行した際のコンソールは以下のようになっている 。
実数を入力:64 64.0の立方根は4.000000000000065
手順
指定した箇所で必ずテストを行うこと。
- newtonメソッドに対する詳細な擬似コードを作成する
- パッケージ j1.lesson10 にクラス Newton を作成 (ファイル名は Newton.javaとなる)
- クラス内に throws IOException の指定をした mainメソッド (public static void main(String[] args) throws IOException { }) を作成
- 必ず throws IOException の記述を付加しておくこと (つまり、import java.io.*;も必要となる)
- クラス内に必要なメソッドの骨格を作成 (こちらには throws IOException は必要ない)
- テスト項目「Newton に対する骨格テスト」をパス
- 擬似コードを各メソッドにコメントとして貼り付ける
- 擬似コードに対するプログラムを書く
- 実際に実行して動作を確認する
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メソッド名), existence | 指定されたメソッドが存在しない |
(メソッド名), public | メソッドを作る際に public が抜けている |
(メソッド名), static | メソッドを作る際に static が抜けている |
(メソッド名), type void | メソッドを作る際に void 以外を指定している |
(メソッド名), throws ... | メソッドを作る際に throws... の指定がない |
課題1006 (optional)
課題1003で作成したプログラムに対する単体テストプログラム NewtonTest.java をパッケージ j1.lesson10 に作成しなさい。
このテストプログラムは、演習で行った際と同様にJUnitを用いて作成すること。また、テストを行うためのメソッドとして、testNewton(), testF(), testG() メソッドを作成すること。
テストケースは以下の通りとする (期待値は各自で計算すること)。
テスト対象 | 引数 | 許容誤差 |
---|---|---|
f(double) | (-2.0) | 0.0001 |
f(double) | (0.0) | 0.0001 |
f(double) | (2.0) | 0.0001 |
g(double) | (-2.0) | 0.0001 |
g(double) | (0.0) | 0.0001 |
g(double) | (2.0) | 0.0001 |
newton(double) | (-27.0) | 0.0001 |
newton(double) | (-1.0) | 0.0001 |
newton(double) | (-0.001) | 0.0001 |
newton(double) | (0.001) | 0.0001 |
newton(double) | (1.0) | 0.0001 |
newton(double) | (27.0) | 0.0001 |
f(double)に対するテストはtestF()へ、g(double)に対するテストはtestG()へ、newton(double)に対するテストはtestNewton()内に記述すること。
手順
指定した箇所で必ずテストを行うこと。
- パッケージ j1.lesson10 にクラス NewtonTest を JUnit・テストケース として作成
- f(double), g(double), newton(double) に対するメソッド・スタブを作成する
- testF(), testG(), testNewton() メソッドにそれぞれテストケースを記述
- 作成したテストケースを実行して動作を確認
- 「Newton に対するテスト一式」 をパス
テストの失敗メッセージ
骨格テスト
メッセージ | 詳細 |
---|---|
(クラス名), existence | パッケージ内に課題で指定したクラスが存在していない。パッケージやクラス名を確認 |
(メソッド名), existence | 指定されたメソッドが存在しない |
(メソッド名), public | メソッドを作る際に public が抜けている |
(メソッド名), static | メソッドを作る際に static が抜けている |
(メソッド名), type <T> | メソッドを作る際に戻り値の型が違う。正しくは <T> |
(メソッド名), throws ... | メソッドを作る際に throws... の指定がない |
単体テスト
メッセージ | 詳細 |
---|---|
(メソッド名), 期待された結果と異なります | (メソッド名)を起動した結果が期待された結果と異なる。テスト項目を参照 |
機能テスト
メッセージ | 詳細 |
---|---|
余計な入力を待っていると考えられます | コンソール入力を取得する命令を必要以上に行っていないか確認 |
次の入力を変換できませんでした (???) | ??? を取得しようとして失敗している。コンソール入力を取得する命令を確認 |
期待された結果と異なります | 出力された結果が期待された値と異なる。「期待された値」と「実際の値」を比較 (エラーメッセージが出力されているエリアの下のほうにあるバーをスクロールさせれば見ることができる) し確認。他にも直接プログラムを実行して結果を調べたり、エラーメッセージの2行目にあるat以下を参考にプログラムを見直す |
無限ループの可能性 | 一定時間内にプログラムが終了しなかった。ループが無限に続いていないか確認 |
メタテスト
メッセージ | 詳細 |
---|---|
(クラス名) | テストが失敗している |
testcase (メソッド名).(引数) | 指定されたメソッドを指定された引数でテストしていない |
課題1008 (special)
以下のような虫食い算 (Xには0~9の任意の値が入り、a,bにはユーザから入力された0~9の値が入る) を解くプログラム Alphametic3.java を package j1.lesson10 に作成しなさい。
X X * X X -------- X X X X a X -------- X b X X
各桁の最上位桁には 0 は入らない。
指針もテストも与えない。好きなようにプログラムを作成すること。
ヒント
擬似コードを示す。
プログラム全体 "aの値を入力:" と表示 a = コンソールへの入力 if a が負の値 または a が 10 以上 "不正な入力です" と表示 終了 "bの値を入力:" と表示 b = コンソールへの入力 if b が負の値 または b が 10 以上 "不正な入力です" と表示 終了 a, b の値を使って、虫食い算の全ての可能性を算出して表示する
与えられた虫食い算を解く(a, b) for 被乗数 を 10 から 99 まで for 乗数 を 10 から 99 まで 1段目 = 被乗数 * (乗数の1桁目) 2段目 = 被乗数 * (乗数の2桁目) 結果 = 1段目 + 2段目 * 10 if 1段目が 3桁 かつ 2段目が 3桁 かつ 結果が 4桁 かつ 2段目の2桁目が a と等しい かつ 結果の3桁目が b と等しい ならば "(被乗数, 乗数)" を表示して改行
桁数を計算する(value) 桁数の初期値を0に設定 while value が 0 でない value の値を10で割って、小数点以下を切り捨て 桁数を 1 増やす ここまでの桁数を返す
指定した桁の値を取得する (value, n) 10 の n-1 乗を作成する value の値を10のn-1乗で割って、小数点以下を切り捨て さらにその値を10で割った余りを返す