「たとえる技術」を読んだ

せきしろ著『たとえる技術』を読んだ。国語に対するニガテ意識が消えない私が、文章になんとかオリジナリティのあるたとえを入れてやろうと、つい頭をひねってしまうほど、たとえ方の技術がやさしく語られた本だ。

たとえる技術

たとえる技術

 

この本では、「たとえる技術」が、時折クスッと笑ってしまうようなたとえの例とともに語られる。この本を読んで私が強く感じたのは、「たとえって、パーソナルな体験の表現で良いのだ」ということだった。本の中では、共感を得やすいたとえを生むために選ぶと良い題材なども紹介されていたので、一般的にはそのようなたとえ方の技術を磨くとよさそうだとは理解できる。しかし、私はそういった共感を得る技術としての「たとえ方」よりも、そのたとえを作り出す話者の経験などに興味が湧いた。著者せきしろ氏が人生でこれまで見てきたであろう風景、感動したであろう出来事などを想像せずにはいられなかった。そこから作られる、全然おもしろくないたとえ、共感されないたとえ。それでも、何らかの話者の体験が、別の体験とあるポイントで結び付けられた結果として生まれるのがたとえだ。「これとそれを、そんなところで結びつけるのか!」という驚き。世界で初めて塩キャラメルを食べた人が感じたであろう、未知の組み合わせ方の面白さが、私には強く印象に残った。

 

そして、これからは積極的にたとえを使ってやろうという気分はすごく高まった。まるで、ためしてガッテンで「たとえを使うと脳に良い」なんて放送された直後のように、私の中でたとえがブームになっている。

私の国語に対するニガテ意識は、この先まだまだ克服できそうにないが・・・。

 

プログラミング問題「六角形のテトロミノ」を解いてみた

オフラインどう書くシリーズの、「六角形のテトロミノ」問題を解いてみた。

この記事はネタバレになってしまうので、日々のコーディング筋トレネタに困っているプログラマの方は、先に問題にチャレンジすることをオススメする。

また、今回私が考えたことなどを振り返って、あらためて言うまでもないのだが、私には数学の技術的な知識が不足していることを痛感した。地道に学んでいきたい。今回私がとった解法について、すでに数学の世界には理論やアルゴリズムが確立されているはずだと思うのだが、浅学な私はそのような知見にたどり着けなかった(何を調べたらよいかも分かっていない)。もしご存知の方がいらしたら、ポインタだけでも教えていただけると幸いだ。

 

 

さて、今回の問題を見て最初に思い浮かぶ常套的な解法は、テトロミノの形を「4つの六角形のうち1つを原点とした位置ベクトル」で表し、そのベクトル列によって形を比較するというものだ。どのように座標に表わすかといった部分で、問題をきれいに表現できたり解けたりする。

このアプローチで解きかけていたのだが、途中でどうしても「回転」のことが気になり始めた。今回の問題では、回転や並行移動を行って重なる図形は同じ形とみなすのだ。つまり、「回転」や「移動」という操作を行っても変化しない「形の特徴」のみを抽出し、それ同士を比較するようにすればよいのではないか?

そんなアイデアが浮かんでしまい、どうしてもその道で行けるところまで進んでみたくなった。

六角形テトロミノの形をどう表わすか

そこで自分なりに考えてみた。考えるヒントとなったのは、中西昌武先生の概念フォーム理論で、データソース間の関係の構造を行列で扱っていたことだ。今回の問題の入口として、ある1つの六角形テトロミノを次のような規則で行列で表わすことにした。

(1) 六角形の各辺を、右上を0として0〜5のインデックスで表わす

(2) 六角形の位置を表わす文字を、六角形の識別子とする

f:id:innx_hidenori:20170415211139p:plain

 

(3) テトロミノを構成する各六角形ごとに、「隣接している六角形」を、隣接している辺インデックスと対象六角形の識別子とで表わす。

例:以下の六角形テトロミノの場合、次のような情報が抽出できる。

f:id:innx_hidenori:20170415212113p:plain

a: (2 → f)、f: (1 → g, 2 →k, 5 → a)、k: (0 → g, 5 → f)、g: (3 → k, 4 → f)

 

(4) 取り出した情報から行列を作る。行: 六角形ごとの情報、列: 辺ごとの情報。4行6列の行列になる。

f:id:innx_hidenori:20170415212523p:plain

 

これで、一旦形の情報を表現することができた。しかし、このままでは問題がある。

最初の行列表現の問題

これまでの手順では、最初に構成されたテトロミノの記号などをそのまま反映しただけなので、当然ながら以下の問題には対処していない。

  • 行列の情報が、テトロミノの回転に依存したまま
  • 行列の情報が、テトロミノの位置に依存したまま

この行列に何らかの手を施して、位置と回転に関する要素を取り除かなければいけない。一体どうしたら・・・

まず、現段階の行列でも、次の特徴は持っている。

  1. 行の順序を入れ替え(aを3行目、kを1行目にするなど)ても、同じ形を表現している
  2. 列をローテーション(インデックス0の列を一番右へ持ってくる)させても、同じ形を表現している

2はテトロミノを回転させる操作にあたる。

1と2を組み合わせると、行の順序を入れ替えたり、列のローテーションを行っても同じ形を表していることになるので、何らかのアルゴリズムで行の順序とローテーション回数が一意に定まるようにしてやれば、位置や回転に依存しない「構造行列」を導けるはずだ。

テトロミノの構造行列を導くアルゴリズム

  1. 行の順序(=テトロミノの各要素の取り出し順)を決めるため、まず、どこを起点にするのかを決める。
    この際、六角形毎の隣接数を評価して最小のものを選択する。これが同数ある場合は、1つ先の隣接要素の隣接数も可算して再評価する。テトロミノの場合は全要素数が4で、その半数である2、つまり今回は1つ先の隣接要素まで評価し、それでも最小スコアのものが同数ある場合は、その中の1つに決める。
  2. 起点六角形で隣接がある辺のうち最小のインデックスをもつものがインデックス0になるように、テトロミノ全体をローテーションする。
  3. 行の順序を決める。ローテーション後のテトロミノに対して起点六角形から開始して、隣接辺インデックスの昇順に、深さ優先で辿っていく。(ローテーションしているので、この時点で辺インデックスが変わっていることに注意)
  4. 行の順序に従って、行を入れ替える。
  5. 六角形の識別子を、行インデックスに変換する。

この操作を行うこと、最初の行列は、

  • 起点六角形:a
  • 順序:a→f→k→g

となり、変換を施すと次のような構造行列になる。

f:id:innx_hidenori:20170415224919p:plain

 

プログラムでは、10個の形の構造行列を最初に求めておき、テスト入力のテトロミノの構造行列を都度求めて、行列同士のマッチングにより形を決定している。ただそれだけだ。

 

この先の課題

もう少し先へ進んでみたいと思っており、具体的には以下の点をなんとかしたい。

  • アルゴリズムの汎用化:N角形の場合、ポリオミノの場合
  • 別のプログラミング言語での実装:この種の問題を解くコードをPHPで書くのはなんだかツライ・・
  • 概念フォーム理論との対比:構造を行列で表わすという点は似ているが、実際に表現している特徴点が異なる、と思っている。その違いをハッキリさせておきたい。
  • ユニットテスト:書く

 

コードの読みやすさの話

読みやすいコードの書き方について、次の記事が話題になっていた。

これについて、 twitterで@koriym氏から問いかけがあった。

 「put B+C into A」と「a = b + c」のどちらが読みやすいコードといえるのか。現時点での私の考えでは、後者の方が読みやすいという考えだ。こう考えるのはなぜか、書いてみる。

 

まず、コードの読みやすさと一括りにしているが、最初に挙げた記事や私のtwitterでの返答で想定しているのは、何らかのアプリケーションのソースコードとしての読みやすさだ。この類のソフトウェアでは、アプリケーションが扱っている問題(What)とそれをどのように解決しようとしているのかといった意図(How)を、コードを読んだ開発者が正しく認知するのに必要なコストが低ければ、概ねそのコードは読みやすいとされるだろう。このように、アプリケーションコードの読みやすさの基準は、どちらかというと問題の側にある。

@koriym氏が挙げた「put B+C into A」と「a = b + c」との違いは、このような目線で評価しうるだろうか? いくつか意見はありそうだが、同じ目線では評価不可能だと私は考える。この比較においては扱っている変数の部分がABC、abcのようなパラメータに置き換えられており、扱っている問題そのものに由来するような表現を見いだせないからだ。したがって、問われているのは、構文としての読みやすさということになる。表している意味が同じだが、形式が異なっている2つの文の、どちらが良いのかという話だ。

この点で、私の考えでは「a = b + c」の方が読みやすい。

「put B+C into A」は、そのコードが行う操作を自然言語的に表していて、読めば操作をイメージできるのだが、そのイメージはコンピュータのCPUで計算した結果をメモリの何処かのアドレスに書き込むような、限定されたイメージだ。putやintoという単語は、読み手の最初の認識を誘導してすばやく意味を連想させるのに役立つ反面、意味の応用力がないのだ。=や+も、同じようなメリットデメリットを持つが、英単語を使ってしまうよりも、その場での意味に馴染ませやすい。

また、構文自身が意味を連想させまた限定もするということは、アプリケーションコードの記述においては、とても邪魔になってしまう。アプリケーションコードを記述するときには、表現したい問題などに由来する言葉や意味が際立っていた方が読みやすい。putやintoなど構文側の単語がいろいろ出てくると、そちらに読み手の意識が引きづられてしまうだろう。

また、順序の点でも「a = b + c」の方が読みやすい。左辺に結果が書いてあることで、そこから右に書いてあることの目的を最初につかめるからだ。

 

視覚への疑い(『目の見えない人は世界をどう見ているのか』を読んで)

伊藤亜紗著『目の見えない人は世界をどう見ているのか』を読んだ。2015年に出版された本だが、私が本屋で偶然見つけたのは2017年2月初旬。私は「視点」関係の話が大好物なので、タイトルを見て0秒で手に取り購入。

目の見えない人は世界をどう見ているのか (光文社新書)

目の見えない人は世界をどう見ているのか (光文社新書)

 

「視点」というテーマがなぜ気になってしまうのか、とても個人的な経験・感覚を書いてみる。以下に書くのはこの本の内容と関係なさそうなことばかりだが、目の見えない人の世界の見方を知ることは、著者も書いているように認識の本質に迫るインスピレーションが私にも多くあったのだ。

自分の目での見え方を見つめる 

私は小学生の頃から、なぜだか自分の視覚を疑っていた。中二病?の一つなのだろう。目に見えるものがなぜそう見えるのか。見えていると認識しているものは、他の人と同じなのか、違うのか。そんなことを考えてしまう小学生だった。

目で見えているものへの疑いの姿勢は、今でも変わっていない。中二病が癒えないオッサンだ。自分の目でどのようなものが見えているのかを、日常の中で試して考えたりしてしまう。その中で、「連続に見えるのは思い込み」という些細な経験の話をしよう。

たとえば、まあまあの晴天の日の午後、青空に雲がゆっっっくりと動いているのが見える。その雲の近くを飛行機が飛んでいる。雲と飛行機の両方を、瞬きせずに凝視してみる。この凝視が私にはとても難しく、凝視しているつもりでもちょっと意識がそれて視点を少し横へ移動させてしまったりするのだけど、何とか数秒凝視することはできる。それを何度かやって確かに感じるのは、雲と飛行機の動きがどうも不連続に見えるということだ。ある瞬間見えた位置と向き(その瞬間の変化量)から滑らかに連続的に動いているように見えた直後、雲と飛行機の位置が一瞬前の位置に戻り、そこからまた連続的に動く。そしてまた少し戻る。そんな風に見える。

たとえば、仕事帰りに寄り道をして遅くに帰宅した日。私の家はまあまあ山奥なので、夜遅くなると人工的な明かりは全くない。満月の日でなければ、星の光のみでほんとうにうっすらと地面が見えるか見えないかという程度の暗闇だ。その状況で、私は懐中電灯などを持たずに、家の周辺を飼い犬を連れて散歩する。ほぼ暗闇なので私はゆっくり移動するのだが、犬にとっては問題ない暗さなのだろう。普段通りちょろちょろと動き回っている。白い毛の犬なので、暗闇の中、リードの先に白い塊が見える。その犬がちょこまかと動く様子をこれまた凝視してみる。すると私の目には、まるでとぎれとぎれにしかパケットが送られてこない動画のように、少し動く映像、その後スキップして、違う位置からまた少し動く映像、というように見える。

人の目が受け取っている情報は、不連続なんじゃないのか? 特に暗いところでは、目が受け取る情報の量(光の量や頻度)が少ないので、より不連続に見えるんじゃないのか? 自分の体感を説明するために、そんな私的な仮説を立ててみたりする。

 

こんなこと、世界のどこかで誰かがすでに研究してたりするから、世の中は面白い。2つほどリンクを紹介して、まとまりのない独り言を終わろう。  

渡辺幸三氏のブログ記事『システム設計に求められる適性』では、オリバー・サックスの著書に触れた以下の部分があった。

オリバー・サックスの名著「妻を帽子と間違えた男」の中で、嗅覚と視覚が3週間にわたって異常に鋭敏になった24歳の男性の実話が紹介されている。その結果、彼は事物を分類したり抽象化してとらえることができなくなったという。彼の感覚が受け取る事物は精妙な違いを伴う個々にユニークなものであるため、それらを上位概念でくくることが感覚的に許容できなくなる。「嗅覚が鋭くなってめちゃラッキー」なんて話ではまったくなくて、人間に特徴的な知性を行使できなくなるという致命的な問題が、一時的ではあるが生じてしまったのだった。 

 感覚が鋭くなることによって、抽象化できなくなる。これも、不連続が際立ってしまうこととつながっている話だと思う。

妻を帽子とまちがえた男 (ハヤカワ・ノンフィクション文庫)

妻を帽子とまちがえた男 (ハヤカワ・ノンフィクション文庫)

 

 

もう1つは、スゴ本ブログの『知覚を生み出す脳の戦略『音のイリュージョン』

こちらは不連続・連続の感覚を、音(聴覚)に対して取り扱ったものだ。

音のイリュージョン――知覚を生み出す脳の戦略 (岩波科学ライブラリー 168)

音のイリュージョン――知覚を生み出す脳の戦略 (岩波科学ライブラリー 168)

 

 

私的アンチパターン:本屋

ソフトウェアエンジニアは、本屋になってはいけないという話をする。Amazonのことではない。

 

私には、わりと本を買い漁ってしまう癖というか衝動がある。始まりは大学生の頃に遡る。京都に住んでいた私は、大学生協書籍部、四条にあるジュンク堂、丸善、それから大学の近くにある古本屋などへ行っては、数学や物理学の本を衝動的に買い漁った。まともに読みこなせたものは数少ないので、とんだ散財癖でしかなかったわけだが。この衝動の原因は、自分の根っこにあるコンプレックスが影響しているのだと分析してはいるが、その話はまた別の機会にしよう。

時は移り20代中盤、プログラマーになってみようと決意した私の衝動の対象は、ソフトウェア関係の書籍になった。現在は絶版になっている書籍を、その頃にたまたま購入していたりして、ラッキーだったと思えるものもなくはない。しかし、Windows 32 APIリファレンスなど、ほとんどは本棚の肥やしで高価なコレクションでしかなかった。とんだ散財癖だ。

ともかく私は、たくさんの本を買ってきた。ある趣味にハマって際限なくお金を使ってしまう現象やその対象を、底なしな状況とかけてだと思うが、沼と呼ぶようだ。まさに私は沼にハマり続けているのだろう。まだ抜け出せていない。

 

さて、しばらく前になるが、IT・Web系twitter界隈で以下のtweetが話題になった。 

私もこれが悪習だということには同意する。その理由を語ってみよう。

本を読むには、コストがかかる

本を買うには金銭的コストがかかる。図書館で借りるとしても、相応の労力が必要だ。また、本を読む速度は人によって違いはあるが、それなりに時間がかかることには違いないだろう。それがその人にとって娯楽にあたるのであればコストと考えることに意味はないが、仕事で使うような技術を学ぶための書籍となれば、読んで学ぶためにかかるコストを度外視することはできない。

また、読む対象の書籍が、良書・名著といわれるものの場合は、読んで理解するためのコストが相対的に高いことが多い。

コストのかかる行為を他人に求めるということには、慎重であるべきだ。 

本に書かれた知識には、受け手にとって最適な学び時がある

映画マトリックス(例えが古くて申し訳ない)のように、知識や技術を脳に直接インストールできたら理想的だ。分かりきっているが、現実はそうなってはいない。

そして、私たちソフトウェアエンジニアが身につけていく開発スキルというのは、ソフトウェアが高度に人間の脳内の活動から作られるものであるにも関わらず、アタマだけで学んでいくことが難しいスキルだと私は考えている。何らかの実践を伴わないと、作り手として成長していけないのは、何もソフトウェアエンジニアに限った話ではない。

そして、取り組む人間の持っている前提知識や問題意識、興味と技術レベルとがマッチすると、その実践によって人は大きく成長する。逆に言えば、実践で大きな学びの効果を得るには、問題意識や興味も育てておかないといけないということだ。

 

本の話に戻ろう。

文章には、文脈=コンテキストがある。著者の持つコンテキスト、時代的な背景などもある。そして、読み手の側にも、今置かれている状況としてのコンテキストがある。

自分が過去に読んで有益だった書籍だからといって、ソフトウェアエンジニアの新人に分厚い本を何冊も薦めるというのは、筋が悪い。コンテキストを無視しているからだ。むしろ、読んで何かを学んだ経験を元に、その学び時を見極めて推薦することこそが、先人の役目だ。

良書と言われる本でも、年を経て読み直すと違う面が見える

人は成長し変化していくものだから、問題意識の対象が同じであっても、別のものに見えてくることはある。また、異なった視点から見えるようになっていることだってある。人は常に何かを学んで成長しているからだ。逆に、見え方が何も変わらない場合もある。

ある本を、時期おいて何度か読むと、初めて読んだときには分からなかった部分が、なぜだかスッと分かるようになっていたという経験は誰しも持っているだろう。そして、さらにまた1年後に同じ内容を読んだら、今度は反論を持つようになっていたということだってあるはずだ。これは論理的にあり得るという話ではなく、現実にあるのだ。

ここから言えるのは、本に対する評価を常にアップデートしていくべきだということだ。もしある本の内容について、何年も評価をアップデートする必要がなかったとしたら、次の3つのどれかの状況だと言える。

  • 本の内容が普遍的
  • 本に書かれている対象に対して、自分の考え方が更新されていない
  • 本の内容を理解していない

 

私は本屋がとても好きだ。しかし、どの本屋へ行っても同じように並べられているような本には興味が湧かない。棚のすみにあってタイトルや背表紙の雰囲気が気になって手に取り、パラっとめくったら気になる文章や表現があった。そんな出会いが好きなのだ。そんな一期一会を逃すまいと、ついつい買ってしまうのだが・・・。

 

毎年毎年代わり映えのしない新人向け書籍リスト、そんなものは無視して良いと思う。それは退屈な本屋でしかないのだから。エンジニアは、本屋ではないのだから。

 

 一方私には、本の沼から抜け出す努力が必要だ。本屋へ行くことが、私にとっては人生のアンチパターンなのかもしれない。