ちゃっくのメモ帳

ちゃっくがメモしときたいことをメモしとくよ

boost/any.cppなんだよっ

C++のboost/any.cppを使ってみた.
ドキュメントとかはなんかこの辺みた.
Chapter 3. Boost.Any - 1.61.0
boostjp.github.io

基本的には任意の型を代入できるような型(多分).
STLも代入できるし,自作クラスとかも代入できる.

つまりvector<boost::any>とかするといろんな型を収めた可変長配列が使用できそう...

値を取り出すときは, boost::any_cast<T>を用いて型をキャストする.
型を判定するには .type()がtype_info型を返すので x.type()==typeid(int)のように判定すれば良い...(はず)

以下試してみたコード

出力は

type int : 1
type char : A
type double : 3.3
type vector<int> : [10,20,30,]
type string : hoge
type fuga : 4

となる.

 

**追記

どうやらanyはC++1y,14ならstd::experimental::any,C++17ならstd::anyがあるらしい.

わざわざboostを使う必要は無いっぽい?

std::experimental::any - cppreference.com

texliveにjlistingを追加するんだよっ

texliveにjlisting.styを追加するときに少し困ったのでメモ

環境はubuntu15.04
tex-live2015

jlisting.styをどこかから落としてくる(なんかhttp://mytexpert.osdn.jp/index.php?Listingsのリンクが消えててそれ以外のところは散らばっているみたい)。

jlisting.styを
/usr/share/texlive/texmf-dist/tex/latex/listings
にコピーする。

sudo cd jlisting.sty /usr/share/texlive/texmf-dist/tex/latex/listings/

とか。

この後に

sudo mktexlsr

とするとパッケージにjlistingが追加される。

とここまで書いてあるサイトは多いけどこれだけだと動かなかった。
この時jlisting.styに読み込み権限がなかったので

sudo chmod +r jlisting.sty

とする必要があった。まあそりゃ読み込み権限がなければ読み込めないよねって話。

OpenTemplate.vimを作ったんだよっ!!!

タイトルどおりOpenTemplate.vimというvimプラグインを作ってみた。
まあ、作ろうと思った理由はテンプレートファイルをどうやって管理すればいいか分からなくてそれなら自分でプラグインを作ってみるかってなったから。
github.com

:OpenTemplate

とすれば拡張子に応じたテンプレートファイルを展開するようになっている。

これまでVimScriptを書いたことが殆ど無かったためtwitterでkoturnさんにいろいろ教えていただきながら書いた。

VimScriptについてappendとかgetとかの便利な使い方を知らなかったことがあった。意外とググっても調べにくかったりするし恐らく:helpを見るのがいいんだろうなぁって思ったけど英語だしね(._.)...........

autoload/に置いたファイルがいつ読み込まれるかとか分からなくて困ったりしたよ(o_o)!

verboseなんだよっ!!

vimを使っているときに想定しない折りたたみが起こっていたので
:echo foldmethod
を見ると
syntax
になっていた。
しかし、vimrcを確認すると
set foldmethod=marker
としている。おそらく何らかのプラグインがfoldmethodを書き換えていると推測。
しかし、なんのプラグインが書き換えているかは分からない。
:set runtimepath
を見ながらプラグインをいちいちチェックしていくのも面倒くさい。
そこでコマンドverboseを使用すると楽になる。

:verbose set foldmethod

とすると最後に変数foldmethodを書き換えたファイルを調べることができる。

つまり
:verbose set 変数名
で変数名が最後に書き換えられたファイルを調べられる。やったね!便利(._.)!!!

Haskellで文字と数値の変換したんだよっ

文字通りHaskellで文字(Char)と数値(Int)への変換方法を記しておく。

文字から数値へ

文字から数値にする1つの方法はordを使う方法。Data.Charをインポートする必要がある。
例では'a'を対応するasciiコード97に変換する。

Prelude> import Data.Char
Prelude Data.Char> ord 'a'
97

別の方法はfromEnumを使用することである。

Prelude> fromEnum 'a'
97

ordとfromEnumの違いはIntを入力として与えた時である。

Prelude> import Data.Char 
Prelude Data.Char> fromEnum 100
100
Prelude Data.Char> ord 100

<interactive>:8:5:
    No instance for (Num Char) arising from the literal `100'
    Possible fix: add an instance declaration for (Num Char)
    In the first argument of `ord', namely `100'
    In the expression: ord 100
    In an equation for `it': it = ord 100

このようにfromEnumにInt型の入力を与えるとそのまま帰ってくるがordに与えるとエラーとなる。
これはfromEnumはEnum型を入力として受け取るのにたいして,ordはChar型を入力に受け取るからである。下のようになっている。

Prelude Data.Char> :t fromEnum
fromEnum :: Enum a => a -> Int
Prelude Data.Char> :t ord
ord :: Char -> Int

数値から文字へ

Int型からChar型への変換方法はtoEnumまたはchrを用いる。chrを使用するにはData.Charをインポートする必要がある。
それぞれ下のように使用する。asciiコード97を'a'に変換する。

Prelude> import Data.Char 
Prelude Data.Char> toEnum 97 :: Char
'a'
Prelude Data.Char> chr 97
'a'

それぞれの型は次のようになっている

Prelude Data.Char> :t toEnum
toEnum :: Enum a => Int -> a
Prelude Data.Char> :t chr
chr :: Int -> Char

上の通りtoEnumはIntからEnum aに変換する。そして変換先の型Charを::を用いて指定する必要がある。(これをしないとエラーになる)

暇だったからSICPの1章の何問かをHaskellで解いてみたんだよっ

春休みに入って暇だったからSICPを眺めてて問題を幾つかHaskellの練習がてら解いてみた

問題1.3

square x = x * x
sum_of_square x y = (square x) + (square y)
prob1_3 x y z 
  | x <= y && x <= z  = sum_of_square y z
  | y <= z && y <= x  = sum_of_square x z
  | z <= x && z <= y  = sum_of_square x y
  | otherwise = -1

問題1.7

square x = x * x                               
average x y = (x + y) / 2                       
improve guess x = (average guess (x / guess))  
good_enough cur pre = if ((abs (cur-pre)) / cur) < 0.001 then True else False  

sqrtiter cur pre x = if (good_enough cur pre) then cur else (sqrtiter (improve cur x) cur x)
mysqrt x = sqrtiter 1.0 10.0 x

問題1.8

improve guess x = ((x/guess/guess) + 2*guess) / 3

good_enough cur pre = if ((abs (cur-pre))/cur) < 0.001 then True else False
cubeiter cur pre x = if (good_enough cur pre) then cur else (cubeiter (improve cur x) cur x)
cube x = cubeiter 1.0 10.0 x

問題1.11

fib n = if n<3 then n else fib (n-1) + fib (n-2) + fib (n-3)

問題1.12

pascal r c
  | r <= 0  = 1
  | c <= 0  = 1
  | r == c  = 1
  | otherwise = (pascal (r-1) (c-1)) + (pascal (r-1) c)

問題1.16

fastpowpow a b n
  | n == 0  = a
  | even n  = fastpowpow a (b*b) (n `div` 2)
  | otherwise = fastpowpow (a*b) b (n-1)

fastpow b n = fastpowpow 1 b n

問題1.17

double a = a * 2

halve a = a `div` 2

mymul a b
  | b == 0  = 0
  | even b  = (mymul (a*2) (b `div` 2))
  | odd b   = (mymul (a*2) (b `div` 2)) + a

問題1.18

double a = 2 * a
halve a = a `div` 2

fastmulmul a b ret
  | b==0    = ret
  | even b  = (fastmulmul (double a) (halve b) ret)
  | odd b   = (fastmulmul a (b-1) (ret+a))

fastmul a b = fastmulmul a b 0

うーん。飽きてしまったから問題を解くのはもういいかなって感じだ。
あとコードが汚い。
やっぱり括弧が多くなってしまうような場所は $ 演算子を使った方が良いのかな

stringstreamを使ってみたんだよ

C++でstringstreamを使ってみた。

空白区切り

何がしたかったかというとC++で空白区切りの文字列を処理したかった。
しかし、C++にはsplit関数がない。そこでstringstreamが使えるらしい。
ソースコード

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main(){
    string s = "abc def ghi jkl mno";
    stringstream ss;

    ss << s;
    string ret;
    while(!ss.eof()){
        ss >> ret;
        cout << ret << endl;
    }
}

出力

abc
def
ghi
jkl
mno

のようになる。

文字列から数値への変換

stringstreamを使えば文字列を数値に変換することもできるらしい
ソースコード

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main(){
    string s ="3.141592";
    stringstream ss;
    double pi;

    ss << s;
    ss >> pi;
    cout << pi << endl;
}

出力

3.141592

また文字列が数字とそれ以外が混ざっていた場合次のようになる

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main(){
    string s1 = "3.14aaa";
    string s2 = "aa3.14";
    string s3 = "aa3.14aa";
    string s4 = "3.1hoge415";
    stringstream ss1,ss2,ss3,ss4;
    double d1=0,d2=0,d3=0,d4=0;

    ss1 << s1;
    ss2 << s2;
    ss3 << s3;

    ss1 >> d1;
    cout << d1 << endl;
    ss2 >> d2;
    cout << d2 << endl;
    ss3 >> d3;
    cout << d3 << endl;
    ss4 >> d4;
    cout << d4 << endl;
}

出力

3.14
0
0
3.1

読み飛ばし

ignoreを使えば読み飛ばしができる。
ignore(n,delim)で
「最大n文字を読み飛ばす。もしくはdelimに一致するするまで読み飛ばす。」
となる。
但し引数がなければignore(1,EOF)となる。

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main(){
    string s = "123,456";
    stringstream ss;
    int r1,r2;
    ss << s;
    ss >> r1;
    ss.ignore();
    ss >> r2;
    cout << r1 << " : " << r2 << endl;
}
123 : 456