<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9198835639547511373</id><updated>2024-09-09T00:04:15.681+09:00</updated><title type='text'>さんぷるクリプト</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>16</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-8075178242515069301</id><published>2012-11-15T19:40:00.000+09:00</published><updated>2012-11-15T19:40:22.494+09:00</updated><title type='text'>g++でコンパイル</title><content type='html'>C++のソースをコンパイルしてみた。&lt;br /&gt;
&lt;div&gt;
で、通らなかった (p_q､)　なんかなぁ。バージョンは常に新しくしたいから結構あげちゃうんだけど、その度洗礼を受ける感じ？&lt;/div&gt;
&lt;div&gt;
今回の洗礼は、この2個。&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;script class=&quot;brush: bash&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
hoge.h:353:11: warning: enumeration value ‘***’ not handled in switch [-Wswitch]
hogehoge.h:19:3: warning: suggest parentheses around arithmetic in operand of ‘|’ [-Wparentheses]
]]&gt;&lt;/script&gt;

で、環境はAWSのEC2で。
&lt;script class=&quot;brush: bash&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
gcc.noarch                            4.6.2-1.8.amzn1              @amzn-main   
gcc-c++.noarch                        4.6.2-1.8.amzn1              @amzn-main   
gcc46.x86_64                          4.6.2-2.65.amzn1             @amzn-main   
gcc46-c++.x86_64                      4.6.2-2.65.amzn1             @amzn-main   
libgcc44.i686                         4.4.6-4.77.amzn1             @amzn-main   
libgcc44.x86_64                       4.4.6-4.77.amzn1             @amzn-main   
libgcc46.i686                         4.6.2-2.65.amzn1             @amzn-main   
libgcc46.x86_64                       4.6.2-2.65.amzn1             @amzn-main  
]]&gt;&lt;/script&gt;
&lt;br /&gt;
なんでかなぁ。とおもっていても仕方ないので、やっつける (`･ω･´+) ｷﾘｯ&lt;br /&gt;
-------------&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;selector11&quot;&gt;
&lt;h4 class=&quot;selector11b&quot;&gt;
warning: enumeration value ‘***’ not handled in switch [-Wswitch]&lt;/h4&gt;
&lt;/div&gt;
&lt;b style=&quot;background-color: #674ea7;&quot;&gt;-Wswitch&lt;/b&gt; というオプションによって、列挙型の項目すべてが指定されていない為にでる警告。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
例えば、enum hoge {1, 2, 3}; とし、switch 文で case 1:... case 3:... のみで case 2:... を書いていない場合、この警告がでる。&lt;br /&gt;
default: を使ってしまうと、(書くのを忘れてしまった) case 2: の場合が当てはまり、警告は出ない。&lt;br /&gt;
用途によっては意図したものにならない可能性もあるので default を書かずおけば、パターンが確認できたりする。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;selector11&quot;&gt;
&lt;h4 class=&quot;selector11b&quot;&gt;
warning: suggest parentheses around arithmetic in operand of ‘|’ [-Wparentheses]&lt;/h4&gt;
&lt;/div&gt;
&lt;b style=&quot;background-color: #674ea7;&quot;&gt;-Wparentheses&lt;/b&gt; というオプションによって、括弧が省略されているため（優先順位がわからない）にでる警告。&lt;br /&gt;
&lt;br /&gt;
例えば、
&lt;script class=&quot;brush: c++&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
to += 0x80 | ((0xFC&amp;snd)&gt;&gt;2)+0x10;
]]&gt;&lt;/script&gt;
これだと警告が出ちゃいます。なので・・・・
&lt;script class=&quot;brush: c++&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
to += 0x80 | (((0xFC&amp;snd)&gt;&gt;2)+0x10);
]]&gt;&lt;/script&gt;
とすると警告が出なくなります。&lt;br /&gt;
0x80 | ((0xFC&amp;amp;snd)&amp;gt;&amp;gt;2) これを評価した後で、+0x10 なのかあやふやだからだと思われます。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
コンパイルオプションに付いてはこちらを参照&lt;br /&gt;
&lt;a href=&quot;http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Warning-Options.html&quot;&gt;http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Warning-Options.html&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.geocities.jp/woodwood77777/gcc_gnu.htm&quot;&gt;http://www.geocities.jp/woodwood77777/gcc_gnu.htm&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b style=&quot;background-color: #674ea7;&quot;&gt;-Wall&lt;/b&gt; をつけているので、いろいろ警告が出た模様。。。。&lt;br /&gt;
headerファイルも変わったみたい。。。&lt;br /&gt;
&lt;a href=&quot;http://gcc.gnu.org/gcc-4.3/porting_to.html&quot;&gt;http://gcc.gnu.org/gcc-4.3/porting_to.html&lt;/a&gt;&lt;br /&gt;
いろいろ大変ですね。おしまい (´･ω･`)&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/8075178242515069301/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2012/11/g.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/8075178242515069301'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/8075178242515069301'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2012/11/g.html' title='g++でコンパイル'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-2634494191665752414</id><published>2012-11-06T00:57:00.003+09:00</published><updated>2012-11-06T01:01:10.293+09:00</updated><title type='text'>AmazonEC2でEBS</title><content type='html'>AmazonEC2で使うストレージにEBSというのがあります。&lt;br /&gt;
ここではEBSを使えるようにする二つの方法を ＿φ(｡_｡*)ﾒﾓﾒﾓします。&lt;br /&gt;
EBSとは Amazon 
&lt;span style=&quot;font-size: large;&quot;&gt;E&lt;/span&gt;lastic &lt;span style=&quot;font-size: large;&quot;&gt;B&lt;/span&gt;lock &lt;span style=&quot;font-size: large;&quot;&gt;S&lt;/span&gt;tore の略で、私はイー・ビー・エスっていいます。&lt;br /&gt;
&lt;br /&gt;
二つの方法
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;新規にVolumeをAttachする場合&lt;/li&gt;
&lt;li&gt;snapshotからVolumeを作成しAttachする場合&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
★共通の注意事項&lt;br /&gt;
インスタンスに Attach にできる Volume は同じ availability zone 内に限られるので、作成時に確認する。&lt;br /&gt;
パンくず：&lt;b&gt;&lt;span style=&quot;color: magenta;&quot;&gt;services &amp;gt; Compute &amp;amp; Networking &amp;gt; EC2&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;a href=&quot;http://aws.amazon.com/jp/&quot;&gt;アマゾン ウェブ サービス&lt;/a&gt;　にアクセス。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;selector11&quot;&gt;
&lt;h4 class=&quot;selector11b&quot;&gt;
新規にVolumeをAttachする場合&lt;/h4&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;主に、メインのストレージは既にあってログやバックアップを別のストレージに分ける場合に使用しています。&lt;br /&gt;
一般的なWebサービスを提供するインスタンスを作る場合、Root Partition（ルートパーティション）＜OSが入っている部分＞は、32GiBくらいにしておけば十分だと思っているからです。&lt;br /&gt;
一概には言えないですけどね (´･ω･`)&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;新規Volume（ヴォリューム）作成&lt;br /&gt;パンくず（左メニュー）：&lt;b&gt;&lt;span style=&quot;color: magenta;&quot;&gt;ELASTIC BLOCK STORE &amp;gt; Volumes&lt;/span&gt;&lt;/b&gt;&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;右上メニュー：Create Volume&lt;/li&gt;
&lt;li&gt;入力項目：&lt;br /&gt;&lt;span style=&quot;color: blue;&quot;&gt;Size&lt;/span&gt;: *** GiB ( GiB / TiB )&lt;br /&gt;&lt;span style=&quot;color: blue;&quot;&gt;Availability Zone:&lt;/span&gt;&amp;nbsp;&lt;span class=&quot;value&quot;&gt;ap-northeast-1a&lt;br /&gt;(&amp;nbsp;&lt;span class=&quot;value&quot;&gt;ap-northeast-1b /&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;value&quot;&gt;ap-northeast-1b /&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;value&quot;&gt;ap-northeast-1b )&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: blue;&quot;&gt;Snapshot:&lt;/span&gt; --- No Snapshot ---&lt;br /&gt;&lt;span style=&quot;color: blue;&quot;&gt;Volume Type:&lt;/span&gt; Standard&lt;/li&gt;
&lt;li&gt;『Yes, Create』&lt;/li&gt;
&lt;li&gt;作ったVolumeが何か分かるように名前を付けておく。&lt;br /&gt;できたVolumeを選択すると下段に以下のタブとともに情報が表示される。&lt;br /&gt;[Details] , [Status Checks] , [Monitoring] , [Tags]&lt;br /&gt;パンくず：&lt;b&gt;&lt;span style=&quot;color: magenta;&quot;&gt;Tags &amp;gt; Add/Edit Tags&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Key=Name , Value=任意の名前&amp;nbsp;--&amp;gt; Save Tags&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;インスタンスにAttach（アタッチ）する&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;右上メニュー：Attach Volume&lt;/li&gt;
&lt;li&gt;入力項目：&lt;br /&gt;&lt;span style=&quot;color: blue;&quot;&gt;Volume:&lt;/span&gt;&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: blue;&quot;&gt;vol-******* in &amp;lt;availability zone&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: blue;&quot;&gt;Instances:&lt;/span&gt; [Select Instance] &lt;span style=&quot;color: blue;&quot;&gt;in &amp;lt;availability zone&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: blue;&quot;&gt;Device:&lt;/span&gt; /dev/sd*&lt;/li&gt;
&lt;li&gt;『Yes, Attach』&lt;/li&gt;
&lt;/ol&gt;
&lt;li&gt;Volumeを使えるようにする&lt;/li&gt;
&lt;ol&gt;
&lt;li&gt;使えるファイルシステムにフォーマット&lt;br /&gt;
&lt;script class=&quot;brush: bash&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
$ sudo su -
# mkfs.ext4 /dev/sdf
]]&gt;&lt;/script&gt;&lt;/li&gt;
&lt;li&gt;マウント&lt;br /&gt;
&lt;script class=&quot;brush: bash&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
$ sudo su -
# mkdir /data（マウント先）
# mount /dev/sdf（ファイルシステム） /data（マウント先）
]]&gt;&lt;/script&gt;&lt;/li&gt;
&lt;li&gt;インスタンスを再起動しても自動的にマウントさせる&lt;br /&gt;
&lt;script class=&quot;brush: bash&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
$ sudo su -
# vi /etc/fstab
+++ /dev/sdf    /data ext4 defaults 0   0
]]&gt;&lt;/script&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/ol&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
これで、ディスクが追加されたように使えます (￣ー+￣)&lt;/div&gt;
&lt;div&gt;
ちなみに、RootPartitionではないのでインスタンスを&lt;b&gt;&lt;span style=&quot;color: red; font-size: large;&quot;&gt;STOPしなくても追加されます&lt;/span&gt;&lt;/b&gt;！&lt;/div&gt;
&lt;div&gt;
つぎは、snapshotからEBSをつくりRootPartitionにする方法を ＿φ(｡_｡*)ﾒﾓﾒﾓします。&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;selector11&quot;&gt;
&lt;h4 class=&quot;selector11b&quot;&gt;
snapshotからVolumeを作成しAttachする場合&lt;/h4&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/2634494191665752414/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2012/11/amazonec2ebs.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/2634494191665752414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/2634494191665752414'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2012/11/amazonec2ebs.html' title='AmazonEC2でEBS'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-2720203391264991197</id><published>2012-10-17T17:53:00.006+09:00</published><updated>2012-10-17T19:16:14.275+09:00</updated><title type='text'>CのApache-module：：subprocess_env構造体</title><content type='html'>r-&amp;gt;subprocess_env構造体には何が入っているか調べてみました。&lt;br /&gt;
概要&lt;br /&gt;
Apacheにはリクエスト毎の情報をもつ request_rec 構造体があります。
subprocess_env構造体は、環境変数の配列です。&lt;br /&gt;
&lt;br /&gt;
include/httpd.h にて、下記のように定義されています。&lt;br /&gt;
&lt;br /&gt;
&lt;script class=&quot;brush:c&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
struct request_rec {
    ....
    /** Array of environment variables to be used for sub processes */
    apr_table_t *subprocess_env;
    ....
};
]]&gt;&lt;/script&gt;この subprocess_env構造体は、apr_table_t 型なので、r-&amp;gt;headers_in 等と同じように取り出し可能です。&lt;br /&gt;
と、いわれましても。。。って思いませんか？&lt;br /&gt;
&lt;br /&gt;
subprocess_env構造体の全容というか、いったい何が入っているのか気になる！&lt;br /&gt;
&lt;br /&gt;
お決まりのようにググってみましたけども、ちっとも出てきません。&lt;br /&gt;
そこで全部の中身をだしちゃうコードを書く事にしました。&lt;br /&gt;
&lt;br /&gt;
あとは、きっと環境が変われば中身も変わる物だから、こんなんですよーってのが無いんだと固く信じてます (*´∀`*)&lt;br /&gt;
（英語力が他かければドキュメントが見つかるのだろうか？むかしなら「Doxygen」のマニュアルが沢山出てきたんだけどなぁ。。。）&lt;br /&gt;
&lt;br /&gt;
では、早速コードを。
&lt;script class=&quot;brush:c&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
int i=0;
const apr_array_header_t *arr_env = apr_table_elts(r-&gt;subprocess_env);
for ( i = 0; i &lt; arr_env-&gt;nelts; i++) {
 apr_table_entry_t *entry = (apr_table_entry_t *)(arr_env-&gt;elts + (arr_env-&gt;elt_size * i));
 ap_rprintf(r, &quot;[%d] : key=%s , value=%s\n&quot;, i, entry-&gt;key, entry-&gt;val);
}
// 一応お決まりのあれも。
const char *value = apr_table_get(r-&gt;subprocess_env, &quot;QUERY_STRING&quot;);
ap_rprintf(r, &quot;QUERY_STRING : %s\n&quot;, value);
]]&gt;&lt;/script&gt;
さて、何がでてくるかな？&lt;br /&gt;
QUERY_STRINGを取って見ているので、適当に ?hoge=bar なんてつけてみる。&lt;br /&gt;
&lt;br /&gt;
■出力結果↓
&lt;script class=&quot;brush:text&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
[0] : key=UNIQUE_ID , value=************************
QUERY_STRING : (null)
]]&gt;&lt;/script&gt;
 Σ(゜∀゜ノ)ノマジか！
&lt;br /&gt;
&lt;b&gt;【NULL】&lt;/b&gt;　じゃん。。。なんで？&lt;br /&gt;
その辺のサンプルコードってよく書いてあるよね？何が違うんだろう。。。と、思っています？&lt;br /&gt;
&lt;br /&gt;
なんと、これにはちゃんとした訳があります。現時点では当然の振る舞いです。&lt;br /&gt;
subprocess_env構造体 の値を取得する前に、とある処理を入れてあげないと、KEY=VALの形でデータがsubprocess_env構造体に入ってこないのです。&lt;br /&gt;
その処理が。。。&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;【ap_add_cgi_vars関数】&lt;/b&gt;&lt;/span&gt;です。&lt;br /&gt;
&lt;br /&gt;
では、早速コードに追記して実行してみます。

&lt;script class=&quot;brush:c&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
ap_add_cgi_vars(r); // ★ここで処理★
int i=0;
const apr_array_header_t *arr_env = apr_table_elts(r-&gt;subprocess_env);
for ( i = 0; i &lt; arr_env-&gt;nelts; i++) {
 apr_table_entry_t *entry = (apr_table_entry_t *)(arr_env-&gt;elts + (arr_env-&gt;elt_size * i));
 ap_rprintf(r, &quot;[%d] : key=%s , value=%s\n&quot;, i, entry-&gt;key, entry-&gt;val);
}
// 一応お決まりのあれも、これも。
const char *value = apr_table_get(r-&gt;subprocess_env, &quot;QUERY_STRING&quot;);
ap_rprintf(r, &quot;QUERY_STRING : %s\n&quot;, value);
ap_rprintf(r, &quot;REMOTE_ADDR : %s\n&quot;, value);
]]&gt;&lt;/script&gt;
さて、何がでてくるかな？&lt;br /&gt;
QUERY_STRINGを取って見ているので、適当に ?hoge=bar なんてつけてみる。&lt;br /&gt;
ついでに、REMOTE_ADDRも取ってみましょう (*´∀`*)&lt;br /&gt;
■出力結果↓
&lt;script class=&quot;brush:text&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
[0] : key=UNIQUE_ID , value=************************
[1] : key=GATEWAY_INTERFACE , value=CGI/1.1
[2] : key=SERVER_PROTOCOL , value=HTTP/1.1
[3] : key=REQUEST_METHOD , value=GET
[4] : key=QUERY_STRING , value=hoge=bar
[5] : key=REQUEST_URI , value=/check?hoge=bar
[6] : key=SCRIPT_NAME , value=/check
QUERY_STRING : hoge=bar
REMOTE_ADDR : (null)
]]&gt;&lt;/script&gt;
やった ヾ(＠⌒▽⌒＠)ノとれました。&lt;br /&gt;
この ap_add_cgi_vars関数は下記のように定義されています。
&lt;br /&gt;
&lt;div&gt;
&lt;table border=&quot;1cellpadding=3&quot; cellspacing=&quot;0&quot;&gt;&lt;thead&gt;
&lt;tr&gt;
&lt;td&gt;void ap_add_cgi_vars (request_rec *&amp;nbsp; &lt;em&gt;r&lt;/em&gt; &amp;nbsp;)&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;/thead&gt;&lt;thead&gt;
&lt;tr&gt;&lt;td&gt;Add CGI environment variables required by HTTP/1.1 to the request&#39;s environment table &lt;br /&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;b&gt;Parameters:&lt;/b&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;2&quot;&gt;
    &lt;tbody&gt;
&lt;tr&gt;&lt;td valign=&quot;top&quot;&gt;&lt;/td&gt;&lt;td valign=&quot;top&quot;&gt;&lt;em&gt;r&lt;/em&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;the current request&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/dd&gt;&lt;/dl&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/thead&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
さて、QUERY_STRINGを取得したい場合は、これだけでOKですが、、、、REMOTE_ADDRを取得したい人はどうしましょう？&lt;b&gt;【NULL】&lt;/b&gt;　じゃん。。。なんで？&lt;br /&gt;
取れない？？&lt;br /&gt;
&lt;br /&gt;
なんて事はありません (*´∀`*)ちゃんと取得できるようになっています。&lt;br /&gt;
その処理が。。。&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;【ap_add_common_vars関数】&lt;/b&gt;&lt;/span&gt;です。&lt;br /&gt;
&lt;br /&gt;
さてさて、コードに追記して実行してみます。&amp;nbsp;さて、取れるでしょうか？&lt;br /&gt;
QUERY_STRINGを取って見ているので、適当に ?hoge=bar なんてつけてみる。&lt;br /&gt;
ついでに、REMOTE_ADDRも取ってみましょう (*´∀`*)&lt;br /&gt;
■出力結果↓
&lt;script class=&quot;brush:text&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
[0] : key=UNIQUE_ID , value=************************
[1] : key=HTTP_HOST , value=XXX.XXX.XXX.XXX
[2] : key=HTTP_USER_AGENT , value=Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:15.0) Gecko/20100101 Firefox/15.0.1
[3] : key=HTTP_ACCEPT , value=text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
[4] : key=HTTP_ACCEPT_LANGUAGE , value=ja,en-us;q=0.7,en;q=0.3
[5] : key=HTTP_ACCEPT_ENCODING , value=gzip, deflate
[6] : key=HTTP_CONNECTION , value=keep-alive
[7] : key=HTTP_CACHE_CONTROL , value=max-age=0
[8] : key=PATH , value=/sbin:/bin:/usr/sbin:/usr/bin
[9] : key=SERVER_SIGNATURE , value=
[10] : key=SERVER_SOFTWARE , value=Apache/2.2.23 (Unix)
[11] : key=SERVER_NAME , value=XXX.XXX.XXX.XXX
[12] : key=SERVER_ADDR , value=YYY.YYY.YYY.YYY
[13] : key=SERVER_PORT , value=80
[14] : key=REMOTE_ADDR , value=ZZZ.ZZZ.ZZZ.ZZZ
[15] : key=DOCUMENT_ROOT , value=/usr/local/apache2/htdocs
[16] : key=SERVER_ADMIN , value=you@example.com
[17] : key=SCRIPT_FILENAME , value=/usr/local/apache2/htdocs/check
[18] : key=REMOTE_PORT , value=50299
[19] : key=GATEWAY_INTERFACE , value=CGI/1.1
[20] : key=SERVER_PROTOCOL , value=HTTP/1.1
[21] : key=REQUEST_METHOD , value=GET
[22] : key=QUERY_STRING , value=hoge=bar
[23] : key=REQUEST_URI , value=/check?hoge=bar
[24] : key=SCRIPT_NAME , value=/check
QUERY_STRING : hoge=bar
REMOTE_ADDR : ZZZ.ZZZ.ZZZ.ZZZ
]]&gt;&lt;/script&gt;
やった ヾ(＠⌒▽⌒＠)ノ完璧。&lt;br /&gt;
この ap_add_common_vars関数は下記のように定義されています。
&lt;br /&gt;
&lt;div&gt;
&lt;table border=&quot;1cellpadding=3&quot; cellspacing=&quot;0&quot;&gt;&lt;thead&gt;
&lt;tr&gt;
&lt;td&gt;void ap_add_common_vars (request_rec *&amp;nbsp; &lt;em&gt;r&lt;/em&gt; &amp;nbsp;)&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;/thead&gt;&lt;thead&gt;
&lt;tr&gt;&lt;td&gt;Add common CGI environment variables to the requests environment table &lt;br /&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;b&gt;Parameters:&lt;/b&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;2&quot;&gt;
    &lt;tbody&gt;
&lt;tr&gt;&lt;td valign=&quot;top&quot;&gt;&lt;/td&gt;&lt;td valign=&quot;top&quot;&gt;&lt;em&gt;r&lt;/em&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;the current request&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/dd&gt;&lt;/dl&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/thead&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
これで必要な情報を取る事ができますね〜 (*´∀`*)&lt;br /&gt;
おしまい。&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/2720203391264991197/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2012/10/capache-modulesubprocessenv.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/2720203391264991197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/2720203391264991197'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2012/10/capache-modulesubprocessenv.html' title='CのApache-module：：subprocess_env構造体'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-721209815626444934</id><published>2012-10-17T16:30:00.000+09:00</published><updated>2012-10-17T20:22:49.244+09:00</updated><title type='text'>AmazonEC2を使ってみる</title><content type='html'>&lt;h4 id=&quot;aya&quot;&gt;
0.アカウントを作る
&lt;/h4&gt;
&lt;div&gt;
&lt;a href=&quot;http://aws.amazon.com/jp/&quot;&gt;アマゾン ウェブ サービス&lt;/a&gt;　にアクセスして作成。
&lt;br /&gt;
この時、クレジットカードが無いと使う事ができないので手元に用意しておくしかない。&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4 id=&quot;aya&quot;&gt;
1.インスタンスを立ち上げる&lt;/h4&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4 id=&quot;aya&quot;&gt;
2.まずはじめにやる事&lt;/h4&gt;
&lt;div&gt;
&lt;span style=&quot;color: #f1c232; font-size: large;&quot;&gt;■rootのパスワード設定
&lt;/span&gt;
&lt;script class=&quot;brush: bash&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
$ sudo su -
# passwd
]]&gt;&lt;/script&gt;

&lt;span style=&quot;color: #f1c232; font-size: large;&quot;&gt;■タイムゾーンの設定
&lt;/span&gt;
&lt;script type=&quot;syntaxhighlighter&quot; class=&quot;brush: bash&quot;&gt;&lt;![CDATA[
# cp -i /usr/share/zoneinfo/Japan /etc/localtime
]]&gt;&lt;/script&gt;

[以後変更されないように設定]
&lt;script type=&quot;syntaxhighlighter&quot; class=&quot;brush: bash&quot;&gt;&lt;![CDATA[
# vi /etc/yum.conf
+++ exclude=tzdata
# /etc/init.d/yum-updatesd restart
]]&gt;&lt;/script&gt;
変更されないようにこうすれば良いっていろんなサイトにあるのだけど、今のところ効かない・・・・・&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #f1c232; font-size: large;&quot;&gt;■ホスト名の変更
&lt;/span&gt;
&lt;script type=&quot;syntaxhighlighter&quot; class=&quot;brush: bash&quot;&gt;&lt;![CDATA[
# vi /etc/sysconfig/network
--- HOSTNAME=localhost.localdomain
+++ HOSTNAME=hostname.foo.bar
# vi /etc/hosts
--- 127.0.0.1 localhost localhost.localdomain
+++ 127.0.0.1 localhost localhost.localdomain hostname hostname.foo.bar
]]&gt;&lt;/script&gt;
&lt;br /&gt;
&lt;span style=&quot;color: #f1c232; font-size: large;&quot;&gt;■swap領域の確保
&lt;/span&gt;&lt;br /&gt;
メモリの2倍で。Diskの小さいのはメモリと同じくらいかなぁ。これはラージの場合。&lt;br /&gt;
smallは何かしらデフォルトで確保されているので、とくに設定は変えないでおいてみた。&lt;br /&gt;
&lt;span style=&quot;background-color: #b4a7d6;&quot;&gt;&lt;span style=&quot;color: #20124d;&quot;&gt;・領域の確保　&lt;/span&gt;&lt;/span&gt;
&lt;script type=&quot;syntaxhighlighter&quot; class=&quot;brush: bash&quot;&gt;&lt;![CDATA[
# dd if=/dev/zero of=/swap bs=1M count=15360
dd: writing `/swap&#39;: No space left on device 　←　これが出るのは容量不足。EBSの拡張した？
6716+0 records in
6715+0 records out
7042113536 bytes (7.0 GB) copied, 112.434 s, 62.6 MB/s
]]&gt;&lt;/script&gt;
&lt;span style=&quot;background-color: #b4a7d6;&quot;&gt;&lt;span style=&quot;color: #20124d;&quot;&gt;・swap領域として初期化（まだ認識はされない）
&lt;/span&gt;&lt;/span&gt;
&lt;script type=&quot;syntaxhighlighter&quot; class=&quot;brush: bash&quot;&gt;&lt;![CDATA[
# mkswap /swap
mkswap: /swap: warning: don&#39;t erase bootbits sectors
        on whole disk. Use -f to force.
Setting up swapspace version 1, size = 1048572 KiB
no label, UUID=9888211c-725d-4dfb-905e-4e9c86834ba

# swapon -s
Filename                Type        Size    Used    Priority
]]&gt;&lt;/script&gt;
&lt;span style=&quot;background-color: #b4a7d6;&quot;&gt;&lt;span style=&quot;color: #20124d;&quot;&gt;・swapとして有効に　&lt;/span&gt;&lt;/span&gt;
&lt;script type=&quot;syntaxhighlighter&quot; class=&quot;brush: bash&quot;&gt;&lt;![CDATA[
# swapon /swap
# swapon -s
Filename                Type        Size    Used    Priority
/swap                                   file        1048572    0    -1
]]&gt;&lt;/script&gt;
&lt;span style=&quot;background-color: #b4a7d6;&quot;&gt;&lt;span style=&quot;color: #20124d;&quot;&gt;・再起動しても確保されるように　&lt;/span&gt;&lt;/span&gt;
&lt;script type=&quot;syntaxhighlighter&quot; class=&quot;brush: bash&quot;&gt;&lt;![CDATA[
# vi /etc/fstab
+++ /swap   swap        swap    defaults        0   0
]]&gt;&lt;/script&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/721209815626444934/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2012/09/amazonec2.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/721209815626444934'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/721209815626444934'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2012/09/amazonec2.html' title='AmazonEC2を使ってみる'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-1363335855009156460</id><published>2012-05-23T20:03:00.001+09:00</published><updated>2012-05-23T20:05:26.852+09:00</updated><title type='text'>初めて symfony でプロジェクトを作ってみた</title><content type='html'>PHPのフレームワークを使ってみた。あんまり好きじゃないけどお仕事ですからね〜 (&amp;gt;_&amp;lt;)&lt;br /&gt;
&lt;br /&gt;
&lt;h4 id=&quot;aya&quot;&gt;

1．取りあえずrootで作っちゃう&lt;/h4&gt;
⇒　本当はアプリケーションアカウントを作って実施すべし。
&lt;br /&gt;
&lt;pre class=&quot;php&quot; name=&quot;code&quot;&gt;$ sudo su -&lt;/pre&gt;
&lt;h4 id=&quot;aya&quot;&gt;

2．プロジェクト用のディレクトリを作成&lt;/h4&gt;
&lt;pre class=&quot;php&quot; name=&quot;code&quot;&gt;# cd /var/www/html/
# mkdir world
# cd world/&lt;/pre&gt;
&lt;h4 id=&quot;aya&quot;&gt;

3．プロジェクト（スケルトン）作成&lt;/h4&gt;
&lt;pre class=&quot;php&quot; name=&quot;code&quot;&gt;# symfony init-project world
  Task &quot;init-project&quot; is not defined.&lt;/pre&gt;
ってエラーが出たら、v1.4系なのにv1.0系のコマンドを使った証拠。やりなおし。
バージョン調べたければ事前に「$ symfony -V」してみる。
&lt;br /&gt;
&lt;pre class=&quot;php&quot; name=&quot;code&quot;&gt;# symfony generate:project world
&amp;gt;&amp;gt; file+     /var/www/html/world/symfony
....
&amp;gt;&amp;gt; tokens    /var/www/html/world/config/doctrine/schema.yml
&amp;gt;&amp;gt; tokens    /var/www/html/world/lib/form/BaseForm.class.php
#&lt;/pre&gt;
いろいろいる物を作ってくれる。
何も無かったところがこんな感じに。
&lt;br /&gt;
&lt;pre class=&quot;php&quot; name=&quot;code&quot;&gt;# ls -l
drwxr-xr-x 2 root root 4096 May 23 11:26 apps
drwxrwxrwx 2 root root 4096 May 23 11:26 cache
drwxr-xr-x 3 root root 4096 May 23 11:26 config
drwxr-xr-x 3 root root 4096 May 23 11:26 data
drwxr-xr-x 3 root root 4096 May 23 11:26 lib
drwxrwxrwx 2 root root 4096 May 23 11:26 log
drwxr-xr-x 2 root root 4096 May 23 11:26 plugins
-rwxrwxrwx 1 root root  446 May 23 11:26 symfony
drwxr-xr-x 5 root root 4096 May 23 11:26 test
drwxr-xr-x 6 root root 4096 May 23 11:26 web&lt;/pre&gt;
&lt;h4 id=&quot;aya&quot;&gt;

4．アプリケーション設置&lt;/h4&gt;
&lt;pre class=&quot;php&quot; name=&quot;code&quot;&gt;# symfony generate:app traveler
&amp;gt;&amp;gt; dir+      /var/www/html/world/apps/traveler/modules
....
&amp;gt;&amp;gt; tokens    /var/www/html/public_html/lib/form/BaseForm.class.php
#&lt;/pre&gt;
なんかまた作ってくれる。
&lt;br /&gt;
&lt;pre class=&quot;php&quot; name=&quot;code&quot;&gt;# ls -l ../world/apps/traveler/
drwxr-xr-x 2 root root 4096 May 23 16:41 config
drwxr-xr-x 2 root root 4096 May 23 16:41 i18n
drwxr-xr-x 2 root root 4096 May 23 16:41 lib
drwxr-xr-x 2 root root 4096 May 23 16:41 modules
drwxr-xr-x 2 root root 4096 May 23 16:41 templates&lt;/pre&gt;
&lt;h4 id=&quot;aya&quot;&gt;

5．開発用ファイルを使えるようにする&lt;/h4&gt;
&lt;pre class=&quot;php&quot; name=&quot;code&quot;&gt;# vi web/traveler_dev.php
この部分をコメントアウト
if (!in_array(@$_SERVER[&#39;REMOTE_ADDR&#39;], array(&#39;127.0.0.1&#39;, &#39;::1&#39;)))
{
  die(&#39;You are not allowed to access this file. Check &#39;.basename(__FILE__).&#39; for more information.&#39;);
}&lt;/pre&gt;
コメントアウトしないと開発環境のアプリケーションにアクセスした時に、
http://hogehoge.jp/hoge1_dev.php/
「You are not allowed to access this file. Check traveler_dev.php for more information.」
ってでて見えない。

&lt;br /&gt;
&lt;h4 id=&quot;aya&quot;&gt;

6．Apacheの設定&lt;/h4&gt;
&lt;pre class=&quot;php&quot; name=&quot;code&quot;&gt;# vi /etc/httpd/conf.d/vhost.conf
NameVirtualHost *:80

&lt;virtualhost *:80=&quot;&quot;&gt;
  ServerName world.hoge.jp
  DocumentRoot &quot;/home/web-apps/world/web&quot;
  DirectoryIndex index.php
  &lt;directory &quot;=&quot;&quot; home=&quot;&quot; web&quot;=&quot;&quot; web-apps=&quot;&quot; world=&quot;&quot;&gt;
    AllowOverride All
    Allow from All
  &lt;/directory&gt;

  Alias /sf /usr/share/pear/data/symfony/web/sf
  &lt;directory &quot;=&quot;&quot; data=&quot;&quot; pear=&quot;&quot; sf&quot;=&quot;&quot; share=&quot;&quot; symfony=&quot;&quot; usr=&quot;&quot; web=&quot;&quot;&gt;
    AllowOverride All
    Allow from All
  &lt;/directory&gt;
&lt;/virtualhost&gt;&lt;/pre&gt;
あとは、Apache起動させてOK.おなじみの画面でたし (*´∀`*)&lt;br /&gt;
&lt;br /&gt;
参考：&lt;a href=&quot;http://www.symfony-project.org/jobeet/1_4/Doctrine/ja/&quot; target=&quot;_blank&quot;&gt;Practical symfony | symfony | Web PHP Framework&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/1363335855009156460/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2012/05/symfony.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/1363335855009156460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/1363335855009156460'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2012/05/symfony.html' title='初めて symfony でプロジェクトを作ってみた'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-8405377529952507279</id><published>2012-02-22T11:43:00.004+09:00</published><updated>2012-02-23T16:42:02.269+09:00</updated><title type='text'>AmazonEC2にS3領域をマウントしてみる</title><content type='html'>今日は、EC2にS3のバケットをマウントしてみました。&lt;br /&gt;
手順はこんな感じ。&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://fuse.sourceforge.net/&quot;&gt;FUSE&lt;/a&gt;にいる物をインストール&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://fuse.sourceforge.net/&quot;&gt;FUSE&lt;/a&gt;インストール&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/s3fs/&quot;&gt;f3sf&lt;/a&gt;インストール&lt;/li&gt;
&lt;li&gt;A3にバケット作成&lt;/li&gt;
&lt;li&gt;マウント&lt;/li&gt;
&lt;li&gt;再起動してもマウント&lt;/li&gt;
&lt;/ol&gt;
参考にしたこちらのサイト通りでほぼOKです。&lt;br /&gt;
&lt;a href=&quot;http://memocra.blogspot.com/2011/07/s3s3fs.html&quot; target=&quot;_blank&quot;&gt;memorycraft: S3ってなんじゃ？(s3fs編)&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
では、インストールログを。。&lt;br /&gt;
&lt;br /&gt;

&lt;h4 id=&quot;aya&quot;&gt;
1.&lt;a href=&quot;http://fuse.sourceforge.net/&quot;&gt;FUSE&lt;/a&gt;にいる物をインストール&lt;/h4&gt;
&lt;pre class=&quot;text&quot; name=&quot;code&quot;&gt;
# yum -y install gcc
# yum -y install gcc-c++
# yum -y install libstdc++-devel
# yum -y install pkgconfig
# yum -y install make
# yum -y install curl-devel
# yum -y install libxml2-devel
# yum -y install openssl-devel
&lt;/pre&gt;
&lt;h4 id=&quot;aya&quot;&gt;
2.&lt;a href=&quot;http://fuse.sourceforge.net/&quot;&gt;FUSE&lt;/a&gt;インストール&lt;/h4&gt;
バージョン確認 2.8.4より新しくないと駄目。
yumで入れられない場合は⇒http://sourceforge.net/projects/fuse/files/fuse-2.X/
&lt;pre class=&quot;text&quot; name=&quot;code&quot;&gt;
$ yum list | grep fuse
fuse.x86_64                           2.8.6-1.10.amzn1             amzn-updates
fuse-devel.x86_64                     2.8.6-1.10.amzn1             amzn-updates
&lt;/pre&gt;
インストール
&lt;pre class=&quot;text&quot; name=&quot;code&quot;&gt;
# yum -y install fuse
# yum -y install fuse-devel
&lt;/pre&gt;
環境変数設定
&lt;pre class=&quot;text&quot; name=&quot;code&quot;&gt;
# export PKG_CONFIG_PATH=/usr/lib64/pkgconfig
&lt;/pre&gt;
カーネルにロード
&lt;pre class=&quot;text&quot; name=&quot;code&quot;&gt;
# ldconfig 
# modprobe fuse
&lt;/pre&gt;
&lt;h4 id=&quot;aya&quot;&gt;
3.&lt;a href=&quot;http://code.google.com/p/s3fs/&quot;&gt;f3sf&lt;/a&gt;インストール&lt;/h4&gt;
&lt;pre class=&quot;text&quot; name=&quot;code&quot;&gt;
# cd /usr/local/src
# wget http://s3fs.googlecode.com/files/s3fs-1.40.tar.gz
# tar zxvf s3fs-1.40.tar.gz 
# cd s3fs-1.40
# ./configure prefix=/usr
# make
# make install
&lt;/pre&gt;
&lt;h4 id=&quot;aya&quot;&gt;
4.A3にバケット作成&lt;/h4&gt;
&lt;br/&gt;
&lt;h4 id=&quot;aya&quot;&gt;
5.マウント&lt;/h4&gt;
キー情報を記載
&lt;pre class=&quot;text&quot; name=&quot;code&quot;&gt;
単一認証
# echo アクセスキー:シークレットキー &gt; /etc/passwd-s3fs
複数認証http://www.blogger.com/blogger.g?blogID=9198835639547511373#editor/target=post;postID=8405377529952507279
# echo バケット名:アクセスキー:シークレットキー &gt; /etc/passwd-s3fs

# chmod 640 /etc/passwd-s3fs 
&lt;/pre&gt;
マウント
&lt;pre class=&quot;text&quot; name=&quot;code&quot;&gt;
# mkdir /mnt/s3
# s3fs myfirst-bucket /mnt/s3
# df -kh
Filesystem            Size  Used Avail Use% Mounted on
/dev/xvda1            7.9G  2.4G  5.5G  30% /
tmpfs                 3.7G     0  3.7G   0% /dev/shm
s3fs                  256T     0  256T   0% /mnt/s3
&lt;/pre&gt;
&lt;h4 id=&quot;aya&quot;&gt;
6.再起動してもマウント&lt;/h4&gt;
&lt;pre class=&quot;text&quot; name=&quot;code&quot;&gt;
# vi /etc/fstab
+++ s3fs#myfirst-bucket /mnt/s3 fuse allow_other,default_acl=public-read 0 0

# vi /etc/rc.d/rc.sysinit
...
. /etc/init.d/functions
+++ modprobe fuse
&lt;/pre&gt;


&lt;h4 id=&quot;aya&quot;&gt;
＊＊＊　うーんうまくできなかった (´；ω；`)ｳｯ…　＊＊＊&lt;/h4&gt;
微妙な感じでうまくいかない。見えたり、見えなかったり。。。よって、こちらのバージョンにした。&lt;br&gt;
&lt;br&gt;
&lt;a href=&quot;http://blog.cloudpack.jp/2011/07/aws-news-s3-s3cmd.html&quot;&gt;cloudpack ブログ - S3ってなんじゃ？(s3cmd編) -
&lt;/a&gt;&lt;br&gt;
オフィシャル：Amazon S3 tools: &lt;a href=&quot;http://s3tools.org/s3cmd&quot;&gt;s3cmd : command line S3 client&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/8405377529952507279/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2012/02/amazonec2s3.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/8405377529952507279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/8405377529952507279'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2012/02/amazonec2s3.html' title='AmazonEC2にS3領域をマウントしてみる'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-9013743726040864136</id><published>2011-09-24T00:54:00.001+09:00</published><updated>2011-10-11T13:06:35.282+09:00</updated><title type='text'>CでDevquiz２０１１スライドパズル　その３</title><content type='html'>&lt;h4 id=&quot;aya&quot;&gt;


















&lt;span style=&quot;font-size: large;&quot;&gt;スライドパズルに関するアルゴリズムのサマリー&lt;/span&gt;&lt;/h4&gt;
ソースさらし祭り(?)に参加されている人の解説などを含め今回調べたアルゴリズムを整理したページです。&lt;br /&gt;
&lt;br /&gt;
広く浅く、全体を俯瞰できるようにすることを目標に書いてみます。 &lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;b&gt;&amp;nbsp;&lt;span style=&quot;font-size: large;&quot;&gt;☆問題の定式化&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
駒数をKとすると可能な盤面はK！個あり、それらを要素とする集合Sを考える。&lt;br /&gt;
&lt;br /&gt;
Sの各要素は駒を一回移動することで遷移できる要素と繋がっていると考えることで無向グラフとみなすことができる。&lt;br /&gt;
&lt;br /&gt;
与えられた問題面ノードからゴールノードまでの経路探索問題と解釈できる。&lt;br /&gt;
なお、Kが３６の場合K!は３．７×１０^３６となり、無限の要素を持つと思って考えていい。&lt;br /&gt;
&lt;br /&gt;
今後、n,g,h,h&#39;を以下の意味で使う。&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;
&lt;i&gt;n：与えられた盤面&lt;/i&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;
&lt;i&gt;g(n)：スタートの盤面からnまでの駒の移動回数&lt;/i&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;
&lt;i&gt;h(n)：nからゴールまでの最短経路の駒の移動回数&lt;/i&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Arial,Helvetica,sans-serif;&quot;&gt;
&lt;i&gt;h&#39;(n)：h(n)の推定値。（マンハッタンディスタンスなどを利用したnからゴールまでの駒の移動回数の推定値）&lt;/i&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;☆&lt;/b&gt;&lt;b&gt;経路探索アルゴリズム：幅探優先探索&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
駒の移動回数の小さい順に探索していくアルゴリズム。&lt;br /&gt;
&lt;br /&gt;
見つかったノードをキューに入れていく形で実装。&lt;br /&gt;
&lt;br /&gt;
過去の盤面をメモリーに保存するため、メモリーサイズで探索できるノード数が限られる。&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://ja.wikipedia.org/wiki/%E5%B9%85%E5%84%AA%E5%85%88%E6%8E%A2%E7%B4%A2&quot;&gt;http://ja.wikipedia.org/wiki/%E5%B9%85%E5%84%AA%E5%85%88%E6%8E%A2%E7%B4%A2&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;☆&lt;/b&gt;&lt;b&gt;経路探索アルゴリズム：深さ優先探索&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
ノードが途切れるか、ゴールに到達するまで深く探索していき、その後はバックトラック。&lt;br /&gt;
&lt;br /&gt;
スライドパズルのような開いた木の最適解を求めるためには下記のIDDFSやIDA*のような手法を使う。&lt;br /&gt;
&lt;br /&gt;
過去の盤面を保存しないのでメモリー消費は小さい。&lt;br /&gt;
&lt;a href=&quot;http://www.blogger.com/goog_1120772171&quot;&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://ja.wikipedia.org/wiki/%E6%B7%B1%E3%81%95%E5%84%AA%E5%85%88%E6%8E%A2%E7%B4%A2&quot;&gt;http://ja.wikipedia.org/wiki/%E6%B7%B1%E3%81%95%E5%84%AA%E5%85%88%E6%8E%A2%E7%B4%A2&lt;/a&gt;&lt;br /&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;☆&lt;/b&gt;&lt;b&gt;経路探索アルゴリズム：IDA*&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
深さ優先探索で以下の閾値を設けて探索を行う。&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&amp;nbsp;g(n) + h&#39;(n) &amp;lt;Threshold&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
ある閾値でゴールが見つからなかった場合は、閾値を徐々に増大させながら探索を繰り返す。&lt;br /&gt;
&lt;br /&gt;
ここでh&#39;(n)が以下を満たす時、最初に見つけた経路が最短経路である事が証明できる。&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;0 ≦ h&#39;(n) ≦ h(n) &lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
この閾値の評価を単に&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;&amp;nbsp; g(n) &amp;lt; Threshold&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
としたものは反復深化深さ優先探索(IDDFS)と呼ばれる。&lt;br /&gt;
&lt;br /&gt;
木構造の根元に近い部分を何度も調べることになるため無駄のように見えるが、ノードの多くは木構造の底辺にあるため、それほどコスト増大にはならない。（深さNに応じてx＾Nでノード数は増大するため、たとえばx=2の場合、高々2倍の演算量にしかならない）&lt;br /&gt;
&lt;a href=&quot;http://www.blogger.com/goog_1120772167&quot;&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://ja.wikipedia.org/wiki/%E5%8F%8D%E5%BE%A9%E6%B7%B1%E5%8C%96%E6%B7%B1%E3%81%95%E5%84%AA%E5%85%88%E6%8E%A2%E7%B4%A2&quot;&gt;http://ja.wikipedia.org/wiki/%E5%8F%8D%E5%BE%A9%E6%B7%B1%E5%8C%96%E6%B7%B1%E3%81%95%E5%84%AA%E5%85%88%E6%8E%A2%E7%B4%A2&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;☆&lt;/b&gt;&lt;b&gt;経路探索アルゴリズム：A*&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
幅優先のキューをプライオリティキューにして、もっとも推定コストの小さいノードを優先して探索しているアルゴリズム。&lt;br /&gt;
&lt;br /&gt;
推定コストとは&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;f(n) = g(n) + h&#39;(n)&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
ここでIDA*同様h&#39;(n)が以下を満たす時、最初に見つけた経路が最短経路である事が証明できる。&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;0 ≦ h&#39;(n) ≦ h(n)&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
幅優先探索の拡張であるのでメモリが探索深度に応じ指数関数的に消費されていくため、ある程度以上の深度まで探索しようとすると、使われないノードを一旦破棄し必要に応じて再利用（SMA*）が必要になる。&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://ja.wikipedia.org/wiki/A*&quot;&gt;http://ja.wikipedia.org/wiki/A*&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;☆&lt;/b&gt;&lt;b&gt;評価関数h&#39;(n)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
高得点を得ていたアルゴリズムはほぼA*かIDA*を利用したものだったが、これらのアルゴリズムでは評価関数h&#39;(n)の精度が重要になる。&lt;br /&gt;
h&#39;(n)がh(n)に近ければ近いほど演算量は小さくなるので、いかにh(n)に近い関数を見つけるかがとても重要！&lt;br /&gt;
&lt;br /&gt;
以下で説明するようにいくつかの手法が考案されており、これらを組み合わせて使う（もっとも値の大きいh&#39;(n)の値を利用する）こともできる。&lt;br /&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;☆&lt;/b&gt;&lt;b&gt;マンハッタンディスタンス（MD)&lt;/b&gt;&lt;/div&gt;
個々の駒に関してゴール位置への移動回数を計算したもの。&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%B3%E3%83%8F%E3%83%83%E3%82%BF%E3%83%B3%E8%B7%9D%E9%9B%A2&quot;&gt;http://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%B3%E3%83%8F%E3%83%83%E3%82%BF%E3%83%B3%E8%B7%9D%E9%9B%A2&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;b&gt;パターンデータベース（PDB）&lt;/b&gt;&lt;/div&gt;
前もって特定のパターンとそのパターンのh(n)を計算しておき、それをハッシュ化して保存しておきh&#39;(n)の計算に利用する手法。&lt;br /&gt;
&lt;a href=&quot;http://www.blogger.com/goog_1120772183&quot;&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.ise.bgu.ac.il/faculty/felner/research/jairpdb.pdf&quot;&gt;http://www.ise.bgu.ac.il/faculty/felner/research/jairpdb.pdf&lt;/a&gt;&lt;br /&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;☆&lt;/b&gt;&lt;b&gt;ギャップ集合&lt;/b&gt;&lt;/div&gt;
MDを利用したh&#39;(n)とh(n)とのギャップがいくつであるかに応じたデータベースをあらかじめ作っておく。&lt;br /&gt;
探索時にそのDBを参照し、ギャップに応じてMDに値を加算する。&lt;br /&gt;
&lt;a href=&quot;http://www.blogger.com/goog_1120772188&quot;&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.jstage.jst.go.jp/article/tjsai/26/2/419/_pdf/-char/ja/&quot;&gt;http://www.jstage.jst.go.jp/article/tjsai/26/2/419/_pdf/-char/ja/&lt;/a&gt; &lt;br /&gt;
&lt;div style=&quot;color: black;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;☆&lt;/b&gt;&lt;b&gt;転倒距離&lt;/b&gt;&lt;/div&gt;
駒の並びを順列と考え、小さい順に並んでいない駒の数（転倒が起こっている回数）を利用&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.ic-net.or.jp/home/takaken/nt/slide/solve15.html&quot;&gt;http://www.ic-net.or.jp/home/takaken/nt/slide/solve15.html&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;☆&lt;/b&gt;&lt;b&gt;ウォーキングディスタンス&lt;/b&gt;&lt;/div&gt;
ゴール盤面で各行（または各列）に属している駒が、その盤面でそれぞれの各行（または各列）に何個あるかというパターンをデータベース化したもの。&lt;br /&gt;
PDBの一種（？）&lt;br /&gt;
４×４くらいまでは有効だが、５×５以上ではデータベースが膨大になり現実的ではない。&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.ic-net.or.jp/home/takaken/nt/slide/solve15.html&quot;&gt;http://www.ic-net.or.jp/home/takaken/nt/slide/solve15.html&lt;/a&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;☆&lt;/b&gt;&lt;b&gt;最短経路以外の解を求める探索&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
ここまでは全て最短経路を求めるためのアルゴリズムだが、今回のDevquizの問題は与えられた移動可能駒数に余裕があり、参加者の多くは非最短解を求めるアルゴリズムを考案・採用されていた。&lt;br /&gt;
&lt;br /&gt;
大別すると以下のパターンに分類できる。&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;☆&lt;/b&gt;&lt;b&gt;上限を守らない評価関数&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
上に述べたように任意の盤面nに対し&lt;br /&gt;
&lt;br /&gt;
0 ≦ h&#39;(n) ≦ h(n) &lt;br /&gt;
&lt;br /&gt;
を満たすような評価関数であれば、最短経路である事が保障されますが、この上限をあえて守らない事でより早くゴールにたどり着こうという発想。&lt;br /&gt;
&lt;br /&gt;
具体的には、MD値を各コマに対して足し上げる際に端の駒の重みを大きくしたり、駒の並び順に応じてペナルティスコアを加算したり等。&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;☆&lt;/b&gt;&lt;b&gt;段階を置いてゴールに辿りつこうという方法&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
いきなりゴール面までの探索をする代わりに、途中に中継点を置いて中継点までの探索を行い、中継点からゴールまでの探索を再度行う方法。&lt;br /&gt;
&lt;br /&gt;
私が行った、&lt;a href=&quot;http://rhythm-prism.blogspot.com/2011/09/cdevquiz.html&quot;&gt;端優先、ステップ実行&lt;/a&gt;はこれにあたる。&lt;br /&gt;
（ 端優先、ステップ実行という名前は私が勝手に付けた）&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;☆&lt;/b&gt;&lt;b&gt;キューのサイズに上限を設ける方法&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
A*など幅優先系のアルゴリズムでプライオリティキューのサイズに上限を設け、上限に達したらプライオリティのもっとも低いノードをキューから削除する方法。&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #ffe599; color: black;&quot;&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;b&gt;☆&lt;/b&gt;&lt;b&gt;経路探索アルゴリズム：双方向探索&lt;/b&gt;&lt;/div&gt;
&lt;br /&gt;
逆方向からも探索する事で演算量を下げる方法。&lt;br /&gt;
やり方によっては最適解にもなる。&lt;br /&gt;
&lt;br /&gt;
x^Nがx^(N/2)となり、大幅に演算量を下げることができる。&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://ja.wikipedia.org/wiki/%E5%8F%8C%E6%96%B9%E5%90%91%E6%8E%A2%E7%B4%A2&quot;&gt;http://ja.wikipedia.org/wiki/%E5%8F%8C%E6%96%B9%E5%90%91%E6%8E%A2%E7%B4%A2&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/9013743726040864136/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2011/09/cdevquiz_24.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/9013743726040864136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/9013743726040864136'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2011/09/cdevquiz_24.html' title='CでDevquiz２０１１スライドパズル　その３'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-4237640785912534382</id><published>2011-09-13T23:25:00.000+09:00</published><updated>2011-09-24T02:05:31.206+09:00</updated><title type='text'>CでDevquiz２０１１スライドパズル　その２</title><content type='html'>&lt;h3 id=&quot;aya&quot;&gt;









解説1&lt;/h3&gt;
&lt;div&gt;
昨日公開したスライドパズルのソースの解説をしていこうと思います。&lt;br /&gt;
まずは特に独自性がありそうな、端優先、ステップ実行と書いたアルゴリズムの解説です。&lt;/div&gt;
&lt;h4 id=&quot;aya&quot;&gt;







端優先&lt;/h4&gt;
&lt;br /&gt;
&lt;table border=&quot;1&quot; cellpadding=&quot;3&quot; cellspacing=&quot;0&quot;&gt;&lt;tbody&gt;
&lt;tr align=&quot;center&quot;&gt;&lt;td height=&quot;20&quot; width=&quot;20&quot;&gt;１&lt;/td&gt;&lt;td height=&quot;20&quot; width=&quot;20&quot;&gt;２&lt;/td&gt;&lt;td height=&quot;20&quot; width=&quot;20&quot;&gt;３&lt;/td&gt;&lt;/tr&gt;
&lt;tr align=&quot;center&quot;&gt;&lt;td&gt;４&lt;/td&gt;&lt;td&gt;５&lt;/td&gt;&lt;td&gt;６&lt;/td&gt;&lt;/tr&gt;
&lt;tr align=&quot;center&quot;&gt;&lt;td&gt;７&lt;/td&gt;&lt;td&gt;８&lt;/td&gt;&lt;td&gt;０&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div&gt;
このような３X３のブロックなしの問題が与えられた場合、人力で解く際は通常、まず１をそろえて、その次２、３、その次４、７、最後に５、６、８と合わせますよね。&lt;/div&gt;
&lt;div&gt;
このロジックを実装したアルゴリズムです。&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
ここで２、３を一緒に合わせるのは２を先に合わせて固定してしまうと３が入らなくなるからですが、これは「&lt;b&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: yellow;&quot;&gt;ある駒（この場合２の駒）を固定することで1方向にしか移動できなくなる駒（この場合は３の駒）を一緒に合わせる必要がある&lt;/span&gt;&lt;/b&gt;」という考えで一般化でき、具体的には&lt;/div&gt;
&lt;pre class=&quot;perl&quot; name=&quot;code&quot;&gt;recurs_func(　駒A　）{
 駒Aを固定する
 for　(　駒B　∈　Aと隣り合っている駒で1方向にしか動かせない駒　）
　　recurs_func(　駒B　）
}
&lt;/pre&gt;
&lt;div&gt;
といった再帰で実現できます。&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
このロジックはブロックがある場合にも拡張でき、例えば&lt;/div&gt;
&lt;br /&gt;
&lt;table border=&quot;1&quot; cellpadding=&quot;3&quot; cellspacing=&quot;0&quot;&gt;&lt;tbody&gt;
&lt;tr align=&quot;center&quot;&gt;&lt;td height=&quot;20&quot; width=&quot;20&quot;&gt;１&lt;/td&gt;&lt;td height=&quot;20&quot; width=&quot;20&quot;&gt;２&lt;/td&gt;&lt;td height=&quot;20&quot; width=&quot;20&quot;&gt;３&lt;/td&gt;&lt;td height=&quot;20&quot; width=&quot;20&quot;&gt;４&lt;/td&gt;&lt;/tr&gt;
&lt;tr align=&quot;center&quot;&gt;&lt;td&gt;５&lt;/td&gt;&lt;td&gt;６&lt;/td&gt;&lt;td bgcolor=&quot;gray&quot;&gt;＝&lt;/td&gt;&lt;td&gt;８&lt;/td&gt;&lt;/tr&gt;
&lt;tr align=&quot;center&quot;&gt;&lt;td&gt;９&lt;/td&gt;&lt;td&gt;A&lt;/td&gt;&lt;td&gt;B&lt;/td&gt;&lt;td&gt;C&lt;/td&gt;&lt;/tr&gt;
&lt;tr align=&quot;center&quot;&gt;&lt;td&gt;D&lt;/td&gt;&lt;td&gt;E&lt;/td&gt;&lt;td&gt;F&lt;/td&gt;&lt;td&gt;０&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div&gt;
といったケースにもうまく適応できます。&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
この場合&lt;/div&gt;
&lt;pre class=&quot;perl&quot; name=&quot;code&quot;&gt;{1}
{2,3,4,8}
{5,6}
{9,D}
{AE}
{BCF}&lt;/pre&gt;
&lt;div&gt;
といった形の配列を作成し、上から順番にIDA*を利用して揃えていくという事を行っています。&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
なお、上からそろえる、左からそろえる、左上（０から遠いところから）揃えると3パターンで試してみましたが、これら３つはほぼ等価で、上からそろえてうまくいくものは、左からでも左上からでもうまくいくし、ダメなものはだめという結果でした。&lt;/div&gt;
&lt;div&gt;
この理由はダメな場合はこの例の｛2,3,4,8}のように一緒に揃えないといけない駒の数が多いとき、IDA*では現実的な計算量に収まらないという状況のようです。&lt;br /&gt;
ここは、マンハッタンディスタンス（MD)に加え並び順も考慮することで改善の余地がありそうだったので時間があればもうちょっと開発したかった部分です。&lt;/div&gt;
&lt;br /&gt;
&lt;h4 id=&quot;aya&quot;&gt;








ステップ実行&lt;/h4&gt;
&lt;div&gt;
一般に、駒の移動回数Nが増えるに従いx^Nのオーダーで計算量が増えていきます。&lt;/div&gt;
&lt;div&gt;
ここで、xは与えられた問題に依存する1から3の間の実数です。（3より小さいのは上下左右4つの方向のうち1方向は前回の盤面に戻る移動なので省略しているから）移動回数とMDの輪が閾値以下という条件で枝刈りするにしてもNが増えると（閾値が増えると）計算量はどうしても膨大になります。&lt;/div&gt;
&lt;div&gt;
そこで最短経路解を取りこぼしてでも（移動回数の制限はかなりあまいという事がわかっていたので）強めの枝刈りを考える事になるのですが、ここではたとえば1億ノードとか指定してあげて、そのノード数探索して見つからなかったら、それまでに探索したノード内で最もMDの小さい値を初期ノードとして再探索するという事を行いました。つまり、最小値を持つモード以外すべて枝刈りするという大胆な方法です。&lt;/div&gt;
&lt;div&gt;
双方向探索と同じようにx^Nをx^(N/2)としてあげようという発想ですね。&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
この方法のメリットはなんといっても実装が簡単である事。&lt;/div&gt;
&lt;div&gt;
また、ステップ毎に強めの枝刈りをして深く探索していく方法だとローカルミニマムにとらわれて脱出できないリスクが高くなりますが、この方法だと無駄だと思われるノードに対しても与えられた探索回数までは広く探索を行うので、ローカルミニマムから脱出する可能性が高くなるというメリットもあります。&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkfIeC-Ss3acly4jfSuefFSTY02gVLypdyvUTtodCv4U4EjwVin2UsIfu0P8IOZyzX8U_WUa3KakpY5uJ_7nF6MGyxB0YvbWy96sLNtACgD4QHGdn_VWG9BOrqe9zXrN7AQgy615ZnUsM/s1600/tmp.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;203&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkfIeC-Ss3acly4jfSuefFSTY02gVLypdyvUTtodCv4U4EjwVin2UsIfu0P8IOZyzX8U_WUa3KakpY5uJ_7nF6MGyxB0YvbWy96sLNtACgD4QHGdn_VWG9BOrqe9zXrN7AQgy615ZnUsM/s320/tmp.gif&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
実際、この方法は強力で単純なIDA*では見つけられなかった問題（計算に時間がかかりすぎた問題）のかなりの数を回答しています。&lt;br /&gt;
&lt;br /&gt;
これらのアルゴリズムの位置づけに関しては&lt;a href=&quot;http://rhythm-prism.blogspot.com/2011/09/cdevquiz_24.html&quot;&gt;こちら&lt;/a&gt;の記事を参照してください。 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/4237640785912534382/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2011/09/cdevquiz.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/4237640785912534382'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/4237640785912534382'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2011/09/cdevquiz.html' title='CでDevquiz２０１１スライドパズル　その２'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkfIeC-Ss3acly4jfSuefFSTY02gVLypdyvUTtodCv4U4EjwVin2UsIfu0P8IOZyzX8U_WUa3KakpY5uJ_7nF6MGyxB0YvbWy96sLNtACgD4QHGdn_VWG9BOrqe9zXrN7AQgy615ZnUsM/s72-c/tmp.gif" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-6878152425498602339</id><published>2011-09-12T18:47:00.000+09:00</published><updated>2011-09-15T00:26:35.573+09:00</updated><title type='text'>CでDevquiz２０１１スライドパズル</title><content type='html'>Devquizへの参加記念にソースコードを晒しておきます。

&lt;br /&gt;
&lt;h4 id=&quot;aya&quot;&gt;


アルゴリズム&lt;/h4&gt;
１、IDA*&lt;br /&gt;
&amp;nbsp; 過去のステップ数と残りの距離見積りの和で与えた閾値を上げながら反復深化&lt;br /&gt;
２、双方向探索&lt;br /&gt;
ゴールから幅優先探索、前方からIDA*を実行しマッチング&lt;br /&gt;
実装中に他の方法で万点取れる目途が付いたので中途半端（というかまだ動いていなかった。。）になっています。&lt;br /&gt;
３、&lt;a href=&quot;http://rhythm-prism.blogspot.com/2011/09/cdevquiz.html&quot;&gt;端優先&lt;/a&gt;&lt;br /&gt;
人がパズルを組み立てる時のように端から順に揃えていくアルゴリズム。&lt;br /&gt;
４、&lt;a href=&quot;http://rhythm-prism.blogspot.com/2011/09/cdevquiz.html&quot;&gt;ステップ実行&lt;/a&gt;&lt;br /&gt;
指定された回数探索を行い、それまでにゴールに達しなかった場合、過去に見つかった残りの距離見積りが最小のものをスタートに再度探索を繰り返す。（それ以外のノードを捨てる）&lt;br /&gt;
５、半自動シミュレーション&lt;br /&gt;
上記で解けない問題が7問残った。この残った問題を半自動で解くためのヒントを元に解いていくシュミレーター。&lt;br /&gt;
&lt;br /&gt;
*距離関数としてはブロックを考慮したマンハッタンディスタンスを使用。&lt;br /&gt;
*２だけはゴールを広げる程度に幅優先でメモリー使ってますが、基本的にはメモリーを消費しない深さ優先をベースに作っています。辿ったノードを記憶しておく幅優先系ではメモリーが厳しいかなと予想してたんですが、A*で大半の問題を解いた人もいるようですね。&lt;br /&gt;
&lt;br /&gt;
&lt;h4 id=&quot;aya&quot;&gt;


excuse&lt;/h4&gt;
高得点を取る事だけを目的に書いていたプログラムなので、書きかけのコードが入っていたりグローバル変数使いまくりのコードになってます。&lt;br /&gt;
きちんと書いて今後公開しますが(気が向いたときw）、一旦提出したそのままのコードをUPします。&lt;br /&gt;
&lt;br /&gt;
150点取れたときの画像(@o@)&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY8LxMA5T3zPKxFi-cQBVRJnkg9wG5aoUrYdQHPh7RnfAwKae5nd4g2U8VMpo-KDzdvilJ9HPK3aPFVkBjOEEh_SkfKGf8ICVwKKZMgxQnB3-QkaFZJgCpCWLQcJCTTmHTTrOehX8Biko/s1600/DevQuiz.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY8LxMA5T3zPKxFi-cQBVRJnkg9wG5aoUrYdQHPh7RnfAwKae5nd4g2U8VMpo-KDzdvilJ9HPK3aPFVkBjOEEh_SkfKGf8ICVwKKZMgxQnB3-QkaFZJgCpCWLQcJCTTmHTTrOehX8Biko/s320/DevQuiz.gif&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h4 id=&quot;aya&quot;&gt;


実際のソース&lt;/h4&gt;
&lt;pre&gt;
&lt;/pre&gt;
&lt;pre&gt;#include&amp;lt;stdio.h&amp;gt;
#include&amp;lt;stdlib.h&amp;gt;
#include&amp;lt;string.h&amp;gt;
#include &amp;lt;unistd.h&amp;gt;

#define YOKO_YUSEN
//#define INVD
#define MAXIDTBL 600
#define MAX_STACK_LEVEL 5000
#define MAX_HANPUKU 2000
#define   MIN(a,b)  ( ((a)&amp;lt;(b) ) ? (a) : (b) )
#define   MAX(a,b)  ( ((a)&amp;gt;(b) ) ? (a) : (b) )

int matrix_size;
int matrix_size_x;
int matrix_size_y;
int hanpuku_done;
int step_done;
int shurink;
int shurink_mask;
unsigned long long max_count;
unsigned long long count_hanpuku;
int step_dist;

unsigned long long level_counter[MAX_STACK_LEVEL+1];
int level_max_md_counter[MAX_STACK_LEVEL+1];
int level_min_md_counter[MAX_STACK_LEVEL+1];
int moving_history[MAX_STACK_LEVEL+1];
int mh_cnt;
int simflg;

int pre_result_threshold;
char *pre_result_string;
char *mondai;
char *kaitou;

enum STACK {UP, DOWN};
enum MODE2 {MOVE, HANPUKU, STEP, STEP_TARGET, FIX,UNFIX};

struct MATRIX{
        char mval[40];
        int sp_pos;
};

struct HASH_LIST {
        struct MATRIX *matrix;
        struct HASH_LIST *next;
};

struct HABA_STACK{
        char mval[36];
};

struct Stock_Arr{
        char r;
        char sp_pos;
        char new_pos[4];
        int md;
        int wd;
        int sd;
        int id;
        int id1;
        int id2;
        int inv1;
        int inv2;
};

struct Stock_Arr stock_arr[MAX_STACK_LEVEL+4];

char New_Pos[36][4];

struct HARR{
        int arr[36][36];
        int arr_len[36];;
        int arr_num;
};


struct MATRIX Matrix;
struct MATRIX Matrix_Min;
struct MATRIX Matrix_Parity;
struct MATRIX Matrix_backup;
struct HARR HArr;
int CrrHarrIdx;

int Threshold;
int Pair_Threshold;
int StackPath[MAX_STACK_LEVEL+1];
int StackPath_Min[MAX_STACK_LEVEL+1];
int *IDTBL1;
int *IDTBL2;
int IDTBL3[MAXIDTBL];
int IDTBL4[MAXIDTBL];
int IDTBL5[MAXIDTBL];
int IDTBL6[MAXIDTBL];
int M_Distance[36][36];
int R_Distance[36][36];
int Parity_omote2ura[36];
int Parity_ura2omote[36];
int max_haba_stack;
struct HASH_LIST **hash_table;
struct HASH_LIST *Hash_List;
int stack_cnt,stack_tail;
int hash_cnt;
int haba;
struct MATRIX *haba_stack;
int min_depth;
int mode=1;

enum Dir {U,L,D,R};
int DirectionX[4] = {0, -1, 0, 1};
int DirectionY[4] = {-1, 0, 1, 0};
char Direction[4] = {&#39;U&#39;, &#39;L&#39;, &#39;D&#39;, &#39;R&#39;};


void dump_harr(){
        int i,j;

        printf(&quot;arr_num:%d\n&quot;,HArr.arr_num);
        for(i=0;i&amp;lt;HArr.arr_num;i++){
                printf(&quot;[%d(arr_len:%d) -&amp;gt;&quot;,i,HArr.arr_len[i]);
                for(j=0;j&amp;lt;HArr.arr_len[i];j++){
                        printf(&quot; %d&quot;,HArr.arr[i][j]);
                }
                printf(&quot;]\n&quot;);
        }
}

void dump_matrix(struct MATRIX *m){
        int i;
        char c,p;

        for(i=0;i&amp;lt;matrix_size_x;i++){
                printf(&quot;-&quot;);
        }
        printf(&quot;\n&quot;);
        for(i=0;i&amp;lt;matrix_size;i++){
                p = m-&amp;gt;mval[i];

                if(p &amp;gt; 8){
                        c = p + &#39;A&#39; - 9;
                } else if(p == -2){
                        c = &#39;=&#39;;
                } else if(p == -1){
                        c = &#39;.&#39;;
                } else {
                        c = p + &#39;1&#39;;
                }
                printf(&quot;%c&quot;,c);

                if(i%matrix_size_x == matrix_size_x - 1){
                        printf(&quot;\n&quot;);
                }
        }
        for(i=0;i&amp;lt;matrix_size_x;i++){
                printf(&quot;-&quot;);
        }
        printf(&quot;\n&quot;);
}

void dump_matrix2(struct MATRIX *m){
        int i,x,y;
        char c,p;

        for(i=0;i&amp;lt;matrix_size_x;i++){
                printf(&quot;-&quot;);
        }
        printf(&quot;       &quot;);
        for(i=0;i&amp;lt;matrix_size_x;i++){
                printf(&quot;-&quot;);
        }
        printf(&quot;\n&quot;);

        for(y=0;y&amp;lt;matrix_size_y;y++){
                for(x=0;x&amp;lt;matrix_size_x;x++){
                        i = y*matrix_size_x+x;
                        p = m-&amp;gt;mval[i];
                        if(p &amp;gt; 8){
                                c = p + &#39;A&#39; - 9;
                        } else if(p == -2){
                                c = &#39;=&#39;;
                        } else if(p == -1){
                                c = &#39;.&#39;;
                        } else {
                                c = p + &#39;1&#39;;
                        }
                        printf(&quot;%c&quot;,c);
                }
                printf(&quot;       &quot;);
                for(x=0;x&amp;lt;matrix_size_x;x++){
                        i = y*matrix_size_x+x;
                        p = m-&amp;gt;mval[i];
                        if(p == -2){
                                c = &#39;=&#39;;
                        } else if(i == matrix_size-1){
                                c = &#39;.&#39;;
                        } else if(i &amp;gt; 8){
                                c = i + &#39;A&#39; - 9;
                        } else {
                                c = i + &#39;1&#39;;
                        }
                        printf(&quot;%c&quot;,c);
                }
                printf(&quot;\n&quot;);
        }

        for(i=0;i&amp;lt;matrix_size_x;i++){
                printf(&quot;-&quot;);
        }
        printf(&quot;       &quot;);
        for(i=0;i&amp;lt;matrix_size_x;i++){
                printf(&quot;-&quot;);
        }
        printf(&quot;\n&quot;);
}

void mv_koma(int this_r){
        int sp_pos,new_sp_pos;
        int tgt;

        sp_pos = Matrix.sp_pos;
        new_sp_pos = New_Pos[sp_pos][this_r];
        tgt = Matrix.mval[new_sp_pos];
        Matrix.mval[sp_pos] = tgt;
        Matrix.mval[new_sp_pos] = -1;
        Matrix.sp_pos = new_sp_pos;

}


void make_goal(struct MATRIX *tgt, struct MATRIX *org){
        int i,j;

        for(i=0, j=0; i&amp;lt;matrix_size; i++){
                if(org-&amp;gt;mval[i] == -2){
                        tgt-&amp;gt;mval[i] = -2;
                } else {
                        tgt-&amp;gt;mval[i] = i;
                        j=i;
                }
        }
        tgt-&amp;gt;mval[j] = -1;

        tgt-&amp;gt;sp_pos = org-&amp;gt;sp_pos;

}



void check_matrix(struct MATRIX *m){
        int i;

        for(i=0;i&amp;lt;matrix_size;i++){
                if(m-&amp;gt;mval[i] == -1){
                        return;
                }
        }
        printf(&quot;ERR: not found space\n&quot;);
        fflush(stdout);
        sleep(100);


}

int fix_mval(char p){
        int c;

        if(p &amp;gt; 8){
                c = p + &#39;A&#39; - 9;
        } else if(p == -2){
                c = &#39;=&#39;;
        } else {
                c = p + &#39;1&#39;;
        }

        return c;
}


void dump_matrix_parity(struct MATRIX *m){
        int i;
        char c,p;

        for(i=0;i&amp;lt;matrix_size_x;i++){
                printf(&quot;-&quot;);
        }
        printf(&quot;\n&quot;);
        for(i=0;i&amp;lt;matrix_size;i++){
                p = m-&amp;gt;mval[Parity_omote2ura[i]];

                if(p &amp;gt; 8){
                        c = p + &#39;A&#39; - 9;
                } else if(p == -2){
                        c = &#39;=&#39;;
                } else {
                        c = p + &#39;1&#39;;
                }
                printf(&quot;%c&quot;,c);

                if(i%matrix_size_x == matrix_size_x-1){
                        printf(&quot;\n&quot;);
                }
        }
        for(i=0;i&amp;lt;matrix_size_x;i++){
                printf(&quot;-&quot;);
        }
        printf(&quot;\n&quot;);
}

int comp(const void *a, const void *b)
{
        return R_Distance[matrix_size-1][*(int*)b] - R_Distance[matrix_size-1][*(int*)a];

}

int next_harr_saiki(int *stack_cnt, int *stack, int crr, struct MATRIX *m){
        int px, py, cx, cy,nx,ny;
        int r1,r2;
        int p_cnt;

        m-&amp;gt;mval[crr] = -2;
        stack[stack_cnt[0]] = crr;
        stack_cnt[0]++;

        px = crr % matrix_size_x;
        py = crr / matrix_size_x;

        for ( r1 = 0; r1 &amp;lt; 4; r1++ ){
                cx = px + DirectionX[r1];
                cy = py + DirectionY[r1];

                if ( cx &amp;lt; 0 || cy &amp;lt; 0 || cx &amp;gt;= matrix_size_x || cy &amp;gt;= matrix_size_y ){
                        continue;
                }

                if(m-&amp;gt;mval[cy*matrix_size_x+cx] == -2){
                        continue;
                }

                p_cnt=0;
                for(r2 = 0;r2 &amp;lt; 4;r2++){
                        nx = cx + DirectionX[r2];
                        ny = cy + DirectionY[r2];
                        if ( nx &amp;lt; 0 || ny &amp;lt; 0 || nx &amp;gt;= matrix_size_x || ny &amp;gt;= matrix_size_y ){
                                continue;
                        }
                        if(m-&amp;gt;mval[ny*matrix_size_x+nx] == -2){
                                continue;
                        }
                        p_cnt++;
                }

                if(p_cnt &amp;lt; 2 || m-&amp;gt;mval[matrix_size-1] == -2){
                        next_harr_saiki(stack_cnt, stack, cy*matrix_size_x+cx ,m);
                }
        }
        return 0;
}

int add_harr(int list_len, int *ranked_list, struct MATRIX *mtr){
        int stck[36];
        int cnt,i,j,found;

        cnt = 0;
        next_harr_saiki(&amp;amp;cnt,stck,ranked_list[0],mtr);
        if(cnt &amp;lt;= 0){
                exit(0);
        }

        for(i=0;i&amp;lt;cnt;i++){
                HArr.arr[HArr.arr_num][i] = stck[i];
        }

        HArr.arr_len[HArr.arr_num] = cnt;
        HArr.arr_num++;

        for(i=0;i&amp;lt;cnt;i++){
                found = 0;
                for(j=0;j&amp;lt;list_len;j++){
                        if(found == 1){
                                ranked_list[j-1] = ranked_list[j];
                        } else if(ranked_list[j] == stck[i]){
                                found = 1;
                        }
                }
        }


        return list_len - cnt;
}


void make_harr(struct MATRIX *m){
        int x,y,i,j,list_len;
        int ranked_list[36];
        int ranked_list_tmp[36];
        struct MATRIX tmp_m;

        CrrHarrIdx=0;
        HArr.arr_num = 0;

        for(i=0,j=0;i&amp;lt;matrix_size-1;i++){
                if(m-&amp;gt;mval[i] != -2){
                        ranked_list[j++] = i;
                }
        }
        list_len = j;

        if(step_dist == 1){
                /*do nothing*/
        } else if(step_dist == 2){
                for(i=0;i&amp;lt;matrix_size;i++) ranked_list_tmp[i] = ranked_list[i];
                for(x=0;x&amp;lt;matrix_size_x;x++)
                        for(y=0;y&amp;lt;matrix_size_y;y++)
                                ranked_list[y*matrix_size_x+x] = ranked_list_tmp[y*matrix_size_x+x];
        } else {
                qsort(ranked_list,list_len,sizeof(int),comp);
        }

        tmp_m = Matrix;
        while(1){
                if(list_len &amp;lt;= 0){
                        break;
                }

                list_len = add_harr(list_len, ranked_list, &amp;amp;tmp_m);
        }
}

void set_m_distance(){
        int i,j;

        for ( i = 0; i &amp;lt; matrix_size; i++ ){
                for ( j = 0; j &amp;lt; matrix_size; j++ ){
                        M_Distance[i][j] = abs(i/matrix_size_x-j/matrix_size_x) + abs(i%matrix_size_x-j%matrix_size_x);
                }
        }
}


int pair_saiki(int depth, int pre_r,int crr, int end){
        int ret;
        int px, py, cx, cy;
        int r;
        int diff;
        int d;

        if ( crr == end ){
                return 1;
        }

        d = M_Distance[crr][end];
        if ( depth + d &amp;gt; Pair_Threshold ){
                return 0;
        }

        px = crr % matrix_size_x;
        py = crr / matrix_size_x;

        for ( r = 0; r &amp;lt; 4; r++ ){
                cx = px + DirectionX[r];
                cy = py + DirectionY[r];
                if(pre_r &amp;gt; r){
                        diff = pre_r - r;
                } else {
                        diff = r - pre_r;
                }
                if(diff == 2){
                        continue;
                }

                if ( cx &amp;lt; 0 || cy &amp;lt; 0 || cx &amp;gt;= matrix_size_x || cy &amp;gt;= matrix_size_y ){
                        continue;
                }

                if(Matrix.mval[cy*matrix_size_x+cx] == -2){
                        continue;
                }

                ret = pair_saiki( depth+1, r , cy*matrix_size_x+cx, end);
                if (ret) {

                        return 1;
                }
        }
        return 0;
}


void set_r_distance(struct MATRIX *m){
        int i,j,ret;

        ret = 0;
        for ( i = 0; i &amp;lt; matrix_size; i++ ){
                if(m-&amp;gt;mval[i] == -2) continue;
                for ( j = 0; j &amp;lt; matrix_size; j++ ){
                        if(m-&amp;gt;mval[j] == -2) continue;
                        for ( Pair_Threshold = M_Distance[i][j]; Pair_Threshold &amp;lt;= MAX_STACK_LEVEL; Pair_Threshold += 2 ){
                                ret = pair_saiki(0, -4,i,j);

                                if ( ret ){
                                        R_Distance[i][j] = Pair_Threshold;
                                        break;
                                }

                        }
                        if(ret &amp;lt; 0){
                                printf(&quot;ERR: R_Distance not fund for [%d][%d]&quot;,i,j);
                                exit(1);
                        }
                }
        }
}

int inv_distance1(){
        int i,j,inv,val1,val2;

        inv = 0;
        for (i=0; i&amp;lt;matrix_size; i++) {
                val1 = Matrix.mval[i];
                if (val1 == -1) continue;
                if (val1 == -2) val1 = i;
                for (j=i+1; j&amp;lt;matrix_size; j++) {
                        val2 = Matrix.mval[j];
                        if (val2 == -1) continue;
                        if (val2 == -2) val2 = j;
                        if (val2&amp;lt;val1){
                                inv++;
                        }
                }
        }
        return inv;
}


int inv_distance2(){
        int i,j,inv,val1,val2;

        inv = 0;
        for (i=0; i&amp;lt;matrix_size; i++) {
                val1 = Matrix_Parity.mval[i];
                if (val1 == -1) continue;
                if (val1 == -2) val1 = i;
                for (j=i+1; j&amp;lt;matrix_size; j++) {
                        val2 = Matrix_Parity.mval[j];
                        if (val2 == -1) continue;
                        if (val2 == -2) val2 = j;
                        if (val2&amp;lt;val1){
                                inv++;
                        }
                }
        }
        return inv;
}

int i_distance(){
        int inv1,inv2;

        inv1 = inv_distance1();
        inv2 = inv_distance2();
        return IDTBL1[inv1]+IDTBL2[inv2];
}

int m_distance(){
        int md;
        int i;

        md = 0;
        for(i = 0; i &amp;lt; matrix_size; i++){
                if ( Matrix.mval[i] &amp;lt; 0 )continue;
                md += R_Distance[i][(int)Matrix.mval[i]];
        }

        return md;
}

int w_distance(){
        int md;
        int id;

        md = m_distance();
        id = i_distance();

        return MAX(md,id);;
}

int step_distance(){
        int sum;
        int i,j,k;
        char c;

        sum = 0;
        for(i = 0; i &amp;lt; HArr.arr_len[CrrHarrIdx]; i++){
                k = HArr.arr[CrrHarrIdx][i];
                c = k;
                for(j=0;j&amp;lt;matrix_size;j++){
                        if(Matrix.mval[j] == c){
                                sum += R_Distance[j][k];
                        }
                }

        }
        return sum;
}

int check_goal(){
        int i;
        for ( i = matrix_size-2; i &amp;gt;= 0; i-- ){
                if ( Matrix.mval[i] != i &amp;amp;&amp;amp; Matrix.mval[i] != -2 ){
                        return 0;
                }
        }
        return 1;
}

int check_step_goal(){
        int i,j;
        for (i=0;i&amp;lt;HArr.arr_len[CrrHarrIdx];i++){
                j = HArr.arr[CrrHarrIdx][i];
                if ( Matrix.mval[j] != j &amp;amp;&amp;amp; Matrix.mval[j] != -2){
                        return 0;
                }
        }
        return 1;
}

int heuristic_distance(){


        return 0;
}

int get_r(char *c){
        int this_r;

        if(*c==&#39;U&#39; || *c==&#39;u&#39;) this_r = 0;
        else if(*c==&#39;L&#39; || *c==&#39;l&#39;) this_r = 1;
        else if(*c==&#39;D&#39; || *c==&#39;d&#39;) this_r = 2;
        else if(*c==&#39;R&#39; || *c==&#39;r&#39;) this_r = 3;
        else this_r = -1;

        return this_r;
}



int steploop(int pre_depth, int depth, int pre_r){
        int i;
        int this_r;
        int sp_pos,new_sp_pos;
        int stack_dir;
        int crr_depth;
        char *npp;
        int found;
        int tgt;
        int sd;
        int harr_arr_len;

        struct MATRIX tmp;

        harr_arr_len = HArr.arr_len[CrrHarrIdx];

        tmp = Matrix;

        found = 0;
        crr_depth = 0;

        stack_dir = DOWN;
        sp_pos = Matrix.sp_pos;
        stock_arr[crr_depth].sp_pos = sp_pos;


        sd = step_distance();
        if(sd == 0){
                found = 1;
                return 1;
        }
        stock_arr[crr_depth].sd = sd;

        if ( sd &amp;gt; Threshold - crr_depth ){
                return 0;
        }

        memcpy(stock_arr[crr_depth].new_pos,New_Pos[Matrix.sp_pos],sizeof(char)*4);
        npp = stock_arr[crr_depth].new_pos;

        for(i=0;i&amp;lt;4;i++){
                if(pre_r - i == 2 || i - pre_r == 2){
                        npp[i] = -1;
                        break;
                }
        }

        for(this_r=-1,i=0;i&amp;lt;4;i++){
                if(npp[i] &amp;gt;= 0){
                        this_r = i;
                        break;
                }
        }

        if(this_r &amp;gt;= 0){
                npp[this_r] = -1;
                stack_dir = DOWN;
        } else {
                fprintf(stderr,&quot;ERR11\n&quot;);
                return 0;
        }

        while(1){


                if(stack_dir == DOWN){
                        /* use stack_dir, this_r, sp_pos */

                        if(crr_depth &amp;gt;= MAX_STACK_LEVEL){
                                fprintf(stderr, &quot;ERR: crr_depth over\n&quot;);
                                return 0;
                        }
                        crr_depth++;

                        if(count_hanpuku &amp;gt; max_count){
                                hanpuku_done = 1;
                                return 0;
                        }
                        count_hanpuku++;

                        stock_arr[crr_depth].r = this_r;
                        new_sp_pos = New_Pos[sp_pos][this_r];
                        stock_arr[crr_depth].sp_pos = new_sp_pos;
                        tgt = Matrix.mval[new_sp_pos];
                        Matrix.mval[sp_pos] = tgt;
                        Matrix.mval[new_sp_pos] = -1;
                        Matrix.sp_pos = new_sp_pos;
                        sd = stock_arr[crr_depth-1].sd;
                        for(i=0;i&amp;lt;harr_arr_len;i++){
                                if(HArr.arr[CrrHarrIdx][i] == tgt){
                                        sd += R_Distance[sp_pos][tgt] - R_Distance[new_sp_pos][tgt];
                                        break;
                                }
                        }

                        if(sd == 0){
                                found = 1;
                                break;
                        }
                        stock_arr[crr_depth].sd = sd;

                        if ( sd &amp;gt; Threshold - crr_depth ){
                                sp_pos = new_sp_pos;
                                stack_dir = UP;
                                continue;
                        }

                        memcpy(stock_arr[crr_depth].new_pos,New_Pos[new_sp_pos],sizeof(char)*4);
                        npp = stock_arr[crr_depth].new_pos;

                        for(i=0;i&amp;lt;4;i++){
                                if(this_r - i == 2 || i - this_r == 2){
                                        npp[i] = -1;
                                        break;
                                }
                        }

                        if(npp[0] &amp;gt;= 0) this_r = 0;
                        else if(npp[1] &amp;gt;= 0) this_r = 1;
                        else if(npp[2] &amp;gt;= 0) this_r = 2;
                        else if(npp[3] &amp;gt;= 0) this_r = 3;
                        else this_r = -1;

                        sp_pos = new_sp_pos;
                        if(this_r &amp;gt;= 0){
                                npp[this_r] = -1;
                                stack_dir = DOWN;
                        } else {
                                stack_dir = UP;
                        }


                } else { // UP
                        if(crr_depth == 0){
                                return 0;
                        }
                        crr_depth--;

                        new_sp_pos = stock_arr[crr_depth].sp_pos;
                        Matrix.mval[sp_pos] = Matrix.mval[new_sp_pos];
                        Matrix.mval[new_sp_pos] = -1;
                        Matrix.sp_pos = new_sp_pos;

                        npp =  stock_arr[crr_depth].new_pos;
                        for(this_r = -1,i=0;i&amp;lt;4;i++){
                                if(npp[i] &amp;gt;= 0){
                                        this_r = i;
                                        break;
                                }
                        }

                        sp_pos = new_sp_pos;
                        if(this_r &amp;gt;= 0){
                                npp[this_r] = -1;
                                stack_dir = DOWN;
                        } else {
                                stack_dir = UP;
                        }

                }
        }

        if(found){
                for(i=0;i&amp;lt;crr_depth;i++){
                        StackPath[pre_depth+i] = stock_arr[i+1].r;
                }
                StackPath[pre_depth+i] = 0;
        }

        return 1;
}

int stepsaiki(int depth, int pre_r){
        int ret;
        int px, py, cx, cy;
        int r;
        int diff;
        int wd;
        struct MATRIX tmp;

        wd = step_distance();
        if(wd == 0){
                Matrix_backup = Matrix;
                return 1;
        }

        if ( depth + wd &amp;gt; Threshold ){
                return 0;
        }

        count_hanpuku++;
        if(count_hanpuku &amp;gt; max_count){
                return 0;
        }

        px = Matrix.sp_pos % matrix_size_x;
        py = Matrix.sp_pos / matrix_size_x;

        for ( r = 0; r &amp;lt; 4; r++ ){
                cx = px + DirectionX[r];
                cy = py + DirectionY[r];
                if(pre_r &amp;gt; r){
                        diff = pre_r - r;
                } else {
                        diff = r - pre_r;
                }
                if(diff == 2){
                        continue;
                }

                if ( cx &amp;lt; 0 || cy &amp;lt; 0 || cx &amp;gt;= matrix_size_x || cy &amp;gt;= matrix_size_y ){
                        continue;
                }

                if(Matrix.mval[cy*matrix_size_x+cx] == -2){
                        continue;
                }

                tmp = Matrix;
                Matrix.mval[py*matrix_size_x+px] = Matrix.mval[cy*matrix_size_x+cx];
                Matrix.mval[cy*matrix_size_x+cx] = -1;
                Matrix.sp_pos = cy*matrix_size_x+cx;
                ret = stepsaiki( depth+1, r );
                if (ret) {
                        StackPath[depth] = r;
                        return 1;
                }
                Matrix = tmp;
        }
        return 0;
}

int check_pre_result_path(){
        int i,x;
        char *c;
        int done;
        int px,py,cx,cy;


        c = pre_result_string;
        if(c == NULL || strncmp(c,&quot;not&quot;,3)==0){
                printf(&quot;not checked\n&quot;);

                return 0;
        }

        for(x=0;c[x];x++){

                done = 0;
                for(i=0;i&amp;lt;4;i++){
                        if(Direction[i] == c[x]){
                                done = 1;
                                break;
                        }
                }
                if(done == 0){
                        printf(&quot;:ERR0: no direction[%d][%s]\n&quot;,x,c);
                        return 0;
                }

                px = Matrix.sp_pos % matrix_size_x;
                py = Matrix.sp_pos / matrix_size_x;
                cx = px + DirectionX[i];
                cy = py + DirectionY[i];

                if ( cx &amp;lt; 0 || cy &amp;lt; 0 || cx &amp;gt;= matrix_size_x || cy &amp;gt;= matrix_size_y ){
                        printf(&quot;:ERR1: bad direction[%d][%s]\n&quot;,x,c);
                        return 0;
                }

                if(Matrix.mval[cy*matrix_size_x+cx] == -2){
                        printf(&quot;:ERR2: bad direction[%d][%s]\n&quot;,x,c);
                        continue;
                }

                Matrix.mval[py*matrix_size_x+px] = Matrix.mval[cy*matrix_size_x+cx];
                Matrix.mval[cy*matrix_size_x+cx] = -1;
                Matrix.sp_pos = cy*matrix_size_x+cx;
        }
        if ( m_distance() ){
                printf(&quot;:ERR3: bad path[%s]\n&quot;,c);
                return 0;
        } else {
                printf(&quot;%s ok\n&quot;,mondai);
                return 1;
        }
}

int check_id(int inv1, int inv2, struct MATRIX *m){

        if( inv1 != inv_distance1()){
                return 0;
        }
        if( inv2 != inv_distance2()){
                return 0;
        }

        return 1;
}

void make_new_pos(struct MATRIX *mtr){
        int px, py, cx, cy,i,r;
        int npos;

        for(i=0;i&amp;lt;matrix_size;i++){
                for(r=0;r&amp;lt;4;r++){
                        px = i % matrix_size_x;
                        py = i / matrix_size_x;

                        cx = px + DirectionX[r];
                        cy = py + DirectionY[r];

                        npos = cy*matrix_size_x+cx;

                        if ( cx &amp;lt; 0 || cy &amp;lt; 0 || cx &amp;gt;= matrix_size_x || cy &amp;gt;= matrix_size_y ){
                                New_Pos[i][r] = -1;
                                continue;
                        }

                        if(Matrix.mval[npos] == -2){
                                New_Pos[i][r] = -1;
                                continue;
                        }

                        New_Pos[i][r] = npos;
                }

        }
}

void fix_new_pos(struct MATRIX *mtr){
        int px, py, cx, cy,i,r;
        int npos;

        for(i=0;i&amp;lt;matrix_size;i++){
                for(r=0;r&amp;lt;4;r++){
                        px = i % matrix_size_x;
                        py = i / matrix_size_x;

                        cx = px + DirectionX[r];
                        cy = py + DirectionY[r];

                        npos = cy*matrix_size_x+cx;

                        if ( cx &amp;lt; 0 || cy &amp;lt; 0 || cx &amp;gt;= matrix_size_x || cy &amp;gt;= matrix_size_y ){
                                New_Pos[i][r] = -1;
                                continue;
                        }

                        if(Matrix.mval[npos] == -2){
                                New_Pos[i][r] = -1;
                                continue;
                        }

                        New_Pos[i][r] = npos;
                }

        }
}

int hash_func(struct MATRIX *matrix){
        int hash,i;

        hash = 1;
        for(i=0;i&amp;lt;matrix_size;i++){
                hash += 137 + (matrix-&amp;gt;mval[i]+13)*i;
        }
        return hash % max_haba_stack;

}

void dump_hash(){
        int i;
        struct HASH_LIST *hlp;

        for(i=0;i&amp;lt;max_haba_stack;i++){
                for (hlp = hash_table[i]; hlp != NULL; hlp = hlp-&amp;gt;next){
                        printf(&quot;key:%d\n&quot;,i);
                        dump_matrix(hlp-&amp;gt;matrix);
                }

        }
}

struct MATRIX *get_hash(struct MATRIX *this_matrix, int hash_val){
        int found,i;
        struct HASH_LIST *hlp;
        char *mval;

        if(hash_val &amp;lt; 0){
                hash_val = hash_func(this_matrix);
        }

        for (hlp = hash_table[hash_val]; hlp != NULL; hlp = hlp-&amp;gt;next){
                found = 1;
                mval = hlp-&amp;gt;matrix-&amp;gt;mval;

                /**/
                for(i=0;i&amp;lt;matrix_size;i++){
                        if(mval[i] != this_matrix-&amp;gt;mval[i]){
                                found = 0;
                                break;
                        }
                }
                if(found == 1){

                        return hlp-&amp;gt;matrix;
                }
        }

        return NULL;
}

int set_hash(struct MATRIX *this_matrix, int this_r){
        int sp_pos,new_sp_pos;
        int tgt;
        struct HASH_LIST *hash_list, *hlp;
        struct MATRIX *m;
        int hash_val;

        hash_list = &amp;amp;Hash_List[hash_cnt];
        memcpy(&amp;amp;haba_stack[stack_tail],this_matrix,sizeof(struct MATRIX));
        this_matrix = &amp;amp;haba_stack[stack_tail];

        sp_pos = this_matrix-&amp;gt;sp_pos;
        new_sp_pos = New_Pos[sp_pos][this_r];
        tgt = this_matrix-&amp;gt;mval[new_sp_pos];
        this_matrix-&amp;gt;mval[sp_pos] = tgt;
        this_matrix-&amp;gt;mval[new_sp_pos] = -1;
        this_matrix-&amp;gt;sp_pos = new_sp_pos;

        hash_val = hash_func(this_matrix);
        m = get_hash(this_matrix,hash_val);
        if(m != NULL){
                return 1;
        }

        hash_list-&amp;gt;matrix = &amp;amp;haba_stack[stack_tail];
        hash_list-&amp;gt;next = NULL;
        hash_cnt++;
        stack_tail++;

        if (hash_table[hash_val] == NULL) {
                hash_table[hash_val] = hash_list;
        } else {
                hlp = hash_table[hash_val];
                while (hlp-&amp;gt;next != NULL)
                        hlp = hlp-&amp;gt;next;
                hlp-&amp;gt;next = hash_list;
        }
        return 0;
}

int haba_tansaku(){
        int i;
        struct MATRIX *this_matrix;
        char *npp;

        stack_cnt=0;
        stack_tail=0;

        haba_stack = malloc(sizeof(struct MATRIX)*max_haba_stack);
        if(haba_stack == NULL){
                fprintf(stderr,&quot;ERR: cant allocate memmory\n&quot;);
                exit(0);
        }

        hash_table = malloc(sizeof(struct HASH_LIST **)*max_haba_stack);
        if(hash_table == NULL){
                fprintf(stderr,&quot;ERR: cant allocate memmory\n&quot;);
                exit(0);
        }
        bzero(hash_table,sizeof(struct HASH_LIST **)*max_haba_stack);

        Hash_List = malloc(sizeof(struct HASH_LIST)*max_haba_stack);
        if (Hash_List == NULL) {
                fprintf(stderr, &quot;ERR: cant alloc memmory\n&quot;);
                exit(1);
        }

        this_matrix = &amp;amp;haba_stack[stack_tail];
        memcpy(this_matrix,&amp;amp;Matrix,sizeof(struct MATRIX));
        stack_tail++;

        while(stack_cnt &amp;lt; stack_tail){

                this_matrix = &amp;amp;haba_stack[stack_cnt];
                npp = New_Pos[this_matrix-&amp;gt;sp_pos];

                for(i=0;i&amp;lt;4;i++){
                        if(npp[i] &amp;gt;= 0){

                                count_hanpuku++;
                                if(count_hanpuku &amp;gt;= max_count){
                                        return 1;
                                }

                                stack_cnt++;
                                if(stack_tail &amp;gt;= max_haba_stack){
                                        return 1;
                                }

                                set_hash(this_matrix,i);
                        }
                }

        }

        return 0;

}
void free_hash(){

        free(hash_table);
        free(haba_stack);
        free(Hash_List);

        hash_table=NULL;
        haba_stack=NULL;
        Hash_List=NULL;

}

int loop(int depth, int pre_r){
        int i;
        int wd;
        int id;
        int md;
        int this_r;
        int sp_pos,sp_pos_p,new_sp_pos;
        int stack_dir;
        int crr_depth;
        char *npp;
        int found;
        int tgt;
#ifdef INVD
        int new_sp_pos_p;
        int val;
        int tgt_p;
#endif
        int inv1,inv2;
        int id1,id2;

        struct MATRIX tmp;
        struct MATRIX tmp_p;
        struct MATRIX *hash_ret;

        tmp = Matrix;
        tmp_p = Matrix_Parity;

        found = 0;
        crr_depth = 0;

        stack_dir = DOWN;
        sp_pos = Matrix.sp_pos;
        stock_arr[crr_depth].sp_pos = sp_pos;
        sp_pos_p = Parity_omote2ura[sp_pos];


        md = m_distance();
        inv1 = inv_distance1();
        inv2 = inv_distance2();
        id1 = IDTBL1[inv1];
        id2 = IDTBL2[inv2];
        id = id1+id2;
        wd = MAX(md,id);
        if(wd == 0){
                found = 1;
                return 1;
        }

        if(haba == 1){
                hash_ret = get_hash(&amp;amp;Matrix, -1);
                if(hash_ret != NULL){
                        return 0;
                }
        }
#ifdef DEBUG
        level_max_md_counter[crr_depth] = md;
        level_min_md_counter[crr_depth] = md;
#endif

        stock_arr[crr_depth].md = md;
        stock_arr[crr_depth].id = id;
        stock_arr[crr_depth].inv1 = inv1;
        stock_arr[crr_depth].inv2 = inv2;
        stock_arr[crr_depth].wd = wd;

        if ( wd &amp;gt; Threshold - crr_depth ){
                return -1;
        }

        memcpy(stock_arr[crr_depth].new_pos,New_Pos[Matrix.sp_pos],sizeof(char)*4);
        npp = stock_arr[crr_depth].new_pos;

        for(this_r=-1,i=0;i&amp;lt;4;i++){
                if(npp[i] &amp;gt;= 0){
                        this_r = i;
                        break;
                }
        }

        if(this_r &amp;gt;= 0){
                npp[this_r] = -1;
                stack_dir = DOWN;
        } else {
                fprintf(stderr,&quot;ERR11\n&quot;);
                return -1;
        }

        while(1){


                if(stack_dir == DOWN){
                        /* use stack_dir, this_r, sp_pos */

                        if(crr_depth &amp;gt;= MAX_STACK_LEVEL){
                                return -1;
                        }

                        crr_depth++;
                        count_hanpuku++;
                        level_counter[crr_depth]++;
                        if(count_hanpuku &amp;gt; max_count){
                                hanpuku_done = 1;
                                if(shurink &amp;gt; 0){
                                        return -1;
                                }
                        }
                        stock_arr[crr_depth].r = this_r;
                        new_sp_pos = New_Pos[sp_pos][this_r];
                        stock_arr[crr_depth].sp_pos = new_sp_pos;
                        tgt = Matrix.mval[new_sp_pos];
                        Matrix.mval[sp_pos] = tgt;
                        Matrix.mval[new_sp_pos] = -1;
                        Matrix.sp_pos = new_sp_pos;
                        md = stock_arr[crr_depth-1].md - R_Distance[new_sp_pos][tgt] +  R_Distance[sp_pos][tgt];
                        if(md &amp;gt; level_max_md_counter[crr_depth]) level_max_md_counter[crr_depth] = md;
                        if(md &amp;lt; level_min_md_counter[crr_depth]){
                                level_min_md_counter[crr_depth] = md;
                                Matrix_Min = Matrix;
                                min_depth = crr_depth;
                                for(i=0;i&amp;lt;crr_depth;i++) StackPath_Min[i] = stock_arr[i+1].r;
                        }

#ifdef INVD
                        sp_pos_p = Parity_omote2ura[sp_pos];
                        new_sp_pos_p = Parity_omote2ura[new_sp_pos];
                        tgt_p = Matrix_Parity.mval[new_sp_pos_p];
                        Matrix_Parity.mval[sp_pos_p] = tgt_p;
                        Matrix_Parity.mval[new_sp_pos_p] = -1;
                        inv1 = stock_arr[crr_depth-1].inv1;
                        inv2 = stock_arr[crr_depth-1].inv2;

                        if(this_r == U){
                                for(i=new_sp_pos+1;i&amp;lt;sp_pos;i++){
                                        if(Matrix.mval[i] &amp;lt; 0){
                                                val = i;
                                        } else {
                                                val = Matrix.mval[i];
                                        }
                                        if (val &amp;gt; tgt){
                                                inv1++;
                                        } else {
                                                inv1--;
                                        }
                                }
                        } else if(this_r == D){
                                for(i=sp_pos+1;i&amp;lt;new_sp_pos;i++){
                                        if(Matrix.mval[i] &amp;lt; 0){
                                                val = i;
                                        } else {
                                                val = Matrix.mval[i];
                                        }
                                        if (val &amp;gt; tgt){
                                                inv1--;
                                        } else {
                                                inv1++;
                                        }
                                }
                        } else if(this_r == L){
                                for(i=new_sp_pos_p+1;i&amp;lt;sp_pos_p;i++){
                                        if(Matrix_Parity.mval[i] &amp;lt; 0){
                                                val = i;
                                        } else {
                                                val = Matrix_Parity.mval[i];
                                        }
                                        if (val &amp;gt; tgt_p){
                                                inv2++;
                                        } else {
                                                inv2--;
                                        }
                                }
                        } else /* R */{
                                for(i=sp_pos_p+1;i&amp;lt;new_sp_pos_p;i++){
                                        if(Matrix_Parity.mval[i] &amp;lt; 0){
                                                val = i;
                                        } else {
                                                val = Matrix_Parity.mval[i];
                                        }
                                        if (val &amp;gt; tgt_p){
                                                inv2--;
                                        } else {
                                                inv2++;
                                        }
                                }
                        }

                        id1 = IDTBL1[inv1];
                        id2 = IDTBL2[inv2];
                        id = id1+id2;

                        stock_arr[crr_depth].id1 = id1;
                        stock_arr[crr_depth].id2 = id2;
                        stock_arr[crr_depth].inv1 = inv1;
                        stock_arr[crr_depth].inv2 = inv2;
                        wd = MAX(id,md);
                        stock_arr[crr_depth].wd = wd;

                        /**/    md = wd;
#endif

                        if(md == 0){
                                found = 1;
                                break;
                        }
                        stock_arr[crr_depth].md = md;

                        if(haba == 1){
                                hash_ret = get_hash(&amp;amp;Matrix, -1);
                                if(hash_ret != NULL){
                                        found = crr_depth;
                                        break;
                                }
                        }

                        if ( md &amp;gt; Threshold - crr_depth ){
                                sp_pos = new_sp_pos;
                                stack_dir = UP;
                                continue;
                        }

                        memcpy(stock_arr[crr_depth].new_pos,New_Pos[new_sp_pos],sizeof(char)*4);
                        npp = stock_arr[crr_depth].new_pos;

                        for(i=0;i&amp;lt;4;i++){
                                if(this_r - i == 2 || i - this_r == 2){
                                        npp[i] = -1;
                                        continue;
                                }
                        }

# ifdef YOKO_YUSEN
                        if(npp[1] &amp;gt;= 0) this_r = 1;
                        else if(npp[0] &amp;gt;= 0) this_r = 0;
                        else if(npp[3] &amp;gt;= 0) this_r = 3;
                        else if(npp[2] &amp;gt;= 0) this_r = 2;
                        else this_r = -1;
# else
                        if(npp[0] &amp;gt;= 0) this_r = 0;
                        else if(npp[1] &amp;gt;= 0) this_r = 1;
                        else if(npp[2] &amp;gt;= 0) this_r = 2;
                        else if(npp[3] &amp;gt;= 0) this_r = 3;
                        else this_r = -1;
# endif

                        sp_pos = new_sp_pos;
                        if(this_r &amp;gt;= 0){
                                npp[this_r] = -1;
                                stack_dir = DOWN;
                        } else {
                                stack_dir = UP;
                        }


                } else {
                        if(crr_depth == 0){
                                return -1;
                        }
                        crr_depth--;

                        new_sp_pos = stock_arr[crr_depth].sp_pos;
                        Matrix.mval[sp_pos] = Matrix.mval[new_sp_pos];
                        Matrix.mval[new_sp_pos] = -1;
                        Matrix.sp_pos = new_sp_pos;

#ifdef INVD
                        sp_pos_p = Parity_omote2ura[sp_pos];
                        new_sp_pos_p = Parity_omote2ura[new_sp_pos];
                        Matrix_Parity.mval[sp_pos_p] = Matrix_Parity.mval[new_sp_pos_p];
                        Matrix_Parity.mval[new_sp_pos_p] = -1;
#endif

                        npp =  stock_arr[crr_depth].new_pos;
                        for(this_r = -1,i=0;i&amp;lt;4;i++){
                                if(npp[i] &amp;gt;= 0){
                                        this_r = i;
                                        break;
                                }
                        }

                        sp_pos = new_sp_pos;
                        if(this_r &amp;gt;= 0){
                                npp[this_r] = -1;
                                stack_dir = DOWN;
                        } else {
                                stack_dir = UP;
                        }

                }
        }

        if(found){
                for(i=0;i&amp;lt;crr_depth;i++){
                        StackPath[i] = stock_arr[i+1].r;
                }
                StackPath[i] = 0;
        }

        Matrix = tmp;
        return found;
}

int saiki(int depth, int pre_r){
        int ret;
        int px, py, cx, cy;
        int r;
        int diff;
        int wd;
        struct MATRIX tmp;

        if ( check_goal() ){
                return 1;
        }

        wd = m_distance();
        if ( depth + wd &amp;gt; Threshold ){
                return 0;
        }

        count_hanpuku++;
        if(count_hanpuku &amp;gt; max_count){
                return 0;
        }

        px = Matrix.sp_pos % matrix_size_x;
        py = Matrix.sp_pos / matrix_size_x;

        for ( r = 0; r &amp;lt; 4; r++ ){
                cx = px + DirectionX[r];
                cy = py + DirectionY[r];
                if(pre_r &amp;gt; r){
                        diff = pre_r - r;
                } else {
                        diff = r - pre_r;
                }
                if(diff == 2){
                        continue;
                }

                if ( cx &amp;lt; 0 || cy &amp;lt; 0 || cx &amp;gt;= matrix_size_x || cy &amp;gt;= matrix_size_y ){
                        continue;
                }

                if(Matrix.mval[cy*matrix_size_x+cx] == -2){
                        continue;
                }

                tmp = Matrix;
                Matrix.mval[py*matrix_size_x+px] = Matrix.mval[cy*matrix_size_x+cx];
                Matrix.mval[cy*matrix_size_x+cx] = -1;
                Matrix.sp_pos = cy*matrix_size_x+cx;
                ret = saiki( depth+1, r );
                if (ret) {
                        StackPath[depth] = r;

                        Matrix = tmp;
                        return 1;
                }
                Matrix = tmp;
        }
        return 0;
}



int HanpukuShinka(){
        int i;
        int sdcnt[3],sdsum[3],max=0,maxi=0;
        count_hanpuku = 0;
        hanpuku_done = 0;
        struct MATRIX matrix_backup, matrix_goal;
        int ret;

        matrix_backup = Matrix;
        if(pre_result_threshold &amp;gt; 0){
                Threshold = pre_result_threshold;
        } else {
                Threshold = m_distance();
        }
        for (ret = 0 ; Threshold &amp;lt;= MAX_STACK_LEVEL; Threshold += 2 ){
                if(haba == 1){
                        make_goal(&amp;amp;matrix_goal,&amp;amp;Matrix);
                        Matrix = matrix_goal;
                        haba_tansaku();
                        Matrix = matrix_backup;

                }
#ifdef DEBUG
                for(i=0;i&amp;lt;MAX_STACK_LEVEL;i++) level_counter[i] = 0;
                for(i=0;i&amp;lt;MAX_STACK_LEVEL;i++) level_max_md_counter[i] = 0;
                for(i=0;i&amp;lt;MAX_STACK_LEVEL;i++) level_min_md_counter[i] = 100000;
#endif
                ret = loop(0, -4);
                if(haba == 1){
                        free_hash();

                        if(ret &amp;gt;= 0){
                                for ( i = 0; i &amp;lt; ret; i++ ) printf(&quot;%c&quot;,Direction[StackPath[i]]);
                                fflush(stdout);
                                break;
                        }
                }

                if (ret &amp;gt;= 0){
                        for ( i = 0; i &amp;lt; Threshold; i++ ) printf(&quot;%c&quot;,Direction[StackPath[i]]);
                        printf(&quot;\n&quot;);
                        fflush(stdout);
                        return 1;
                } else {
                        if(hanpuku_done &amp;gt; 0) {
                                if(shurink &amp;gt; 0){
                                        hanpuku_done=0;
                                        count_hanpuku = 0;
                                        Matrix=Matrix_Min;
                                        if(shurink_mask &amp;gt; 0){
                                                for(i=0;i&amp;lt;3;i++){
                                                        max=0;
                                                        maxi=0;
                                                        step_dist = i;
                                                        make_harr(&amp;amp;Matrix);
                                                        sdsum[i] = 0;
                                                        for(CrrHarrIdx=0;CrrHarrIdx&amp;lt;HArr.arr_num;CrrHarrIdx++){
                                                                if(step_distance() == 0){
                                                                        sdsum[i] += HArr.arr_len[i];
                                                                } else {
                                                                        break;
                                                                }
                                                        }
                                                        sdcnt[i] = CrrHarrIdx;

                                                        if(sdsum[i] &amp;gt; max){
                                                                max = sdsum[i];
                                                                maxi = i;
                                                        }
                                                }
                                                step_dist = maxi;
                                                make_harr(&amp;amp;Matrix);

                                                if(shurink_mask &amp;gt; 1 &amp;amp;&amp;amp; sdsum[maxi] &amp;gt; 0){
                                                        for(CrrHarrIdx=0;CrrHarrIdx&amp;lt;sdcnt[maxi];CrrHarrIdx++){
                                                                for(i=0;i&amp;lt;HArr.arr_len[CrrHarrIdx];i++){
                                                                        Matrix.mval[HArr.arr[CrrHarrIdx][i]] = -2;
                                                                }
                                                        }
                                                }
                                        }
                                        Threshold = m_distance();
                                        for ( i = 0; i &amp;lt; min_depth; i++ ) printf(&quot;%c&quot;,Direction[StackPath_Min[i]]);
                                        shurink--;
                                        continue;
                                }
                                break;
                        }
                }

        }

        if(ret &amp;lt; 2){
                printf(&quot; not found in HanpukuShinka(start distance(%d),count_hanpuku(%lld)) for Threshold:%d\n&quot;,m_distance(),count_hanpuku,Threshold+2);
                fflush(stdout);
                return 0;
        }

        Threshold = m_distance();
        for ( ; Threshold &amp;lt;= MAX_STACK_LEVEL; Threshold += 2 ){
                haba = 0;
                ret = loop(0, -4);
                haba = 1;

                if (ret != 0){
                        for ( i = 0; i &amp;lt; Threshold; i++ ) printf(&quot;%c&quot;,Direction[StackPath[i]]);
                        printf(&quot;\n&quot;);
                        fflush(stdout);
                        return 1;
                } else {
                        if(hanpuku_done &amp;gt; 0) {
                                break;
                        }
                }
        }

        printf(&quot; not found in HabaYusen &amp;amp; HanpukuShinka(start distance(%d),count_hanpuku(%lld)) for Threshold:%d\n&quot;,m_distance(),count_hanpuku,Threshold+2);
        fflush(stdout);
        return 0;
}

int StepShinka(){
        int i;
        int ret;
        int this_r;
        int pre_depth;

        count_hanpuku = 0;
        this_r = -4;
        pre_depth = 0;
        for(CrrHarrIdx=0;CrrHarrIdx&amp;lt;HArr.arr_num;CrrHarrIdx++){
                ret = 0;
                for ( Threshold = step_distance(); Threshold &amp;lt;= MAX_STACK_LEVEL; Threshold++ ){
                        Matrix_backup = Matrix;
                        ret = steploop(pre_depth, 0, this_r);
                        if ( ret &amp;gt; 0 ){
                                break;
                        }

                        if(count_hanpuku &amp;gt; max_count){
                                break;
                        }
                        Matrix = Matrix_backup;
                }


                if(ret == 0){
                        printf(&quot; not found in StepShinka(count_hanpuku(%lld)) for Threshold(%d),CrrHarrIdx(%d)\n&quot;,count_hanpuku,Threshold+1,CrrHarrIdx);
                        fflush(stdout);
                        return 0;
                }



                for ( i = 0; i &amp;lt; Threshold; i++ ) printf(&quot;%c&quot;,Direction[StackPath[pre_depth+i]]);
                if(simflg) for ( i = 0; i &amp;lt; Threshold; i++ ) moving_history[mh_cnt++] = StackPath[pre_depth+i];
                pre_depth += Threshold;
                this_r = StackPath[Threshold-1];
                for(i=0;i&amp;lt;HArr.arr_len[CrrHarrIdx];i++){
                        Matrix.mval[HArr.arr[CrrHarrIdx][i]] = -2;
                }
                fix_new_pos(&amp;amp;Matrix);
        }
        printf(&quot;\n&quot;);
        fflush(stdout);

        return 1;
}

int get_tgt(char c){

        if(c == &#39;=&#39;){
                c = -2;
        } else if(&#39;Z&#39; &amp;gt;= c &amp;amp;&amp;amp; c &amp;gt;= &#39;A&#39;){
                c = c - &#39;A&#39; + 9;
        } else if(&#39;z&#39; &amp;gt;= c &amp;amp;&amp;amp; c &amp;gt;= &#39;a&#39;){
                c = c - &#39;a&#39; + 9;
        } else if(&#39;9&#39; &amp;gt;= c &amp;amp;&amp;amp; c &amp;gt;= &#39;1&#39;){
                c = c - &#39;1&#39;;
        } else if(c == &#39;.&#39; || c == &#39;0&#39;){
                c = -1;
        } else {
                c = -3;
        }
        return c;
}

void sim(){
        int md,i,j;
        char buff[MAXIDTBL];
        int mode2=-1;
        int this_r;
        char *c;
        int tgt;
        struct MATRIX Matrix_org,Matrix_tmp,Matrix_stp;
        int ret;
        char New_Pos_org[36][4];

        Matrix_tmp = Matrix;
        Matrix_org = Matrix;
        memcpy(New_Pos_org,New_Pos,sizeof(New_Pos));
        mh_cnt = 0;
        if(kaitou){
                printf(&quot;%s %s\n&quot;,mondai,kaitou);
        } else {
                printf(&quot;%s\n&quot;,mondai);
        }
        printf(&quot;\n&quot;);
        dump_matrix2(&amp;amp;Matrix);

        if(kaitou){


                c = kaitou;
                while(*c){
                        this_r = get_r(c);
                        if(this_r &amp;lt; 0) continue;

                        if(New_Pos[Matrix.sp_pos][this_r]&amp;gt;=0){
                                mv_koma(this_r);
                                moving_history[mh_cnt++] = this_r;
                        }
                        c++;
                }

                printf(&quot;\n&quot;);
                dump_matrix2(&amp;amp;Matrix);
        }

        if(mode == 0) printf(&quot;moving mode input:\n&quot;); else printf(&quot;command mode input:\n&quot;);
        for ( j = 0; j &amp;lt; mh_cnt; j++ ) printf(&quot;%c&quot;,Direction[moving_history[j]]); printf(&quot;\n&quot;);

        while(fgets(buff,MAXIDTBL-1,stdin) != NULL){
                for(i=0;buff[i];i++){
                        if(mode == 0){
                                if(i==0){
                                        if(buff[0] == &#39;c&#39;){
                                                mode = 1;
                                                dump_matrix2(&amp;amp;Matrix);
                                                if(mode == 0) printf(&quot;moving mode input:\n&quot;); else printf(&quot;command mode input:\n&quot;);
                                                for ( j = 0; j &amp;lt; mh_cnt; j++ ) printf(&quot;%c&quot;,Direction[moving_history[j]]); printf(&quot;\n&quot;);
                                                break;
                                        }
                                }
                                if(buff[i] == &#39;\n&#39;){
                                        dump_matrix2(&amp;amp;Matrix);
                                        if(mode == 0) printf(&quot;moving mode input:\n&quot;); else printf(&quot;command mode input:\n&quot;);
                                        for ( j = 0; j &amp;lt; mh_cnt; j++ ) printf(&quot;%c&quot;,Direction[moving_history[j]]); printf(&quot;\n&quot;);
                                        break;
                                }
                                this_r = -1;
                                if(buff[i]==&#39;U&#39; || buff[i]==&#39;u&#39;) this_r = 0;
                                if(buff[i]==&#39;L&#39; || buff[i]==&#39;l&#39;) this_r = 1;
                                if(buff[i]==&#39;D&#39; || buff[i]==&#39;d&#39;) this_r = 2;
                                if(buff[i]==&#39;R&#39; || buff[i]==&#39;r&#39;) this_r = 3;

                                if(buff[i] == 0x1b &amp;amp;&amp;amp; buff[i+1] == &#39;[&#39;){
                                        if(buff[i+2] == &#39;A&#39;){this_r = 0; i+=2;}
                                        if(buff[i+2] == &#39;B&#39;){this_r = 2; i+=2;}
                                        if(buff[i+2] == &#39;C&#39;){this_r = 3; i+=2;}
                                        if(buff[i+2] == &#39;D&#39;){this_r = 1; i+=2;}
                                }

                                if(this_r &amp;lt; 0) continue;



                                if(this_r &amp;lt; 0) continue;
                                if(New_Pos[Matrix.sp_pos][this_r]&amp;gt;=0){
                                        mv_koma(this_r);
                                        moving_history[mh_cnt++] = this_r;
                                }

                                md = m_distance();
                                if(md == 0){
                                        dump_matrix2(&amp;amp;Matrix);
                                        for ( j = 0; j &amp;lt; mh_cnt; j++ ) printf(&quot;%c&quot;,Direction[moving_history[j]]);
                                        printf(&quot;\n&quot;);
                                        printf(&quot;done\n&quot;);
                                        return;
                                }

                        } else { //command mode
                                if(buff[i] == &#39;\n&#39;){
                                        if(mode2 == STEP){
                                                Matrix_stp = Matrix;
                                                ret = StepShinka();
                                                if(ret &amp;lt;=0){
                                                        Matrix = Matrix_stp;
                                                }
                                                md = m_distance();
                                                if(md == 0){
                                                        dump_matrix2(&amp;amp;Matrix);
                                                        for ( j = 0; j &amp;lt; mh_cnt; j++ ) printf(&quot;%c&quot;,Direction[moving_history[j]]);
                                                        printf(&quot;\n&quot;);
                                                        printf(&quot;done\n&quot;);
                                                        return;
                                                }
                                        }

                                        dump_matrix2(&amp;amp;Matrix);
                                        if(mode == 0) printf(&quot;moving mode input:\n&quot;); else printf(&quot;command mode input:\n&quot;);
                                        for ( j = 0; j &amp;lt; mh_cnt; j++ ) printf(&quot;%c&quot;,Direction[moving_history[j]]); printf(&quot;\n&quot;);
                                        mode2 = -1;
                                        break;
                                }
                                if(i==0){
                                        if(buff[0] == &#39;m&#39;) {
                                                if(buff[1] == &#39;\n&#39;){
                                                        mode = 0;
                                                        if(mode == 0) printf(&quot;moving mode input:\n&quot;); else printf(&quot;command mode input:\n&quot;);
                                                        for ( j = 0; j &amp;lt; mh_cnt; j++ ) printf(&quot;%c&quot;,Direction[moving_history[j]]); printf(&quot;\n&quot;);
                                                        break;
                                                } else {
                                                        mode2 = MOVE;
                                                }
                                        }else if(buff[0] == &#39;h&#39;) mode2 = HANPUKU;
                                        else if(buff[0] == &#39;s&#39;){
                                                mode2 = STEP;
                                                HArr.arr_num = 1;
                                                HArr.arr_len[0] = 0;
                                        }else if(buff[0] == &#39;S&#39;) mode2 = STEP_TARGET;
                                        else if(buff[0] == &#39;i&#39;){
                                                printf(&quot;mh_cnt:[%d]\n&quot;,mh_cnt);
                                                for ( j = 0; j &amp;lt; mh_cnt; j++ ) printf(&quot;%c&quot;,Direction[moving_history[j]]);
                                                printf(&quot;\n&quot;);

                                        }else if(buff[0] == &#39;f&#39;) mode2 = FIX;
                                        else if(buff[0] == &#39;F&#39;) mode2 = UNFIX;
                                        else if(buff[0] == &#39;U&#39;){
                                                for ( j = 0; j &amp;lt; mh_cnt; j++ ) printf(&quot;%c&quot;,Direction[moving_history[j]]);
                                                printf(&quot;\n&quot;);
                                                Matrix = Matrix_org;
                                                Matrix_tmp = Matrix;
                                                memcpy(New_Pos,New_Pos_org,sizeof(New_Pos));
                                                mh_cnt = 0;
                                                if(mode == 0) printf(&quot;moving mode input:\n&quot;); else printf(&quot;command mode input:\n&quot;);
                                                break;
                                        }else if(buff[0] == &#39;m&#39;){
                                                mode2 = MOVE;
                                        }else if(buff[0] == &#39;N&#39;){
                                                for ( j = 0; j &amp;lt; mh_cnt; j++ ) printf(&quot;%c&quot;,Direction[moving_history[j]]);
                                                printf(&quot;\n&quot;);
                                                return;
                                        }else if(buff[0] == &#39;b&#39;) {

                                        }else {
                                                dump_matrix(&amp;amp;Matrix);
                                                printf(&quot;bad command...ignored.\n&quot;);
                                                if(mode == 0) printf(&quot;moving mode input:\n&quot;); else printf(&quot;command mode input:\n&quot;);
                                                break;
                                        }
                                        continue;
                                }
                                if(mode2 == MOVE){
                                        this_r = -1;
                                        if(buff[i]==&#39;U&#39; || buff[i]==&#39;u&#39;) this_r = 0;
                                        if(buff[i]==&#39;L&#39; || buff[i]==&#39;l&#39;) this_r = 1;
                                        if(buff[i]==&#39;D&#39; || buff[i]==&#39;d&#39;) this_r = 2;
                                        if(buff[i]==&#39;R&#39; || buff[i]==&#39;r&#39;) this_r = 3;

                                        if(buff[i] == 0x1b &amp;amp;&amp;amp; buff[i+1] == &#39;[&#39;){
                                                if(buff[i+2] == &#39;A&#39;){this_r = 0; i+=2;}
                                                if(buff[i+2] == &#39;B&#39;){this_r = 2; i+=2;}
                                                if(buff[i+2] == &#39;C&#39;){this_r = 3; i+=2;}
                                                if(buff[i+2] == &#39;D&#39;){this_r = 1; i+=2;}
                                        }
                                        if(this_r &amp;lt; 0) continue;
                                        if(New_Pos[Matrix.sp_pos][this_r]&amp;gt;=0){
                                                mv_koma(this_r);
                                                moving_history[mh_cnt++] = this_r;
                                        }
                                        md = m_distance();
                                        if(md == 0){
                                                dump_matrix2(&amp;amp;Matrix);
                                                for ( j = 0; j &amp;lt; mh_cnt; j++ ) printf(&quot;%c&quot;,Direction[moving_history[j]]); printf(&quot;\n&quot;);
                                                printf(&quot;done\n&quot;);
                                                return;
                                        }

                                }
                                if(mode2 == STEP){
                                        tgt = get_tgt(buff[i]);
                                        if(tgt &amp;gt;= 0){
                                                HArr.arr[0][HArr.arr_len[0]] = tgt;
                                                HArr.arr_len[0]++;
                                        }
                                }
                                if(mode2 == FIX){
                                        tgt = get_tgt(buff[i]);

                                        if(tgt &amp;gt;=0){
                                                if(Matrix.mval[tgt] &amp;gt;= 0){
                                                        Matrix_tmp.mval[tgt] = Matrix.mval[tgt];
                                                        Matrix.mval[tgt] = -2;
                                                }
                                        }
                                }
                                if(mode2 == UNFIX){
                                        tgt = get_tgt(buff[i]);

                                        if(tgt &amp;gt;=0){
                                                if(Matrix_tmp.mval[tgt] &amp;gt;= 0){
                                                        Matrix.mval[tgt] = Matrix_tmp.mval[tgt];
                                                        Matrix_tmp.mval[tgt] = -3;
                                                }
                                        }
                                }


                                //}//for

                }//command mode

        }
}

}
int set_data(char *in_file){
        int i,j;
        char *c,*p,*t;
        static char buf[1024];
        static char str[1024];
        int len;
        static FILE  *fp=NULL;
        int x,y;
        char *ret;

        if(fp == NULL){
                fp = fopen(in_file, &quot;r&quot;);

#ifdef INVD
                for(i=0; i&amp;lt;MAXIDTBL; i++){
                        IDTBL3[i] = (i/2);
                        IDTBL4[i] = (i/3) + (i%3);
                        IDTBL5[i] = (i/4) + (i%4)/2;
                        IDTBL6[i] = (i/5) + (i%5)/3 + ((i%5)%3);
                }
#endif

        }
        if(fp == NULL){
                printf(&quot;ERR: cant open [%s]\n&quot;,in_file);
                exit(0);
        }

        while(1){
                ret = fgets( buf, 1023, fp );
                if(ret == NULL){
                        return 0;
                }

                if(strchr(buf,&#39;,&#39;)){
                        break;
                }
        }


        len = strlen(buf);
        buf[len-1] = 0;

        if(strstr(buf,&quot;input &quot;)){
                strcpy(str,&amp;amp;buf[6]);
                mondai = &amp;amp;buf[6];
        } else {
                strcpy(str,buf);
                mondai = buf;
        }

        t=strchr(mondai,&#39; &#39;);
        if(t){
                *t++ = 0;
                kaitou = t;
                if((t =strchr(kaitou,&#39; &#39;)) != NULL){
                        *t = 0;
                }
        } else {
                kaitou = NULL;
        }

        // file format
        // [4,5,5G3486F7092C1ADJEHBI:not found in HanpukuShinka for Threshold:201]
        // [6,5,82935=174ABCD=RHTNJKFLI0PQSOGM ULDDRUULLULULLDRURRDDDLURDRDLLUURDRDRULDR]

        str[1] = 0;
        str[3] = 0;
        matrix_size_x = atoi(str);
        matrix_size_y = atoi(&amp;amp;str[2]);
        matrix_size = matrix_size_x * matrix_size_y;

        c = &amp;amp;str[4];

        t = strchr(c,&#39; &#39;);
        if(t){
                *t++ = 0;
                pre_result_string = t;
        } else {
                pre_result_string = NULL;
        }


        if(t){
                p = strchr(t,&#39;:&#39;);
        } else {
                p = NULL;
        }
        if(p){
                *p++ = 0;
                pre_result_threshold = atoi(p);
        } else {
                pre_result_threshold = 0;
        }


        for ( i = 0; i &amp;lt; matrix_size; i++ ){
                if(c[i] == &#39;=&#39;){
                        c[i] = -2;
                } else if(c[i] &amp;gt;= &#39;A&#39;){
                        c[i] = c[i] - &#39;A&#39; + 9;
                } else {
                        c[i] = c[i] - &#39;1&#39;;
                }
                Matrix.mval[i] = c[i];
                if(c[i] == -1){
                        Matrix.sp_pos = i;
                }
        }


        for(i=0;i&amp;lt;matrix_size;i++){
                x = i % matrix_size_x;
                y = i / matrix_size_x;
                Parity_omote2ura[i] = x*matrix_size_y+y;

                x = i % matrix_size_y;
                y = i / matrix_size_y;
                Parity_ura2omote[i] = x*matrix_size_x+y;
        }

        for(i=0;i&amp;lt;matrix_size;i++){
                j = Matrix.mval[Parity_ura2omote[i]];
                if(j == -1){
                        Matrix_Parity.mval[i] = j;
                } else if(j == -2){
                        Matrix_Parity.mval[i] = j;
                } else {
                        Matrix_Parity.mval[i] = Parity_omote2ura[j];
                }
        }



        if(matrix_size_x == 3) IDTBL1 = IDTBL3;
        if(matrix_size_x == 4) IDTBL1 = IDTBL4;
        if(matrix_size_x == 5) IDTBL1 = IDTBL5;
        if(matrix_size_x == 6) IDTBL1 = IDTBL6;

        if(matrix_size_y == 3) IDTBL2 = IDTBL3;
        if(matrix_size_y == 4) IDTBL2 = IDTBL4;
        if(matrix_size_y == 5) IDTBL2 = IDTBL5;
        if(matrix_size_y == 6) IDTBL2 = IDTBL6;

        set_m_distance();
        set_r_distance(&amp;amp;Matrix);

        make_harr(&amp;amp;Matrix);

        make_new_pos(&amp;amp;Matrix);


        return 1;
}

int main(int ac, char **av){
        char *in;
        int ret;
        int i,cnt;;

        if(ac &amp;lt; 3){
                printf(&quot;useage:cmd inputfile how [max_count]\n&quot;);
                exit(0);
        }

        in = av[1];
        if(ac &amp;gt;= 4){
                max_count = (long long)atoi(av[3]) * (long long)10000;
        } else {
                max_count = (long long)MAX_HANPUKU * (long long)10000;
        }



        haba_stack = malloc(sizeof(struct MATRIX)*max_haba_stack);
        if(haba_stack == NULL){
                fprintf(stderr,&quot;ERR: cant allocate memmory\n&quot;);
                exit(0);
        }

        hash_table = malloc(sizeof(struct HASH_LIST **)*max_haba_stack);
        if(hash_table == NULL){
                fprintf(stderr,&quot;ERR: cant allocate memmory\n&quot;);
                exit(0);
        }
        bzero(hash_table,sizeof(struct HASH_LIST **)*max_haba_stack);

        Hash_List = malloc(sizeof(struct HASH_LIST)*max_haba_stack);





        while(1){
                ret = set_data(in);
                if(ret == 0){
                        exit(0);
                }

                if(matrix_size_x &amp;lt; 3 || matrix_size_x &amp;gt; 6 || matrix_size_y &amp;lt; 3 || matrix_size_y &amp;gt; 6){
                        continue;
                }

                if(strcmp(av[2],&quot;check&quot;) == 0){
                        check_pre_result_path();
                        continue;
                }

                if(strcmp(av[2],&quot;sim&quot;) == 0){
                        simflg = 1;
                        sim();
                        continue;
                }

                if(kaitou){
                        for(cnt=0,i=0;kaitou[i];i++){
                                if(kaitou[i] != &#39;U&#39; &amp;amp;&amp;amp; kaitou[i] != &#39;L&#39; &amp;amp;&amp;amp; kaitou[i] != &#39;D&#39; &amp;amp;&amp;amp; kaitou[i] != &#39;R&#39;) cnt++;
                        }
                        if(cnt == 0){

                                printf(&quot;input %s %s\n&quot;, mondai,kaitou);
                                fflush(stdout);
                                continue;
                        }
                }


                if(strcmp(av[2],&quot;md&quot;) == 0){
                        printf(&quot;%d\t%s\n&quot;,m_distance(),mondai);
                        continue;
                }
                printf(&quot;input %s &quot;, mondai);
                fflush(stdout);

                if(strcmp(av[2],&quot;hanpuku&quot;) == 0){
                        HanpukuShinka();
                        continue;
                }

                if(strcmp(av[2],&quot;shurink&quot;) == 0){
                        if(ac &amp;gt;= 5){
                                shurink = atoi(av[4]);
                        } else {
                                shurink = 1;
                        }

                        if(ac &amp;gt;=6){
                                shurink_mask = atoi(av[5]);
                        } else {
                                shurink_mask = 0;
                        }
                        HanpukuShinka();
                        continue;
                }

                if(strcmp(av[2],&quot;haba&quot;) == 0){
                        if(ac &amp;gt;= 5){
                                max_haba_stack = atoi(av[4]) * 1024*1024/(sizeof(struct MATRIX)*sizeof(struct HASH_LIST **)*2);
                        } else {
                                max_haba_stack = 1024*1024/(sizeof(struct MATRIX)*sizeof(struct HASH_LIST **)*2);
                        }

                        haba = 1;
                        HanpukuShinka();
                        continue;
                }

                if(strcmp(av[2],&quot;step&quot;) == 0){
                        if(ac &amp;gt;= 5){
                                step_dist = atoi(av[4]);
                        } else {
                                step_dist = 0;
                        }
                        StepShinka();
                }

                if(strcmp(av[2],&quot;matrix&quot;) == 0){
                        dump_matrix(&amp;amp;Matrix);
                        continue;
                }

        }
        exit(0);
}&lt;/pre&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: arial, sans-serif; font-size: x-small;&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;line-height: 14px;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/6878152425498602339/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2011/09/devquiz.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/6878152425498602339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/6878152425498602339'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2011/09/devquiz.html' title='CでDevquiz２０１１スライドパズル'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY8LxMA5T3zPKxFi-cQBVRJnkg9wG5aoUrYdQHPh7RnfAwKae5nd4g2U8VMpo-KDzdvilJ9HPK3aPFVkBjOEEh_SkfKGf8ICVwKKZMgxQnB3-QkaFZJgCpCWLQcJCTTmHTTrOehX8Biko/s72-c/DevQuiz.gif" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-3792127264932147835</id><published>2011-04-14T15:50:00.015+09:00</published><updated>2011-10-11T13:04:08.419+09:00</updated><title type='text'>PHPでpcntl_forkでふぉーくの薀蓄</title><content type='html'>えー、勢いあまってPHPでマルチプロセスを実装してみました。&lt;br /&gt;
ある意味血迷ってるといまさらながら思いますが、最初は・・・言語かえるのやだし、ちょこっとググッたらできそうな感じだったので。。。&lt;br /&gt;
&lt;br /&gt;
もちろん、やっとちゃんと動きましたよ。&lt;br /&gt;
ええかなりちゃんとしてます。&lt;br /&gt;
でも、、、Cとかお流行のJAVAに書き換える日はもう見えてるんで。ええ。&lt;br /&gt;
&lt;br /&gt;
&lt;h4 id=&quot;aya&quot;&gt;
ググれば出てくるさんぷるクリプト&lt;/h4&gt;
&lt;br /&gt;
大体、「PHP　pcntl_fork」でぐぐればいっぱい使い方が見つかります。みつかるけど・・・これだけではなんだかようわからない。&lt;br /&gt;
&lt;a href=&quot;http://php.net/manual/en/function.pcntl-fork.php&quot;&gt;PHP: pcntl_fork - Manual&lt;/a&gt;&lt;br /&gt;
&lt;pre class=&quot;php&quot; name=&quot;code&quot;&gt;
//子プロセス生成
$pid = pcntl_fork();
if ($pid == -1)
{
  // fork失敗
  echo &#39;Failed forc process.&#39;;
  exit(1);
}
else if ($pid) 
{
  //親プロセス
  $mypid = getmypid();
  printf(&quot;mypid:%d pid:%d\n&quot;, $mypid, $pid);
  pcntl_waitpid($status);
}else{
  // 子プロセス
  $mypid = getmypid();
  printf(&quot;mypid:%d pid:%d\n&quot;, $mypid, $pid);
  exit(0);
}&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
実装したい場合って割と複雑なんですね。で、特にApacheと一緒に使うわけじゃないので、更にいろいろとあるわけです。（Apacheと一緒に使うならこれは使わないほうがいい。）&lt;br /&gt;
&lt;br /&gt;
batch処理をするのにPHPを選んでる時点でちょっと負けた気がする。。。&lt;br /&gt;
ちなみに、batchで使うときのPHPは&lt;span style=&quot;font-weight: bold;&quot;&gt;クライアントモード&lt;/span&gt;とか&lt;span style=&quot;font-weight: bold;&quot;&gt;CGIモード&lt;/span&gt;とか言うみたいなのだけれど、本当かどうかは不明。&lt;br /&gt;
&lt;br /&gt;
で、このクライアントモードでしか使わないので、いろいろな制限を無制限にしちゃったりしている。&lt;br /&gt;
その上でマルチプロセスで一気に平行処理をして歩いいというのが今回の目的。&lt;br /&gt;
&lt;br /&gt;
&lt;h4 id=&quot;aya&quot;&gt;
実装する仕事&lt;/h4&gt;
&lt;br /&gt;
・リモートファイルの取得&lt;br /&gt;
・中身の集計&lt;br /&gt;
・各ジャンルごとにデータベース（MySQL）に集計結果を格納&lt;br /&gt;
&lt;br /&gt;
この流れで平行で10個くらい走って間もらいます。ちなみに、直列でも可。&lt;br /&gt;
ただ1日は24時間しかなくて1個2時間かかってたらずーっと仕事してることになって効率が悪い。&lt;br /&gt;
マルチプロセスでそれぞれ仕事してくれたらまぁ3時間で全部終わるくらいになることを期待しているのん。&lt;br /&gt;
&lt;br /&gt;
さて、さて。。結局はちら様のソースを元に作らせていただいた↓&lt;br /&gt;
&lt;a href=&quot;http://d.hatena.ne.jp/with_no_parachute/20091116/1258392300&quot;&gt;PHPでの並列処理について - With-No-Parachute D-side&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
ただ、すんなりこのとおりでは動かなかった。&lt;br /&gt;
こちら様の前提は、&lt;span style=&quot;font-weight: bold;&quot;&gt;PHP5.3.ｘ&lt;/span&gt;で、うちはなんと、&lt;span style=&quot;font-weight: bold;&quot;&gt;PHP5.2.ｘ&lt;/span&gt;&lt;br /&gt;
そんなに大事ではないのだけれど、ちょっとかっこいいなぁって思っていた「無名関数」っていうのが使えないので&lt;br /&gt;
&lt;pre class=&quot;php&quot; name=&quot;code&quot;&gt;
// 子プロセスで行う仕事
if (!is_array($this-&amp;gt;work)) //外部クロージャが設定されている場合
{
  $function = $this-&amp;gt;work;
  $function($arg);
}&lt;/pre&gt;
&lt;br /&gt;
これが使えない。もう一個の方は問題なく実行できたのでそちらのみ利用。しかし、両方書いておいて下さるなんて素敵だ。&lt;br /&gt;
&lt;br /&gt;
あとは、ファイル分割をしたときのスコープがいろいろと変わってくるので、何度と無くテストをして動いてくれるまで持っていく。&lt;br /&gt;
このときに注意が必要なのは、&lt;span style=&quot;font-weight: bold;&quot;&gt;シグナルハンドラのセット位置&lt;/span&gt;と、&lt;span style=&quot;font-weight: bold;&quot;&gt;declare(ticks=1) {}&lt;/span&gt;の記述場所。&lt;br /&gt;
&lt;br /&gt;
位置を間違えると期待通りの振る舞いにはならない。&lt;br /&gt;
あと忘れてはならないのが、MySQLのこと。こちら様の例にはMySQLの例は記載されていないので、やはりまたぐぐる。&lt;br /&gt;
次に参考にさせていただいたのがこちら様↓&lt;br /&gt;
&lt;a href=&quot;https://www.codeblog.org/blog/moriyoshi/20070208.html&quot;&gt;小泉守義のPHPソースコードウォッチ - pcntl_fork() - fork() で複製される fd に注意セヨ....&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
こちらにも書かれているとおり、接続する場所がとても重要。親と子の間でデータが渡せるとはいえ、コネクションはNGなのだ。&lt;br /&gt;
なぜか共有すると、誰かの処理が終わった時点でみんなのコネクション（オブジェクト？）が破棄されているような振る舞いになる。&lt;br /&gt;
あの大嫌いな。。。。。あれが出る。&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;Lost connection to MySQL server&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;MySQL server has gone away&lt;/span&gt;&lt;br /&gt;
とかとか。毎回同じのが出るわけでもないし、ある種ハマルこと間違いない（－－&lt;br /&gt;
&lt;br /&gt;
ここはひとつ素直におまじないだと思って、子プロセスでコネクションを張ろうと心に誓うのがよい。&lt;br /&gt;
が、しかーし。。更に大きな落とし穴がある。&lt;br /&gt;
こちら様や、ほかの方々の例をみるとみなさま全て&lt;span style=&quot;font-weight: bold;&quot;&gt;mysql_connect()&lt;/span&gt;を使っていらっしゃる。実はこれが大きなヒント！&lt;br /&gt;
&lt;br /&gt;
自分、PDOっス（－－&lt;br /&gt;
&lt;br /&gt;
と思っては見たものの、中身はmysql_connect()なわけだから、何も考えずに実装。&lt;br /&gt;
意外と問題なくて、mysql_connect()のところを　&lt;span style=&quot;font-weight: bold;&quot;&gt;$dbh = new PDO();&lt;/span&gt;　煮してあげればO.K.&lt;br /&gt;
&lt;br /&gt;
が、しかーし、地獄はここから始まった。。。苦節2weekぐらいかも。なれないstraceとかして原因を探るとか（意味わかんないから眺めて勘だより）ぐぐりまくりましたよ。&lt;br /&gt;
もちろんBugも疑い、「バグジャン」っていってる外人さんに「バグじゃないよ。ちゃんと使い方みな」なんて書いてるPHPの中の人らしきコメントを読んだり。。。&lt;br /&gt;
マジ疲れました。&lt;br /&gt;
で、結局。PHPの中の人が正しい　（＊&#39;▽&#39;）db（&#39;▽&#39;＊）　ねー。&lt;br /&gt;
&lt;br /&gt;
&lt;h4 id=&quot;aya&quot;&gt;
さんぷるクリプト&lt;/h4&gt;
&lt;br /&gt;
なんか切れるほう&lt;br /&gt;
&lt;pre class=&quot;php&quot; name=&quot;code&quot;&gt;
try{
  $pdo = new PDO( $dns, $user, $pass, array(
    PDO::ATTR_PERSISTENT =&amp;gt; true,
    PDO::MYSQL_ATTR_LOCAL_INFILE =&amp;gt; true,
    PDO::MYSQL_ATTR_INIT_COMMAND =&amp;gt; &#39;SET CHARACTER SET ujis;&#39;
  ));
  $pdo-&amp;gt;setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}catch( PDOException $e ){
  printf(&quot;PDOException:%s\n&quot;,$e-&amp;gt;getMessage());
  exit(1);
}&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
切れないほう&lt;br /&gt;
&lt;pre class=&quot;php&quot; name=&quot;code&quot;&gt;
try{
  $pdo = new PDO( $dns, $user, $pass, array(
    PDO::MYSQL_ATTR_LOCAL_INFILE =&amp;gt; true,
    PDO::MYSQL_ATTR_INIT_COMMAND =&amp;gt; &#39;SET CHARACTER SET ujis;&#39;
  ));
  $pdo-&amp;gt;setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
}catch( PDOException $e ){
  printf(&quot;PDOException:%s\n&quot;,$e-&amp;gt;getMessage());
  exit(1);
}&lt;/pre&gt;
&lt;br /&gt;
どっちも繋がるのだけど、切れるほうは割と始めのほうで切れる。それいご切れないのに、最初の何かがきれうる。&lt;br /&gt;
ずーっと悩んでたんですけどね、あれです、見ていただいたとおり。。。&lt;br /&gt;
子プロセスに仕事させたいなら&lt;span style=&quot;font-weight: bold;&quot;&gt;持続的な接続&lt;/span&gt;ってやつはご法度なんです（－－　&lt;span style=&quot;font-weight: bold;&quot;&gt;mysql_pconnect()&lt;/span&gt;　は、つかっちゃーいかんのです！&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.php.net/manual/ja/function.mysql-pconnect.php&quot;&gt;PHP: mysql_pconnect - Manual&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
1 番目の違いとして、この関数は接続時にまず 同じホスト、ユーザ名、パスワードを有する(持続的)リンクが すでにオープンされていないかどうかを調べます。
 それがみつかった場合、新規の接続をオープンする代わりに そのリンクの ID が返されます。&lt;/pre&gt;
&lt;br /&gt;
ほかの子プロセスのを掴んじゃったりするんじゃないかい・・・・&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;
2 番目の違いは、スクリプトの実行が終了しても SQL サーバとの接続が 閉じられないということです。
そのかわりに、将来再利用されるために リンクがオープンされたままとなります（mysql_close() は、mysql_pconnect()によって確立されたリンクを 閉じません）。&lt;/pre&gt;
&lt;br /&gt;
けっこういっぱいプロセスがいるから、また変なのをつかんじゃうよね？&lt;br /&gt;
&lt;br /&gt;
と、思うしだいでありました。&lt;br /&gt;
本当のところはわからないのだけれど、変えたら切れなくなったし。。。&lt;br /&gt;
まだまだ謎がおおいんですね。&lt;br /&gt;
&lt;br /&gt;
&lt;h4 id=&quot;aya&quot;&gt;
お世話になったリンクのまとめ&lt;/h4&gt;
&lt;br /&gt;
&lt;a href=&quot;http://php.net/manual/en/function.pcntl-fork.php&quot;&gt;PHP: pcntl_fork - Manual&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.php.net/manual/ja/function.mysql-pconnect.php&quot;&gt;PHP: mysql_pconnect - Manual&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://d.hatena.ne.jp/with_no_parachute/20091116/1258392300&quot;&gt;PHPでの並列処理について - With-No-Parachute D-side&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://www.codeblog.org/blog/moriyoshi/20070208.html&quot;&gt;小泉守義のPHPソースコードウォッチ - pcntl_fork() - fork() で複製される fd に注意セヨ....&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://d.hatena.ne.jp/yutakikuchi/20110202/1296579267&quot;&gt;system callのtraceについて - YutaKikuchiのTechBlog&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.phpkode.com/source/p/phppdo/phppdo-1.4/drivers/mysql.php&quot;&gt;mysql.php at PHPPDO - Free PHP Code&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/3792127264932147835/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2011/04/phppcntlfork.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/3792127264932147835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/3792127264932147835'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2011/04/phppcntlfork.html' title='PHPでpcntl_forkでふぉーくの薀蓄'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-2046759183663630294</id><published>2011-01-26T14:53:00.003+09:00</published><updated>2011-01-26T16:03:11.904+09:00</updated><title type='text'>PHPでビット演算、シフト演算</title><content type='html'>ビットをフラグ代りに使うことが増えてきたので。。。&lt;br /&gt;1ビット1アイテムって思うと、最大で63個まで持ってるか分かるようになる的な。&lt;br /&gt;なんで63個かっていうと64個だとMySQLにしまえない可能性があるみたい。&lt;br /&gt;（使ってるVerが古いってのもあるし、そもそも勘違いかもだけどー。）&lt;br /&gt;とりあえず、PHPで書いたさんぷる。&lt;br /&gt;&lt;br /&gt;&lt;h4 id=&quot;aya&quot;&gt;さんぷるクリプト&lt;/h4&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;&lt;br /&gt;// 色情報&lt;br /&gt;$items=array(&#39;red&#39;=&gt;1, &#39;blue&#39;=&gt;2, &#39;green&#39;=&gt;3, &#39;white&#39;=&gt;4, &#39;black&#39;=&gt;5);&lt;br /&gt;// 人情報&lt;br /&gt;$peoples = array(&#39;LILY&#39;=&gt;0, &#39;LOGAN&#39;=&gt;0, &#39;OLIVIA&#39;=&gt;0);&lt;br /&gt;/*&lt;br /&gt; * 選択情報を作る&lt;br /&gt; */&lt;br /&gt;$peoples[&#39;LILY&#39;] =&lt;br /&gt; (1 &lt;&lt; $items[&#39;red&#39;])&lt;br /&gt; | (1 &lt;&lt; $items[&#39;green&#39;])&lt;br /&gt; | (1 &lt;&lt; $items[&#39;black&#39;]) ;  // red, green, black を選ぶ&lt;br /&gt;&lt;br /&gt;printf(&quot;name:% 7s int:% 4d bit:%08b\n&quot;,&lt;br /&gt; &#39;LILY&#39;, $peoples[&#39;LILY&#39;], $peoples[&#39;LILY&#39;]);&lt;br /&gt;&lt;br /&gt;$peoples[&#39;LOGAN&#39;] =&lt;br /&gt; (1 &lt;&lt; $items[&#39;blue&#39;])&lt;br /&gt; | (1 &lt;&lt; $items[&#39;green&#39;])&lt;br /&gt; | (1 &lt;&lt; $items[&#39;black&#39;]) ;  // blue, green, black を選ぶ&lt;br /&gt;&lt;br /&gt;printf(&quot;name:% 7s int:% 4d bit:%08b\n&quot;,&lt;br /&gt; &#39;LOGAN&#39;, $peoples[&#39;LOGAN&#39;], $peoples[&#39;LOGAN&#39;]);&lt;br /&gt;&lt;br /&gt;$peoples[&#39;OLIVIA&#39;] =&lt;br /&gt; (1 &lt;&lt; $items[&#39;red&#39;])&lt;br /&gt; | (1 &lt;&lt; $items[&#39;white&#39;])&lt;br /&gt; | (1 &lt;&lt; $items[&#39;black&#39;]) ;  // red, white, black を選ぶ&lt;br /&gt;&lt;br /&gt;printf(&quot;name:% 7s int:% 4d bit:%08b\n&quot;,&lt;br /&gt; &#39;OLIVIA&#39;, $peoples[&#39;OLIVIA&#39;], $peoples[&#39;OLIVIA&#39;]);&lt;br /&gt;&lt;br /&gt;print &quot;======================\n&quot;;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * 皆が選択している色だけを選らぶ&lt;br /&gt; * (論理積)&lt;br /&gt; */&lt;br /&gt;$common_col=0;&lt;br /&gt;$common_col=&lt;br /&gt; $peoples[&#39;LILY&#39;] &amp; $peoples[&#39;LOGAN&#39;] &amp; $peoples[&#39;OLIVIA&#39;] ;&lt;br /&gt;printf(&quot;common colors int:% 4d bit:%08b\n&quot;, $common_col, $common_col);&lt;br /&gt;chkSelections($common_col);&lt;br /&gt;&lt;br /&gt;print &quot;======================\n&quot;;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * 選択されている全ての色を選ぶ&lt;br /&gt; * (論理和)&lt;br /&gt; */&lt;br /&gt;$common_col=0;&lt;br /&gt;$common_col=&lt;br /&gt; $peoples[&#39;LILY&#39;] | $peoples[&#39;LOGAN&#39;] | $peoples[&#39;OLIVIA&#39;] ;&lt;br /&gt;printf(&quot;common colors int:% 4d bit:%08b\n&quot;, $common_col, $common_col);&lt;br /&gt;chkSelections($common_col);&lt;br /&gt;&lt;br /&gt;exit;&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt; * ビットが立っているものを探す&lt;br /&gt; */&lt;br /&gt;function chkSelections($selections)&lt;br /&gt;{&lt;br /&gt;  global $items;&lt;br /&gt;  &lt;br /&gt;  foreach ( $items as $col_name =&gt; $col_num )&lt;br /&gt;  {&lt;br /&gt;    $chk_bit=( 1 &lt;&lt; $col_num );&lt;br /&gt;    if( $selections &amp; $chk_bit ) // ビットが立ってる&lt;br /&gt;    {&lt;br /&gt;      printf(&quot;Select color:% 6s\n&quot;, $col_name);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;シフト演算でビットが立っているところを探していく方法もあるけど。&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;php&quot;&gt;&lt;br /&gt;$col_num=0;&lt;br /&gt;while( $selections )&lt;br /&gt;{&lt;br /&gt;  if( $selections &amp; 1 )&lt;br /&gt;  {&lt;br /&gt;    printf(&quot;Select color number:%d bit:%08b\n&quot;, $col_num, $selections);&lt;br /&gt;  }&lt;br /&gt;   $selections = $selections &gt;&gt; 1;&lt;br /&gt;  $col_num++;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4 id=&quot;aya&quot;&gt;MySQL&lt;/h4&gt;&lt;br /&gt;選択情報をMySQLに格納して、クエリで取得することもできる。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;SELECT * hoge WHERE select_bit &amp; ${col_num} ;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;これでその色を選択している情報が引っ張れるです。</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/2046759183663630294/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2011/01/php.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/2046759183663630294'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/2046759183663630294'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2011/01/php.html' title='PHPでビット演算、シフト演算'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-8872551431710579475</id><published>2010-12-21T15:59:00.001+09:00</published><updated>2010-12-21T16:00:56.224+09:00</updated><title type='text'>PerlのImage::Magick</title><content type='html'>画像合成をする場合に使うライブラリのさんぷるクリプト&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.imagemagick.org/script/index.php&quot;&gt;ImageMagick&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4 id=&quot;aya&quot;&gt;さんぷるクリプト&lt;/h4&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;perl&quot;&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;use strict;&lt;br /&gt;use warnings;&lt;br /&gt;&lt;br /&gt;use Image::Magick;&lt;br /&gt;&lt;br /&gt;my $dir = &#39;images&#39;;&lt;br /&gt;my $width = 192;&lt;br /&gt;my $height= 53;&lt;br /&gt;&lt;br /&gt;my $i3 = Image::Magick-&gt;new(width=&gt;$width, height=&gt;$height, magick=&gt;&#39;GIF&#39;);&lt;br /&gt;$i3-&gt;Read(&quot;$dir/layer3.gif&quot;);&lt;br /&gt;&lt;br /&gt;my $i2 = Image::Magick-&gt;new(width=&gt;$width, height=&gt;$height, magick=&gt;&#39;GIF&#39;);&lt;br /&gt;$i2-&gt;Read(&quot;$dir/layer2.gif&quot;);&lt;br /&gt;$i3-&gt;Composite(image=&gt;$i2, compose=&gt;&#39;Over&#39;, x=&gt;0, y=&gt;0);&lt;br /&gt;&lt;br /&gt;my $i1 = Image::Magick-&gt;new(width=&gt;$width, height=&gt;$height, magick=&gt;&#39;GIF&#39;);&lt;br /&gt;$i1-&gt;Read(&quot;$dir/layer1.gif&quot;);&lt;br /&gt;$i3-&gt;Composite(image=&gt;$i1, compose=&gt;&#39;Over&#39;, x=&gt;0, y=&gt;0);&lt;br /&gt;&lt;br /&gt;$i3-&gt;Write(&quot;$dir/mix_i.gif&quot;);&lt;br /&gt;&lt;br /&gt;#binmode STDOUT;&lt;br /&gt;#$i3-&gt;Write(&#39;gif:-&#39;);&lt;br /&gt;&lt;br /&gt;exit;&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/8872551431710579475/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2010/12/perlimagemagick.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/8872551431710579475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/8872551431710579475'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2010/12/perlimagemagick.html' title='PerlのImage::Magick'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-4840027328012266783</id><published>2010-12-21T15:54:00.003+09:00</published><updated>2010-12-21T15:58:00.185+09:00</updated><title type='text'>PerlのGD</title><content type='html'>画像合成をする場合に使うライブラリのさんぷるクリプト&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.boutell.com/gd/&quot;&gt;GD&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4 id=&quot;aya&quot;&gt;さんぷるクリプト&lt;/h4&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;perl&quot;&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;use strict;&lt;br /&gt;use warnings;&lt;br /&gt;&lt;br /&gt;use GD;&lt;br /&gt;&lt;br /&gt;my $dir = &#39;images&#39;;&lt;br /&gt;my $width = 192;&lt;br /&gt;my $height= 53;&lt;br /&gt;&lt;br /&gt;my $image = new GD::Image($width, $height);&lt;br /&gt;&lt;br /&gt;my $i3 = new GD::Image(&quot;$dir/layer3.gif&quot;);&lt;br /&gt;$image-&gt;copy($i3, 0, 0, 0, 0, $width, $height);&lt;br /&gt;&lt;br /&gt;my $i2 = new GD::Image(&quot;$dir/layer2.gif&quot;);&lt;br /&gt;my $i1 = new GD::Image(&quot;$dir/layer1.gif&quot;);&lt;br /&gt;$i2-&gt;copy($i1, 0, 0, 0, 0, $width, $height);&lt;br /&gt;$image-&gt;copy($i2, 0, 0, 0, 0, $width, $height);&lt;br /&gt;&lt;br /&gt;open(OUT, &quot;&gt;$dir/mix.gif&quot;);&lt;br /&gt;binmode OUT;&lt;br /&gt;print OUT $image-&gt;gif;&lt;br /&gt;close(OUT);&lt;br /&gt;&lt;br /&gt;exit;&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/4840027328012266783/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2010/12/perlgd.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/4840027328012266783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/4840027328012266783'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2010/12/perlgd.html' title='PerlのGD'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-9181846193752187890</id><published>2010-12-20T16:43:00.011+09:00</published><updated>2012-10-17T17:06:26.795+09:00</updated><title type='text'>CのApache-module：：基本GETパラメータ</title><content type='html'>apacheモジュールでGETパラメータを受け取る方法。&lt;br /&gt;
GETとPOSTでは処理が違うのがミソですね。。POST難しい。。。&lt;br /&gt;
&lt;br /&gt;
GETパラメータはrequest_rec構造体のメンバであるargsに文字列として渡されます。&lt;br /&gt;
1個しかないと分かっていれば簡単ですけど、つらつらと渡されることもあるので、複数のパラメータがあると想定します。&lt;br /&gt;
&lt;br /&gt;
方法はループ処理で取得するのでお好みなのを使えばいいと思うのですが、とりあえず2個のサンプルを書いてみました。

&lt;h4 id=&quot;aya&quot;&gt;
for 文を使う&lt;/h4&gt;
&lt;script class=&quot;brush:c&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
const char *sep = &quot;&amp;amp;&quot;;
char *str = apr_pstrdup(r-&amp;gt;pool, r-&amp;gt;args);
char *items, *last;
for ( items = apr_strtok(str, sep, &amp;amp;last);
 items != NULL;
 items = apr_strtok(NULL, sep, &amp;amp;last)
){
   // 個々のパラメータ処理
}
]]&gt;&lt;/script&gt;
&lt;h4 id=&quot;aya&quot;&gt;
do ... while 文を使う&lt;/h4&gt;
&lt;script class=&quot;brush:c&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
char *str = apr_pstrdup(r-&amp;gt;pool, r-&amp;gt;args);
char *last;
char *items = apr_strtok(str, sep, &amp;amp;last);

do {
   // 個々のパラメータ処理
} while (NULL != (items = apr_strtok(NULL, sep, &amp;amp;last)));
]]&gt;&lt;/script&gt;
&lt;br /&gt;
&lt;h4 id=&quot;aya&quot;&gt;
個々のパラメータ処理&lt;/h4&gt;
&lt;br /&gt;
keyとvalをハッシュに格納します。&lt;br /&gt;
また、同一keyで異なるパラメータが送られてきても受け取れるようにvalは配列にします。&lt;br /&gt;
&lt;script class=&quot;brush:c&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
const char *sep = &quot;&amp;amp;&quot;;
char *str = apr_pstrdup(r-&amp;gt;pool, r-&amp;gt;args);
char *items, *last, *st;
apr_array_header_t *values; // 同一keyで異なるパラメータを格納するための配列

/* パラメータ格納用のハッシュテーブル作成 */
apr_hash_t *hash = NULL;
hash = apr_hash_make(r-&amp;gt;pool);

/* パラメータ取得 */
for ( items = apr_strtok(str, sep, &amp;amp;last);
 items != NULL;
 items = apr_strtok(NULL, sep, &amp;amp;last)
){
// space変換
for (st = items; *st; ++st)
{
 if(*st == &#39;+&#39;){ *st = &#39; &#39;; }
}
// keyとvalueに分割
st = strchr(items, &#39;=&#39;);
if (st) {
 // value あり
 *st++ = &#39;\0&#39;;
 ap_unescape_url(items);
 ap_unescape_url(st);
}else{
 // value なし
 st = &quot;&quot;;
 ap_unescape_url(items);
}
// ハッシュに登録済みかチェック
values = apr_hash_get(hash, items, APR_HASH_KEY_STRING);
if (values == NULL)
{
 // 可変長配列(apr_array_header_t)初期化
 values = apr_array_make(r-&amp;gt;pool, 1, sizeof(char*));
 // ハッシュに要素追加
 apr_hash_set(hash, items, APR_HASH_KEY_STRING, values);
}
// 配列に要素追加
*((char **)apr_array_push(values)) = apr_pstrdup(r-&amp;gt;pool, st);
}
]]&gt;&lt;/script&gt;
&lt;br /&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;○確認方法&lt;/span&gt;&lt;br /&gt;
curllが入っていれば簡単。
&lt;script class=&quot;brush:bash&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
　$ curl &quot;http://hogehoge.jp/first?name=R%20S&amp;key=33&amp;key=22&amp;key=11&quot;
]]&gt;&lt;/script&gt;
複数パラメータは、&lt;span style=&quot;font-weight: bold;&quot;&gt;”&lt;/span&gt; --- &lt;span style=&quot;font-weight: bold;&quot;&gt;”&lt;/span&gt; でくくらないと切れてしまいますー。&lt;br /&gt;
&lt;br /&gt;
Telnetの場合はこんなん
&lt;script class=&quot;brush:bash&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
　$ telnet localhost 80
　Trying 127.0.0.1...
　Connected to localhost.localdomain (127.0.0.1).
　Escape character is &#39;^]&#39;.
　GET /first?name=R%20S&amp;key=33&amp;key=22&amp;key=11 HTTP/1.1
　Host: localhost
]]&gt;&lt;/script&gt;
&lt;span style=&quot;font-weight: bold;&quot;&gt;○関数メモ&lt;/span&gt;&lt;br /&gt;
&lt;script class=&quot;brush:c&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
char* apr_pstrdup  (
apr_pool_t *p,  // request_rec構造体のpool
const char *s   // poolから取りだしたいメンバ名
)

char* apr_strtok  (
char *str,       // 分割したい文字列
const char *sep, // デリミタ
char **last      // デリミタより後の文字列が関数により格納
)
]]&gt;&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/9181846193752187890/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2010/12/capache-moduleget.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/9181846193752187890'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/9181846193752187890'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2010/12/capache-moduleget.html' title='CのApache-module：：基本GETパラメータ'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-5820768265646665429</id><published>2010-12-16T18:27:00.007+09:00</published><updated>2012-10-17T16:51:25.725+09:00</updated><title type='text'>CのApache-module：：基本</title><content type='html'>apacheモジュールの超基本形。スタティックページならこんなんでOK.&lt;br /&gt;
ついでにapacheの設定も書いておきましょ。。

&lt;script class=&quot;brush:c&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[
/*
**  mod_first.c -- Apache sample first module
**  [Autogenerated via ``apxs -n first -g&#39;&#39;]
**
*/

#include &quot;httpd.h&quot;        // 必須
#include &quot;http_config.h&quot;  // 必須
#include &quot;ap_config.h&quot;    // 必須
#include &quot;http_protocol.h&quot;// 必須

#include &quot;http_log.h&quot;     // ap_log_rerror(),

#define _MY_DEBUG(...) ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r-&amp;gt;server, __VA_ARGS__)

/* The sample content handler */
static int first_handler(request_rec *r)
{
int rec_time = apr_time_msec(r-&amp;gt;request_time);
_MY_DEBUG(&quot;call first_handler() %d&quot;, rec_time);

if (strcmp(r-&amp;gt;handler, &quot;first&quot;))
return DECLINED;

r-&amp;gt;content_type = &quot;text/html&quot;;

if (r-&amp;gt;header_only)
return OK;

ap_rputs(&quot;The sample page from mod_first.c\n&quot;, r);

return OK;
}

static void first_register_hooks(apr_pool_t *p)
{
ap_hook_handler(first_handler, NULL, NULL, APR_HOOK_MIDDLE);
}

/* Dispatch list for API hooks */
module AP_MODULE_DECLARE_DATA first_module = {
STANDARD20_MODULE_STUFF,
NULL,                 /* create per-dir  config structures */
NULL,                 /* merge  per-dir  config structures */
NULL,                 /* create per-server config structures */
NULL,                 /* merge  per-server config structures */
NULL,                 /* table of config file commands     */
first_register_hooks  /* register hooks */
};
]]&gt;&lt;/script&gt;

&lt;h4 id=&quot;aya&quot;&gt;
httpd.confに書くこと&lt;/h4&gt;

&lt;script class=&quot;brush:text&quot; type=&quot;syntaxhighlighter&quot;&gt;&lt;![CDATA[ 
LoadModule first_module modules/mod_first.so

&amp;lt;Location &quot;/first&quot;&amp;gt;
SetHandler first
&amp;lt;/Location&amp;gt;
]]&gt;&lt;/script&gt;
</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/5820768265646665429/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2010/12/capache-module.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/5820768265646665429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/5820768265646665429'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2010/12/capache-module.html' title='CのApache-module：：基本'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9198835639547511373.post-4223174102475085902</id><published>2010-12-01T15:14:00.005+09:00</published><updated>2010-12-01T16:25:40.218+09:00</updated><title type='text'>PerlのImage::Imlib2</title><content type='html'>画像合成をする場合に使うライブラリのさんぷるクリプト&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://docs.enlightenment.org/api/imlib2/html/&quot;&gt;Imlib2&lt;/a&gt;：インストール方法は簡単なyum使ってるのでまぁ・・・参考程度で。&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;取り合えずgifが作られればいいので、必要だというlibgifとlibungifを入れる。&lt;br /&gt;libungifにlibgifも入っているらしいので、libungifを入れる。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;本体入れる&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Perlモジュール入れる&lt;/li&gt;&lt;br /&gt;&lt;li&gt;使う&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;&lt;H4 id=&quot;aya&quot;&gt;さんぷるクリプト&lt;/H4&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;perl&quot;&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;use strict;&lt;br /&gt;use warnings;&lt;br /&gt;&lt;br /&gt;use Image::Imlib2;&lt;br /&gt;&lt;br /&gt;my $dir = &#39;images&#39;;&lt;br /&gt;&lt;br /&gt;my $image = Image::Imlib2-&gt;load(&quot;$dir/layer3.gif&quot;);&lt;br /&gt;&lt;br /&gt;my $i2 = Image::Imlib2-&gt;load(&quot;$dir/layer2.gif&quot;);&lt;br /&gt;$image-&gt;blend($i2, 0, 0, 0, $image-&gt;width, $image-&gt;height, 0, 0, $image-&gt;width, $image-&gt;height);&lt;br /&gt;&lt;br /&gt;my $i1 = Image::Imlib2-&gt;load(&quot;$dir/layer1.gif&quot;);&lt;br /&gt;$image-&gt;blend($i1, 0, 0, 0, $image-&gt;width, $image-&gt;height, 0, 0, $image-&gt;width, $image-&gt;height);&lt;br /&gt;&lt;br /&gt;$image-&gt;set_quality(100);&lt;br /&gt;$image-&gt;image_set_format(&#39;png&#39;);&lt;br /&gt;$image-&gt;save(&quot;$dir/mix.png&quot;);&lt;br /&gt;&lt;br /&gt;exit;&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://rhythm-prism.blogspot.com/feeds/4223174102475085902/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://rhythm-prism.blogspot.com/2010/12/perlimageimlib2_01.html#comment-form' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/4223174102475085902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9198835639547511373/posts/default/4223174102475085902'/><link rel='alternate' type='text/html' href='http://rhythm-prism.blogspot.com/2010/12/perlimageimlib2_01.html' title='PerlのImage::Imlib2'/><author><name>あっぴー</name><uri>http://www.blogger.com/profile/14711780771062162352</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='26' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-zdd7CCO7R1xqjdG9NMaAzyXAp7NCAo_B_9A5wDcdnwFfQDFDxh2g510Dsdtwgs_4e0rXDflj8l03VVuxQpuwqouRFHmuejmcEY5OTc6MQJeBrv2zLuzsaa0bjyouIWo/s220/e.jpg'/></author><thr:total>0</thr:total></entry></feed>