逆FizzBuzz問題を解いてみた

FizzBuzz問題を解いてみました。

ただし、答えを知らない状態で解きたかったので、殆ど調べずに書いています。

もしかすると間違ってるかも……?

github.com

FizzBuzz問題とは

逆FizzBuzz問題 (Inverse FizzBuzz) - 猫とC#について書くmatarilloの雑記

上記ページから引用させていただくと、「FizzBuzz問題。あるリストが与えられたときに、FizzBuzzを実行するとそのリストを出力するような最短の連続数列を求めよ。」という問題です。

自分なりに解釈したのが以下。
数えた数字が、3の倍数かつ5の倍数(つまり15の倍数)ならFizzBuzz、5の倍数ならBuzz、3の倍数ならFizzを出力する関数がある。
Fizz, Buzz, FizzBuzzから成る列があった時、この列を出力しうる関数への入力を算出するのが逆FizzBuzz問題
ただし算出する数列は、数列の長さと先頭の数が最小のものとする。

 解き方

自分は以下の方法で解きました。

  1. FizzBuzzの列は周期を持っており、関数への入力の先頭の数字は3から15になる
  2. 最初のFizzBuzzを、FizzBuzzが無ければBuzzとFizzの関係を手掛かりに先頭の数字を確定
  3. 先頭とした数からFizzBuzzの列を生成していき、最後尾の数字を特定

3番は少し非効率なやり方ですが、作成したプログラムでは、この時与えられたFizzBuzzの列とチェックを行い、仮に違いがあった場合は入力されている数列がおかしいということでエラーを出力しています。

最後に

解くためのプログラム作成に3時間程掛かってしまいました。

最近C++ばっか書いてたとは言え、Javaの基本的なプログラムの書き方やInteliJ IDEAの使い方すら忘れていて……。

元ネタではGoogleの面接でこの問題を解かされたそうですが、自分ならまず間違いなく落とされてそうな感じですね……。

読書感想「医師の作った「頭のよさ」テスト」

 こちらの本を読んだので、感想を書きます。

医師のつくった「頭のよさ」テスト 認知特性から見た6つのパターン (光文社新書)

医師のつくった「頭のよさ」テスト 認知特性から見た6つのパターン (光文社新書)

 

人の個性と認知特性

 頭のよさと言うと、どうしても学力のような一意で絶対的なものという印象がありますが、この本では、「認知特性が得手不得手を決定する」という立場から、人間の能力と認知特性に関する話が紹介されます。

 冒頭には35問からなる認知特性診断テストがあり、自分の認知特性を6つのタイプに分けて診断することができます。6つの認知特性の大まかな説明は以下の通り。

  1. <視覚優位者>カメラアイタイプ:写真のように2次元で思考するタイプ
  2. <視覚優位者>三次元映像タイプ:時間や空間軸を使って3次元で思考するタイプ
  3. <言語優位者>言語映像タイプ:文字や文章を映像化してから思考するタイプ
  4. <言語優位者>言語抽象タイプ:文字や文章を図式化してから思考するタイプ
  5. <聴覚優位者>聴覚言語タイプ:文字や文章を耳から入れる音として情報処理するタイプ
  6. <聴覚優位者>聴覚&音タイプ:音色や音階といった、音楽的イメージを脳に入力するタイプ

 また、認知特性と合わせて紹介されるワーキングメモリの話も、興味深く読むことができました。

自分を知ることの重要性

 自分はストレングス・ファインダー(旧版の方)を読んだことがありますが、そこで痛感したのは、どう努力をしようにも、まず自分が自分を知らないということです。 努力してもできない事や得意でないことよりは、自分の得意を重視した方が自信につながるというのは、自分にとってとても重要な気付きでした。

https://www.amazon.co.jp/さあ-才能-じぶん-に目覚めよう-あなたの5つの強みを見出し-活かす-マーカス-バッキンガム/dp/4532149479/

さあ、才能(じぶん)に目覚めよう 新版 ストレングス・ファインダー2.0 | トム・ラス, 古屋博子 |本 | 通販 | Amazon

 自分を知るという視点で見ると、この本は「自分がどのように物事を見ているか」という傾向を教えてくれるよい本だったと感じます。 実際に診断をやった上で読み進めていくと、自分ができること、できないことに関して、『あーこれはそういうことだったのか』という納得を得ることができました。

 因みに自分の認知特性は以下のようになりました。

 

  1. <視覚優位者>カメラアイタイプ:25
  2. <視覚優位者>三次元映像タイプ:18
  3. <言語優位者>言語映像タイプ:29
  4. <言語優位者>言語抽象タイプ:13
  5. <聴覚優位者>聴覚言語タイプ:20
  6. <聴覚優位者>聴覚&音タイプ:15

 

 この診断によると、自分は文字や文章を映像化してから思考すること、写真のように2次元で思考すること、文字や文章を耳から入れる音として情報処理することが、大まかに得意なようです。

 26以上の特性は特に優れているということで、自分は文字や文章を映像化してから思考するようにする機会の多いことに向いているということでしょう。

 一方、14以下の認知特性は弱いということで、文字や文章を図式化してから思考することは苦手なようですが、全体のバランスとしては悪くないのかな、と感じました。

 本の中ではそれぞれのタイプに関してより詳細な説明が出てきます。

他人を知ること

 この本を読んだのが丁度帰省していた頃だったので、両親にお願いしてこちらの診断をやってもらいました。その結果は以下のようになりました。

  1. <視覚優位者>カメラアイタイプ:24
  2. <視覚優位者>三次元映像タイプ:16
  3. <言語優位者>言語映像タイプ:17
  4. <言語優位者>言語抽象タイプ:33
  5. <聴覚優位者>聴覚言語タイプ:13
  6. <聴覚優位者>聴覚&音タイプ:7
  1. <視覚優位者>カメラアイタイプ:38
  2. <視覚優位者>三次元映像タイプ:31
  3. <言語優位者>言語映像タイプ:17
  4. <言語優位者>言語抽象タイプ:19
  5. <聴覚優位者>聴覚言語タイプ:7
  6. <聴覚優位者>聴覚&音タイプ:10

 面白かったのは、行動の説明が結構ついたことです。

 結果の通り、両親ともに聴覚系の認知が弱く、実際言葉だけでやり取りしてすれ違う様子は見ていましたが、これが分かりやすい形で示されたことには驚きました。 この気付きは、『これからは文字に書いてやり取りするようにしたら?』という提案にも繋がりました。

 父はその場で言葉だけで多くの情報を説明しようとしてこちらを混乱させることが多々ありましたが、これも「父の中だけでは全ての情報が図式として整理されている」ことが原因だったようです。

 両親に限らず、他人の強い認知に対してよりよく響くような形に情報を加工して渡すのがいいのかな、と思えた点では、より大人数でやると面白い診断だと思えました。

少し残念な点

 ここまでは褒める内容を書いてきましたが、ここからは少し残念だったと感じている点です。

 特に診断に関してのことですが、設問が少なく、設問の内容も一瞬首を傾げるようなものが多くありました。 診断結果の偏差が結構大きくなってしまっているように感じます。

 比較対象が値段も厚さも段違いなストレングス・ファインダーなので、お手軽さが取り柄となっているこの本に求めるものではないのかもしれませんが、個人的にはもっと正確に診断して欲しいと感じました。

 後は細かい点ですが、診断の集計がとても面倒でした。 ネット上で受けられるようにしておけばいいのにと強く思います。

最後に

 残念な点は書きましたが、全体で見ると、とても良い本だったと思います。 前述の通り、自分は自分や他人を知ることは、自分の行動を考えたり、コミュニケーションを取る上で非常によいことだと思っています。 この視点で見ると、とてもお勧めできる本でした。

PC自作、情報の集め方

自作PCを作る前には、情報を集める必要があります。特に凝ったPCを作ろうとすればするほど下調べは重要になってきます。

こういった情報の集め方は重要だと思いますが、ググっても今一ピンとくるサイトが引っかからなかったので、自分が意識している情報の集め方を書きます。

「調べる」以外のこと

ただググっても出てこない、という時に、自分で調べるのが本当に効率的かは分かりません。

場合によってはネット上に答えが無いということもありますし、「調べる」以外にも情報を得る方法はあります。

メーカーに問い合わせる

意外と盲点になっている方法で、特にパーツのメカニカルデータは公表されていない場合もあり、調べても、質問しても、誰も答えられないという状況はよくあります。

そういった場合には、メーカーに対して質問を投げるのが最も効率的なやり方です。

自分としては、基本的に他人に質問を投げる前にメーカー問い合わせをした方が良いだろうとも思っています。返答にかなりの確実性が期待できますし、返答の内容に関して、相手が責任を持ってくれるというのは大きいです。

友人を頼る

0番目の方法、誰かの知恵を借りるというのが一番早いです。

自作PCを本気で考えようとすると、どうしても広範囲なパーツの知識が必要になるので、調べるには相応の時間が掛かります。時間がもったいないというなら他人を頼ってみるのも良いでしょう。

そんなことするならBTOとかゲーミングノートとかでも良い気がしますが……。

2ch価格.comなどで質問してみるのも良いですが、こちらは回答が来るか確実性に欠ける点には注意が必要です。

調べ方

自分は、ただググっても出ない時には、「検索を工夫する」、「他言語の情報を当たる」、「間接的に情報を得る」、という3つの方法を意識しています。

Google検索の機能を利用する

まず基本中の基本として、Google検索を上手く使わなければ、必要な情報に辿り着くことはできません。ただググるだけでは、古すぎる情報が混ざってしまったり、似た別の情報が混ざってしまったりして、上手く情報を辿れないことは非常に多いです。

そういった際には、Google検索の機能を利用して結果を絞り込む必要があります。特に期間指定、除外、完全一致の3つは使えるようになっておくと、自作PCだけでなく、色々と役立ちます(ツール内の完全一致オプションではなく、検索ワードに対する完全一致オプションです)。

期間指定はGoogle検索のツールから、除外は除外したいワードの先頭にマイナスを置き、完全一致はダブルクォートで囲います。例えば、CPUクーラーのCryorig C1について、C1に完全一致し、同メーカーのCPUクーラーC7を除く検索は以下のようになります。

「Cryorig "C1" -C7」

以下のドキュメントには除外や完全一致以外にも詳しい説明があります。

support.google.com

この他にも、画像検索を用いることで、言語のみの検索とはまた違った形で情報を得られる場合があります。

Google検索とは違いますが、Ctrl+fでのページ内検索も併用してやることで、検索の効率は大幅に上がります。

日本語以外の情報を当たる

自作PCについての情報は、日本語で見つからなかったとしても、英語や中国語といった日本語以外の言語で落ちている場合が多いです。

読める読めないの問題があるので、自分は基本的に日本語→英語→中国語の順で調べるようにしています。

中国語に関しては調べることが少ないので何とも言えませんが、少なくとも英語ではPCパーツ関連のかなり踏み込んだ情報を取り扱う大手サイトが複数あるので、日本語よりも情報が豊富なのは確かです。

ググる以外の手段

上記のような工夫をしてもまだ情報に辿り着けないような場合、自分はYoutubeや様々な通販サイトのレビューなどを見るようにしています。

これらはGoogle検索の仕様で検索結果に表示されない場合があるので、それぞれのサイト内で検索するとまた違った情報を得ることができる場合があります。

特に自分がよく利用するのはYoutubeです。

間接的に情報を得る

検索方法を工夫をしてもどうしようもないことが多いのは、複数製品の比較や、パーツとパーツの物理的な干渉問題です。これらの情報は、普通の人間が比較する機会がまず無かったり、その特定の組み合わせについて検証している人間が居なかったりと、情報が存在する確率が低い傾向にあります。

情報が存在しない場合には、自分は間接的に情報を割り出すことをしています。

例えばCPUクーラー同士の比較であれば、別環境で同一CPUでのデータがある場合や、CPU温度と、CPUのTDP、TDWといった情報からある程度情報を割り出して比較することができる場合があります。少なくとも「2製品でどちらが優れているか」、という傾向を割り出すだけであれば、割と簡単にデータを得ることができます。

ケースやCPUクーラー、メモリといった干渉の有無を確認する際には、その製品と別の製品の組み合わせから干渉の有無を割り出せる場合があります。前述した画像検索やYoutubeでの検索は、画像や動画では実物を色々な角度から見るこという利点があるので、このように情報を得ようという場合には非常に役立ちます。

他には、メモリのヒートシンク高を商品画像から割り出したこともあります。メモリは横幅が決まっているので、意外と簡単に割り出すことができました。

ただし、情報の精度という点では直接的に情報を得た場合に敵わず、検索時間も長くなる点には注意が必要かなと思います。

まとめ

「検索を工夫する」、「他言語の情報を当たる」、「間接的に情報を得る」、「他人に聞く」、この4つが必要な情報を得るために重要な要素だと自分は思っています。

調べごと以外で

個人的には、自作PCに限った話ではなく、ブログやSNSなどで優れた情報発信者を見つけておくことが重要だと思っています。

自分は、自作PCに関してであれば、企業系のサイト以外では、自身で取ったデータを掲載しているようなサイトは信用し、2chまとめのようなサイトはほぼ信用しないことにしています。

情報を調べる際には、その発信者が信用できるかと、その発信者の動向をこれからも追うか、という観点で見てみると、より深い知識を得ることにつながるかな、と思います。

読書感想「最悪の事故が起こるまで人は何をしていたのか」

 こちらの本を読んだので、感想を書きます。

最悪の事故が起こるまで人は何をしていたのか

最悪の事故が起こるまで人は何をしていたのか

 

 有能な人が無能者になる瞬間

 普段から物知りなのに、ある知識について勘違いしていたり、緻密に計画を立てたのに、ほんの少しの勘違いから計画を台無しにしてしまったり、それまでは有能だった人間が、一瞬無能となってしまうシーンを、自分は日常の中で多々見かけます。

 

 これが内輪の話であれば、その失敗は笑い話になったり、あるいは記憶にも残らずに忘れ去られ、その人の評価は"有能な人"のままです。 しかし、これが外部を巻き込む話であれば、その規模が大きければ大きいほど、どれだけの能力を持った人間であっても、一瞬の無能が一生のレッテルへと変じます。

 

 自分はこの本を読んで、その一瞬の無能こそが最悪の事故を引き起こす原因だという事実と、 同時に、その一瞬から一個人が逃れることの難しさを感じました。

どれほど低い確率でも、0でないならそれは起きるということ

 この本では、様々な事故の発生するまでの過程が描かれますが、その中に共通しているのは、そこに『誰かを害してやろう』だとか『誰かを不幸にしてやろう』なんていう悪意は一切無く、ただ大勢の人間の「無知・無能・無関心」が積み重なっていく様子しか無いという点です。

 

「無知・無能・無関心」は、たった一つでもシステムを壊滅させ、破壊をまき散らす可能性を持っているものです。 それが沢山集まったなら、例えどれだけシステムが危険性を排除したとしても、可能性は0ではなくなり、そしていつかコトが起きてしまう――その過程が、この本では余すところなく描写されています。

 

 本文中で語られる、「現在の機械やシステムというものは複雑で巨大なものとなり、その管理のためには一個人ではどうしようもない程の知識と能力、そして危機への警戒心が必要となっている」、という筆者の主張に、自分は強く同意します。

個人が努力し、それでも無知のは当たり前、問題はその更に先

 自分は、重大な事故の後で現場の人間を責める人間も多々見かけます。 しかし、自分はこの本を読む前から、この主張は大部分が間違ったものであると感じていました。

 少なくともある個人の取った行動が訓練の通り、もしくは訓練されたものでなかったとするなら、それによる事象に対する責任は、個人の教育に責任を持つ組織に帰せられるべきものであり、またそれに関わった個人が専門家として十分な知識を持っていたという実例は多くあるからです。

 

 

 この本を読んで気付いたことは、このような状況が生まれる背景には、「とてもよく訓練された個人の集団というだけでは管理できない物が数えきれないほどにある」という事実と、「その事実に気付き、危機感を持ち、本気で改善しようと考えられる人間は思ったよりも少ない」という事実があるということです。

 そして、例えそれらの事実に気付いていたとしても、可能性が0でないのなら、自分もまたいつか『無能者』になりかねない事実についても気付かされました。

 

 この本を読んだ感想として、また自分の意見として、「重要なのは問題を未然に防ぎ、それを評価するシステムだ」ということを強く感じています。前述の通り、既に今世の中にある物の多くは、「とてもよく訓練された個人の集団というだけでは管理できないもの」だからです。

「優秀な副操縦士

 この本の中では、パイロットの人的過失による航空事故において、副操縦士が果たす役割について触れている項目があります。 それによると、重大な事故においては、運航に遅れがあり、機長が操縦していて、経験の浅い副操縦士が機長のミスを指摘できないでいた、という状況が余りにも多いということでした。

 これは機長や副操縦士が無能だったという話ではなく、機長が気付かない部分を副機長が気付いたか、気付いたとして、修正に移ることができたのか、という話です。

 

 この本の中ではこの事実を基に、「ズケズケとものを言う腕利きの副操縦士」が事故防止には重要だという主張が登場しますが、これこそが危機管理とそれに関するシステム構築の最大の課題だと自分は感じました。

「ズケズケとものを言う腕利きの副操縦士」には、危機を察知できるだけの注意力と、危機と対策を判断できるだけの知識と、自分よりも知識があるであろう人間に、その場で先んじるだけの行動力が必要になります。

 

 自分は、危機管理のシステムにおいて最後に重要となるのは、「権威に対しても屈せずに危険を指摘する人間」だと、この本を読んで感じました。

 この本の中では、洗練された危機管理のシステムがありながら、それを権威が無視させた結果としての大惨事も多く紹介されます。 そしてその権威とは、例えば年齢であり、利益であり、日程でありました。 つまり、上は権威を振りかざさず、下は権威に逆らってでも行動できる風土こそが、事故の予防には必要なのだろうと、自分は感じます。

自分は「優秀な副操縦士」で在れるだろうか

 自分はまだ大学生で、決定的な判断に関わる機会は少ないです。 しかし、実際に他人の『一瞬の無能』に立ち会う瞬間は多くありますし、勉強した内容から、ある分野で年長者よりも知識を持っているという場合も増えてきました。 自分がこれから進む道においては、危機管理を意識したシステムの下で過ごすことができる確率は恐らく低いのだろうとも思っています。

 個人としても、やはり知らない事があり、それが全く無関係の第三者を害することがあるということも自覚しつつあります。

 

 そしてこの本は、そんな未熟な個人である自分が、いざという時に「優秀な副操縦士」であることを求められうるということを考える良い機会になりました。 色々と見逃しがちでしたが、もっと意識してやっていきたいと感じます。

 

「最悪の事故が起こるまで人は何をしていたのか」は、ここに書いたこと以外にも、多くのタメになる知識が載っている、お勧めの一冊です。

最後に

 個人的には、航空機事故について扱った、「メーデー!」シリーズがとても参考になると思います。

様々な刺激があるので、ニコニコ動画で見るともっと参考になるかなと思います(ボソッ

第1話「タン航空3054便」
 

Androidで、C++とJavaの実行速度を少しだけ比較

AndroidC++コードの実行速度とJavaコードの実行速度を少しだけ比較してみました。
この検証に使ったコードは以下に公開しています。
github.com

環境

開発環境 Android Studio2.3
NDKバージョン 14.1.38168.74
実行デバイス(Androidバージョン) SH-02H(6.0.1)

実行したコード

実行したコードは、for文中にif文を挟むコードです。
計測されている時間はミリ秒です。

エミュレータではJavaの方がC++よりも実行速度が速くなったりと実行速度がおかしかったので実機で計測しました。

C++の導入やそのコードの使用方法については省略します。

C++
extern "C"
JNIEXPORT jint JNICALL Java_com_wrongrong_cpptest_MainActivity_cppForTest(JNIEnv* env, jobject obj){
    int i,j;
    j = 0;

    for(i = 0;i < 200000000;i++){
        if(i&1 == 1)j++;
    }
    return j;
}
Java
public class JavaForTest {
    public int javaForTest(){
        int i,j;
        j = 0;

        for(i = 0; i < 200000000; i++){
            if((i&1) == 1)j++;
        }
        return j;
    }
}
検証用コード
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    TextView tv = (TextView) findViewById(R.id.sample_text);
    String ln = System.lineSeparator();
    JavaForTest jft = new JavaForTest();
    int i,j=0;
    long jftS,jftE,cppS,cppE;

    for(i = 0;i < 200000000;i++)j += i;

    jftS = System.currentTimeMillis();
    i = jft.javaForTest();
    jftE = System.currentTimeMillis();

    cppS = System.currentTimeMillis();
    j = cppForTest();
    cppE = System.currentTimeMillis();

    //出力の整形
    StringBuilder sb = new StringBuilder(String.valueOf(i - j)); sb.append(ln);
    sb.append("Java:"); sb.append(String.valueOf(jftE - jftS)); sb.append(ln);
    sb.append("C++:"); sb.append(String.valueOf(cppE - cppS)); sb.append(ln);
    sb.append("Java/C++:"); sb.append(String.valueOf((double)(jftE - jftS) / (double)(cppE - cppS)));

    tv.setText(sb.toString());
}
脚注

実行速度安定化のための空ループを挟んでみたが、挟まない方がC++Java両方に関して、実行速度は高速でした。
一方、ループを挟まない場合、先に実行した方のコードの実行速度が速くなる傾向がありました。
レジスタの関係でしょうか?

実行結果

JavaC++に対して大体13倍ほど実行速度が遅いという結果になりました。
プログラム実行速度の計測に関して余り知識が無いので何とも言えませんが、やはりリアルタイム処理のような高速性の求められる処理では、C++を用いて処理を行った方が良いのでしょう。

Androidアプリで、タイトルバーを消す方法

色々なサイトを見たが動かない場合によくぶち当たったので、自分の環境で動いた例のサイトを備忘用に保存。

やったこと

values/styles.xml内で、parent="Theme.AppCompat.Light.DarkActionBar"となっている部分をparent="Theme.AppCompat.Light.NoActionBar"と書き換える。

参考サイト

丸々以下の内容。
ja.stackoverflow.com