続・東大理系 1 年生むけ CS スパルタ教育〜Java から Ruby へ〜(プ会 2008.1)
久野靖∗

2008.1.17

1

前回 (2007 年 5 月) のあらまし• 当日課題提出人数の変遷: 1:52 → 2:42 → 3:38
→ 4:34 → 5〜13:約 25 で安定。やめる人はさっさ□ 1 年後期理系選択科目「計算機プログラミング」→ 2006とやめて後はやめない

年度から「情報科学」に模様替えしてクラス指定科目に• 学生さんの反応は「難しい」というのは当然あるが、難しいから駄目、というわけではない (さすが• 理系 1 年生全員に科目枠を割り当て (選択しないことは可能だが、選択しない場合そのコマは空きコマ

東大?)• マークシートアンケート (東大実施、出席しない人がになる)いるので回答数は 18) →総合評価:• 「情報科学 (CS)」を教えることが目標となる

大変満足 10、

ほぼ満足 2、普通 4、やや不満 2。難易度:• 教える内容範囲は「標準スライド」により各担当者

易しす

ぎ 1、適切 6、やや難しい 9、難し過ぎ 2。(最後まに周知 (?)。内容はかなり広範囲かつ深いで出た人という点を割り引く必要あり。)• 使用するプログラミング言語は Ruby に統一。ただしプログラミングの習得は目的でない□ 2006 年度に対する久野の考察…

• 2006 年度については「試行」として上記に準拠し• 標準スライドがハードなのに輪を掛けてスパルタにしてしまったが、学生は好意的だった→ありがたい

なくてもよい。2007 年度から本格施行ことです□ 久野の選択 (2006 年度)• ドリトル言語での中学/高校での経験→「難しい」こ• 自分が作った資料でないと教えられないという人なので、ずっと自作資料で Java 言語を教えて来たとはマイナスではなく、難しいことを達成するのは楽しいという生徒が多い (教員が下手を打って達成• プログラミングは書かなければ身につかないという信条なので、毎週 2 回 (当日+次回まで) 小課題でプさせ損ねない限りは)• プログラムを書かせつつ CS を教えるのは大いに可能

ログラムを提出してもらってきた• 題材としての CS は奥が深く面白い (たぶん学生にとっても)、という点は改めて見直した• 上記方針は維持し、ただし翌年度に備えて内容範囲
を「標準スライド」をカバーするものに書き換える。
題材を扱う順序は自分で設計

2• 内容と言語を一緒に書き換える気力はないので→2006 年度は Java 言語を使用

2007 年度の実施に当たって□ 東大から示された前年度よりの変更点□ 久野クラスの実施結果…

• 履修率が良くないので難易度を下げる→難易度と学生の人気とは必ずしも関係ないのでは? 難しくて• 標準スライドが広く深いため、かなり詰め込みのもやりがいがあり自分のためになると思えば来てく

内容

れるという印象• にもかかわらず、自分の趣味なところ (言語処理系)• 標準スライドの内容を削って少なくする→自分もやのところはさらに内容を上積みしてしまった (ついりすぎたと思ったので少なくするつもりだったが、…)あんまり削ると面白くなくなるのではと懸念• 結果、当該箇所は超スパルタになったので学生さん• 内容は標準スライドの「必須」部分をカバーしていには申し訳ないことをしたと考えている

れば順番や扱いは各教員に任される→それはそのつもりで準備してきたので∗ 筑波大学大学院経営システム科学専攻1• 評価は共通試験+各担当者独自評価→毎回のレポー• 次回レポートの解説を次回講義の最初に行う。このトは維持し、その点数と共通試験とを 50:50 でつけ部分では、まず問題を考えてもらう→それに対応す

ることにするる CS 概念を講義、という順が可能□ 最大の変更点:□ レポートとその評価「Java から Ruby へ」
実行時エラー/論理エラー取りに比べ• 当日課題 (A レポート) は当日 24 時、次回課題 (Bてコンパイル時エラー取りははるかに容易→強い型

レポート) は次回講義 10 分前が締め切り (でも期の言語でコンパイル時エラーを取って実行、という

限は臨機応変に延長)。授業に来る人は 10 人ちょっ

経験はぜひとも積んで欲しい☆

と、残りは資料で勉強してレポートを出すだけ (完• 久野の信念:

全 e-learning?)• とはいえ、Ruby の使用が指定されたので、Ruby だとどうなるかやってみることは興味津津。☆のため• 課題は資料に「演習」として掲載、8 個くらい (うち半分くらいは数個の小課題から成る) →難易とり

最後に数回 Java をやってもらう• 資料は前年度に扱う題材をコンバートしたので、基まぜ、「自分の腕前に合った課題を選択」するよう

本的には各例題を Ruby に書き直して細かい説明

促す→とにかく何かはプログラムを書くことを優先• レポートはメールで提出させ、Web で全員ぶんを公開。公開時にすべてに短いコメントを付けた→互いがやっていることを見られるようにを Ruby 用に直す (結果、Ruby というべきところに Java と書いてあること多々に…)• いくつかの (けっこう多くの) 箇所で、Java と Ruby
でストーリを変更する必要 (後述)

http://lecture.ecc.u-tokyo.ac.jp/~kuno/is07/report/• 評価は△ (遅刻や不十分)、○ (普通)、◎ (特に買う点がある) の 3 段階。◎は自由課題的演習の時に3つける

2007 年度授業の概要□ 以下、各回の内容と思ったこと。

□ 全体方針• 現在、#1〜#11 まで完了し、標準スライドの「さまざ• 標準スライドの内容をカバーするが (ちょっとでき

まなプログラミング言語」以外をすべて完了 (Rubyてないところもあるかも)、取り上げる順番は変更

でやる内容はすべて完了)。残り 3 回は「さまざまするなプログラミング言語」とおまけ 2 回を Java でや• 取り上げる各内容について、 (原則として)Ruby プ

る予定

ログラムを用いて確認ないし追体験を行えるように• 出席人数は 1:30 → 2〜11:約 20 で安定する (演習課題を用意するということ。ただし演習を全部やるのは無理なので学生の選択)• そのため、Ruby プログラミングが身につくように、

3.1

プログラミング的に易→難の順に題材を配置する□ 各回の授業の運用#1: アルゴリズムとプログラム/数値の表現□ 計算の手順がアルゴリズムで、それをコンピュータで実行できるように表記したものがプログラムだ、とい• 毎回 (授業時間は 90 分)、おおむね 2 つ程度のトピックを紹介する。資料は授業の数日前に PDF でう話 (前期の復習)

公開• Ruby の「三角形の面積」プログラムを提示しそのまま動かさせる。

• 1 つ目について講義/説明した後、それに対応する
例題プログラムを「そのまま」打ち込んで動作確認

def triarea(w, h)s = (w * h) / 2.0
return s
end

してもらう。

• その後、それを多少手直ししてやるとできる演習が複数用意されているので引き続きやってもらう。(こ• 動いたら「2 数の和」
「円柱の体積」など同様の (単純計算の) プログラムを書かせるの演習内容を「当日レポート」として提出。) ここまでで大体 50 分〜1 時間 (説明 20+演習 30)• すべての例題はメソッドの形で書き、エディタでファ• 頃合いを見計らって演習を中断し、2 つ目のトピッ
クを講義/説明。これに対応する演習から 2 つ選ん

イルに打ち込ませ、irb でロードして引数をつけて呼び出し実行させる

で次回までのレポートとする。

2• 前年の Java に比べると、入力する行数が圧倒的に

return result
end

少なく、おまじないが少ないため、最初の演習に掛かる労力は非常に少なくなった。これはさすがだと• これを打って動かした後「2 数のより大きいものを打ち出す」「3 数の〃」を演習してもらう。3 つ、4思った。

• しかしそれでナメていたため、「エディタでファイルに打ち込む」というのを丁寧に説明せずにはまっ

つになると初心者はそれなりに苦労するので楽しんでもらえるた。学生はそういうことをしたことがないので苦労□ if 文が終わったら while 文を説明し、「積分の公式をしていた (が、1 週間経ったらあとはまったく OK)

知らなくても積分が求められる」と言って数値積分の□ 数値の表現について、整数の 2 の補数表現と、実数の浮概念を説明する

動少数点表現の説明。数の有限性/有限精度、誤差 (情• 例題は while 文を使って 2 次関数の定積分 (正解が分かっている) を求める→誤差がバラバラ→ dx=W/N
を累計しても誤差のためループが N+1 回になったりすることを示す→回数を決めてループしカウンタから x を求める→計数ループを教える→刻みを小さくするとそれに応じて安定に誤差が減っていることを示す

報落ち、桁落ち) の説明• Java のときは整数があふれて負になるとかを体験する課題を出していたが、Ruby は勝手に多倍長にするためこれができない。しかたないので時間計測法を提示して「ある値から先は計算時間が長くなるが、

def integ1(a, b, n)
dx = (b - a) / n;s = 0.0
x = awhile x < b
y = x**2# 関数 f(x) の計算
s = s + y * dx
x = x + dx
end
return s
end

そのある値はいくつか調べよ」という課題にした。

• 浮動少数点の誤差を実際に観察する課題。これはJava でも同じ。非常に緻密に調べてくれた学生もいるし、適当にやって誤差がありました、程度の学生もいた• 全体として、単なる計算のコードだけでできる課題
なので初回の B 課題にぴったり

3.2

def integ2(a, b, n)
dx = (b - a) / n;s = 0.0
n.times do |i|x = a + i * (b - a) / n;y = x**2# 関数 f(x) の計算
s = s + y * dx
end
return s
end#2: 制御構造/数値積分□ 前述の通り、課題として出した整数演算時間の段差と実数の誤差の問題について解説□ 制御構造がないと何もできないので、とにかくまず if
文を教える。

• 例題は「絶対値の計算」で、1 つの動作に複数の書き方があることを強調• 単調増加な関数で左端公式 (?) だと常に小さいこと

def abs1(x)if x < 0result = -x
else
result = x
end
return resultendを説明し、ヒント (中点公式、台形公式、両者の混合の考え方) を示して次回までの演習問題としてやらせる• このほか、sin/cos のテーラ展開式を示してこれをループで計算してみるという問題も用意• さらに制御構造の演習として、素数の判定と素数の列挙 (ナイーブに全部割ってみる方式) の課題も出

def abs2(x)if x < 0return -x
else
return x
end
end

し、速度改良してみよと指示。この課題は例年、学生に人気がある (計算量の前フリにもよい)• 計数ループは「数値.times do ... end」を教えてしまい、ついに現時点まで for 文を教えていな
い。Ruby なんだから Ruby らしい方がいいじゃん?

def abs3(x)result = x
if x < 0 then result = -x end

3

3.3

#3: f(x)=0 の求解/データ型• 階乗、組み合わせの数、再帰的定義、非負整数の 2進表現の 3 つについて再帰的定義を提示し、再帰メ□ 前回課題の説明として、シンプソンの公式による積分

ソッドを書かせる演習の説明と打ち切り誤差の話をする。テーラ展開式をそ• 例題と同様のパターンで書けばできるのですんなりのまま計算すると誤差でめちゃくちゃになる話もする

再帰に入れるという印象□ f(x)=0 の解も数値的に解けるよという話をしてから、単調増加関数を前提として区間 2 分法の説明とニュー□ レ コ ー ド 型 に つ い て 解 説 し「Pixel =トン法の説明を (あらすじだけ) して、そのコードを自Struct.new(:r, :g, :b)」で ピ ク セ ル 値 を 表 す
レコードを例示。これの 2 次元配列で画像を表現でき力で演習として書いてもらうることを説明• これまでは例題をちょっと手直し程度だったが、こ• initimage(画像データの初期化)、writeimage(ファイルへの PPM 形式での書き出し)、fillcircle(円を塗りつぶし) を示し、この程度で画像が作れることを示したあと、長方形や直線などを作る課題と「美しい絵」を作る課題を提示の演習ではゼロからコードを書いてもらう。でも難しいので、その場で穴埋め程度になるようにヒントを出した□ 基本データ型 (数値、文字、論理値、nil) と複合デー

def mypicture
initimagefillcircle(150, 30, 60, 255, 100, 70)
fillcircle(190, 100, 30, 100, 200, 80)
writeimage("t.ppm")
end

タ型 (配列、レコード、オブジェクト) の説明• Ruby だと文字列がオブジェクトで文字型がないので苦しい。また、シンボル型があるのでどうしようかと思ったが説明してしまう (レコードを作る時に□ 「美しい画像」について、簡単な絵でも構わないとし

必要)たが、学生は皆いろいろ頑張ってくれた。

• 配列については沢山つかうので具体的例題で説明。
配列内容の合計を取る程度• 素数列挙の改良として割ってみるのを√まででやめる等を例示し、その後「素数を配列に取っておいて素数だけで割ってみる」「エラトステネスのふるい」の考えを示して作ってみる課題を説明• このあたりで、繰り返し、枝分かれ、配列を使ったプログラムがそれなりに書けるようになった感じ

3.4#4: 手続き (関数) と副作用/レコードと画像□ 前回課題の説明として素数列挙の問題を中心にプログ
ラム例を解説□ メソッドを分けることで「抽象化」がなされていたことを後づけで指摘。またグローバル変数の概念を説明し、グローバル変数を書き換えると副作用のあるメソッ
ドになることを説明。続いて再帰関数の概念を GCD(最大公約数) で説明 (前にループによる最大公約数をやっているので)
def gcd(x, y)
if x == yreturn x
elsif x > yreturn gcd(x-y, y)else
return gcd(x, y-x)
end
end

4

5

3.5

#5: さまざまな整列手法/時間計算量□ 配列の整列について#3 で出した課題の解説として単純
選択法、バブルソートを示し、N を変化させて時間計測を行う演習□ マージソート、クイックソートを解説□ 時間計算量の考え方を解説□ ビンソート、基数ソートの考え方を解説し実装する課
題を提示□ その他の題材として最大公約数のユークリッド互除法、
フィボナッチのループ版と 22 行列版、組み合わせのパ
スカル三角形版を考え方だけ示し実装と時間計算量の計測/見当を課題として提示

3.6#6: 連立方程式の数値解法/ランダムアル
ゴリズム□ 前回課題の各種アルゴリズムの実装例と時間計算量分析□ 連立一次方程式のガウス消去法を説明し、Gauss-Jordan に 直 す 演 習 。ま た Jacobi 法 の 原理と実装例を説明しテスト実行による収束の検討とGauss-Seidel 法に直す演習□ 乱数と擬似乱数、ランダムアルゴリズム、モンテカルロ法による数値積分について説明し適当な関数の積分と試行数による精度分析を課題として提示□ 乱数を使ったゲームの例として「数当て」を説明し、任意のゲームを作ってにみるという課題を提示
def kazuatea = (rand(10000)+10000).to_s[1..4]; count = 0
while true doprintf("your guess? ")s = gets; hit = 0; blow = 0
4.times do |i|
4.times do |j|if s[i] == a[j] thenif i == j then hit = hit + 1
else
blow = blow + 1
end
end
end
end

6

@head = @prev = Cell.new("", @cur)end
def atend
return @cur == @tailend
def top@prev = @head; @cur = @head.next
end
def forward
if atend then return end@prev = @cur; @cur = @cur.next
end
def insert(s)@prev.next = Cell.new(s, @cur); @prev = @prev.next
end
def print
puts(" " + @cur.data)end

if hit == 4 then puts "you win!"; return end
count = count + 1
if count > 9 thenputs "you lose! answer = #{a}."; return
end
puts "hit = #{hit}, blow = #{blow}."endend□ ゲームを作りたい人はかなり頑張ってゲームを作り提出してくれた (文字だけでやる RPG とか)

3.7#7: 常微分方程式の数値解法/オブジェク
ト指向□ 常 微 分 方 程 式 と は 何 か 整 理 し た 後 、Euler 法 、Runge-Kutta 法 (2 次) の考え方とコード、および
Runge-Kutta 法 (4 次) の考え方と公式までを示し、head: prev:

cur:
How

are

head:

prev:

cur:

How

are

head:

prev:

cur:

How

top

精度を検討するかまたは 4 次の実装をする演習

forward□ オブジェクト指向とはプログラムが扱うデータを「もinsertの」として考える「考え方」であると説明し、クラス、インスタンス、インスタンス変数、インスタンスメソッ

old

head:
forwardドなどの言語機構/概念を解説• 例題として「犬」のクラスを示しその変更を演習と
して提示

How
old

head:
deleteclass Dog
def initialize(name)@name = name; @speed = 0.0; @count = 3
end
def talkputs(’my name is ’ + @name)end
def addspeed(d)@speed = @speed + dputs(’speed = ’ + @speed.to_s)
end
def setcount(c)@count = c
end
def bark@count.times do puts(’Vow! ’) end
end
end

tail:

How

you?

EOF
tail:

you?

EOF

are

you?

EOF

prev:

cur:

are

you?

tail:

prev:
are

tail:
EOF

cur: tail:
you?

EOF

old

□ 演習として「現在行削除」「現在行と次の行の交換」「1
つ戻る」「全体の順序逆転」から 1 つ作ってもらう• おまけとしてファイル読み書き、置換コマンドの実装を説明 (本当にエディタとして使えるようにする
ために不可欠)□ 表と探索の概念を説明し、線形探索、2 分探索木の実
装例を時間計測例とともに示す。時間計算量の検討を課題として提示• Ruby の Hash について表の一種として説明し、具体的な記法や使い方を示したあと、これの時間計測も課題として提示• 「有理数」クラスを示しその演算追加と「複素数」
クラスの作成を演習として提示

3.9
3.8

#8: 動的データ構造/表と探索#9: 抽象構文木/動的分配/字句解析/再帰下降解析□ 前回課題の解説として単リストの操作を解説。またハッ□ 動的 (再帰的?) データ構造について説明し、単リスト

シュ法の解説と実装例を示し、線形探索、2 分探索木、とその操作を説明

Ruby の Hash も含めて時間計測と計算量の検討例を示す

class Buffer
Cell = Struct.new(:data, :next)
def initialize@tail = @cur = Cell.new("EOF", nil)

□ 式木/抽象構文木の概念を説明し、簡単な式木を組み立てて評価する例題を提示した後、演算の追加や制御構造の追加を演習7

end$vars = {}class Addclass Seq < Nodedef initialize(l, r) @left = l; @right = r end
def initialize(l, r) super; @op = ’;’ end
def exec() return @left.exec + @right.exec end
def exec() @left.exec; return @right.exec end
def to_s()
end
return ’(’ + @left.to_s + ’ + ’ + @right.to_s + ’)’ class Loop < Nodeend
def initialize(l, r) super; @op = ’L’ end
end
def exec()class Mul
v=0; @left.exec.times do v=@right.exec end; return v
def initialize(l, r) @left = l; @right = r end
end
def exec() return @left.exec * @right.exec end
end
def to_s()
return ’(’ + @left.to_s + ’ * ’ + @right.to_s + ’)’ def test1
e =end
Seq.new(
end
Assign.new(Var.new(’n’), Lit.new(5)),
class Lit
Seq.new(
def initialize(v) @left = v end
Assign.new(Var.new(’x’), Lit.new(1)),
def exec() return @left end
Seq.new(
def to_s() return @left.to_s end
Loop.new(end
Var.new(’n’),
class Var
Seq.new(
def initialize(v) @left = v end
Assign.new(Var.new(’x’),
def exec() return $vars[@left] end
Mul.new(Var.new(’x’), Var.new(’n’))),
def to_s() return @left.to_s end
Assign.new(Var.new(’n’),
end
Sub.new(Var.new(’n’), Lit.new(1))))),
def test
Var.new(’x’))))$vars[’x’] = 5
puts(e)e = Add.new(Var.new(’x’), Lit.new(1))
return e.exec
puts(e); puts(e.exec)end
e = Add.new(Lit.new(3),Mul.new(Var.new(’x’), Lit.new(2)))
irb(main):006:0> test1
puts(e); puts(e.exec)(((n$)=(5#));(((x$)=(1#));(((n$)L(((x$)=
e = Mul.new(Add.new(Var.new(’x’), Lit.new(3)),((x$)*(n$)));((n$)=((n$)-(1#)))));(x$))))
Lit.new(2))=> 120puts(e); puts(e.exec)end□ 字句解析器の考え方とコード例を示す
irb(main):004:0> test
(x + 1)
6(3 + (x * 2))13((x + 3) * 2)16=> nilclass Scanner
def initialize(s) @str = s + ’$’; @pos = 0 end
def peek() return @str[@pos..@pos] end
def next()
if @pos < @str.length-1 then @pos = @pos + 1 end
end
def to_s()
return @str[0..@pos-1] + ’!’ + @str[@pos..-1]
end
end□ 類似したノードクラスを継承により短く定義できることを示す□ BNF、文法、構文解析木の解説。構文解析木を描かせる□ ループ文なども同様に定義できることを示す

演習;□ 再帰下降解析器の考え方とコード例を示す;==

def prog(sc)s = stat(sc); c = sc.peekyif c == ’$’ || c == ’}’ then return sx
1
elsif c == ’;’ then sc.next; return Seq.new(s, prog(sc))
x = 1 ; y = x + 1 ; yelse puts(’STAT:’ + sc.to_s); return Noop.new
end
endclass Assign < Nodedef stat(sc)def initialize(l, r) super; @op = ’=’ end
c = sc.peek
def exec()
if c == ’{’ thenv = @right.exec; $vars[@left.getleft] = v; return v
sc.next; p = prog(sc)
end
x

1

+

y

8

if sc.peek != ’}’ then$atm = [{’a’ => 1},puts(’NO_}:’ + sc.to_s); return Noop.new{’b’ => 0, :final => true}]end
def accept(s)sc.next; return p
cur = 0elsif c == ’L’ thens.length.times do |i|sc.next; e = expr(sc); return Loop.new(e, stat(sc))
k = $atm[cur][s[i..i]];
if k == nil then return false else cur = k end
else return expr(sc)endendreturn $atm[cur][:final] == true
end
end
def expr(sc)e = factor(sc); c = sc.peek
if c == ’+’ then sc.next; return Add.new(e, expr(sc))• Hash のリテラルを使うことで「まんま」書ける感
elsif c == ’-’ then sc.next; return Sub.new(e, expr(sc))
じ→ Ruby の利点
elsif c == ’*’ then sc.next; return Mul.new(e, expr(sc))
elsif c == ’/’ then sc.next; return Div.new(e, expr(sc)) • いくつかオートマトンを示して受理するものは何か
elsif c == ’=’ then sc.next; return Assign.new(e, expr(sc))
考えさせる。また Ruby で動かして確認させる
else return eend□ パズルやゲームが状態空間探索として定式化できるこ
end
def factor(sc)とを説明し、例として箱入り娘を解くコードを提示 (64c = sc.peek; sc.next
行)
if c >= ’a’ && c <= ’z’ then return Var.new(c)elsif c >= ’0’ && c <= ’9’ then return Lit.new(c.to_i)
elsif c == ’(’ then
下 下 母 父
母
父
娘
男 女 親 親親親e = expr(sc)if sc.peek != ’)’ then
番頭
小 小
番頭
下
下
puts(’NO_):’ + sc.to_s); return Noop.new
男
女
小 小
小
end
娘
小
小
小
sc.next; return eelse puts(’FACTOR:’ + sc.to_s); return Noop.new
end
end
def test2• これは昨年の内容になかったものだが、奥さんに「状e = prog(Scanner.new(’n=5;x=1;L5{x=x*n;n=n-1};x’))
態探索がなかったら CS じゃない」と言われてそのputs(e)
気になったので…
puts(e.exec)end• 課題として好きなゲームやパズルを解くものを提示□ 昨年よりはかなり譲歩したが、まだ「難しい」との意
見多数…

3.11

• 簡単のため式が演算子右結合にしてあるのはよかっ#11: 動的計画法/パターン認識□ 動的計画法→パターン認識の前フリとして標準スライ

たのか…

ドで指定

#10: スタックとキュー/状態空間の探索• 動的計画法の考え方を「釣り銭問題」「ナップサッ□ 抽象データ型としてのスタックとその実現 (配列、リス「ナップサック問題」のトレースバック表示、「合宿ト)。抽象データ型としてのキューとその実現 (配列、の部屋わり」問題のプログラムのいずれかを作ってリスト)。いずれも実例は配列版のみ示し、連結リスト

もらう

3.10

ク問題」で説明し、「釣り銭問題」の硬貨群の変更、版を実装する演習課題• 多くの学生にとって (ほぼ全員)「考え方は分かっても自分で作れるようになる気がしない」。課題も一• 式木を深さ優先 (スタック)、幅優先 (キュー) でた

番易しいものの提出ばかりだった

どってみせる• JR 路線図をたどる課題、エディタバッファを 2 つ□ 文字列のアラインメント→できればこのプログラムをのスタックで実装する課題

自力で作れるようになって欲しいところだが、授業 1
回では難しいかも□ 有限オートマトンの復習/オートマトンを Ruby で実装□ パターン認識、forward algorithm、Viterbi アルゴa

リズム→一応説明してコードも掲載しているが、これb

も 1 回では時間がない感じ

9

4

まとめ

• 情報科学についても、Ruby によるプログラミング
も、そこそこ理解できた気がします。比較的易しい□ まだ「さまざまなプログラミング言語」1 回+Java2 回

内容や、プログラミングに関してはほとんど理解でを残していますが…

きなかった内容もありました。Ruby を通して情報□ Java から Ruby へ→思ったより変わらなかった。

科学の学習を行うというのは出来たと思います。

• 情報科学の考え方が理解できても、いざそれを Ruby

• Ruby だからいい点…短く書ける、irb で配列リテ
ラル等を打ち込める (文字からデータ構造を作る部で表現するとなると大きな困難が伴い、大変苦戦しました。個人的な意見としては情報科学の学習が主分のコードが要らない)

目的であれば、プログラミングに関してはもうちょっ• Ruby だと困る点…グラフィクスがない、勝手に多と易しくしてもよかったような気がします。

倍長など仕掛けが埋もれている• バランスはちょうど良いと思いました。難易度は、• 強い型検査、コンパイラのチェックはちゃんと通す

後半が結構高かったです。

習慣をつけて、それからスクリプト言語に行って欲• この講義では演習の方に重点を置いていたような気しいと思うがします。原理的なものについては理解できても、□ 昨年よりハードさは和らいだがまだハードだと思う

実際プログラムを作ろうとすると難しいことが多□ 学生さんの感想 (下記) を見ていると、やはりプログラ

かったです。

ラミングが魅力的だからと思うことにして… :-)• 内容は理解できても、ルビー化できないときが多々ありました。難しいです。

□ 各回の題材についてはそれなりに興味を持ってもらえ• 少し課題が大変なときもありましたが、全体としてていると思う (いかにも情報科学なので学生もそう思っ

ちょうどいい難度だったと思います。 はじめてのてくれている?)

プログラミングでしたが、楽しくなんとかついていミングを学んでいるという意識が強い。それはプログ

くことができました。

□ これからも、「情報科学を学んでもらいながら」「プロ• この授業はプログラムの実習が中心だったので、もう少し, 解説に力を入れてほしかったと思います。

グラミングも楽しんでもらう」ことを目指して頑張ります• この講義は、位置付け、バランス、難易度のいずれも程良い感じの良い講義だと思います。効率良く情5

学生アンケートから

報科学の内容が身についたように思います。

• Ruby は簡素な言語だなあと思いました。内容は時間の指数関数的に難しくなっていった気がします。

□ すべてのレポートで 3 問ずつアンケートに回答してもらっている• Ruby プログラミングの難易度が高すぎる気がしま• だいたいは、2 個の内容についての質問+感想・要望

す。初学者にはきついです。

• #11 だけはプ会向けの質問を 2 つ入れた• どちらかというと、Ruby プログラミングがメインだったような感じがしないでもないです。ただ、プ□ Q. この講義は「情報科学」の学習を目的とし、その確ログラミングができる=情報科学が学べている、と認手段として「Ruby によるプログラミング」を演習しいうきもするし、なんともいえないです。

て頂いていますが、本クラスにおけるその両者の位置• 後半はプログラミング未経験者には無理でしょう。
継承や演算子オーバーロード (実質) がいきなり出

づけやバランス、難易度についてどう思いますか。

• 一部非常に難しい演習もありましたが、それを除けばバランスは取れていると思います。

てくるのは……(苦笑• 情報科学を学んでいるというより、どっちかというとほとんど「Ruby でのプログラミング」を学んでい• 情報科学としてはバランスはちょうど良かったと思います。難易度は途中で急に上がったような…

るという感じでした。ただ、そっちのほうがよかった• こういうのはよくわかりませんが、個人的には小難しい話を延々とするよりはこの講義のように実習をので、たくさん学べてうれしかったですが。難易度多めに取り入れるほうがいいと思います。ただ難易タ構造あたりからはかなりきつく、おもちゃ言語で度はもうちょっと低くてもいい気がします。

は力尽きました。

はクラスぐらいまではよかったのですが、動的デー• 情報科学を学ぶために Ruby を利用するのは最初疑問でしたが、まぁありかなって思います。

• 講義の難易度が途中から著しくあがった気がしま
す・
・
・
10

• ちょうど良かったです。時々与えられる自由な課題

ムでも計算方法が違う事で計算時間に非常に大きなが大変でしたが、やりがいがありました。

差が出る事は実際にプログラムを動かす事で実感する事ができたと思います。

□ Q. 講義開始時の自分を振り返り、今回までの講義で自• ソートの辺りからは (OO はなんとなく分かっていま

分がどんなことを学んだか簡単にまとめて見てくださしたが) 知らないことばかりで、いろいろ新しく勉

い (全体的な感想も含めてどうぞ)。

強させてもらいました。

• ・自分はプログラミングの経験はありましたが、Rubyを新たに習得することができました・実用的なプロ• アルゴリズムの組み立て方など

グラミングができるぐらいのアルゴリズムは学べた• データ型やクラスなどの概念は分かったと思いますが、プログラミング言語としての Ruby はまだまだと思います。
・でも結局完全には理解できていない

分からないことだらけです。あと、/の逆向きの記号理論はあります。そして、あやふやなアルゴリズムがまだ打てません。なので、上のプログラムも/(のもあります。試験までに復習しないと…

逆)n がありません。

• Ruby が書けるようになったのがよかったですね。課
題も楽しかったです。

• プログラミングというものを習得し、コンピュータ• Ruby でちょっとしたプログラムをつくれるようにだこと」に対して真っ先に思い浮かんだものです。

なってくらいであまり進歩を感じませんが、プログ• アルゴリズム関連弱かったので、経験できてよかっの動くしくみの一部を垣間見た。というのが、「学ん

ラミングに取り組む中で「こういうモノがあって、たです。

こういう使い方が出来る」というようなことをたく• 講義開始時はプログラムなんて全く分からず、もちろんソースなんか見てもただの意味不明な羅列にしさん見た気がします。

• エディタバッファとかは今後使いそうです。後半の授業は難しかったですが、得るものも多かったです。

かすぎなかったのですが、現在ではソースを見て何をしているのかなんとなくは理解できるようになり• とりあえず、プログラミング自体初めて扱うものました。数学的な話題 (連立方程式とか微分方程式だったので、新鮮でした。なかなか複雑なもので、とか) はほとんど忘れてしまっていますが、基本的自分で新しいプログラムを作るのはかなり難しそう

な構文、クラスの使い方、配列、ハッシュ等は大方ですが、この講義で基礎を学べたと思います。

使えるようになりました。興味深い内容も多くあり、• 講義開始時に比べて、パソコンがどのようなロジッ

楽しくまなぶことができました。(字句解析器はきクで動いているのかがよく理解できるようになった。

つかったですが)またごく簡単なものに関してだけであるが、プログ• 内容が量的に結構大目で大変でしたが、プログラム
がどんな風に組み立てられているのがが少しわかっ

ラムを書いたり、書いてあるものを理解できるようになった。あと、記号とか打つのが速くなりました。

• 講義開始時は再帰的なものがとても苦手だったのでて面白かったです。

• ものごとの表現方法はいろいろあるのだと思いま

すが、現在ではある程度扱えるようになりました。

した。

• プログラムの計算量について結構理解できまるようになりました。同じことをやるのでも、プログラムの種類によってかかる時間がかなり違っているということには驚かざるを得ません。

• 数学に似てても全く異なる分野でした。使いこなせ
るのは html どまり…
• まずプログラミングという、色々な手法を組み合わせて、一つの動作をおこすものが作れるんだとわかりました。そういうものを自分で作ってうごかすのは、楽しかったです。

• この情報科学の授業で学んだ事で最も興味深かったのは誤差と計算量でした。 浮動小数点、桁落ち、情報落ちの仕組みを理解する事で, これまで原因が分からなかった乗除計算の時に微小な誤差が生じる仕組みが理解できました。また、同じ目的のプログラ

11