BFmeta で遊ぶ

この記事は Brainf*ck Advent Calendar 2019 の 14 日目です。昨日はあんでぃさんの『brainfuck でオセロを書く(後編)』でした。

adventar.org


(自分語りパートです。)

こんにちは。去年 AtCoderBrainfuck の提出をしまくって Language Owner に載ったものの、最近サボっているため 3 位を脅かされそうになっています。やっぱりこういうのは継続が大事ですね。

最近 Brainfuck を書いた場面といえば、先月学園祭があったのですが、自分の所属しているプログラミングサークルではプログラミングをテーマにした生放送をやっていました。そこに「実用プログラミング言語・難解プログラミング言語コードゴルフで戦う」という企画があり、プレイヤーとして Brainfuck を書きました。まあ制限時間がシビアなので、お題を満たすコードが書けたらゴルフせずに次の言語に移ったんですけどね……。詳しい話は別の記事でも書いています。あと 18・19 日目の Szkieletor さんの話でもその辺りに触れられると思います。

本題

さて、世の中には Brainfuck の命令を置き換えたり命令を拡張したような有象無象の派生言語がある中(そこまで強く批判しているわけではないです)、当アドベントカレンダーの 3 日目に prime さんがこのような記事を書いてくれました。

primenumber.hatenadiary.jp

というわけで BFmeta で遊んでいきたいと思います。

インタプリタ

まず自分はブラウザ上でなんでもやりたがる人間なので、ブラウザで動かせるインタプリタを作りました。

n4o847.github.io

といっても急に作ろう!となったわけではなくて、上で触れたサークルに現在「コードゴルフ分科会」というのがあって、そこで難解プログラミング言語の処理系を各自作ろうみたいな回があったので、それを機に作ったものです。デザインとか機能とかまだ納得行ってないのでこれから直して行きます。

これでスマホでもプログラムが書けますね!

はろーわーるど

公式にはこんな Hello World が載っています。

[>]<<<<<<<<<<<<<[.>]Hello World!

ヌル文字を許容すると

[>]>[.>]\0Hello World!

(これ試してみたのですが、 < が一個多いような?) ←改行の分だそうです。

まずは Hello World の他の書き方を探すところから始めます。

Brainfuck ではデータポインタの位置だけ考えれば良かったのが、BFmeta ではプログラムポインタとデータポインタ両方の位置を考える必要があります。Hello World の出力にあたって、プログラムポインタとデータポインタをうまく「分離する」必要があるのですが、単に > だと揃ってしまうので、[>] のようにして何らかの境界にデータポインタを引き寄せなければなりません。

ヌル文字許容版を参考にすると、ASCII コードで扱えるうち文字コードが小さいのはタブ(0x09)や改行(0x0a)なので、そのあたりをデリミタにしましょう。

Hello World!
----------[++++++++++.>----------]

これで (文字数) + 35 bytes ですね。複数行に対応するために、処理を一行目に持ってきたらどうでしょう。

----------[++++++++++>----------]>[.>]
Hello World!

なんとこれは動きませんでした(最初自作インタプリタのバグを疑いました)。エラーをみると Unmatched bracket ] と書いてあるのですが、動きを追うと、[ が 10 減らされたところで ] からジャンプできてないんですね。リフレクション怖い!と思うと同時に BFmeta の可能性を感じるエラーですね。

データポインタを右ではなく左に引き寄せるのはどうでしょう? BFmeta では負のインデックスが扱えることが言語仕様で決まっているので、データポインタを左に追いやればプログラムポインタと別行動をさせられます。

!dlroW olleH>>>>>>>>>>>[.<]

これで (文字数) × 2 + 3 bytes ですね。

もっと考えると、データ領域とプログラム領域を交互に配置することで互いの影響を受けないことがわかります。

[!>d]l<r[o.W< <o]l_l_e_H

これで (文字数) × 2 bytes ですね。そうすると逆に配置する必要もなくなり、

H[e.l>l>o] _W_o_r_l_d_!

これで (文字数) × 2 - 1 bytes ですね。

ところで、よく見るハローワールドはコンマが入っていると思いますが、この例には入っていません。そりゃ、コンマはプログラムに影響を及ぼすので置きたくないですからね。これをごまかさない方法を考えます。

普通の Brainfuck プログラムでコメントアウトしたいときに「メモリが 0 であることが保証されている場所で [ ] で囲む」という手法がありますが、同じように考えて、特殊文字を「エスケープ」することができます。

[H>e.l>l]o[,] _W_o_r_l_d_!

これで、6 文字目以降ならギリギリエスケープできることがわかりました。

以上でわかったのが、「データ領域とプログラム領域を適切に分離することで、今までの Brainfuck と同じように扱える」ということですね。

リフレクション

ここまで来ると、リフレクション、やりたくないですか?

まず命令の文字コードを確認します。

命令 文字コード
+ 0x2B
, 0x2C
- 0x2D
. 0x2E
< 0x3C
> 0x3E
[ 0x58
] 0x5D

命令に使う文字は、 +,-. <=> [\] みたいに分かれてそこそこ近くに集まっていることがわかります。

というわけで、「そこを最初に通ったときとそれ以降に通ったときで命令が変わる」コードに挑戦してみます。

[>]<<<<<[[>[-]>[-]<<[->+>+<<]>>[-<<+>>]]+<<-__.]

これは自己を書き換えることで +- を交互に出力し続けるコードです。

後ろの -_ の部分が、奇数回目に -- 、偶数回目に ++ となります。+ に 2 を足せば - になるのが原理なんですが、2 を足すには 2 回 + を書かなければいけなく、それを「2 を引く」にするには両方に 2 を足さなければいけなく、これでは倍々に増えていってしまうので書き換えた - を右にコピーしています。

こんなんやらなくても +[-.++.-] のほうが早いので、どう活かせるかというと難しいですね。+- の差が 1 だったらもう少しきれいになったかも……。

> とか [ の書き換えはプログラムポインタの位置が変わるので + を考えるより格段に難しいと思います。[ を書き換えると対応を変えられるのでプログラムポインタの大域的な脱出ができたり……とか妄想してますが、よくわかりません。人間の頭で考えられるものなんだろうか……。

誰か BFmeta でできる面白いリフレクション考えてください。

TSG LIVE! 4 ライブコードゴルフ大会 writeup + 解き直し ( Perl, sed, Haskell )

この記事は TSG Advent Calendar 2019 の 7 日目です。昨日(今日)は taiyoslime さんの「2019年駒場祭ライブコードゴルフ(実用言語編)」でした。

adventar.org


駒場祭2019でTSGが催した企画、『TSG LIVE! 4 ライブコードゴルフ大会』に参加した感想です。

↓ライブの様子はこちらからご覧になれます。

www.youtube.com

どんな問題が出たの?

お題

2桁の整数が100個、改行区切りで与えられる。それぞれの数について、九九表に存在するとき1、そうでないとき0を出力せよ。

詳しいルールは https://esolang.hakatashi.com/contests/komabasai2019/rule で見られます。

当日の方針

当日は、C言語><>(フィッシュ)LibreOffice Calc を同じチームである iLiss さんに任せて、自分は中央付近にあるスクリプト言語郡(RubyPerl、Pyrhon、Node.js)を取ったあと、取れる位置にある & 自分が書けそうな esolang (sedBrainfuck、Whitespace) を取る方針で行きました。時間があったら GolfScript に挑戦したかったですが、書いたことのないものを時間内にやるのは難しいですね……。でも書けるものは書ききれたので良かったです。前回 の NoSub を悔やんでいた iLiss さんが今回 C を取ってくれたのはいい話です。

最終的な盤面はこちらです。

f:id:n4o847:20191207191949p:plain

他の記事の宣伝

この問題にはいくつか解法がありますが、中でも作問陣が考えた「符号化」解法は、RubyPython で他の解法の追随を許さない強いコードが書けてしまいます。その解説や、その他実用言語(C言語、Node.js)での解法は昨日(今日)の taiyoslime さんの記事

taiyoslime.hatenablog.com

で書かれているのでそちらを是非読んでみてください。

また、><>(フィッシュ)、GolfScript、Aheui(아희)Tetris による解法は 9 日目に kuromunori さんが、Brainfuck による解法は 18 日目に Szkieletor さんが書いてくれるらしいので、そちらも読んでみてください。

というわけでこの記事では、それら以外で縮めたら面白そうなものを取り上げて書いてみます。

Perl

ライブの最中、視聴者から「39 bytes になった」みたいなコメントがあったらしく……?(未確認)

それを目指していきたいと思います。

競技中に出したコードは以下です。 (55 bytes)

$a=<>,print((grep{$a%$_<1&&$a/$_<=9}1..9)?1:0)for 0..99

これなんで本番で思いつかなかったのか不思議なんですが、ループを行ごとに改善します。 (51 bytes)

$a=$_,print((grep{$a%$_<1&&$a/$_<=9}1..9)?1:0)for<>

変数への格納が長いので、正規表現で捕捉しましょう。 (48 bytes)

//,print((grep{$'%$_<1&&$'/$_<=9}1..9)?1:0)for<>

見つかったかどうかを 1 と 0 に置き換えるのが長いので、// (== 1) と組み合わせて数値に変換します。 (41 bytes)

print//-!grep{$'%$_<1&&$'/$_<=9}1..9for<>

判定部分を改善します。 (39 bytes)

print//-!grep$'%$_<($'/$_<=9),1..9for<>

39 bytes になりました! わいわい

sed

Twitterエゴサすると、 89 bytes になった人がいますね。それを目指していきたいと思います。

sed は演算するよりも埋め込みです。ということで当日 1 回目です。 (312 bytes)

/^\(1\|2\|3\|4\|5\|6\|7\|8\|9\|2\|4\|6\|8\|10\|12\|14\|16\|18\|3\|6\|9\|12\|15\|18\|21\|24\|27\|4\|8\|12\|16\|20\|24\|28\|32\|36\|5\|10\|15\|20\|25\|30\|35\|40\|45\|6\|12\|18\|24\|30\|36\|42\|48\|54\|7\|14\|21\|28\|35\|42\|49\|56\|63\|8\|16\|24\|32\|40\|48\|56\|64\|72\|9\|18\|27\|36\|45\|54\|63\|72\|81\)$/c1
c0

入力が 2 桁であることに気づいて 2 分後に出したのが当日 2 回目です。 (237 bytes)

/10\|12\|14\|16\|18\|12\|15\|18\|21\|24\|27\|12\|16\|20\|24\|28\|32\|36\|10\|15\|20\|25\|30\|35\|40\|45\|12\|18\|24\|30\|36\|42\|48\|54\|14\|21\|28\|35\|42\|49\|56\|63\|16\|24\|32\|40\|48\|56\|64\|72\|18\|27\|36\|45\|54\|63\|72\|81/c1
c0

さて、まだ無駄があります。まずはソートしてユニークします。 (113 bytes)

(1..9).map{|a|(1..9).map{|b|a*b}}.flatten.select{|x|x>9}.sort.uniq.join("\\|")
/10\|12\|14\|15\|16\|18\|20\|21\|24\|25\|27\|28\|30\|32\|35\|36\|40\|42\|45\|48\|49\|54\|56\|63\|64\|72\|81/c1
c0

十の位でまとめてみます。 (68 bytes)

/1[024568]\|2[014578]\|3[0256]\|4[02589]\|5[46]\|6[34]\|72\|81/c1
c0

一の位でまとめると伸びてしまいます。 (76 bytes)

/[1234]0\|[28]1\|[1347]2\|63\|[1256]4\|[1234]5\|[135]6\|27\|[124]8\|49/c1
c0

[1234]0[1234]5 が一緒? (69 bytes)

/[1-4][05]\|[28]1\|[1347]2\|63\|[1256]4\|[135]6\|27\|[124]8\|49/c1
c0

ここで、入力→出力を以下のような表にしてみます。

0 1 2 3 4 5 6 7 8 9
1 1 1 1 1 1 1
2 1 1 1 1 1 1
3 1 1 1 1
4 1 1 1 1 1
5 1 1
6 1 1
7 1
8 1
9

うーん、規則性なし!w

結局十の位でまとめたやつの 3[0256]1[024568] の部分集合なので 67 bytes になりました。

/1[48]\|2[014578]\|[13][0256]\|4[02589]\|5[46]\|6[34]\|72\|81/c1
c0

Haskell

Haskell ゴルフは 駒場祭 codegolf day2 writeup (or Haskellゴルフのすすめ) - Lを探す日常 とかを見て、かねてからやりたかったやつです。

ビット埋め込みはあまり Haskell っぽさが出なくて学習に向いてないと思ったので後回しにします。

まず九九表を生成する方針で愚直に書きます。この時点でちょっとてこずりました。 (103 bytes)

import Control.Monad
main=replicateM_ 100$do
 a<-readLn
 print$fromEnum$elem a[x*y|x<-[1..9],y<-[1..9]]

do 構文を展開してみます。 (100 bytes)

import Control.Monad
main=replicateM_ 100$readLn>>=print.fromEnum.flip elem[x*y|x<-[1..9],y<-[1..9]]

縮むかと思ったけど、 do 構文ってゴルフ的にも結構えらいんですね。

限界を感じたので、「Haskell ゴルフ」とかでググった記事を読み漁ります。すると String -> StringIO () にできる interact がえらいというのが随所で書いてあるので使います。 (86 bytes)

main=interact$unlines.map(show.fromEnum.flip elem[x*y|x<-[1..9],y<-[1..9]].read).lines

え、めっちゃえらい。あと、各行処理は (>>=f).lines が短いらしい。lines :: String -> [String] の各要素を f :: String -> String に渡して、 String[Char] であることからひとつのリストにまとめるんですね! この辺 Haskell って感じでめっちゃいいですね。 (78 bytes)

main=interact$(>>=show.fromEnum.flip elem[x*y|x<-[1..9],y<-[1..9]].read).lines

こうなると九九表の生成も Haskell チックな演算子を使うと嬉しくなる気がします。 (76 bytes)

main=interact$(>>=show.fromEnum.flip elem((*)<$>[1..9]<*>[1..9]).read).lines

ここで、もう一つの解法であるビット埋め込みを試してみると (76 bytes)

main=interact$(>>=show.(`mod`2).div 0x20101814325195b35d400.(2^).read).lines

で並びました。埋め込みを使わなくても並ぶことができたのは嬉しいです。

あとは elem を中置にし、 [1..9] をまとめて 74 bytes です。

r=[1..9]
main=interact$(>>=show.fromEnum.(`elem`((*)<$>r<*>r)).read).lines

fromEnum が長いんですが、ここは関数合成を使っているのでググったテクニックを使ってもあまり縮まなかった……。

感想

自分のコードゴルフ経験は部内の大会以外だと AtCoder 上のゴルフくらいで、そこだと決まった一部の言語で争うことになるので、他の言語を練習するというのもいいですね。Haskell ゴルフは今回始めてやってみましたが、ここで Functor・Applicative・Monad が活きてくるのエモいですね。

上で挑戦したものもまだ縮むかもしれないので、見つけた方はぜひ報告お願いします。

明日は smallkirby さんの「TSGに連れて来られるまでのお話とpwnの学び始めを懐かしんだ後に適当なpwnのwriteupを書いたら発狂して湖に飛び込みYoutuberデビューする予定」です。

追記

コメントの 39 bytes はこれらしいです。

これで各種倍数の判定ができるのは知らなかったので驚きなんですが、色々使えそうなテクニックですね。


Perl 32 bytes が出てきました。

バイト列を直接埋め込んでいるんですねー。当日使ったシステムにはファイル提出機能もあるので有効そうです。


Whitespace で書いていただきました。

本番中はこんなクソコードを書いていたんですが、ちゃんとゴルフすると短くなりますね。

SECCON CTF 2019 QUALS 参加記

SECCON CTF 2019 予選に参加した。CTF のコンテストに出た経験はほとんどなく、普段なら出なかったかもしれないが、smallkirby (@python_kirby) に誘ってもらったことを機に取り組んでみることにした。なんか部の何人かは前回優勝者として作問に関わっていたらしく、だいぶ遠い世界だなあと思ってしまう。

相方は pwn とか rev とかができる人だったので、自分は web を見てみるかーと思ったが最終的には何もわからなかった。結果点数の低い問題を探して解く人になった。

コンテストは日本時間で15時~翌日15時だった。コンテストといえば競プロ、特に数時間程度のアルゴ形式ばっかりやっていた自分としてはどうスケジューリングすればいいかわからなかった。結局、15時~21時まで解き、21時~24時は AtCoder Beginners Contest に出て、24時~6時でまた解き、13時に起きてパソコンの前に座って無をした。

[misc] Welcome / [misc] Thank you for playing!

CTF にはこういう儀式的なものがあるんですね。ド初心者でも 0 より真に大きい結果を残して帰れてほっこり。

[crypto] coffee_break

crypto の中で点数がだいぶ低かったので見てみた。Python で書かれた暗号化プログラムと、フラグを暗号化した結果が与えられる。

暗号化は二重になっていて、1回目は独自の暗号、2回目は AES-ECB というアルゴリズムで暗号化されていた。後者についてググったところブロックごとに独立で暗号化されるらしく、関係あるのかと思ったが、結局計算量が多いことには変わらない。その後の調べで「復号できるんかい!」となり、2回目を外す。1回目の独自暗号はループが文字ごとに独立で回されており、1文字ずつ総当りしていけば解ける。探索が途中で止まったが、思い立って _ を探索に含めたらフラグを得られた。

[misc] Beeeeeeeeeer

難読化されたシェルスクリプトが渡される。実行すると目まぐるしく動くアスキーアートが出てくる。

シェルスクリプト${} とか $(()) とか $'' みたいな部分を展開していくと、長い Base64 データが埋め込まれていて gunzip されている箇所がある。そこを取り出して解凍してみると、また難読化シェルスクリプトが出てくる。このスクリプトに「Beeeeeeeeer」と名付けた。

それも展開していくと、「ビープ音が何回出たかのクイズに答え、それがパスワードになって openssl aes-256-cbc で復号される」という内容であることがわかる。ビープ音(\a)は出せなかったので文字に書き換えて、結果をどこかに出力するようにするとまた難読化シェルスクリプトが出てくる。このスクリプトに「Beeeeeeeer」と名付けた。

次の難読化はちょっと雰囲気が変わっていたが JavaScript 難読化で知っていたものと似た感じだった。この辺ツールか何かで復号できるんだろうか。パスワードを聞かれるプログラムだが、コメントでパスワードが「bash」であることが書かれている。次は「Beeeeeeer」で、「Beer」になるまでやるのかな…と絶望していたが、ここでフラグが出て終了らしい。

フラグは今までの難読化で使われた変数を集めたもので、3回目は bash、2回目はビープ音の最終的な回数っぽかったので 3、1回目は読むと hogefuga だったので入れたら通った。3回をバラバラに処理しているので変数を目で拾っているが、想定解はなんだったのだろうか。

[web] Option-Cmd-U

URL を入れるとそのソースコードを表示するページがある。そこ自体の PHP スクリプトを見られるので見ると、フラグは /flag.php にあるが、内部ネットワークからしか見られないらしい。

ずっと考えてわからず、終了後答えをみたら http://nginx/ が鍵らしい。URL の正規化を利用すると nginx のチェックをスルーしつつアクセスできるらしい。Nginx もよく知らなかったし、完全に知識不足だったので悲しい。

[web] web_search

SQL インジェクションで、特定の文字列は消されてしまうらしい。コメントとかタブ文字とかでやってみたが実行できる文がうまく作れなかった。

感想

ぐええ

きびしいね

でも続けていきたいね

古典ラテン語

随時更新する。

中山恒夫『標準ラテン文法』 白水社 による。

動詞

直接法現在能動相(§6)

(1) (2) (3) (3b) (4)
単1 am-ō mone-ō reg-ō capi-ō audi-ō
 2 amā-s monē-s reg-i-s cap-i-s audī-s
 3 ama-t mone-t reg-i-t cap-i-t audi-t
複1 amā-mus monē-mus reg-i-mus cap-i-mus audī-mus
 2 amā-tis monē-tis reg-i-tis cap-i-tis audī-tis
 3 ama-nt mone-nt reg-u-nt capi-u-nt audi-u-nt
不定 amā-re monē-re reg-e-re cap-e-re audī-re
現在幹 amā- monē- reg-e- cap-e- audī-

不規則動詞(§10)

sum ferō
単1 s-u-m d-ō e-ō fer-ō
 2 es dā-s ī-s fer-s
 3 es-t da-t i-t fer-t
複1 s-u-mus da-mus ī-mus fer-i-mus
 2 es-tis da-tis ī-tis fer-tis
 3 s-u-nt da-nt e-u-nt fer-u-nt
不定 es-se da-re ī-re fer-re

未完了過去(直接法能動相)(§17)

(1): amā-ba-m, -bā-s, -ba-t, -bā-mus, -bā-tis, -ba-nt
(2):
(3): reg-ēba-m, reg-ēbā-s, ...
(3b): capi-ēba-m, ...
(4):
sum: er-a-m, erās, ...
possum: pot-er-a-m, ...
prōsum: prōd-er-a-m, ...
dō: da-ba-m, ...
eō: ī-ba-m, ...
ferō: fer-ēba-m, ...

  • 現在幹に -ba- がつく
  • (3), (3b), (4) は -ēba- がつく
  • 単1、単3、複3は最後が単母音
  • 単1は -ba-m 他は -bā-*, -ba-*

未来(直接法能動相)(§18)

(1): amā-b-ō, -bi-s, -bi-t, -bi-mus, -bi-tis, -bu-nt
(2):
(3): reg-a-m, -ē-s, -e-t, -ē-mus, -ē-tis, -e-nt
(3b): capi-a-m, ...
(4):
sum: er-ō, er-i-s, ...
possum: pot-erō, ...
prōsum: prōd-erō, ...
dō: da-b-ō, ...
eō: ī-b-ō, ...
ferō: fer-a-m, ...

  • 単1は -bō か -am
  • それ以外は
  • (1), (2) は -bi- / -bu-
  • (3), (3b), (4) は -ē- / -e-

名詞

第1変化(§8)

fābula fābluae
fābulae fābulārum
fābulae fābulīs
fābulam fābulās
fābulā fābulīs

第2変化(§11, 12)

dominus dominī oppidum oppida
domine
dominī dominōrum oppidī oppidōrum
dominō dominīs oppidō oppidīs
dominum dominōs oppidum oppida
dominō dominīs oppidō oppidīs
deus deī, diī, dī
dīve (deus)
deī deōrum (deum)
deō dominīs
deum deōs
deō deīs, diīs, dīs
puer puerī ager agrī
puerī puerōrum agrī agrōrum
puerō puerīs agrō agrīs
puerum puerōs agrum agrōs
puerō puerīs agrō agrīs

人称代名詞・再帰代名詞(§16)

1単 1複 2単 2複 3再帰
egō nōs vōs
meī nostrī, nostrum tuī vestrī, vestrum suī
mihĭ nōbīs tibĭ vōbīs sibĭ
nōs vōs sē (sēsē)
nōbīs vōbīs sē (sēsē)

注:属格は所有の意味には用いられない。-ī は属格支配の目的語、-rum は部分の属格。

単男  女  中 複男  女  中
is ea id eae ea
ēius ēius ēius eōrum eārum eōrum
iīs (eīs) iīs (eīs) iīs (eīs)
eum eam id eōs eās ea
iīs (eīs) iīs (eīs) iīs (eīs)

注:属格は所有も表す。

その他

接続詞(§7)

  • et, -que, atque (ac)「and」
  • neque (nec)「and not」
  • et ... et ...「both ... and ...」
  • neque ... neque ...「neither ... not ...」
  • sed「but」
  • nōn modo (sōlum) ... sed etiam...「not only ... but also ...」
  • aut, vel, -ve「or」
  • aut ... aut ..., vel ... vel ...「either ... or ...」

前置詞(§14)

対格支配

  • ad「へ,のそばに」
  • ante「の前に,に面して」
  • apud「のもとに,のところに」
  • inter「の間に」
  • ob「の前に,のために」
  • per「を通って,によって」
  • post「の後に」
  • prope「の近くに」
  • propter「のために」
  • trāns「を越えて,のかなたに」

奪格支配

  • ā, ab, abs「から」
  • cum「と,と一緒に,を伴って」
  • dē「から(下へ),について」
  • ex, ē「から(外へ),」
  • prae「のために」
  • prō「の前に,を背にして,のために(利益)」
  • sine「なしに」

奪格・対格支配

  • in「の中に,の上に;の中へ,の上へ」
  • sub「の下に;の下へ」
  • super「について;の上方に,を越えて」

sum と eō の合成動詞(§15)

  • absum「いない,離れている」
  • adsum「出席している;助ける」
  • dēsum「欠けている」
  • possum「できる」(<pot-+-sum)
  • prōsum「役に立つ」
  • abeō「去る」
  • adeō「近づく,訪れる」
  • ineō「入る,始める」
  • pereō「滅びる」
  • redeō「戻る」(<re-+-eō)

  • pos-sum, pot-es, pot-est, pos-sumus, pot-estis, pos-sunt

  • prō-sum, prōd-es, prōd-est, prō-sumus, prōd-estis, prō-sunt

ラズパイをセットアップ(して失敗したり成功したり)した話

Raspberry Pi 3 Model B+ を買ってヘッドレスセットアップした話です。

誰かに教える記事というより、自分用の記録のつもりです。

そういえば、買った 1 週間後に Raspberry Pi 4 Model B がリリースされて草ですね。

準備

買ったもの

まずは電気街に行って、ラズパイ本体を買いました。本体 5600 円+税、ケース 700 円+税 でした。

f:id:n4o847:20190624233155j:plain ↑ 外箱

f:id:n4o847:20190624233216j:plain ↑ ケースに本体をはめた様子

後日、大学の生協で microSD カードを買いました。16 GB で 680 円+税 でした。あまり質を求めていないので、まあこれくらいでいいでしょう。

あったもの

まず LAN ケーブルは家にありました。(まあ最終的に使わないんですが)

さらにラズパイには 5.0 V・2.5 A の電源が必要なのですが、iPad の AC アダプタを代用しました。iPad の AC アダプタは 5.0 V・2.4 A なので大体間に合うかと思います。

USB Type-A と Micro-B の変換コネクタも既にあったものを使いました。

セットアップ(失敗編)

Windows のノート PC を使います。

まず Raspbian をダウンロードします。初心者は NOOBS から始めると良いと書いてあるので NOOBS を ZIP 形式でダウンロードします。1.4 GB 以上あって、40 分くらいはかかりました。Lite はあとから Raspbian をダウンロードするものらしいですが試していません。

Download NOOBS for Raspberry Pi

f:id:n4o847:20190625182627p:plain

次に、microSD カードをフォーマットします。調べた感じだと「SD カードは 4 GB ~ 32 GB だと FAT32、64 GB ~ 2 TB だと exFAT というファイルシステムでフォーマットされているが Raspberry Pi がサポートしているのは FAT16FAT32 である」みたいな理由で 64 GB 以上だとフォーマットのためのソフトが必要らしいのですが、16GB FAT32 なら標準でできるのでやります。

f:id:n4o847:20190625204601p:plain

すぐ終わるので、その後ダウンロードした NOOBS 以下のファイルをすべて microSD にぶち込みます。

f:id:n4o847:20190625185633p:plain

SSH 接続を有効にするために、ルート直下に ssh という名前(拡張子無し)の空ファイルを作ります。

microSD をラズパイに挿して、ノート PC とラズパイを LAN ケーブルでつなぎ、ラズパイを電源につなげます。すると赤ランプが点灯し、緑ランプが点滅します。

arp -a

というコマンドでラズパイの IP アドレスがわかるので、

ssh pi@169.254.215.63

みたいな感じで SSH 接続します。

……が、何度やっても

ssh: connect to host 169.254.215.63 port 22: Connection refused

で失敗しました。ping はつながるっぽいし、ssh ファイルがあることを確認しつつフォーマットを繰り返したり無線 LAN 接続を試したり色々しましたが結局だめでした。

そこで方針を変えて一からやったら成功したので、その方法を記録しておきます。

セットアップ(成功編)

Raspbian を入れるのに PiBakery というのを使う&無線 LAN 接続する方法です。

(上の手順をやってしまった場合)まず、SD カードを初期状態に戻します。

diskpart

を実行して、

list disk :: 確認
select disk (SD カードのディスク番号)
list partition :: 確認
clean

みたいにしてリセットします。

次に SD Card Formatter をインストールします。(成功にこれが関わってるかは不明だが一応)

SDメモリカードフォーマッター - SD Association

特に複雑な設定は無かったです。

f:id:n4o847:20190626001527p:plain

次に PiBakery をインストールします。こちらも 1.5 GB ほどあるので少々待ちます。

PiBakery - The blocks based, easy to use setup tool for Raspberry Pi

ルータの SSID とパスワードを調べてこんな感じで SD カードに書き込みます。

f:id:n4o847:20190626000148p:plain

arp -a

ARP テーブルを確認した後、ラズパイに microSD を挿し、電源をつなぎます。LAN ケーブルは使いませんでした。

赤ランプが点灯し、緑ランプが点滅してしばらくしたら、再び

arp -a

でテーブルを表示し、先ほどとの差分を確かめます。ラズパイの IP アドレスが分かったら

ssh pi@192.168.~

で接続します。(ssh は自分がいつの間にか入れていたコマンドで、もともと Windows には無い気がする。その場合 Tera Term などを入れて使ってください。)

そうすると繋がりました!

pi@raspberrypi:~ $ sudo raspi-config

で設定が開くので、パスワードを変更したりロケール設定を変えたりしました。

次に、VNC Viewer をインストールします。

Download VNC Viewer | VNC® Connect

起動させたら先程の IP アドレスを入れ、つながったらユーザ名とパスワードでログインします。すると画面が映ります! わいわい!

f:id:n4o847:20190626011322p:plain

おわり

疲れたのでここまでです。最初 SSH 接続できなかったのは本当謎です。迷走しすぎて失敗時と成功時でだいぶ条件変わってるんですが、PiBakery でブート時に VNC 接続を有効にしたから繋げられたのだろうとは思います。

まあこれから色々遊んでいきたいです。

TSG LIVE! 3 ライブコードゴルフ大会 writeup

五月祭2019でTSGが催した企画、『TSG LIVE! 3 ライブコードゴルフ大会』に参加した感想です。

1日目

youtu.be

2日目

youtu.be

1日目 戦略とか反省とか

自分がプレイヤーとして参加したのは1日目です。TSG は過去の TSG LIVE! でもコードゴルフ、CTF、競プロ、ゲーム開発など色々なライブプログラミングをしてきましたが、駒場チームと本郷チームに分かれて戦うのは今回が初です。

結果はこんな感じでした。

esolang.hakatashi.com

f:id:n4o847:20190519140046p:plain

競技が始まって、自分が RubyPerl、ペアである iLiss さんが C と Python を担当するということになりました。RubyPerl ははじめに正規表現による解を思いついて、提出した後それほど縮む気がしなかったので上と右の esolang に挑むことにしました。esolang といえば Brainf*ck みたいなところがあるので時間をかけながらも通し、 bash に行きました。bashAWK が使えないことに気づいて sed に切り替えてやっと通し、前回の『TSG LIVE! 2』のリベンジのつもりで ><> に挑み、通したり縮めたりした時点で終了まで3分となり、諦めてしまいました。

反省としては PythonJava、wake あたりです。

iLiss さんが C で苦戦していて、自分が手伝うべきか esolang に行くべきか訊いたら C は自分で通すということだったので、やはり彼に任せたいと思って任せました。そのおかげで自分は esolang に集中できたというのもあります。Brainf*ck は絶対通したいという気持ちと、前回の『TSG LIVE! 2』で ><> に時間をかけて通せなかったのが辛かったのでやはりそのリベンジをしたかったというのがあります。

とすると、ちゃんと勝ちに行くなら、非 eso である PythonJava を取りに行くべきだったんですね。ただ ><> が終わった時点で時間が少なかった上、RubyPerlbash に使ったのが正規表現解だったのに対し Python正規表現は長くて使えないのでアルゴリズムを考え直す余裕がなく、終わってしまいました。

Java はそもそも自分は経験がなく、過去のコードゴルフ大会の writeup を読むなどして事前に練習してくるべきでした。

wake は終わってから気づいたんですが、bash (sed) に使った方法がそのまま使えるんですね。言語仕様については事前に読んでおいたつもりでしたが、そこに至らなかったのは反省です。

終了後本郷チームに聞いたところ、もとから RubyPerl を取るつもりはなかったらしく、結局駒場が右上、本郷が左下を広げていって、陣地の取り合いが起こらないゲームとなってしまいました。これも反省点です。

終了後 iLiss さんが落ち込んでいる様子でしたが、これは自分も過去のコードゴルフ大会で経験していることだし、TSG 内で今後もコードゴルフ大会は活発に行われていくので、そこで経験を積んでゴルフ沼にハマっていってほしいと思ってます。

1日目 解説

ゴルフ経験がない人に向けてコードの解説をしていきます。

問題は こちら です。

ruby, 36 bytes

$><<gets.gsub(/(.)(\d)/){$1*$2.to_i}

過去のコードゴルフで猛威を奮っている kurgmさんが事前準備で到達したコードや、AtCoder で意味不明な量の shortest を取っている kotatsugame さんが到達したコードも全く同じものらしいので、これが最短なのではないかと思います。最短じゃなかったら教えてください。

$> は標準出力オブジェクトで、<< というメソッドで出力ができます。puts は空白が必要なのでそれより短いです。文字列の出力なので p は使えません。

gets で入力し、.gsub(置換対象){置換処理} で置換します。数字がなければ放っておいて、数字がついていれば「何らかの1文字+数字1文字」で検索できます。この各文字を「キャプチャ」する正規表現/(.)(\d)/ です。キャプチャすると、その後 $1$2 といった形で取り出すことができます。Ruby文字列 * 回数 で文字列をリピートできるので、$2 を数値に変えて、その回数分 $1 を繰り返したものを置換結果としています。

perl, 28 bytes

print<>=~s/(.)(\d)/$1x$2/gre

こちらも kurgm さんと kotatsugame さんが同じ長さに達しているので、おそらく最短でしょう。kurgm さんのコードは動画中にありますが shebang を使った別の形で、アルゴリズムは同じです。

<> は入力を1行受け取ります。s/置換対象/置換結果/ は置換用の正規表現で、=~ でマッチさせるのですが、そのままだと破壊的な置換となってしまい入力に対しては使えないので、r フラグをつけます。g はマッチしたものすべてを置換します。e フラグは置換結果の部分を Perl の式として解釈します。さきほどの Ruby と同様、キャプチャしたものが $1$2 に入っているので、「文字列 x 回数」でリピートします。

brainfuck-esotope, 311 bytes

,----------[++++++++++.>+>,--------------------------------------------------[-[-[-[-[-[-[-[-[++++++++++++++++++++++++++++++++++++++++++++++++++++++++++<<[-]>>[-<<+>>]<[-]>]<[-<.........,>]>]<[-<........,>]>]<[-<.......,>]>]<[-<......,>]>]<[-<.....,>]>]<[-<....,>]>]<[-<...,>]>]<[-<..,>]>]<[-<.,>]><<----------]

わかりやすく整形するとこうです。

文字 フラグ 回数
, -10 [ +10 . >   改行まで繰り返す。とりあえず出力
  +   ②フラグON
  >,   ③入力
  -50 [   '2' じゃなかったら
  - [   '3' じゃなかったら
  - [   '4' じゃなかったら
  - [   '5' じゃなかったら
  - [   '6' じゃなかったら
  - [   '7' じゃなかったら
  - [   '8' じゃなかったら
  - [   '9' じゃなかったら
  - [   ここはミスです
    +58   もとの入力に戻す
    <<[-]>>   ①を消す
    [-<<+>>]    ③を①へ移す
    <[-]>   フラグを消す
  ] <[-<.........,>]>   ここはミスです
  ] <[-<........,>]>   フラグが残っていたら '9' なので 8 回出力
  ] <[-<.......,>]>   '8' なので 7 回出力
  ] <[-<......,>]>   '7'
  ] <[-<.....,>]>   '6'
  ] <[-<....,>]>   '5'
  ] <[-<...,>]>   '4'
  ] <[-<..,>]>   '3'
  ] <[-<.,>]>   '2'
 <
 < -10]

見てもらえばわかりますが、不要なものがいくつか入ってますし、そもそも '2' から '9' まで全部チェックするのはゴルフとしてよくありません。なのになぜこれを書いたかというと、 esolang は縮めるよりまず通すことが重要 だからです。コードゴルフ大会は限られた時間で複数言語を解かなければならないので、esolang は愚直に通すことを目指したほうがよいです。

bash-busybox, 138 bytes

sed ':L
s/\(.\)9/\1\18/
s/\(.\)8/\1\17/
s/\(.\)7/\1\16/
s/\(.\)6/\1\15/
s/\(.\)5/\1\14/
s/\(.\)4/\1\13/
s/\(.\)3/\1\12/
s/\(.\)2/\1\1/
tL'

これも通せればよいということで、29 の判定を愚直にしています。この愚直な判定は wake に流用すべきだったという悔しさがあります。

とはいえ、もう少し時間があったら domperor さんに取り返されていたので危ないし、ちゃんと縮めるべきだったかもしれません(結果オーライですが)。

%20 さんが 56 bytes のコードをつぶやいていました。

fish, 76 bytes

i:a=?;>:oi:88*(?vv>
v           -*86<
v$o:$<^          <
>1-:?^            ^

><> と書いて fish と読みます。kuromunori さんと kurgm さんが事前に用意したコードは 50 bytes なので、それよりは結構長いですね。

スタックを使う言語で、2次元のソースコード上を進んで行くのが特徴です。< > ^ v で左右上下に進み、? で条件分岐します。

ただこれ、同じアルゴリズムでも配置を工夫すると空白と矢印が消せて 38 bytes になります。

i:a=?;\
88*(?v>:oi:
v-*86<
>1-:?!v$:o$

おまけ:2日目

2日目の結果はこんな感じでした。

esolang.hakatashi.com

f:id:n4o847:20190519140129p:plain

問題は こちら です。

駒場チームが圧倒的に強いですね。%8%3 が天才で、これを思いついたかどうかが決め手だったといえます。

あと、事前準備で bitmath さんが書いた C 49 bytes が凄みがありますね。char[]int として計算しているとかやばいですね。

自分も RubyPerl で挑戦してみました。%8%3 は自力で思いついたものではないのでずるいですが……。

ruby, 35 bytes

gets.to_i%8%3<2&&$.-=p(1)until$.>99

perl, 30 bytes

1while<>%8%3<2?print 1:$a++<99

追記:%8%3<2 より *5&4 の方が短い。

映画『がっこうぐらし!』を観た内容・感想とか

映画『がっこうぐらし!』を観に行った内容と感想。

見ていない人向け

一言で言うと、良かった。作品の本質的な部分は掴みつつ、ちゃんと現実世界化してくれている。


ここから先はネタバレ要素を含みます。


話の流れ

まず話の流れを整理しておく。うろ覚えがあったり順番が前後しているかもしれない。各イベントの間には日常パートが入っていることもあるが書ききれていない。

舞台は高校で、陸上部で練習をしているくるみのシーンからはじまる。くるみはどうも転びやすいらしく、保健室で、養護教諭兼保健の先生兼園芸部顧問である佐倉慈のお世話になる。そこでいわゆる保健室登校をしている子、ゆきと知り合う。ゆきは佐倉先生のことをめぐねえと呼んだり、先生の持ってきたぬいぐるみにグーマちゃんと名付けたりしていている。先生によると、「いじめられたりしているわけじゃないんだけど、ちょっと浮いている子で、ここが彼女の避難場所なの」ということらしい。その後くるみは、OBとして陸上部に参加している葛城先輩に恋心を抱いていていることもあり、恋愛相談のことで保健室に通ったりしているうちに、ゆきと打ち解けたり、先生のことをめぐねえと呼んだりするようになる。りーさんも園芸部部長ということで一瞬めぐねえに声をかけに登場する。そして保健室から帰ろうとしたくるみは、先輩に声をかけられて……

と、ここまでがくるみの回想だったように朝のシーンになる。学園生活部であるくるみ、ゆき、りーさん、そしてめぐねえ、の朝食。(ここでよく見ると……というのは後で話す。)学園生活部が合宿として学校に寝泊まりしていることなど、このあたりは学園生活部が何なのかの導入になる。その後屋上で野菜を採る。ゆきは採れた野菜をクラスの友達に楽しそうに見せに行く。くるみ、りーさんも教室へ向かい「ゆき、もう行くぞ」と声をかけると、そこには独りで会話を続けるゆきの姿と、荒れた校舎が……でタイトルが出てくる。

食糧とか生活必需品が足りていないということで、くるみとりーさんは食堂へ調達しに行く計画を立てる。スコップとかバットを持っていくも割と危うい。なんとか食堂にたどり着き、色々あさっていると、扉の奥から声がして、開けたくるみが襲われる。応戦状態になるが、相手の「人です」という言葉でおさまる。

教室で噛まれていないことを確認後、自己紹介。見つかったのは2年生の直樹美紀で、髪も服もボロボロだった。ここでゆきにみーくんというあだ名を付けられる。みーくんはゆきや学園生活部の態度に不信感を抱きながら共同生活を送ることとなる。少し落ち着くと、ゆきを除いて会議になる。みーくんは「こんな髪も服もきれいな状態で! 食堂がどんなに大変だったのか知らないでしょう!」と食堂での様子を話す。友達である圭と、机の上に乗って「かれら」をしのごうとしたが、圭は引きずり込まれてしまった、というものだった。りーさんも「こっちだって最初からこうだったわけじゃない、」と経緯を話す。当時、急に事件がおこり、十数人くらいの生徒と先生は屋上へ避難した。パニクるゆき。葛城先輩を抱え込むくるみ。だが屋上でも感染者が発生し、数人を残して下へ逃げてしまう。めぐねえは「下へ行ってはだめ」と呼びかけるが、もう遅く、窓の透けた扉の向こうで「助けて!」と叫ぶ生徒を見ながら扉を閉め、生き残ったのが学園生活部のメンバーだった。

みーくんとしては学校を早く抜け出したいらしく、職員室を勝手にあさり、車で逃げ出そうとする。一度目はくるみに止められる。みーくんはゆきを抱え込んでいる学園生活部の状況について非難する。そこでくるみは学園生活部が、事件で落ち込んでいた自分たち、特にゆきを励ますために、めぐねえが企画したものであることを話す。みーくんはそんなの互いに寄りかかってるだけだ、だのゆきが足手まといになるなら置いていけばいい、だの言い、喧嘩になる。まあゆきはその言い争いを裏で聞いているわけだが。

校内放送で急にクラシックが流れる。音源へ向かう習性のある「かれら」をみーくんが校舎にあつめ、脱出を図ろうとしたらしい。途中でゆきに見つかるが、バールで「かれら」を倒しながらも脱出を続ける。だが車の鍵がどの車のものか探しているうちに「かれら」に囲まれてしまう。ゆきと適当な車の上に乗ってしのごうとするも、みーくんは圭のことを思い出し発作を起こしてしまう。

くるみが駆けつけ、「かれら」の注意をそらす。りーさんが BGM を『天国と地獄』にかけ直すと、ゆきは「体育祭だね!」と気を取り直す。くるみの「障害物競走だ、走れ!」という掛け声で、ゆきはみーくんの手をとり、車の上から校舎へ走り出す。みーくんは本当に体育祭でゆきと走っているような感覚に包まれる。この件のあと、みーくんは独り階段で落ち込むが、案の定ゆきはちょっかいを出しに行く。みーくんがなんで先輩はそんなに元気でいられるのか、と訊くと、ゆきは本当は自分のいないところでくるみやりーさんが疲れていたり喧嘩しているのは知っていて、自分は元気でいたい、というようなことを答える。

みーくんの戦闘能力を見たくるみは、防災倉庫前に溜まっている「かれら」を片付けようとみーくんを誘う。みーくんは、前に学園生活部にゆきが必要だと言っていたことがなんとなくわかった、というようなことを言う。結束が高まったところで向かい、「かれら」をなぎ倒していくが、みーくんはその顔を見て圭を思い出し(というか実際に圭だったのかもしれない、そこまでわからなかった)、ひるんでしまう。くるみに助けられなんとか倉庫前は討伐する。知らない生徒ならいいが、知っている生徒だと……と話すと、くるみもその時は目をつむっている、という話になり、屋上での回想になる。事件当時、葛城先輩に逃げろと声をかけられ、ともに屋上へ向かうが、途中で合った部活の友達が感染していた。噛まれそうになるが先輩にかばわれる。傷を負った先輩を抱えて屋上に逃げ込んだが、その後先輩も発症して襲われそうになり、くるみはそれをスコップで……

防災倉庫が開いたので、食糧や生活必需品が大量に手に入った。大量の食糧を前にはしゃぐゆきは、前より子供っぽくなっている……という話をしていると急にやつが現れ、くるみが襲われるがりーさんが消化器で殴り飛ばした。

夜、ゆきが、外が光っていて夜景がきれいーと言い出すが、実際には町の外に光はない。4人で窓の外を眺めながら、卒業したら進学か就職だね、という話になり、みんなの話をまとめると進学、だけどその前に卒業しなきゃね、という話になる。

学祭をやろう、という話になり、4人で飾り付けを進め、占い喫茶を開く。ゆきが占い師で、みーくんの未来は輝いています、りーさんは素敵なお嫁さんです、くるみちゃんの未来は見えませんwとかやっていると、火災警報器が鳴る。昇降口へ向かうと「かれら」が音に惹かれたせいでバリケードが突破され、しかも一人燃えているやつがいた。戦っているうちにゆきとくるみ、りーさんとみーくんに分断されてしまう。くるみはりーさんとみーくんを部室に逃し、ゆきも校舎を通って部室へ向かうよう指示する。だが警報機のせいで校舎中の「かれら」が興奮し、各所のバリケードや扉を留めていた板が破られてしまう。りーさんとみーくんは部室へ向かい、扉を封鎖したが破られる。くるみは屋上に逃げ高台へ避難するも囲まれる。

くるみは全てを諦めかけていたが、葛城先輩のことを思い出す。先輩は発症する前、自分がOBとして学校に残っていたのは、くるみのことが気になっていたからだ、ということを明かしていた。くるみは自分も先輩のことが好きだということを伝えられていないまま先輩を殺めてしまった。幻覚の先輩がくるみのとなりに現れ、くるみが告白する。好きだったことを伝えられた、もうこれでいい、というと、先輩はだめだよ、くるみは生きているから。俺がくるみのことを好きになったのは、くるみがよく転ぶのを見ていたからだ。転んでも諦めないで立ち上がったからだ。諦めちゃだめだ。と伝える。くるみは気を取り直す。

くるみは屋上から部室へ駆けつける。焼死体を見て、2人はだめだったのかと勘違いしたが、奥から声が聞こえる。襲われている2人にバールをパスする。くるみも応戦して、噛まれそうになる……が平気だったっぽい。とりあえず部室にいた「かれら」は一掃できたが、ゆきがいないことに気づく。

火事の煙で倒れていたゆきは目を覚ました。ゆきの周りの「かれら」は焼け死んでいたので助かったようだ。煙の中にめぐねえが見える。待って! と追いかけるとそこは保健室だった。

3人がゆきを見つける。そこにはゆきと、かつてめぐねえだったものが立っている。めぐねえは自分を紐で縛り付けていたのでゆきは安全だった。くるみ、りーさんもショックを受けるが、めぐねえを楽にするためにも葬ることにする。ここで回想になる。事件後、ゆき、くるみ、りーさん、めぐねえは保健室で医薬品を回収していた。だがベッドの下に潜んでいるやつに襲われる。めぐねえは3人をかばって噛まれてしまう。くるみがスコップで倒したが、めぐねえはもう治らない。めぐねえは泣く3人それぞれにメッセージを託して、保健室に閉じこもる。

めぐねえを葬った後、ボロボロの部室に戻る。ゆきは「きれいにしなきゃ、めぐねえに怒られちゃう」と片付けようとするが、りーさんが留める。ゆきは「わかってた。全部わかってたよ。学校がこうなってたことも、めぐねえがずっと前からいなかったことも」と打ち明ける。それもあってか「卒業、だな」という流れになり、学園生活部は卒業式を執り行うことになる。

卒業式では各々が挨拶、卒業証書授与をして、『仰げば尊し』を歌った。式後、学校に別れを告げ、めぐねえが遺していた車に乗り込み、学校の外へ走り出す。

見た人向けの感想

結論から言えば、尺の都合や実写にする上で改変された各要素に、合理性と原作へのリスペクトを感じた。『がっこうぐらし!』の世界を現実に起こすとしたらこうなる、というのを最大限やってくれた、『がっこうぐらし!』が好きな人にとって良い作品だと思う。

漫画・アニメとの大きな相違点

めぐねえ・ゆきの立場

めぐねえが養護教諭&保健の先生&園芸部顧問だった。ゆきが保健室登校であることなども絡めて、保健室の先生が生徒の相談相手になりやすい?ということを考えると、割と自然な改変ではあると思う。アニメでは英語の先生で、授業の板書に今後の展開を示唆するような英文が書かれていて話題になったが、映画の授業(ゆきの妄想)では病気の感染経路について書かれていた。ちゃんと読んだら何かしらあったのかもしれない。

太郎丸

太郎丸はいない。登場させると話が膨れるので、時間制限を考えるとまあそうか。

みーくんの発見

漫画・アニメではショッピングモールだったが食堂になった。これも尺の問題でしょうがない。知っている人からすると圭が引き込まれるシーンで色々こみ上げてしまうけど、初見だと圭の存在感薄いかも? わからない。

くるみ

くるみは噛まれない。りーさんとみーくん救出のシーンで微妙に噛まれたように思えたが、本人が大丈夫と言っている。この映画に続きがあるかというと微妙なので、伏線にもならなそうだし、普通に噛まれてはいないのだろう。

漫画・アニメとの細かい相違点

学校の設備とか

職員用マニュアルだとか、そういう壮大な設定に関わる要素は出てこない。食糧もただの防災用だった。電気ガス水道も、火事でダメになるまでは普通に使えたのだろう。節電とかしている描写はなかったが。

言い回し

漫画・アニメでは「そんなのただの共依存じゃないですか!」となっていたみーくんのセリフが「そんなのただ寄りかかってるだけじゃないですか!」に変わっていた。漫画・アニメでも特徴的なシーンではあったが、「共依存」といわれてぱっと文字が出ては来にくいので、わかりやすいものに変えたのかもしれない。

ゆきの認識

ここが一番引っかかったが、火事の後ゆきは、事件が起こったことやめぐねえがいなかったことをずっと認識していた、と明かした。車で学校を出るシーンでも、「私達の他にも生き残りがいるかも!」と言っていた。漫画・アニメでは、卒業後ゆきの認識が多少はっきりしてきたとはいえ、今までのものが演技だった、と明言はしていない。映画でも演技だったとまでは言っていないが、わざとやっていた部分があるような言い方をしている。(「今まで迷惑かけたよね、ごめんね」と反省している。)これは意図的な改変のように思えるが、理由をつけるとしたら、彼女たちの「卒業」があるのだろう。みーくんがゆきを足手まといだと指摘していたこと、ゆきの告白を聞いてくるみが卒業しようと言ったことを考えると、校舎や備品が焼けたことだけでなく、学園生活部がめぐねえから自立をすることも卒業のトリガーになったのかもしれない。

漫画・アニメではゆきだけ制服の色が違うことについて色々考察があったけど、逆に映画でゆきの制服が他の人と同じなのは、映画でのゆきが実は正常だったことを示唆しているのかもしれない? みーくんを制服で2年生だと判断するシーンがあったので変に注目されないようにというのもあるかもしれないが。

配役について

最初映画のイメージが公開されたとき、ゆきとみーくんが一瞬で見分けられた。髪型とか振る舞いとかもあるかもしれないが、漫画・アニメのような髪色の違いがなくても雰囲気でわかるあたり、ピッタリだったのかもしれない。くるみとりーさんは髪型判断だったのでそういうのはなかった。

くるみ

配役順の通り、この映画ではくるみがかなり主人公的だった。くるみの恋心も話にだいぶ関わるので、くるみの案外乙女チックという部分が大きく出ていたかもしれない。パンフレットでも触れられていたけど背が高い。陸上部なら妥当か。

ゆき

ゆきみが高い。というか、ゆきのようなキャラクターは現実では考えにくいけど、それをうまく現実世界に持ってきたような、ちゃんとリアルにいそうにした感じ。「ごみん」が一回出てきて笑った。

りーさん

映画ではりーさんを主軸に置いた展開というのがなかったので、割と影薄めになっていたかもしれない。漫画やアニメであったゆきの保護者的要素がなくなっていたので、りーさんっぽさを決定づけるシーンが無かったというのはしょうがないけど、ちゃんとりーさんではあった。

みーくん

最初は敵意むき出しみたいな目だったのがどんどん柔和になっていくのがとてもよいですね。卒業式のときちゃんと眼帯してるのもよい。

めぐねえ

上記の通り若干設定変わってるけど、めぐねえだった。漫画であった、自分は大人側だ、みたいな心情の場面はなくて、実際生きてるのも少しの間だったからこそ、佐倉慈としてよりもめぐねえとしてのほうが表れていそう。でも保健室での別れのシーンは佐倉慈だった。

演技について

申し分ないし、心配するほどのこともない。強いて言えば喧嘩のシーンとかもの足りない気はしたけど、女子高生のリアル喧嘩とか見たことないのでなんとも言えない。

音・歌について

途中、確かみーくんが脱走するシーンで、リバース音?逆再生っぽい背景音があって、ホラー的なものだとは思うが、『アフターグロウ』を思い出した。

合唱曲は『大切なもの』と『仰げば尊し』の2曲流れた。漫画でもアニメでも卒業式のシーンは『仰げば尊し』だったので当然ではあるが。アニメでも漫画でも泣いたし同じように泣いた。

主題歌とエンディングは終了後一気に流れた。パンフレットに歌詞が載っていたけど、歌詞が作品と関連のある内容かというとよくわからない。作品と絡めて考察することは不可能ではないけど、別に単体でも成り立っているような感じだった。

伏線とか

初っ端の学園生活部の朝食のシーン、よく見るとめぐねえの分が用意されていない。その後の食事シーンでもうまい具合にめぐねえの手前が隠されているが、食器が一切ない。学祭が完成して打ち上げのシーンでも、めぐねえのコップだけ空である。他にも初期のみーくんのセリフがめぐねえにかぶり気味だったり、このあたり漫画やアニメをちゃんと踏襲していて面白かった。

きれいな学校がゆきの妄想だったという話について。アニメではこれが隠されて、1話でそれがひっくり返るというところに一つの面白さがあったが、映画ではこれをしないで良かったと思う。そもそもアニメでは日常系というジャンルが確立されている上、週ごとに12~3回放送できるので装いを変えることができるが、映画では日常系とだけ銘打って見に来る新規がいるのかわからないし、そこで実はホラーでしたという展開をやっても複雑になるだけだからだ。そもそも日常から非日常への急変は作品の一面でしかなく、『がっこうぐらし!』の本質はそれらの共存、非日常の中で日常を作り出そうとする美しさと力強さにあると思う。監督はモチーフとしてのホラーはあるが根本にあるテーマは青春だ、と語っていたが、その方向性が現れていた。

「かれら」について

ゾンビが思ったより綺麗だった? いや、食堂に向かうシーンで急にアップで出てきたシーンはびっくりして飛び上がってしまったが。なんだか、かれらがウロウロしている様子がとてもマインクラフトっぽかった。

危うくはあるけど女子高生が倒せているのにこれだけ人がやられている、というのは漫画でもアニメでも同じだが、これは原因であるウイルスが空気感染力を持つことによるというのが漫画で明かされている。

みーくんとくるみが、「かれら」が知っている人だった場合のことを話していたシーンを見るに、「かれら」が綺麗なのは話の上で必要だったことなのだろう。漫画やアニメで顔を見て人物を判定しているのは確か圭のシーンくらいだったけど、髪型で判断していそうだし、そもそも漫画とアニメではシーンによって「かれら」の綺麗さに幅があったり謎オーラが出ていたりするが、実写にする上でその辺りを曖昧にできなさそうなので、まあそうなるのかな、とは思う。あと感染後すぐに発症していたりするのでその場合はあまり汚くならないか。

火事のあと、校内中のかれらが焼け死んだら流石に臭いのでは? と思ったが、そのような描写はなかった。

スコップやバールでなぎ倒していたけど血とかが出ている様子はなかった。それより倉庫でりーさんが消化器で何度も殴っていてそっちのほうがダメージありそうで笑ってしまった。

特徴的だったシーン

みーくんが PTSD を起こすシーン

自分はこういう災害とかパニックとかを見ると泣きそうになってしまう癖があって、みーくんが発作を起こすシーンは来るものがあった。だからこそ、ゆきに手を取られて救われて、ゆきを見直すようになったのだとしみじみ感じる。

夜景を見ながら将来のことを語るシーン

表面上は希望にあふれた未来の会話をしてるけど、学校の外は真っ暗で、背後にとてつもないどうしようもない絶望感がある、みたいな印象を強く受けたシーンだった。このミスマッチが『がっこうぐらし!』の世界観そのまんまでとても良い。

めぐねえと分かれるシーン

これは泣く。

卒業式

漫画でもアニメでも泣くのでわかってたけど泣いた。

結論

結論は先に述べているけど、『がっこうぐらし!』の世界をどうやったら現実に持ってこれるか&この時間制限で表現できるか、ということがかなり考慮されていると思う。監督が言っている、コスプレっぽさをなくすだとか、ホラーでありつつメインは青春ものだとかそういう方向性が自分の求めていたものにマッチしていたのかもしれない。かつ、絶望の中で暮らしを続ける彼女たちを見て、漫画やアニメを見たときと同じ、楽しそうだな、という感情を想起することができた。自分が『がっこうぐらし!』好きだから色々バイアスかかっているかもしれないし、知らない人が見てどういう感想を持つのかはわからないが、好きな人にこそ観てほしい作品というのは頷けるなと思った。

他の感想を見た感想

結構肯定的な感想が多くて嬉しい。

キャベツは『がっこうxxx』の方だったのね。正直キャベツとか霞むくらい本編良かったのであれだけで判断材料にはならないよね。

りーさんが消化器で何度も殴っているのはりーさんの非力さを表しているという解釈があってあーそっちじゃんってなった。りーさんごめんなさい。

おまけ:『がっこうxxx』を観た感想

Amazon Prime に登録したので『がっこうxxx』の方も観た。

本編より血が出ていた気がした。

本編と関係ないか……と思って観ていたが、めぐねえのことがクローズアップされていた。めぐねえの学校に対する考えとか、カウンセリング力の高さとか、ああこの世界のめぐねえはこうなんだなあと感じさせてくれる。やっぱりこの世界のめぐねえは保健室の先生で良かったなと思った。

梢とゆかりが夜めぐねえのところに向かうシーン、結局2人はめぐねえらに会えないということがわかっていたのもあってドキドキした。結局、知っている人のことは殺められない、という本編にも関わる心情が出てきた。2人そろってやられてしまうのはちょいこじつけだけど、そうやって終わってしまうのか……というやりきれなさがある。それをやってのけたくるみのメンタル……

璃子と真帆の話にみーくんが首を突っ込んできたのはちょっと謎。まあ生きてる圭がみーくんと楽しそうに会話してるシーンは貴重なので見られたのでよかった。

教頭が「今はこの先だけが安全なんだ!」と言っていたのは何かの伏線? 本編では学校側の事情が出てきていないけどどうなんだろう?

結果として、『がっこうxxx』は本編の後に観るほうがいいような気がする。本編とは意図が違うところにあるような気がするというか、本編を観て理解した部分を元にこちらで考えられる部分が大きいというか。