しあわせの必要条件

17歳のころに学ぶべきこと/無遅刻・無欠席を礼賛する風潮はどうかと思います の、

しあわせの必要条件は「自由」であることだ。

に思うところあったので感じてることをメモメモ。

こんな事を書いて会社を辞めた僕がこれに共感したって書くと、仕事してない僕は自由だー!って言ってるみたいだけど、ここで言う「自由」とは、何かをしなくて良い自由というより、何をするか自主的に選択する自由と言った方が言わんとするニュアンスに近いと思う。

ここ数日、なんでかなって考えてたことがあった。
根詰めて勉強するのは体力的にもキツイし、孤独だし、思うように進まなくてイライラしたりする。
それなのに、強がりでも何でもなく、今僕は大きい大きい幸福感を感じてる。
予想してた精神状態と違う。もっとシビアなメンタルコントロールが要ると思ってた。

やりたかった事をやれてるから?ちょっと違う。今月は色々あってやれてない。焦りはあるし充実感薄い。
仕事のストレスが無いから?多少はあるかも。でもその分将来への不安とかストレスになってるはず。

そこでしっくりきてた考えがこれだった。
もしかして:今の状況を自分で選択している実感があるから

自分で考えて選択した結果が今だと実感する事は、選択の正誤に関係なく、精神的に良い影響がきっとある。多少の不安やストレスならかき消してしまうほどの。
起業家にやたらテンション高い人が多いように見えるのは、そう振る舞う必要があるだけじゃなく、選択による幸福感も影響してるんじゃないかな。
単に選択肢があるだけじゃなく、結果に責任を持つ覚悟や、自分の頭で精一杯考えたことが、選択の「実感」につながってる感じ。

必要条件なのかは分からないけど、今感じている限りすごく大きな心理的作用なので、

  • 強制的に選択を奪う不要なルールや同調圧力にはもっと敏感になろう。
  • 幸せに働いてもらうには多くの選択を相手に委ねたい。できることは最小限の制約の明示とゴールの共有。
  • 選択できる人が選択できない人に同じ負荷を強いてはいけない。
  • 限られた人しか選択できない世の中は構造的に欠陥がある。

とか考えてた。

僕は僕で、しあわせな人間が高いパフォーマンスを発揮できることをちゃんと示したいなと思ったりしています。

ソートのアルゴリズム

Googleの新卒採用向けHangoutをひやかしで見てたら、社員の方がこんな感じのことを言ってた。

Googleの面接といっても難しいことは聞かれなくて、CS(Computer Science)の人なら答えられるであろう質問だった。自分の場合だと、クイックソートを書かされて、そこから性質や計算量のオーダーなどについての説明を求められた

CSやってた人として恥ずかしくない技能を身につけたい!って思いながら毎日過ごしてる自分としては気になるコメント。
ほうほう、クイックソート…。どんなんやったっけ。うろ覚えなまま15分かけて実装するも、あえなく無限ループ。さらに30分かけてバグを取ったのがこちらのコードになります…orz 面接終わってるな。

#include <iostream>
#include <vector>
using namespace std;

void quicksort(const vector<int>::iterator begin, const vector<int>::iterator end) {
  if (end - begin <= 1) return;
  // pivotには単純に先頭要素を使う
  int pivot = *begin;

  // 両サイドから走査して、pivot未満の要素とpivot以上の要素の
  // 組が見つかったらswap
  vector<int>::iterator left = begin, right = end - 1;
  do {
    while (*left < pivot && left < right) left++;
    while (*right >= pivot && left < right) right--; 
    if (left < right) {
      swap(*left, *right);
    }
  } while (left != right);

  // [begin, left)がpivot未満、[left, end)がpivot以上なので、
  // leftを境に分割する。ただしleft==beginの時は全要素pivot以上なので
  // pivotになった左端の要素は左側の区間に振り分けて区間を小さくする
  vector<int>::iterator mid = left;
  if (mid == begin) mid++;

  // 分割した区間に対して再帰的にsort
  quicksort(begin, mid);
  quicksort(mid, end);
}

int main() {
  static const int a[] = {3, 2, 1, 2, 6, 5, 9, 1, 8};
  vector<int> v(sizeof(a) / sizeof(a[0]));
  v.assign(a, a + v.size());

  quicksort(v.begin(), v.end());

  for (int i = 0; i < v.size(); i++) cout << v[i] << " ";
  cout << endl;
}

車輪も1回くらいは作っとくべきだよね。

書いてるうちに気になったのが、STLのsortはどんな実装になってるんだろう?ってこと。検索するとSigmarさんが調べてブログに書いてくれてた。代表的な実装ではこんな感じになっているのだそう。

  1. まずはクイックソート
  2. 再帰がある一定以上深くなったらヒープソートに切り替え
  3. ある程度ソートが進んだら、最後は挿入ソートで仕上げる

手順1と2をまとめてイントロソートっていうらしいです。なるほどなるほどー
汎用的なままよいパフォーマンスを発揮するために工夫されてるんだなぁ

あと、調べてる時に遭遇した、Haskellで書いたクイックソートがかっこよすぎた。

qsort [] = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)

Haskellも勉強して嗜んでみたいです。

1月のまとめ

東京帰ってきてから3週間くらい。やってたことをメモメモ。

勉強した本

1対1対応の演習/数学I・数学A

やり方は、例題は5分で分からんかったらヒントだけ見てもっかい考える、演習題は20分考えて分かんなかったら答え見る、って感じ。タイマー持ってやってた。
かかった時間は1A合わせて1週間くらいだったと思う。
教科書レベルの内容を確認するために白チャートも買ってたけど結局ほとんど使わなかった。(上記本内の「要点の整理」とネットで事足りた。)

高校生1年生向けだけあって、大事な事が高密度に盛り込まれてるなあと思う。
集合、命題論理、確率とかは僕が普段考えごとする時にも基礎になってて、その部分の基本理解を固め直した事で少し頭の霧が晴れた感覚。
30分くらい集中を維持するための訓練にもなった。
終わった頃ちょうどセンターの時期だったのでやってみたけど97点でしたワーイ(現役の時より良かった!)

プログラミングコンテストチャレンジブック 第2版

まだ初級編だけ終わったとこだけど1週間以上かかってる。
中の人が頭良すぎるのか、紙面の都合なのか、基礎的な内容から急に発展的な結論に飛んだりするので、理解するために紙にいろいろ書いて考えたりWikipediaとかネット調べたりしてちょっとづつ進めた。数学の基礎なしできっちり理解するのは難しいと思う。
それでもいい本。きっと読みきれば相当の力が付く。
勉強の仕方としては、練習問題の解答とか各手法のコードを理解した後、必ず自分で答え見ずに書きなおすようにしてた。コード理解するフェーズでは写経した上でデバッグ文入れて…とかやるんだけど、その後必ずそらで1から書き直す。僕の場合は「STLを可能な限り活用する」「グローバル変数は使わない」みたいな自分ルール追加して書きなおしてたけど、違う言語で書くのも効果的だと思う。第2版から付いてくる練習問題も当然やる。

参加したコンテスト

Facebook Hacker Cup 予選 (ソースとコメント)
 o-o 646位/? 通過。
Facebook Hacker Cup Round1 (ソースとコメント)
 ooo 756位/? 通過。
TopCoder SRM 531 Div2 (ソースとコメント)
 o-o 18位/1240 Rating:1187->1303

遊んだゲーム

Skyrim (PC)
 今年いっぱいこのゲームだけで乗りきれるんじゃないかと思ってる
jubeat plus (iPad)
 むりーって思う曲もいつの間にかついていけるようになってる感覚が楽しい
なめこ栽培 (iPhone)
 中毒性を少し理解したけど2日目に飽きた

ほか

あとは手続き関係こなしたりご飯作ったりゴロゴロしたり本屋めぐったり知らない言語とかツールをつまみ食いしたりしてた。
とにかくすっごく長く感じた。2月以降も長いといいなあ。