物理部室の亡霊と、最後の挑戦状

高三

第1章

夏休みのある日、前日の雨とは違い、快晴でとても暑い。今日も高校三年生の私は夏期講習のために浅野に登校している。
また、物理部では今日も文化祭に向けて作品制作が行われている。今日は朝からプラレールを改造している中学3年生の部員のB、同じく中3の部員A、高一で電子工作班員のD、Eなどが活動している。
中学3年生のBは文化祭の準備のために部室にある3Dプリンターを見ると、なにか、QRコードが入った小さな物体が印刷されていた。
「誰か昨日これを印刷した人いますか?」
Bは部員に尋ねるが、皆違うと言った。
これはなんなのだろう。Bはそう不思議に思いスマートフォンでそのQRコードを読み込んでみた。そうしたらアクセスしたサイトに以下のように書いてあった。

我は物理部に棲まう亡霊。君たちに最後の試練を与えよう。我が遺した『宝』を見つけ出したくば、この学舎に散らばる叡智の欠片を集めよ。まず、我らが学び舎の礎を築きし者が見つめる先へ。

「なんだこれ。誰かのいたずらかな?だけれども、実際に印刷までされているからには単なるいたずらではなさそうだ」
そうBは思い部員数人を誘ってみた。
「なんかこのQRコードを読み込んだら物理部の亡霊からの挑戦状が開いたんだけれども、誰か参加する?」
「なんか面白そうなので参加したいです」
そうして中2の電子工作班員(以下電工班員)と中3、高二の数人が集まった。
「『我らが学び舎の礎を築きし者が見つめる先へ。』とあるからには銅像山のことかな?」
Bはそう言った。
「おそらくそうですね」
Gが答え、皆で銅像山に向かった。

(参考)構内マップ

第2章 銅像山にて

(参考 2025年1月撮影) 浅野総一郎像と100周年リング

部員たちは銅像山に登った。
「久しぶりに銅像山登ったな。前に来たのは中1の最初じゃなかったっけ?」
高校一年の部員のEは言った。
「いや、でもまずはどこを探せばいいんだろう?」
「まずはリングを探してみよう」
そうBは提案して、部員一同リングへ登った。
「意外にこっちから海側の景色きれいだね」
Dがそう言っていると、どこかで物音がした。
「あれ、いま銅像山にこの部員しかいないはずなんだがな」
高二の部員が疑問に思った。
「だけれども、あの木の陰に誰かいそうだよ。行ってみよう」
Gは提案した。
部員皆リングから降りて物音がした花壇の近くに行った。しかし、特に誰も見つからなかった。そのまま銅像山を歩いていた時、
「なぜこんなところから振動がするんだろう?」
Gは花壇の中からなにかを見つけたらしく言った。
「なんだ、何だ?」
他の部員たちも集まってきた。
Eがその基盤を取り出して言った。
「あれ、これは高三のK先輩が作っていた自作Arduinoじゃなかったっけ?最後に結局はんだ付けが間に合わすブレッドボードのままで終わってしまったやつじゃん」
「ということは最初に送ってきたやつはK先輩では?」
Aが呟いた。
「多分そうだね」
他の部員もそれに同意した。
しかし、少しして高二の部員のGが言った。
「でもそうだとしたら、このArduinoいつからここにあるんだ?バッテリーは満タンらしいし、更に昨日雨だったからこれを置いたのは多分さっきだったんじゃないかな?」
「でも、K先輩が置いた可能性もあるでしょ」
Aが訪ねてきた。
「いや、先輩が今日は講習があるとか言っていたし」
Gが答えた。
「なら、ちょっと見てきます」
Eが確認に行ったところ、ちょうど夏期講習の授業中だった。
「ということは」
「そうだよ。K先輩じゃない別の人、多分あの木に隠れたやつが置いたんだ」
Gが言った。
そうして部員は銅像山の隅々まで探したが、結局誰も見つからなかった。そのため、部員は再びブレッドボード上で組まれた自作Arduinoに集まった。
「何だこの部品は?なんか見たことないやつがついているぞ」
Bがスマホでその部品の型番を調べた。
「これは調べたところ、コンパスモジュールらしい。もしかして基盤を回すと……」
そう言ってArduinoの基盤を動かすと特定の角度の場所で緑色のLEDが強く光った。
「というのは次はこの向きですね」
Gが叫んだ。
「ただそっちの方向って何があったっけ?」
Eが問いかけた。
「向こうには校舎とかがある気がしますが……」
Gが呟いた
「あのリングの上からだとそっち側がよく見えるかな?」
そうEが提案して、部員たちは再度リングに上がった。
「あ、ここからグラウンドが見えます。更に方向もあっています」
Eが叫んだ。
「そうだ。グラウンドだ。」
部員たちはグラウンドへ向かった。

第3章 グラウンドにて

(参考 2024年11月撮影) グラウンドからの中学棟

部員たちは銅像山を降り、グラウンドに向かった。
「あれ、今日は誰もいませんね」
「今日は合宿に行っているのでしょうか?」
「といってもグラウンドって言っても結構広いですよね」
「なら手分けをして探しましょうか?」
グラウンドについた部員たちは手分けをして次のヒントを探すことにした。
BはAと一緒にグラウンドのトラック付近を探すことにした。
「なにか隠れているとしたらベンチかな?」
そう言ってベンチ周辺を徹底的に探した。
「ここからの中学棟ってきれいだね」
しかし、何十分探しまくっても何も見つからなかった。
「一旦大階段下に戻りますか」
Bらが戻ったらそこには部員たちが再度集まっていた。
「いや、今日はとても暑いですね」
Eが汗を流しながら呟いた。
「向こうの方を探しましたが、見つかりませんでした」
Dがため息をついた。
「実はグラウンドじゃないのかな?」
Eは言った。
「いや、Arduinoはこっちを指していたぞ」
その時だった。突然Aのスマホに次のような通知が来た。

我は亡霊だ。今、お前らはグラウンドにいるな。ただ、そこじゃないんだ。もう一度最初のところに戻り給え。

「何だこれは?」
Aは驚いて叫んだ。
「ということは誰か私達のことを追跡しているということだな」
「なら、K先輩が犯人ではないということだな。実際、まだ休み時間になっていないはずだし、流石にあの真面目な先輩が講習を逃亡することもないだろうし」
Gが言った。
「どちらにしろとも銅像山に戻ってみるしかないな」
そのようにDが提案して部員たちは再度銅像山に登った。
「最初の場所って実は花壇のところのことかな?」
「それならこの方角ってどこを指しているのかな?」
Bはスマホを取り出してマップを開いた。
「この方角だと本館と中学棟の間の通路を通って…… あ、清話書林(図書館)だ」
「そっちだったのか」
そう言って部員たちは清話書林に向かった。
「といってもこの亡霊、結構いろいろなところに誘導しますよね」

第4章 T-steam:Pro

清話書林に着いた部員たちは手分けをして次のヒントがないかどうかを探し回ることにした。
「今度はどこに隠してあるのだろう?」
Eは疑問に思いながら本棚の上などを探していた。
「流石にすべての本を探すわけにはいかないしな」
その時、2階の物理関連の本棚の通路に、なにか紙切れが落ちていた。
「なんだろう、これは?」
そこには次のように書いてあった。
『部室に行き、昼食をとり、13時に倉庫の奥にある作品を準備したまえ』
Eは部員を集めて部室に戻った。部室に戻ったら電子工作班員のFがいた。
「あれ、Fさん、どうしたのですか?」
Dが尋ねた。
「いや、今日はちょっと寝坊してこの時間になってしまったんですよね」
「ちなみに、文化祭で展示予定のドローンの出来はどうですか?」
「家で試験飛行は一応成功して、あとはどうやって展示するのかを考えているところです」
「あと、今、『物理部の亡霊』から挑戦状が来ているのですが参加しませんか?」
「いやあ、今、別の作品で忙しいので断ります。物理部恒例ですが、夏休み中に遊んでいると作品が完成しないので」
Fは丁寧に断った。そのため、残りの部員たちは昼食後、再び亡霊からの挑戦状を解くことにした。
「倉庫の奥にある作品って何でしょうね」
Gが疑問に思って呟いた。
「まずは倉庫に行ってみないと」
Dが答えた。部室の隣にある理科倉庫には去年の文化祭で使用した作品や作りかけのもの、更には残骸も転がっている。
「この中から探せってことでしょ、どれだろうかな?」
「あれ、あそこになにか紙が貼られている作品がありますよね。昔の先輩のLEDキューブですね」
Dが言った。
「いつも文化祭で使い回されているやつですね」
Eが言った。
「この紙はこれを準備しろってことで貼ったってことかな?」
「なら準備しますか」
そう言ってEは倉庫に眠っているLEDキューブを持ってきた。
「これでどんな指示が来るのだろうか?」
しかし10分程度経っても何も起きなかった。
「実はこれは違うのでは」
Gが言った。その時だった。突然部活にあるスピーカーから爆音が鳴り、次のような機械音声が流れた。
『今すぐT-STEAM:Pro 2024で使用した車を廊下に準備し、電池を接続せよ』
「このスピーカーはブルートゥース接続だから犯人は近くにいるな」
Dが豊島岡女子学園が主催したT-STEAM:Pro「障害を回避する自律走行型ロボットを開発せよ!」で制作した車を準備し、廊下に置いたら突然走り出した。
「この車どこに行くんだ?」
「まあ、ゆっくり追いかけますか」
Gが提案した。車はそのまま廊下をゆっくり走っていき、アリーナの方へ向かった。
「でも、この動き、大会と同じ感じですね。ということはプログラムを書き換えていないってことですかね」
そう大会に参加したメンバーの1人のDが思った時、車がちょうどアリーナの入口につながるスロープを登ろうとしていた。
「大会の時、実は坂が登れずに、そこでギブアップしてしまったんですよね。一応モーターのトルクは足りていたのですがコードのほうがミスってしまっていて……」
Dが呟いた。
「それならこれもまた登れないのでは?」
Gが言った。しかし、車は突然速度を上げて坂を勢いよく登りきった。
「というのは誰かがコードを書き換えたってことだな」
車はアリーナに入り、階段に近づき、そのまま階段を転げ落ちた。
「危ない、壊れるところだった」
Bはすぐに車を取った。
「実際にテストのときに何度も机から落としたり壁に激突させたりして何度か壊していているんですよ。これ何号機で知ったっけ?」
Dが呟いた。更に車は電池切れになってしまって動かなくなった。
「ただ、この先どうすればいいのでしょうか?」
Gが呟いた。
「なんかあそこでモーター音がしませんか」
Dが言った。
「なんかするな、行ってみよう」
Bは部員を連れて、アリーナの2階に降りた。
「なんかドローンが飛んでいるぞ」
Bが叫んだ。
「あれ、これって誰のドローンだっけ?」
Gが言った。
「Fさんのですね」
Eが答えた。
「でも、Fはどこにいるんだろう」
こういったすぐにドローンはアリーナの2階のランニングコース上に止まった。
「あそこになにかあるのかも、行ってみよう」
ランニングコース上には小さな封筒が落ちていた。
「『物理部員へ』って書いてあるよ。何が入っているのだろう」
Eが封筒を開けてみるとUSBメモリが入っていた。
「部室に戻ったらパソコンに刺してみよう」
そう言ったらまたドローンが飛び出した。
「あ、あそこにFがいますよ」
Bが1階のアリーナ入口を指差して叫んだ。部員は1階のFと合流した。
「Fさん。物理部の亡霊はあなたでしょうか?」
Gが聞いた。
「てか、さっき部活で活動していましたよね。どうしたのですか?」
Dが聞いた。
「実はこれは別の人に頼まれて実行したのですよ。今日は意図的に遅めに来て、裏でBが3Dプリンターを触ったのを見てゆっくりと銅像山に向かったのですよ。それであのArduinoを花壇に隠して裏からみんなのことを見ていたんですよ」
「なんか物音がしたのはあなただったのですね」
「バレてしまいましたか。その後、みんなのことを追跡していたのですが何故か皆さんグラウンドに向かいましたよね」
「はい」
「一応これも予期していて、今日は暑いから10分程度したら通知を送って退避させると指示があったのですよ。流石にこれには気がついてくれらしく良かったです」
「その後、清話書林に行きましたがそれは見ていたのですか?」
「いや、その後、部室に戻って誰もいないことを確認して普通に作業をしていました。実はこのドローンの最終点検をやっていたのですよ」
「あのスピーカーから鳴らしたのもあなたですか?」
「そうですね。その後、T-Steam:Proの車を追いかけてゆっくりアリーナに向かっている間に高校棟1階を通って先回りしていました。みなさんがちょうどドローンを飛ばし始めたときに来てしまって少しびっくりしてしまいました」
「ちなみにこの依頼人は誰かな?」
「依頼者にこれ以上言うなと言われているのでこれ以上言えません。あと、USBメモリ見つけましたよね?あの中身は見てみましたか?」
「このあと部室に帰ってやる予定です。これに参加してくれますか?」
「別に構わないよ。だって実はこのUSB準備していないし」

第5章 生成AI

部室に戻り、USBメモリをパソコンに差し込んだら「problem.html」というファイルがあった。
「なんだろうこれは?」
Bが尋ねた。
「まずは開いてみましょうか」
Fがこう言い、ファイルを開いた。

「なんだこのiとかは」Bが言った。
「いや、これは競プロ(競技プログラミング)の問題だ。C君なら解けるよね」
Gが言った。

「まずはXから順に求めます」
Cが解説をしながらコードを書き始めた。

『東側のビルの方が高い』は 『西側のビルの方が低い』と言い換えられます。なので、後ろの要素が前の要素よりも小さいものの組の数、すなわち数列Hの転倒数を求めます。転倒数を求めるのには競プロでは一般的にはBIT(Binary Indexed Tree)が使われています。しかし、この問題のHの要素の上限が\(1e9(10^9)\)であるため、そのままBITに乗せることはできないため、BITに乗せるために、座標圧縮をします。この場合、計算量は\(O(NlogN)\)になり、十分高速であり、実行時間にはなんとか間に合うはずです。

「流石に競プロをやり込んでいるだけあって早いね」
Cが素早くコードを書いていったので部員たちは驚いた。

「次にYを求めます。各ビルjに対して、すぐ西にありjより高い、最も近いビルiを愚直に求めるとします。この場合、普通に求めると\(O(N^2)\)になり、実行時間制限に引っかかってしまいます。そのため、stackを使い、各\(j\)について、\(j=0\)から\(j=N-1\)まで順に以下の操作をすることによって、計算量を削減します。
1.西にあるビルを近いもの(stackのtopにあるもの)から見る。
2.もしビルjよりも低い場合、stackから削除する。
3.もしビルjよりも高い場合、それがビル\(i\)となる。
4.ビルiが特定できたら、stackに\(j\)を挿入して、次の\(j\)を試す。
2番目の操作をしていい理由は次のとおりです。ビルjについての操作をしている時にstackから削除する要素の1つをkとするとき、\(H_k<=H_j\)かつ\(k<j\)である。なので、\(j<l\)であるlについての操作の時、\(H_l<=H_k\)であったとしても、\(k\)より\(j\)の方が東にあるので、\(k\)がすぐ西にありlより高い、最も近いビル\(i\)にはなり得ない。よってstackから削除しても問題ないです。
stackでは1つ要素を見る度に、
1.stackからその要素を削除する
2.\(j\)を1つ進める
のどちらかの操作が行われ、それぞれ高々\(N\)回までしか行われないため、計算量は\(O(N)\)となり、十分高速であり、実行時間に間に合うことができます。

Cがコードを書き終えた。
「これでいいだろう」
コードを実行したら「正解」というダイアログが出たあと、ページが遷移した。

見事だ。だが、これが最後の問いとなる。 この6枚の夕日のうち、一つだけが人間によって撮影された 『本物の夕日』 だ。 残りはAIが生成した偽物。一度選んだら、もう後戻りはできない。慎重に選んでくれ。

「なんかこんな感じのやつを去年先輩が論文を書くためにということでやっていたな」
「まあ、これを解けというからには解きますか」
Gが言った。
「パット見た感じどれも写真ぽいけれども……」
「1つずつ拡大して見ていくか」
「まず、5番だけれども雲の感じなんか違う」
「そうだね、よく見たらなんか雲がおかしいね」
「次に、4番だけれどもなんか太陽が正確な円ではないのは?」
「いや、でもこれは写真の撮り方の問題もあるかもしれないけれども、いや、どう見ても雲の上下で分割しているな。ということはこれもAIかな?」
「そんなこと言ったら3番もなんか雲の上下で太陽が別れていない?」
「いや、これはそうでない気もするがな」
「多分前の論文の時の調査の感じ、K先輩の問題ならおそらく答えは1か2つだと思われます」
Gが言った。
「更に1番も雲の形が違うからおそらくAIだな」
「と言うことで、残った奴らは2,3,6番だな」
「Gが言うには解答は多くても2つということだな」
「2番もなんか画質荒いしAIでは?」
「なら3番もなんか太陽がおかしいよね」
「ということは、6番だね」
そう言って6番の画像をクリックした。しかし、数秒間何も起きなかった。
「押せていなかったのかな?」
その時だった。パソコンから突然爆音が鳴り出して画面には「不正解」と表示された。
「え、違うの?」
他のものを選択しようとも選択できない。
「まあ、リロードすれば……」
こうGが言ってブラウザの再度読み込みボタンを押したが特に何も変わらなかった。
「なんか仕組まれているかな?」
そう言ってhtmlのソースを開いた。
「なんかコメントが書いてあるぞ」


1
2
3
4
5
6
7
8
9
やはりこの問題は間違えたか。私が去年の論文を書いたときよりも画像生成AIが進歩したから相当難しかったかな?  
それぞれの画像は以下のAIで生成したものだ。  
1. Imagen 4.0 Ultra Preview 0606  
2. FLUX.1 Schnell  
3. 写真(https://publicdomainq.net/photo-sunset-sky-0083979.jpg)
4. GPT Image 1  
5. DALL E3  
6. Imagen 3.0 002  
あと、これを企画したのも私だ。まずはクイズに正解してくれよ  

「やっぱ亡霊はK先輩でしたね」
「ただどうやって再チャレンジしましょうか?」
「これってコード内にlocalstorageっていう文字が書いてあるからブラウザに結果を保存しているのでは」
Gが言った。
「なら別のブラウザで開けば問題ないですね」
そうDが言って別のブラウザでファイルを開き直した。
「コメントに書いてあった通り3番ですね」
「でも、他のものも結構本物っぽいですが」
「これもコメントに書いてあったとおりですが、去年の調査では一部難しいのがあった程度ですが1年もすればAIが更に進化して見分けが難しくなってきた、てことですね」
「なら、あと数年したらどうなってしまうのだろうかな?」
「更に難しくなってきそうですね」
「まあ、そんなことは良しとして早くクイズを解きましょうか」
そう言って3番を選択した。
『正解です。』
「では『物理部の亡霊』のところに行くぞ」

終章

(参考 2025年1月撮影) 高校棟から

部員たちは先輩が自習している高三フロアにやってきた。
「いたぞ、今勉強しているから迷惑かな」
そう思ったらちょうど先輩が問題を解き終えたみたいで立ち上がった。
「あ、先輩、実は物理部の亡霊って、あなたのことですか?」

ああ、実はそうだよ。私は中1からずっと物理部にいて様々な活動をしてきた。中1では何をやったのかちゃんと覚えていないけれども、中2ではプラレールの改造をやってみた。高一では文化祭の時にコロナにかかってしまい参加できず、作りかけの作品を投げ出してしまった。高二では自作Arduinoが中途半端に終ってしまい、その後やろうとしていたことができなかった。一応高二の文化祭のときに卒論と称して『生成AIの生成物を見分けることができるのか』という部誌のためにアンケートを取ったが、それも正直完全に納得がいく形にはならなかった。更にT-Steam:Proでは中3の頃に先輩のお陰で優勝できたが、高一は専門領域外だったから仕方がないが、専門領域だった高二でも敗北してしまった。敗因はメンバーの1人のDから聞いていると思うが、最後に急いでコードを編集してテストができなかったため、モーターの出力を下げすぎて坂が登れなかったからだ。ちなみにあのコードは別のときに展示するために修正しておいた。これらの理由から、今でも文化祭で遊ばれているゲームを作った先輩や、今でも文化祭で展示の中心となっている作品を作った電工班の先輩などの他の先輩とは違い、あまり伝説を残すことができなかった。だから、最後に少しでも伝説を残そうと計画したんだ。協力者のFから話は聞いたが、みんながうまく協力してここまでたどり着いたみたいだね。後輩がうまくやってくれるかが少し心配だったがうまく協力してここまでやってきてくれて安心したよ。

Kが答えた。
「いや、こちらこそ。わざわざ忙しい時間を使って準備までしてもらって」
「あ、すまんがそろそろ次の問題をやらないといけないんだ」
「あ、ならすみません。今日はありがとうございました」
部員たちが教室から出ていき、私は参考書に目を落とした。自分の本当の戦いは、まだ始まったばかりなのだから。

次へ編集後記>
前へCPUの創り方 in Python>