担当授業のこととか,なんかそういった話題。

主に自分の身の回りのことと担当講義に関する話題。時々,寒いギャグ。

ダッシュ目撃情報。

2024-04-10 20:33:53 | mathematics
十年近く前に,函数 f(x) の導函数を表す f ' (x) の読み方が,日本では未だに「エフ・ダッシュ・エックス」であるが," ' " は(この記事ではアポストロフィーにしか見えないかもしれないが)現代英語では prime(プライム)としか呼ばれない,というネタを書いたことがある。

その記事にはありがたいことに識者からのコメントがついて,大変有益な情報を得ることができた。

まず,日本評論社から出ている『数学セミナー』の 1985 年 11 月号の p.13 に,渡辺正氏(当時,東京大学生産技術研究所)の「「ダッシュ」と「活動寫眞」」と題する 1 ページのエッセイがあり,そこでなぜプライムを日本ではダッシュと読むのかの論考が述べられている。

渡辺氏はその疑問を知り合いのネイティヴにいろいろ尋ねたところ,第二次世界大戦のころまで英国ではダッシュと読んでいたが,大戦後にプライムと読むように変更されたのだという。

いずれにせよ,戦後生まれの若い世代(当時!)の英国人研究者はすでにダッシュと読むことを知らぬまま育っているということで,もはや古語というより死語というべきであろう,という厳しい見解が述べられている。

その記事が書かれてから 40 年が経とうとしているが,未だに日本ではダッシュが受け継がれていると思われる。とはいえ,私は高校の教育現場から離れてしばらく経つので,令和の時代でもそうなのかについてはやや不安が残る。

調査方法はいくつか考えられる。

まずは自分が担当する新入生にそれとなく聞いてみる。これが一番確実であろう。何しろ,ほとんどの学生がつい一か月前まで現役の高校生だったはずなのだから。

それに比べるとかなり間接的にはなるが,学部生くらいの若い講師による YouTube での微分積分講義を視聴することである。今の世の中,そういった動画で自主的に学習する中高生もそれなりにいるであろうから,むしろ「ダッシュ読み」撲滅委員会としては積極的に「ダッシュ読み」の監視を行うべきともいえる。もっとも,取り締まりというのは嫌な感じが付きまとうものであるが。年齢的には人生後半に入ってしばらく経つわけだから,ぼちぼち「老害」と世間から嫌がられることを覚悟のうえで「文化的」な活動に勤しまねばならないかもしれない。嫌われる勇気を奮わねばな。

さて,一昔前の英国で「ダッシュ」と読まれていたという証拠と,戦後のいつまでダッシュと読まれていたかを推察するための資料の 2 点を提供しようと思う。

Charles Babbage, 1864.



まず考古学的な文献であるが,今から 200 年ほど前の Cambridge 大学の,特に微分積分学の時代遅れであることに危機感を感じ,自主的に Analytical Society(解析協会)なるものを若い学者で結成し,大陸(フランス)の Lacroix の解析協定を英訳するなど,当時の水準での Canbridge 大学の数学教育の「世界標準化」を目差した Charles Babbage 氏の自伝的回想録 "Passage from the Life of a Philosopher"(『一哲学者の生涯からの小節集』とでもいったところだろうか。志村五郎氏の『記憶の切絵図』というタイトルを連想するが,『断片』とまではいかないかな。)の一節 (passage) にこんなものがある。Chapter IV. Cambridge のほぼ冒頭にある。

..., in the dots of Newton, the d's of Leibnitz, or the dashes of Lagrange.

Cambridge で伝統として受け継がれてきた,流率と呼ばれる,現在の導関数に相当するであろう数学的概念を表すのに使われる Newton 由来の記法とされるドット(流量と呼ばれる,函数に該当すると思われるものを表す文字の上に点を打つ。現在でも物理学,特に力学あたりで用いられている古の記法である),Leibniz(現在は t を入れずに書くのが標準的なようだ)の d,これは x の函数 y の x に関する導関数を dy/dx と書いたり,積分を ∫f(x) dx と書いたりするときに使われる,あの d のことであり,最後は Lagrange が導入したとされる,Newton のドットの変種に相当する,件の「ダッシュ」を用いる流儀と,三通りを列挙している箇所である。

Babbage 氏は Lacroix のテキストで Leibniz 流の "d-ism" に触れて感激したらしい。微分積分学の理論の習得を容易にするこの素晴らしい記法をイギリスの数学教育界に取り入れねば,という熱い情熱で解析協会の設立,そして Lacroix のテキストの英訳,出版という活動を行ったと推察される。

そういえば,自国の数学教育レベルを憂いて若き俊英たちが団結して自国の数学レベルを上げるためのテキストの編纂事業を立ち上げるというのは,Babbage の時代から 100 年ほど後のどこかの国で繰り返されたことのような気がしなくもないが,それについてちゃんとした調査は今後の課題である。

Babbage 氏らが当時まとめた報告書のタイトルは

The Principles of pure D-ism in opposition to the Dot-age of the University

という,ユーモアに満ち溢れたハイセンスなものなのだが,本当にこのようなタイトルが付けられたのかどうか気になるところである。

未見であるが,"Irascible Genius"(今風に訳すと『沸点の低い天才』とでもなろうか。怒りんぼだったそうな。)というタイトルの伝記があるそうなので,機会があれば手に取ってみたいものである。

話はズレるが,Babbage の訓として「バベッジ」と書かれるのが普通のようだが,綴り的には「バッベジ」になりそうな気がする。

Passages の意味を確認しようと思って検索したのだが,片仮名で passage の読みが「パッセージ」と書かれていた。次の成り立ちは

Babbage
passage

のように両者そっくりなので,それなら「バッベージ」になりそうなものなのだが,ネイティヴの発音はどう聞こえるのだろうか。

Babbage 氏は数学における記法の重要性についてかの有名な大数学者 Gauss 氏に書簡を送ったことがあるというエピソードもとても気になる。

また,フランスでは 1823 年だかに若き数学者 Cauchy 氏による解析教程が出版され,極限概念の取り扱いが刷新されようとしていた時代でもある。

ほぼ,同じ頃,粉屋の息子の George Green 氏が独学で Laplace の天体力学の(たぶんフランス語の)著書から学び取ったことを,当時最先端の話題であったであろう,電磁気学の数学的な理論構築の試みをまとめた冊子を自費出版 (1828) したり,チェコの哲学者 Bolzano がやはり実数の連続性だの関数の連続性だの(中間値の定理)に関する先駆的な考察を発表 (1817) したりと,まさに 19 世紀の学問が大きなうねりを伴って爆発的に発展しようとしつつあったところであった。そんな機運の中で,Babbage 氏も独自の道を進み,プログラミング可能な自動計算機の先駆けとなる,差分機械や解析機械という壮大なプロジェクトに身を投じたわけである。

それにしても,なぜ Cambridge 大学における数学理論の発展が停滞したのか,気になるところである。また,18 世紀はフランスの時代と言ってもよいほどにフランスの数学者が多数活躍したし,19 世紀の後半になっても Liouville やら Darboux やら Goursat,Hermite,Jordan など,名だたる大数学者がひしめいていたわけだが 20 世紀の初頭はドイツが数学のメッカといった様相を呈したように思われる。このような比較的短いスパンでの数学研究の主要地の変遷というものが,もし本当にあったとするならば,どういった背景によるものなのか,気になるところである。

ちなみに,Cambridge 大学の 19 世紀末頃までの数学研究の変遷については,W. W. Rouse Ball 氏の "A History of the Study of Mathematics at Cambridge" なる著作があるので,そういうものを紐解けば謎が明らかになるかもしれない。この書の 20 世紀版はちょうど 100 年ほど後に出た P. M. Herman 氏編集の "Wranglers and Physicists" かな,と思ったのだが,副題は 19 世紀の Cambridge 物理学に関する研究,となっているので,Rouse Ball 氏の物理学版らしい。

ともかく,1864 年に,英国で dash と書いても通じたであろうことが伺える資料であった。

John Backus, 1959.



私の 10 年ほど前のブログ記事にいただいたコメントには,1955 年の論文の脚注に dash と書かれているのを見かけたことがある,という,これまた貴重な情報が提供されており,それがもしかすると最後の目撃情報になるかと思われた。

だがしかし,である。

たぶんその頃,私は周期的に正規表現だの BNF だのを学び直したくなる発作を起こすのだが,その際にネットで入手した,BNF の発明者の一人と言われる John Backus 氏による報告文 "The syntax and semantics of the proposed international algebraic language of the Zurich ACM-GAMM Confarence" の最後のページ,p.132 の左の段の第 1 行に,それはあった!

If one wants to count backwards, a dash is added to i, e, g.

for all i ' ≧s

(meaning i=19, 18, ... s).


皆さん,確認されましたか?

そう,i に dash を付けて i ' と書く,という仕様を述べております。

あー,この発見を 10 年近くもの間ずっと胸に秘め続けていて苦しかった・・・!

いや,この記事のようにさっさとブログに書けばよかったのだが,どこで dash という単語を見かけたのかわからなくなって,ここ数年は何度もこの文書もしくは関連する文書を読み直しては,あれ,見当たらない・・・?と不首尾に終わって,ネタに上げられなかったんですよぉ~。

今年もまた BNF のことを思い出す発作が起きて,ようやく,久方ぶりにこの文書を再入手したので,Lagrange の dashes の話と共に記事として認めた次第である。

そしてもちろん新たな疑問も湧くけれども。

Backus 氏は生まれも育ちもアメリカらしいのに,当時もまだ dash と言っていたのか?

だがしかし,これはアメリカとヨーロッパの電子計算機学会の共同会議で協議された事柄に関する報告書であるため,ヨーロッパ圏の人々の語法を意識して dash を用いた可能性も無きにしも非ずである。

そして,この文書を最後に,欧米圏から果たして本当に dash が絶滅したのかどうか,それはもちろん,何らかの偶然に導かれた発見がなければ目撃年度の更新は起き得ないわけであるが,1959 年よりも新しい証拠が見つかるかどうか,残りの人生の楽しみの一つとしておくとしよう。

そもそも古めの微分積分学のテキストを漁っても,y ' を何と読むか,なんて文章で説明書きが見当たらないんだよねぇ。そこが悩みどころでもある。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Feynman が学んだ微分積分学の教科書。

2024-04-10 20:02:23 | mathematics
いやー,ホント,何でもネットで手に入ってしまう時代であることだなあ。

Feynman が自伝的著作 "Surely You're Joking, Mr. Feynman!" の `A Different Box of Tools'(岩波現代文庫版『ご冗談でしょう,ファインマンさん』だと上巻かな?)で,いわば数学者相手に「ファインマン爆撃」をかまし続けたというエピソードの後に,高校時代に Bader 先生から,この本の内容をすっかり理解出来たらまたおしゃべりしてもいいから,と手渡されたのが Woods の "Advanced Calculus" だったという,さらなる過去の回想が述べられている。

それは当時 MIT の教授だった Frederick S. Woods 氏の著書で,1926 年に初版が出たらしい。次いで 1934 年にいくつかの修正が加えられた New Edition が出た。

さて,ここで気になることが一つ。1918 年生まれの Feynman 氏は 1935 年に MIT に入学している。彼が学んだのは Woods の旧版と新版のどちらだったのであろうか?

そして他にも気になることがいくつかある。

Feynman 氏が MIT に在籍していた中で, 著者の Woods 氏と対面する機会はあったであろうか?

もしその夢の対面が実現していたら,Feynman 氏の自伝にそのエピソードが語られているはずである。何しろ彼はすっかりその本の虜になってしまっていたのだから!

残念なことに,ちょうど 1934 年に 70 歳を迎えたであろう Woods 教授は MIT を退職されていたようである。まさに Feynman 氏と入れ替わりであって,夢の対面は実現しなかったものと思われる。

もう一点。`A Different Box of Tools' の締めくくりは,Woods 本で学んだ積分記号下の微分(積分と微分の順序を入れ替える計算操作。俗に Feynman trick と呼ばれることがあるが,Leibniz の積分規則といい,微分積分法の黎明期にすでに編み出されていた古の計算技法である)のおかげで,MIT や Princeton の理系の秀才たちが,彼らが学校で習った標準的なやり方で求められずにウンウンうなっている積分の計算を,自分は積分記号下の微分でたいていうまく求めてしまったものさ,と締めくくっているのだが,出し抜かれた他の秀才たちがなぜその計算技法を知らなかったのか,という疑問である。Woods 本は当時の標準的なテキストではなかったのだろうか?

ちなみに,このエピソードが私にとっては印象的過ぎて,うまくいっているとは思えないが,2 変数関数の微分積分学を教える際に,積分記号下の微分法をほんのわずかでも紹介するよう,意識するように心がけている。

もっとも,このエピソードが語るところは,教師に教わったことなんかよりも,自ら進んで楽しみながら学び取った知識の方が断然役に立つんだもんね,といったことであろうから,私のなけなしの配慮など,何の役にも立っていないだろうという気しかしないのであるが。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

アインスタイン全集(全 4 巻)。

2024-04-10 18:41:46 | physics
先に結論を申し上げると,古書店で入手できるようだが,買うのは見送ることにした,である。


数理論理学の研究者であった前原昭二氏 (1927--1992) の晩年の著書『線形代数と特殊相対論』(日本評論社,1993 年)の巻末の「文献案内」に,1922 年から 1923 年にかけて改造社から出版された『アインスタイン全集』なるものが挙げられているのが目に留まった。

前原氏は,これは非売品であるが,1947 年か 1948 年に古本屋で求めたという。

この非売品というフレーズと,改造社という,聞いたことがあるような内容な出版社名が気になり,まずは国会図書館デジタルコレクションで検索してみた。

その結果,「送信サービスで閲覧可能」というステータスで所蔵されていることが分かった。

訳者の一人である石原純氏はちょうど 1947 年に亡くなっている。前原氏が古本屋で見つけたのは,石原氏の遺品だったのではなかろうか,などとつい妄想を逞しくしてしまう。

ところで,翻訳書の著作権というものがどのような扱いなのか知らないのだが,仮に著作者が石原氏であった場合,死後 70 年が経過しているので,著作権保護期間は満了していそうなものである。けれども,国会図書館の判断は「まだ満了ではない」もしくはその確認が取れていない,ということのようだ。

訳者は他に二名いるので,それらの方々に由来する著作権保護期間満了がまだ先のことなのかもしれない。

あるいは,原著者に相当する Einstein 氏が亡くなったのは 1955 年のことで,著作権者を Einstein 氏に帰するということならば,満了は来年あたりということになりそうである。

非売品であったという話はとある古書店のブログ記事にも記されていた。そこの在庫は売り切れたようであるが,ネットの検索結果によると,4 巻セットが税込みで 25,000 円あたりが相場らしい。税込み 19,800 円というものもあった。ビミョーに手が届くお値段ではあるが,買うのは,うーん,やめておこう。

どうでもいいが,前原氏の『線形代数と特殊相対論』と同時に手に取った本は彌永昌吉氏の『幾何学序説』であるが,前原氏の「文献案内」に『幾何学序説』が挙げられており,氏がかつて彌永氏の,その『幾何学序説』の下地となった講義に出席していたとの思い出が語られている。2 冊とも B5 版であるので,重ねて私のカバンに詰めたのだが,その偶然をこれら二氏の霊はどう感じられたであろうか。

さて,改造社という気になる会社のことも調べたところ,例によって Wikipedia の解説記事に目を通すこととなった。そこには確かに改造社の招きでアインスタイン博士が来日したとある。さらには,湯川秀樹氏がその際にアインスタイン氏の講演を聞き,それがきっかけで理論物理学の道を志したとある。

はて,そんなドラマティックな話だったっけな?

Wikipedia のそのくだりにはなんの出典も示されていない。だが,私は湯川氏の手になる『旅人 ある物理学者の回想』(もとは朝日新聞社から刊行され,現在は角川ソフィア文庫の一冊として出版されている)の「波と風と」の章にアインシュタイン来日の話を記しているが,

アインシュタインが折角京都で講演したのに、私は聞きに行かなかった。

とはっきり述べている。このように当人がはっきり述べているのだから,Wikipedia の記載は明白な誤謬である。それもそのうち正さねばなるまい。

なお,後に三高で湯川氏の同期生となった数学者小堀憲(あきら)氏は講演を聞いたそうである,とも述べているが,そちらはアインシュタイン氏の講演を聞いたにもかかわらず,理論物理学ではなく数学の道に進んだのであるから,講演に感銘を受けた当時の日本の青少年が理論物理学を志すという「アインシュタイン効果」のほどがますます怪しくなってくる。

湯川氏と同世代の物理学者といえば朝永振一郎氏がすぐに思い浮かぶが,幼少期の思い出を記した文を探すのは少し手間がかかりそうであるので,その作業は保留にしたい。

近年,ノーベル物理学賞を受賞した南部陽一郎氏は 1921 年生まれで,アインスタイン博士来日は大正十一年の十一月,つまり 1922 年のことであるから,1 歳ほどの幼児がそもそもアインシュタインの講演を聞いたとは思われない。一般ゲージ理論の生みの親である内山龍雄氏といえども 1916 年生まれで,6 歳,現在でいえばちょうど就学児童になるばかりの頃に講演を聞いて早々に将来の道を決めたとはありそうにないことである。

そんなわけで,日本物理界のどんな大御所が実際にアインスタイン効果を受けたのか,という別の興味が湧いてくるが,今流行りの AI の助けを借りるなどすれば調査がはかどるであろうか。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

場合分けと 2 進数。

2024-04-10 16:19:32 | 情報系
場合分けが複数あるとき,各場合に一意的な識別番号 (id) を割り振って,その id がこれこれのとき,こうしろ,といった具合に作業を整理すると考えやすいように思われる。

そのような番号の割り振りをどう行うかについてであるが,まず,ある状況が,Cnd1 から Cnd N までの N 通りのいずれか一つに当てはまる,といった,あらゆる状況をすべてカバーした場合に分けられているものとする。

そのとき,例えば条件が Cnd 1 から Cnd 4 まであるとして,Cnd 1 と Cnd 3 は成立するが Cnd 2 と Cnd 4 には当てはまらないような場合には 1010 というコードをあてがう。

あるいは,Cnd 4 のみ成立し,他はすべて成り立たない場合は 0001 をあてる。

これは,ちょうど N ビットの 2 進数の,上から数えて k 番目(最上位を 1 番,最下位を N 番とした場合)のビットを,Cnd k が成立するなら 1,成立しないなら 0 と置くやり方である。

このようにすると,N 種類の条件が成立するかしないか,区別できるのは 2N パターンあるわけだが,それらをちょうど N ビットの 2 進数で識別できるようになる。

数学で同じようなアイデアに出会うのは N 個の要素だけを持つ有限集合の部分集合が何通りあるかを数え上げるときである。その集合の各要素につき,それを入れる,入れないの 2 通りの状態が考えられるので,場合の数の積の法則により,部分集合が全部で 2N 個あることがわかる。

今回の作業用の識別子という言い回しで,私はベルトコンベアーに載ったバーコード付きの商品を思い浮かべるのである。

バーコードを機械が自動的に読み取り,その内容に応じて行き先を分岐し,商品は行き着いた先でそれぞれの加工を受ける,といった様子を想い描いているのである。

なお,このようにしておくと,例えば条件 3 が成立しているような場合全体を一括して扱いたい場合は,識別子の上から 3 番目のビットが 1 であるような場合かどうかを調べる,といったシンプルな処理が可能となる。

そもそも機械語あたりで必須と言えるであろう,とある処理の結果や,システムの状態をフラグなるもので表すという発想が,私が言うところの識別子に他ならない。

そんなわけで,ここで述べたようなアイデアはおそらく至る所で使われている,基本的なものに違いない,と期待している。
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

CASL II で FizzBuzz る。

2024-04-10 12:03:01 | 情報系

FizzBuzz 問題とは



基礎的なプログラミング能力が身に付いているかどうかを確認する試金石として,次のような問題が知られている。

1 から 100 までの数を順に表示するプログラムを作れ。
ただし,3 の倍数は数字の代わりに Fizz,5 の倍数は Buzz,3 と 5 の両方の倍数のときは FizzBuzz と出力するものとする。

これはもともと,複数人が集まった時に順に数字を言い合う遊びとして知られるものだそうで,2007 年に Imran Ghory という人がブログでブログラマ志望者を篩い分けるのにちょうどよい課題ではないかと提案したのが,プログラミングの世界における FizzBuzz 問題の起こりである。(後述の「起源」の項目を参照のこと。)

この問題を自力で解きたいという方は,以下の「出会い」と「起源」までは目を通していただいても構いませんが,それ以降は読まないことをお勧めいたします。

なお,通常は 1 から唱え始めるもののようだが,0 から始めるとすれば,それは 15 の倍数なのだから,ゲーム名の「FizzBuzz!」を叫んでゲームを開始することになるので,trivial かつ「ど」minor な改変として,「0 から 100 までの数」にすることを提案したい。

FizzBuzz 問題との出会い



私が初めて FizzBuzz 問題というのに触れたのは 10 年ほど前かなと思って自分のブログ記事を検索してみたら,7 年前の秋のことであった。

そこには,十進 BASIC で作った解答が載せてある。

今回はそれをオワコン(号泣)の CASL II で書いてみようというわけである。

なお,十進 BASIC の方は保守が非常に行き届いており,久々に公式サイトを覗いてみると,Mac や Linux (Intel 系?),Raspberry Pi なんていう変わり種にまで移植されていて,オラびっくりこいただよ。

極めつけは Chromebook かな。ちょうど一年前に Chromebook を購入して(使い辛いので全く使っていないが)試した覚えがある。私が買った機種は Arm 系の CPU だということを突き止めるのに小一時間費やしたが,無事に十進 BASIC が稼働して感激したのは懐かしい思い出である。もっとも,Chomebook では設定画面で開発者モードとかそんな感じのをオンにすれば Linux が使えるので,十進 BASIC が Linux に移植された時点で Chromebook もオマケで参加に入ったということであろう。

余談ついでに,CPU の違いは OS が吸収してくれるものではないかと思っていたのだが,そういうものでもないらしい。一番人間に近い側のアプリにおいて OS や CPU の違いを意識せずに済むように,OS が中間管理職よろしく,ヒトとハードウェアの間を取り持つ「被せ物」になっているという私の素朴な認識は正しくないということなのだろう。

ところで,7 年前ならばまだ CASL II が現役でブイブイ言わせていた時代(今となっては晩年と言い表すべきか)なので,そのときに CASL II で FIzzBuzz に挑戦するのが妥当だったであろう。当時の記憶は全く残っていないが,11 月 1 日付けのブログ記事であることから察するに,その季節は例年後期の半ばの大学祭休みで体調を崩すので,そんな中でちょこっとだけ遊んでみたといった程度であったろう。しかるに,ろくにマスターしていないアセンブラ言語なんぞを学び直そうという気力はなかったに違いない。


FizzBuzz 問題の起源



ついでながら,7 年前に参照した Jeff Atwood 氏のブログ記事 "Why Can't Programmers..Program?" の日本語訳が読める日本語で書かれたブログはいくつか健在である。この記事を書いている現在,日本語版の Wikipedia の Fizz Buzz の項目には,FizzBuzz 問題の解答となるソースコードを書けるかどうかでプログラマ志望者を選別する面接手法を Jeff Atwood 氏のブログ記事に由来すると記しているが,それは誤りである。

上に引用した "Why Can't ..." の記事において,Atwood 氏は Reginald Braithwaite のブログ記事 "Don't Overthink FizzBuzz"(「FizzBuzz 問題について深刻に考え込まないようにね」といった意味合いだろうか)を読んだ感想から始めている。

その引用元である Reginald Braithwaite 氏のブログ記事は,Imran Ghory 氏のブログ記事から,自身のジャグリングに関するブログ記事をたどってきた人たちがいることに気付いた,という出だしで始まっている。その Imran Ghory 氏のブログ記事は,かつて Imranontech.com というドメイン名のサイトに掲載されていたと見られ,Atwood 氏と Braithwaite 氏はともにそのサイトへのリンクを貼っているが,2024 年 4 月現在,そのドメインは空き家となっている。代わりに imranghory.org というサイトがあり,そのトップページに,

In 2007 I invented the Fizzbuzz interview question for developer competence.

と記しており,そこに貼られたリンク先には,Fizz Buzz Test というタイトルのまとめ記事(スマホ向けのレイアウト??)があるが,そこで Source として挙げられた元記事 "Using FizzBuzz to Find Developers who Grok Coding" へのリンクは wordpress のブログ記事のように見えるものの,やはり売りに出されている Imran On Tech (imranontech.com) にリダイレクトされてしまうので,現時点で私はこれぞという原典にたどり着けないままでいる。

ただし,Jeff Atwood 氏に FizzBuzz 問題の提唱者を帰している日本語版 Wikipedia の記述は間違っていると判断してよいであろう。それは自称プロオタク (professional geek) の Imran Ghory 氏であると訂正せねばなるまい。なお,とりあえず英語版だけ確認したところ,FizzBuzz 問題の由来に関しては 1 ミリも記述がない。というか,プログラミングにおける FizzBuzz 問題の項目自体に一つも出典が明記されていない。

ところで,FizzBuzz という単語でネット検索をすると様々なプログラミング言語,および,様々な「縛り」を課した下での解答がたくさんヒットする。まさにそのような方法で個別にプログラムを収集することは可能であるが,いろんなプログラミング言語における解答をまとめたサイトがあると面白いかなと思う。先ほど触れた Fizz Buzz Test というサイトはややそれに近い。最近,hello, world プログラムの Wikipedia 記事も読む機会があったが,英語版の方には,サンプルプログラムとして hello, world を挙げている数多くのプログラミング言語の Wikipedia 記事へのリンクリスト (Wikipedia articles containing "Hello, World!" programs) が掲載されているので,それらを覗きに行くだけでもとても楽しいブラウジングができそうである。残念ながら日本語版にはそれがない。手打ちで作成したのだとすると大変だが,そのようなリストを自動生成する方法があるようなら日本語版にも同様のリストを追加したいものである。Wikipedia の書き方のヘルプ項目のうち,リンクの項目を見たとき,「東海大学」のページに対して 4,000 以上のリンクが貼られているなどの話(Wikipedia: リンクのしすぎで危機状態)が載っている項目に行き着いたことがある。それをどうやって調べるかというと,Wikipedia の各項目のページにある「元リンク」というメニューをクリックすると,その記事にリンクを張っている,Wikipedia 内の他のページの一覧が表示されるのである。それをうまく使えば hello, world プログラム一覧が容易く作成できそうな気はしている。が,それをすぐにどうこうというわけではない。

他に,全く別の記事であからさまな誤り(と思しき記述)が記載されている項目もあるのだが,そちらももう少し調査を詰め次第,訂正するつもりでいる。


CASL II で解答を作る際の困難



本題に戻ろう。

仮想アセンブラ言語 CASL II で Fizz Buzz プログラムを作るのは,なかなか大変である。

Fizz Buzz プログラムというのは,1 から 100 までの数を順に表示するプログラムであるが,3 の倍数で 5 の倍数でないときは Fizz,3 の倍数でなく 5 の倍数のときは Buzz,そして 3 と 5 のどちらの倍数でもあるとき,つまり 15 の倍数のときは FizzBuzz と表示せよ,という条件付きである。

それをどう実現するかを,プログラミング志望者は自分が知っているプログラム言語で,与えられた制限時間内にプログラミングしなければならない,というのが,プログラマ採用面接試験でほどよい課題ではないか,という話である。実際に企業等での採用面接現場においてどのくらいこのテストが行われてきたか,もしくは行われているかはわからないが,何がしかのプログラミング言語の基礎的なことを一通り学んだ後での演習問題としては手ごろであると思う。

その理由として私が考えるのは次の通りである。


  1. 番号を 1 から 100 までカウントするのに,通常,for 文のような基本的なループ制御が必要となる。
  2. 番号が 3 の倍数であるかどうかといった判定に,四則演算,特に,ある数がある数の倍数であるかを見分ける方法が必要となる。
  3. 番号が 3 の倍数であって 5 の倍数でなければ Fizz と表示する,といった,if 文のような基本的な条件分岐制御が必要となる。
  4. 条件分岐の際に,あるデータが指定された条件を満たしているかどうかの判定が必要となる。
  5. 結果をモニタ等に出力する,基本的な入出力の方法が必要となる。


かなり細かく分ければこんなところであろうか。

ここで,CASL II というアセンブラ言語において,もっともハードな項目は 5 である。

CASL II では OUT というマクロ命令を使用して標準出力(パソコンなどの画面と考えてほぼ差し支えないが,Windows にしろ Linux や Mac にしろ,実際にはモニタ画面上に表示される「窓」(ウィンドウ)などで結果を表示する,などと述べるのがより正確であろう)に文字列等を表示することができるが,現存するシミュレータの中には OUT 命令をサポートしていないものもあるため,自作プログラムの動作確認があまりお手軽ではない。

そういった環境問題だけでなく,CASL II そのものに由来する大問題が一つある。それは,カウンタ番号を数字として表示するのが一番難しいということである。

実は Fizz だの Buzz だのといった文字列を表示する方が簡単なのである。CASL II では文字定数というものが使えるので,
         OUT F3,LEN
F3     DC 'Fizz'
LEN  DC 4

のような命令群で,標準出力装置に Fizz という文字列を表示することが可能である。

OUT F3,LEN というのは,F3 というラベルが貼られた番地内のデータを,LEN で指定された文字数分だけ標準出力に出力せよ,という命令であって,表示したい文字列そのものを文字定数という形式で 'Fizz' のようにそのまま記述することが許される。

なお,CASL II(の最終版)ではリテラル(直値,即値。イミディエイト (immadiate) とも呼ばれる)という記述方式が認められているので,それを利用すると,先ほどの 2 つの DC 命令の行を省いて

OUT ='Fizz',=4

のように記述することも可能である。これは,先に示したプログラム(の一部なので,プログラム片とでも称すべきであろうか)において,F3 に Fizz という文字列を,LEN のところに 10 進表示の数 4 を代入したものに相当する。CASL II の仕様では,むしろ逆に後に示した 1 行プログラムの方を先に示した 3 行プログラムに相当するものに変換してアセンブルされるものとなっている(IPA 公式の資料■アセンブラ言語の仕様「2.5 機械語命令」参照)。

ただし,OUT 命令は機械語命令ではなくてマクロ命令のグループに属するため,1 行プログラムのようなリテラルを用いた記述を許すのかどうかはグレーゾーンである。したがって,OUT 命令でリテラル形式を認めるかどうかはシミュレータ作成者の判断に委ねられるというのが私の見解である。

Daytime さん作のシミュレータでは,リテラルを用いた次のような 1 行プログラムがちゃんと通る。
TEST START
          OUT ='hello, world',=12
          RET
          END

ただし,その挙動には 1 つの疑問が残る。

それは,RET 命令を書くべきかどうかである。初め,私は RET は不要だと考えて書かなかったのだが,シミュレータは作業の終わりどころが掴めないらしく,しばらく経つと hello, world を 2 行目,3 行目,・・・,と延々と繰り返し書いていくのである。どうやら無限ループになってしまっているらしい。

どうやら,END 命令はプログラムの終わりを定義するものの,プログラムの実行の停止を意味するものではないらしい。

そういうわけで,実質的にプログラムの実行を停止させるのは RET 命令のようである。これは,このプログラム TEST を実行し終えたよ,ということで,プログラムを終了し OS に制御を戻す印である(仕様の「3. プログラム実行の手引」内の「3.1 OS (4)」)。今後は RET を書くのをサボらないように気を付けたい。

CASL II シミュレータを自作したいと常々思っているものの,そうしないでいる要因の一つは,仕様を隅々まで正しく理解できている自信が全くないところである。少なくとも私には公式の仕様だけを頼りに,その仕様の通りに正しく動作するシミュレータを作ることは無理そうである。

話を戻そう。Fizz だの Buzz だのを出力するだけならお安い御用だ,ということは分かっていただけたのではないかと思う。

問題は,普通の数字である。Fizz Buzz ゲームは,もとは数人で順番に 1 から数字を言っていき,3 の倍数が当たったら Fizz という,といったルールの遊びなので,我々が日常的に使用している 10 進表示で標準出力に表示したい。

ところが,カウンタ変数内の数字は内部的には 16 ビットの 2 進数として扱われているので,それを 10 進表示の数に直すのには少なくとも 2 つの工程が必要となる。

まず,16 ビットの 2 進数を 10 進表示に直す。具体的には,その 2 進数を 10 進数に直したときの,100 の位,10 の位,1 の位の数を読み取る。

そして,その読み取った結果を 10 進数に見える数字の並びで出力する。これはつまり,数字を文字列として扱うことを意味する。

CASL II の OUT 命令で出力できるのは文字列である。それは内部的には各文字に対応する文字符号(文字コード)という 2 進数として扱われる。

CASL II では JIS X 0201 という規格で定められた文字の符号表を用いることになっている。したがって,例えば,3 の倍数でも 5 の倍数でもない「普通の」数 31 を表示させるには,
 OUT ='31',=2

のような記述が必要である。これをうっかり
 OUT =31,=2

のように書いてしまうと,=31 は 10 進数の 31 に相当する数値,に相当する文字符号とみなされる。

まず,10 進表示の 31 は 16 ビットの 2 進表示で

0000 0000 0001 1111

となる。これを 16 進表示に直すと,CASL II では 16 進数であることを示すのに,冒頭に # を付ける習わしなので,

#001F

となる。この 1 語(=16 ビット)の上位 8 ビットは,OUT 命令においては OS が無視するので 00 であってもなくてもどちらでもよい。

肝心なのは下 8 ビットの 1F の部分であるが,上位の数字が 1 のときは「制御文字」というゾーンに属していて,数字やアルファベット,記号から外れるため,標準出力にはおそらく何も表示されない。

少なくとも,我々が期待する「31」という,3 という数字と 1 という数字の 2 文字からなる文字列は決して表示されないのである。

このようなわけで,2 進数を 10 進数風に変換する手続きと,10 進数として各桁の数字をちゃんと並べた文字列を出力する機構を自前で用意しなければならない,という苦難を無事に乗り越えなければならない。

そんなわけで,CASL II 学習者にとって,この問題は入門コースの卒業試験としてはいささかレベルが高いように感じられる。初級,もしくは中級の試験問題といってよさそうである。

上級コースの試験はさしずめビット列操作であろうか。それは結局,基本情報技術者試験の問題がそれに相当すると言ってよいであろうが。


暫定案



解答のプランのみを記しておく。

2017 年の自分の十進 BASIC による解答と本質的には同じアイデアに基づく。

というか,その記事を書いたことはすっかり忘れていたのに,CASL II のプログラム案を書き上げた今,その記事を読み直してみると,同じ発想に基づいた解答であることに気付いた。中の人が同じであるから当然とも言えるが,無意識に当時考えたことを思い出したのであろう。

1 から 100 まで,カウンタの値を 1 ずつ増やしていくわけだが,そのメインのカウンタだけではなく,次の 2 つの補助的なカウンタを自前で用意しておく。

  • 1, 2, 0 を繰り返す,周期 3 のカウンタ,かっこよく言うと,メインカウンタの値を 3 で割った余りに相当する,mod3 カウンタ。
  • 1, 2, 3, 4, 0 を繰り返す,周期 5 のカウンタ,名付けて mod5.

ただし,CASL II ではラベル名には英大文字と数字しか使えない(ラベル名の最初の文字は必ず英大文字)。また,CASL II には変数という概念もない。実際に使用するのは汎用レジスタと呼ばれるものであるが,プログラムを作成する際に初めから汎用レジスタのどれをどういった役割のカウンタに使用するか,という割り当てをすると,私はこんがらがってくるので,仮に小文字を用いたラベルの変数をこうして用意しておき,一通りプログラムが完成したら,小文字変数ラベルのところを対応する汎用レジスタ名で置き換えていくと作業がしやすいのではないかな,と考えている。

これらのカウンタは,例えば mod3 の値が 3 になったら,その段階で mod3 の値に 0 を代入してこのカウンタをリセットすることにすれば,「3 で割る」といった操作をどう実現すればよいか,頭を悩ませる必要がなくなる。また,このときは Fizz と表示させることも忘れてはならない。

このように,「3 の倍数であるか」,「5 の倍数であるか」という判定を行うのに,除法を用いず,周期 3 や周期 5 のカウンタを用意することで代用するというのは,CASL II だからこその工夫である。なにしろ,CASL II では除法や剰余(余り)を求める手続き自体,自分で一から組まなければならないのである!

さて,3 の倍数であるかどうかだけを判定し,そうであるときとそうでないときとで異なる出力をするということなら問題は比較的単純なのだが,5 の倍数かどうかも考えねばならず,3 と 5 の公倍数であるときにはまた違った動作が要求される(文字列の結合が手軽に扱えるプログラミング言語であれば,公倍数のときに特別な処理を考える必要はない)。

落ち着いて考えれば,このプログラムは 4 通りの異なる出力を行う必要がある。

3 の倍数でも 5 の倍数でもなければ,カウンタの数字をそのまま出力する。

3 の倍数であって 5 の倍数でなければ Fizz と出力する。

3 の倍数でなくて 5 の倍数であれば Buzz と出力する。

3 の倍数であり,5 の倍数でもあれば FizzBuzz と出力する。

こうして並べてみると(表にまとめるのがもっと分かりやすいが),ちょうど 4 通りであるから,2 ビットの符号をこれらの場合に割り当てて識別するのはどうか,というアイデアに自然と導かれるであろう。

例えば,2 ビットの変数 cases を用意しておき,cases が 2 進表示で 00 のときが数字そのまま,01 のときが Fizz,10 のときが Buzz,11 のときが FizzBuzz のように,cases の値に応じて 4 通りのどの出力を行うかを分岐させればよい。

なお,互いに排反な(どの 2 つの場合も同時には起こり得ない)場合に分けてあるので,どの場合に相当するかの篩い分けをする際,関門は 3 つ用意するだけで済む。

というわけで,例えば次のような部分的な擬似 CASLL II コードを書けば良いことになる。
CPA x,y というのは算術比較という命令で,SF (Sign Flag) と ZF (Zero Flag) という 2 種類のフラグレジスタ (FR) の値が,この順に,

x<y のときは 10 に,
x=y のときは 01 に,
x>y のときは 00 に

セットされる。これは x-y が算術減算とみて負になるか,ちょうど 0 になるか,正になるかということに相当していると考えればよいだろう。

このように比較した結果に応じてそれぞれの場合の処理を行わせるには,分岐命令と組み合わせるのが常道である。

このような,「比較演算」+「結果に応じた分岐処理」というのがプログラミングの要である。

そして分岐処理のうちに「跳躍」(飛躍)が含まれていないと,プログラムが冗長にならざるを得ない(for 文や do loop 文なしで if 文だけで,1 から 100 までの数字の和を求めるような繰り返し処理を実現しようとしたら,非常に長いプログラムになりそうである。そう考えると,同型の処理をまとめておいて,それを繰り返し呼び出して用いる for 文などは再帰的な処理の一種とみてよいのであろう)。

というわけで,識別子 cases の値が 01 のときの処理を記すと,
 CPA cases,=1
 JMI NUM ; cases<1 のとき,つまり cases=0 のときはカウンタの値の数字をそのまま出力する処理(ラベルを NUM とした)に移る。
 JZE F3 ; cases=1 のときは ZF=1 なので,この分岐命令で Fizz のみを出力する処理(ラベルは F3)に移る。
 CPA cases,=2 ; 上の分岐命令で飛ばされていないということは cases=10 または cases=11 のときである。
 JZE B5 ; cases=2 のときは ZF=1 なので,この分岐命令で Buzz のみを出力する処理(ラベルは B5)に移る。
 OUT ='FizzBuzz',=8 ; ここまでの分岐命令で飛ばされずにここまでたどり着くのは cases=11 のときだけであるから,FizzBuzz と出力させる。
 JUMP LOOP ; 一連の繰り返し処理の最初に戻る。 

といった感じになる。もちろん,この数行をシミュレータにコピペしただけではプログラムは動かない。というか,そもそもアセンブルエラーが出て,実行以前の状態に留まるであろう。

また,実際の CASL II プログラムの一部として使用する場合には,cases という変数名のところに,汎用レジスタ GR0 から GR7 までのどれか,他の用途に用いていない,空いているものを当てはめて,そのレジスタ名ですべて置き換える必要がある。

ところで,こういう,アセンブラ言語をほんの少しだけ高級にしたものを,アセンブラを通るような正式のプログラムに直す段階に何か名前はついているのだろうか?

アセンブラ言語で書かれたプログラムを機械語に直すのは「アセンブル」というそうで,それを機械ではなく人間が行う場合は「ハンドアセンブル」などというらしい。

cases を GR3 などと手で書き換えていくのはハンドアセンブルに近いので,なんかそういったカッコイイ呼び方があると嬉しい。

今回紹介したかったのは,場合分けをスムーズに行う場合,各場合に対応する「識別子」を自分で設定して,その識別子に応じた処理を別に考えるとよいのではないか,というプログラミング方針である。

そしてそれは 7 年前,2017 年に一度このブログで同じ話題を取り上げたことがあり,その繰り返しになってしまった,というのがオチである。

ともかく,ここにはソースプログラムを挙げないが,普通の数字の表示をさぼって,3 でも 5 でも割り切れない数字は全て * と表示する簡易版は完成しており,Daytime さんのシミュレータで(おそらく)正しく動作していることを確認した,とだけ報告しておく。

Daytime さんの CASL II 講座の方にも解説があるようだが,2 進数を 10 進表示に直すといったミッションについてはまだ考えていないので,そちらの実装もうまくいったら続編を書くかもしれない(し,書かないかもしれない)。


トホホのホ~ (;´д`)
コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする