読者です 読者をやめる 読者になる 読者になる

特定の文字列を含んだファイルを格納したディレクトリをユニークに抽出するシェルスクリプト

found_dirs=()
for filepath in `find foobar -follow -type f`
do
    result=`grep ${filepath} -e hogehoge -l`
    if [ ${#result} -gt 0 ] && [ -f ${result} ]; then
        found_dirs+=(`dirname ${result}`)
    fi
done
echo "${found_dirs[@]}" | tr ' ' '\n' | sort -u

メモ

  1. 配列に次々と追加していき最後にソート&ユニークをかける方法がカンタン
  2. trコマンドは文字列の一括置換
  3. ${#str}で文字列長を取得
  4. 日本語キーボードでバッククオート(`)を打つには shift+@

Homebrewからrbenvの導入を試みたらrubyのインストールが上手くいかなかった

ことの発端は,とあるプログラムがruby依存だったことにあります.
ライトウェイト言語である以上,rubyでもバージョン管理が大変ですね.

pythonにおけるvirtualenvと同じ位置づけとして,
rubyではrbenvというものがあります.

Ruby - Homebrewのインストールとrbenvのインストール Mac編 - Qiita
にしたがって,一気にrbenvまでインストールしちゃいましょう

brew install rbenv
brew install ruby-build
brew install rbenv-gemset
brew install rbenv-gem-rehash

以上でrbenvのインストールは終了です.簡単ですね.
無事,rbenvが導入できたので早速rubyをインストールしていく. ...つもりが,ここでエラー発生.

rbenv install 2.0.0-p247 // これはOK
rbenv install 1.9.3-p547 // これはエラー

1.9.3系ではコンパイラが違っているのかな?

checking whether the C compiler works... no

などとエラー吐かれてしまう.
gccはインストールしてあるはずなのに…と,思っていたらこんな投稿を発見.
Mac(Mavericks)にRuby1.8.7を入れようとしたら大変だった話 - Qiita
環境変数CCとしてgccのパスを設定してあげる必要があるとのこと.
(CCコマンド自体のエイリアスを張り替えてもいいのですがこっちのほうが精神的に健全ですね)

CC=PATH_TO_GCC rbenv install any_version_you_want
(例) CC=/usr/local/Cellar/gcc48/4.8.3/bin/gcc-4.8 rbenv install 1.9.3-p547

ということで無事,ruby1.9系と2.0系の共存ができました.
rbenvを使っているのでコマンド一発で切り替えも可能です.

ref [1]: Ruby - Homebrewのインストールとrbenvのインストール Mac編 - Qiita
ref [2]: Mac(Mavericks)にRuby1.8.7を入れようとしたら大変だった話 - Qiita

powerpointで作成した図をeps(ベクター形式)で保存する方法 (Mac版)

  1. パワポで好きなように図を作る
  2. 1つの図に対して1枚スライドを対応させる
    (次のpsファイルとして書き出す際に,スライドごとにpsファイルが作成される)
  3. psファイルとして書き出す
    [powepoint メニュー] -> [ファイル] -> [プリント]

    f:id:sat0yu:20140624141130p:plain

    f:id:sat0yu:20140624141139p:plain

  4. ps2epsコマンドでpsファイルからepsへ変換
    $ps2eps --rotate=+ foobar.ps
    この際,なぜか画像が90℃回転してしまうので--rotateオプションで逆回転させる

完備辞書を実装した(デバッグした

以前に実装したものがバグだらけ…というか勉強不足でブロックサイズなどなどがめちゃくちゃでした.
ということで改めて実装しなおしました.

2**16 = 65535ビットまでならコードをいじらずにそのまま使えます.
それ以上にビットを管理したいのであればソース中のsBlockやlBlockあたりをいじれば動くと思われます(確認はしていません

ソースコード:
https://raw.githubusercontent.com/sat0yu/algorithm/master/bitvector.cpp
検証用データ:
https://raw.githubusercontent.com/sat0yu/algorithm/master/data/bits.dat

検証用データはパスとかいい具合に調整して使ってください

 

コマンドラインから.pngを.epsへ変換

tex周りをmakefileで一発コンパイルしようとしたところ,
画像配置のにpng -> eps変換が必要になった
もちろんxbbを使う方法もある…

  • 前提: Imagemagickおよびxpdfがインストール済み
    (いずれもbrewでインストールできます)
  • アウトライン:png -> pdf -> eps
  • 変換手順:
    %convert XXX.pdf XXX.eps
    %pdftops -eps XXX.pdf XXX.eps

実はconvertコマンドでpng -> eps変換できます.
できますが,ファイルサイズがどデカくなりますorz
そこで,ひとたびpdfを経由し,zipで圧縮をかけるらしいです.
元ネタ:Convert .pdf to .eps in terminal | Jinha Kim

"sudo pip install -U cython" returns error: unknown argument: '-mno-fused-madd' [-Wunused-command-line-argument-hard-error-in-future]

手持ちのMBAクリーンインストールしてから,すっかりCythonを入れ忘れてた.
ところが,いつもどおりpipでインストールしようと思っっていたら謎いエラーが待ち構えていた.
困った時のstackoverflowさん.いつもお世話になっています.
結果としては,環境変数として以下を定義してあげると回避できるみたい.

%ARCHFLAGS="-Wno-error=unused-command-line-argument-hard-error-in-future"

ただしsudo pipする場合にはsudo側で環境変数を定義してあげないとだめ.
(sudo時に環境変数を引き継ぐオプションあった気がするんだけどなあ)
そこで,手っ取り早く今回はsudoではなくsuしてやる.

%sudo su
$ARCHFLAGS="-Wno-error=unused-command-line-argument-hard-error-in-future"
$pip install cython

元記事(stack overflow):pip install salt returns 'clang: error: unknown argument: '-mno-fused-madd' [-Wunused-command-line-argument-hard-error-in-future]

C++で完備辞書(ビットベクトル)を実装してみた

[2014.06.06] 実装しなおしました.
完備辞書を実装した(デバッグした - sat0yu's blog


高速文字列解析の世界
を輪読しているので,復習がてら”密な場合”を実装してみた.
"疎な場合"は闇が深そうだけどいずれ実装してみたい. 次はウェーブレット木.たのしみ.

#include<iostream>
#include<stdlib.h>
#include<string.h>

using namespace std;

class FullyIndexableDictionary{
private:
    int n, l, s, len_p;
    unsigned char *B;
    char *L, *S, *P;
public:
    ~FullyIndexableDictionary(){
        free(B);
        free(L);
        free(S);
        free(P);
    };
    FullyIndexableDictionary(const char* _B){
        //const char* _B = "10100000...
        // In Fullyindexabledictionary, we need to possess given bit sequence
        n = strlen(_B);
        B = (unsigned char*)malloc( sizeof(unsigned char) * (n >> 3) );
        for(int i=0; i<n; ++i){
            if( _B[i] - '0' ){ B[ (i >> 3) ] |= (1 << (7 - (i & 0x07))); }
        }

        // let us consider a bit vector B the size of n = 256 (bits)
        // n = 256;
        // the size l = lg^2(n) = 64 covered by L[i],
        // and an element of L can be stored in lg64 = 6 (bits)
        l = 64;
        // the size s = lg(n)/2 = 4 covered by S[i],
        // and an element of S can be stored in lg4 = 2 (bits)
        s = 4;
        // |P[0, 2^s)| = 16
        len_p = 1 << 4;

        L = (char*)malloc(sizeof(char) * (n/l));
        S = (char*)malloc(sizeof(char) * (n/s));
        P = (char*)malloc(sizeof(char) * len_p);

        // initialize L[0,n/l), S[0,n/s)
        L[0] = S[0] = 0;
        for(int i=0,j=0,k=0; i < _n; ++i){
            if( !( i % l ) ){
                ++j;
                L[j] = L[j-1];
            }

            if( !( i % s ) ){
                if( !( i % l ) ){ S[k] = 0; }
                ++k;
                S[k] = S[k-1];
            }

            if( B[(i >> 3)] & (1 << (7 - (i & 0x07))) ){
                ++L[j];
                ++S[k];
            }

        }

        // initialize P[0,i)
        for(int i=0; i < (1 << s); ++i){
            P[i] = 0;
            for(int j=1, j_end = (i << sizeof(char)); j < j_end; j <<= 1){
                if( i & j ){ ++P[i]; }
            }
        }
    };

    int rank(int i){
        // create a mask; like "11111000", #0 is (s - i % s)
        unsigned char mask = 0xff << ( s - (i % s) );

        // extract a bit sequence stored in B;
        // if (i / 4) != (i / 8 * 2), for example i = 15
        // then, use lower bits the size of s
        unsigned char bitseq = B[(i >> 3)];
        if( (i >> 2) != ((i >> 3) << 1) ){
            bitseq <<= s;
            bitseq >>= s;
        }else{
            bitseq >>= s;
        }

        return L[( i / l )] + S[( i / s )] + P[ bitseq & mask ];
    };
};

int main(){
    const char* B = "1010000000010100010100000000101010000000111000101111000000000000010001010010100001000001010100010001010001001001010000101000010001000101001010000100000101010001000101000100100101000010100001000100010100101000010000010101000100010100010010010100001010000100";
    FullyIndexableDictionary fid = FullyIndexableDictionary(B);
    for(int i=0; i<strlen(B); ++i){
        int r=0;
        for(int j=0; j<i; ++j){ if( B[j] - '0' ){ ++r; } }
        if(fid.rank(i) != r){
            printf("rank(B,%d):%d [counted naively:%d]\n”, i, fid.rank(i), r);
        }
    }
}