JavaScriptのJSONでDate型を扱う

JavaScriptJSON.stringify、JSON.parseはDateに対応していない(というかJSONの仕様に日付型がそもそもない)。なのでJSON.stringifyをDateに対して実行するとISO 8601フォーマットでの日時を表す文字列になる。

var str = JSON.stringify(new Date());
console.log(str); //"2014-03-18T23:05:45.477Z"


一度こうなったらJSON上ではただの文字列型なので、この文字列をJSON.parseしても結果はただのstring型になってしまう。

var obj = JSON.parse(str);
console.log(typeof(obj)); //string


JSON.parseは第2引数に挙動をカスタマイズする関数オブジェクトが渡せるようになってるので、これを使って日付っぽい文字列が来たら日付として扱うことにする。

モダンなブラウザーなら動くんじゃないかな多分。

ターミナルヘブンズロック

screen自前でコンパイルしたりしたけどcopy modeのキーバインド変えたかったんだけどコンフィグの書き方が意味分かんなすぎたのでtmuxに乗り換えることにした。設定書きやすくて素晴らしい。

でもダメなところもあってTerminal.appだとウインドウ切り替えた時のレンダリングが妙に遅い。チラツキが見える。よくわからないけど試しにとiTerm2に変えてみたらチラツキ見えなくなったのでこっちを使っていくことにした。
テーマはzenburnに設定。せっかくなんでバックグラウンドにイメージ置こうと思ってちょっと考えた結果Fenderロゴを配置してみた。

合わせてEmacsのテーマもzenburnに。なんか人気らしいので当初はsolarizedにしようとしたんだけどどうにも色が正しく出ないのでやめた。とりあえずこんな感じ。

f:id:oscdis765:20140308194326p:plain

emacs + screen + Terminal.appでカーソルがずれるのを何とかする

OS Xemacs + screen + Terminal.appを使ってて、いわゆる全角の記号などを扱うと表示がおかしくなることがよくあった。というかOS XだけじゃなくWindowsPUTTYからLinuxSSHでも起きてた気がするけど。ふと気が向いたのでこれを解決しようとしたら出来た。

まず、ターミナルの設定 > 詳細 >「Unicode 東アジア A (曖昧) の文字幅を W (広) にする」にチェック。

次にOS Xのscreenが古いのでソース持ってきて自前でコンパイルする。せっかくなんでついでに256色対応もしとく。

git clone http://git.savannah.gnu.org/cgit/screen.git
cd screen/src
./autogen.sh
./configure --enable-colors256 && make


.screenrcになんか良しなにしてくれる一行を追加。これが古いscreenだと使えない。

cjkwidth on


.zloginでターミナル起動時にscreen立ち上がるようにしてるんで、ここをさっきのコンパイルしたのに変更。

if [ $TERM != "screen" ]; then
    exec /path/to/screen -S main -xRR
fi


以上!

キャッシングプロキシー書いた

頻繁に見に行く大好きなサイトなのだけど、残念ながら非常に重いサイトがあって、前から何とかしたかったのでWebrick使ってファイルをキャッシュするプロキシー書いた。 

 

proxy_serviceのオーバーライドなど雑な実装だし、ちゃんとしたプロキシー用途には耐えないので、プロキシー設定ファイルを使って特定サイトのみ対象とする。

 

また、Macだとプロキシー設定ファイルを使う場合、httpに載ってないといけない。なのであらかじめ上記プロキシーではpublicフォルダ以下を公開する設定にしてるので、proxy.pacをpublicにコピー、http://localhost:18080/proxy.pacをネットワークの設定に設定する。

ポーカーの役の判定

class Cards
  class Card
    attr_reader :suit, :rank
    def initialize(suit, rank)
      @suit = suit
      @rank = rank
    end
  end

  attr_reader :suits, :ranks
  def initialize(cards)
    @cards = cards.map{|e| e.kind_of?(Card) ? e : Card.new(*e)}
    @ranks = @cards.map(&:rank).sort
    @suits = @cards.map(&:suit)
  end

  def same_rank_counts
    same_ranks = ranks.group_by{|r|r}.values
    same_ranks.map(&:size).sort.reverse
  end

  def straight?
    steps = ranks.map{|r|r-ranks[0]}
    steps==[0,1,2,3,4] || steps==[0,9,10,11,12]
  end

  def flush?
    suits.uniq.size == 1
  end

  def hand
    case same_rank_counts
    when [2,1,1,1]
      :one_pair
    when [2,2,1]
      :two_pair
    when [3,1,1]
      :three_of_a_kind
    when [3,2]
      :full_house
    when [4,1]
      :four_of_a_kind
    else
      case [straight?, flush?]
      when [true, false]
        :straight
      when [false, true]
        :flush
      when [true, true]
        if ranks == [1,10,11,12,13]
          :royal_flush
        else
          :straight_flush
        end
      else
        :hi_card
      end
    end
  end
end

if __FILE__ == $0
  ranks = (1..13).to_a
  suits = [:spade,:heart,:diamond,:club]

  all_cards = suits.product(ranks)
  result = Hash.new(0)
  all_cards.combination(5).each_with_index{|a, i|
    cards = Cards.new(a)
    result[cards.hand] += 1
    p result if i%100000 == 0
  }
  
  p result
end