boostをインストールした

# cd /usr/ports/devel/boost-all
# make install clean

これで導入は完了./usr/local/include/boost にヘッダファイル,/usr/local/lib にライブラリファイルができるはず.boostの中にはヘッダファイルのみでコンパイルできるものと,ライブラリをリンクさせなければならないものがある.ヘッダファイルのみの場合は,includeしてコンパイルすればよい.ライブラリが必要なものはリンカで指定してやる必要がある.デフォルトではリンカは /usr/lib を検索するため,/usr/local/lib に存在するライブラリを発見できないからである.指定する方法は2つある.LD_LIBRARY_PATHに /usr/local/lib を追加する方法と,コンパイル時に指定する方法である.指定するオプションは -L である.

$ g++ foo.cpp -L /usr/local/lib -lboost_system

これは,/usr/local/lib をライブラリ検索のパスとし,libboost_system をリンクする例である.

boost::asioを使ってtwitter api にbasic認証する.

basic認証して,home_timelineを取得する例を示す.今回はjson形式を取得した.picojsonはjsonをデコードするために使用した.XML形式や,RSS形式でやる場合はpicojsonは必要ない.twitter apiが扱う文字コードUTF-8であることに注意.またtwitter apibasic認証を廃止するようなので以下のコードはそのうち使えなくなる.basic認証のサンプルとして残す.

#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include "picojson.h"

using namespace std;
using namespace boost::asio;
using namespace picojson;

int main()
{
    ip::tcp::iostream s( "twitter.com", "http" );

    s << "GET /statuses/home_timeline.json HTTP/1.0\r\n";
    s << "Host: twitter.com\r\n";
    s << "Authorization: Basic Zm9vOmJhcg==\r\n";
    s << "\r\n";
    s << flush;

    string line;
    while( getline(s, line) )
        if( line == "\r" ) break; // cut header

    if(s){
        value v;
        string err = parse(v, s);
        cout << v;
    }
}

basic認証のときは,ユーザー名とパスワードを:で結んだものをbase64エンコードして与える.上記の例はユーザー名 foo, パスワード bar の例である.以下のようにして作成した.

$ echo -n 'foo:bar' | nkf -MB
Zm9vOmJhcg==

boost::asioを使うにはライブラリをリンクする必要があるため,以下のようにコンパイルする.

$ g++ source.cpp -L /usr/local/lib -lboost_system

ちなみにbinaryがリンクしているライブラリはlddコマンドで確認できる.

$ ldd a.out
a.out:
      libboost_system.so => /usr/local/lib/libboost_system.so (0x280a7000)
      libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x280ab000)
      libm.so.5 => /lib/libm.so.5 (0x281a1000)
      libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x281bb000)
      libc.so.7 => /lib/libc.so.7 (0x281c6000)
      libthr.so.3 => /lib/libthr.so.3 (0x282de000)

SRM468 RoadOrFlightEasy

はじめて臨んだTopCoder.以下のような強引なやり方は思いついたもののC++での書き方がわからず時間内にsubmitできず.行っているのは,差分のvectorをつくって,差分を降順ソート.roadTimeの合計-(差分の先頭からK個分の和).ただし,差分の値が0以下ならroad経由のほうが同等かそれ以上早いため,そこで打ち切り.

#include <map>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

class RoadOrFlightEasy {
public:
  int minTime(int N, vector <int> roadTime, vector <int> flightTime, int K) {
    int ret = 0;
  vector<int> diff;
  
  for(int i = 0; i < N; i++){
    int r = roadTime[i];
    int f = flightTime[i];
	diff.push_back( r - f );
	ret += r;
  }
  sort(diff.begin(), diff.end(), greater<int>());

   for(int i = 0; i < K; i++){
	if( diff[i] <= 0 ) break;
	ret -= diff[i];
   }
  return ret;
  }
};

7.0から8.0へ

面倒くさがって上げてなかったFreeBSD7.0をFreeBSD8.0へあげた.そのときの作業メモを残す.

csupを使ってソースを入手するのだけれど,なるべく早いサーバーを調べたい.そのためには,fastest_cvsupを使う.

# cd /usr/ports/sysutils/fastest_cvsup && make install clean
# fastest_cvsup -c jp // 日本での早いサーバーを調べる.

今回は,cvsup6.jp.freebsd.orgが最速だったのでこいつを使うことにする.

# vi /usr/share/examples/cvsup/standard-supfile
  *default host= cvsup6.jp.freebsd.org に書き換え.
# cvsup -g -L 2 standard-supfile // ソースの取得

ソースの取得ができたら次はコンパイル&インストールを行う./etc以下のバックアップは各自必要ならとる.

# cd /usr/src
# make buildworld
# make buildkernel
# make installkernel
# shutdown -r now

再起動後,シングルユーザーでログインする.数字の4でシングルユーザーモードでログインできる.

# adjkerntz -i
# mount -a -t ufs
# mergemaster -p
# cd /usr/src
# make installworld
# mergemaster
# reboot

mergemasterは/etcのファイルを更新するコマンド.手動で更新するのが面倒な場合は,mergemaster -UPi.

Software Design総集編を買った

付属のindex.htmlから閲覧用のflashを呼び出して使う形なんだけど,このflashが使いにくい.なので,libs/backnumber.xmlを利用してHTMLを生成するRubyスクリプトを書いた.Ruby初めて使ったのでRubyっぽくないコードだと思う,たぶん.HTML生成部分とロジックが混じってて汚いけど,使いすてだし,まぁいいか.

●使い方
スクリプトUTF-8で保存後,CDのトップディレクトリで実行.うまくいくと,2000...2009.htmlが生成される.CSSも書こうとしてsytle.cssと指定したが,結局面倒くさいので書いてない.

require "rexml/document"
include REXML

class Converter
	def initialize
		@doc = Document.new File.new("libs/backnumber.xml")
		@html = ""
	end
	
	def books(y = nil)
		@html = "<html>\n<head>\n\t<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\" />\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />\n\t<title>SoftwareDesign #{y}年</title>\n</head>\n<body>\n<h1>Software Design総集編 2000-2009</h1>\n"
		@html << "<ul>"
		for i in 2000..2009
			@html << "<li><a href=\"#{i}.html\">#{i}年</a></li>"
		end 
		@html << "</ul>"
		@html << "<h2>Software Design #{y}年</h2>\n"
		@doc.elements.each("/datas/data[@year=#{y}]/book") do |book|
			m = book.attributes["month"]
			img_path = book.attributes["coverImage"]
			@html << "<h3>#{y}#{m}月号</h3>\n"
			@html << "<div id=\"#{y}#{m}\">\n<img src=\"#{img_path}\" />\n"
			pages(y, m)
			@html << "</div>\n"
		end
	end
	
	def pages(y = nil, m = nil)
		@html << "<table>\n\t<tr><th>分類</th><th>タイトル</th><th>ページ</th></tr>\n"
		@doc.elements.each("/datas/data[@year=#{y}]/book[@month=#{m}]/page") do |page|
			title = page.attributes["title"]
			type = page.attributes["type"]
			file_path = page.attributes["filepath"]
			pages = page.attributes["pages"]
			file_path.gsub!(/\\\\/, '\\')
			@html << "\t<tr><td>#{type}</td><td><a href=\"#{file_path}\">#{title}</a></td><td>#{pages}</td></tr>\n"
		end
		@html << "</table>\n"
	end
	
	def output(file_name = 'foo.html')
		@html << "</body>\n</html>"
		f = File.open(file_name, "w")
		f.write(@html)
		f.close
		@html = ""
	end
end

c = Converter.new
for i in 2000..2009
    c.books(i)
    c.output("#{i}.html")
end

Xorg7.4にしたらマウスやキーボードが動かなくて困った

xorg.confの修正は以下.

Section "ServerLayout" に Option "AllowEmptyInput" "off" 追加.
Section "ServerFlags"
    Option         "AutoAddDevices" "False"
EndSection
RgbPath      "/usr/local/share/X11/rgb" はコメントアウト

x11-drivers/xf86-input-keyboard なんかをUpdate.

/etc/rc.confは以下を追加.

hald_enable="YES"
dbus_enable="YES"
moused_enable="YES"