「成分解析」解析結果

今2ちゃんねるで「成分解析」というソフトがはやってるみたいですね.絶好の解析練習対象なので,やっちゃいました.

なお,解析結果が正しいとは限りません.結果は自己責任で使ってください(使う人って居るの?w

(04/04追記)Javaに移植しました.

(04/06追記)CでCGIにも移植しました.

(04/15追記)魔界の仮面弁士さんが各種移植版をまとめてくれました!感謝.

この結果を使った場合,ぜひ私に教えてください.あと情報提供元も明記してくれるとうれしいなとか思ったり.商用利用のときは必ず連絡してください.(しないと思うけどなw)

文字列の変換

まずは,文字列を合成することからはじめる.

長い文字列(Shift-JIS形式)を,4バイトの数値へ変換する.

 

返したい数値をcodeとする.

また,N=0とする.

  1. 与えられた文字列のNバイト目を取得する.これをstrとする.
  2. strを((N and 3) << 3)だけ左シフトする.
  3. codeに上の結果を足す.
  4. Nに1を足す
  5. 1に戻る

こうして,4バイトの数codeを得る.

 

種類とパーセンテージの取り出し

種類とパーセンテージを取りだす関数を用いる.この関数をランダム関数と呼ぶことにする.

ランダム関数は後に示す.

 

[残りのパーセンテージ]に100を代入する

  1. 種類の決定
    1. ランダム関数を用いて得た結果を100で割って余りを求める
    2. その余りが種類である.品物リストは最後に示す.
    3. 今までに得た品物リストと比較し,同じであったらループの最初へ戻る
  2. パーセンテージの決定
    1. ランダム関数を再度用いて得られた結果を[残りのパーセンテージ]で割った余りを求める
    2. それに1を足したものがパーセンテージである.
    3. [残りのパーセンテージ]から上で得た結果を引く.
  3. [残りのパーセンテージ]が0になったら抜ける.でなければ最初に戻る.

なお,残りのパーセンテージが50%の時は,「~の半分は~」になり,残りの種類も50%の時は「~のもう半分は~」になります.100%のときは「~はすべて~」になりますのでご注意ください.

 

ランダム関数

言葉での説明が辛いので擬似コードで書く.

引数には前回の結果を使う.

初回の引数は「文字列の変換」で得られた数値である.

unsigined int seed = 0; //グローバル変数.
		//初期化には,文字列から変換した数値を使う
unsigned int random(){
	int result;
	seed *= 214013;
	seed += 2531011; // ->次に呼び出されたときのseedに使う
	result = seed;
	result = result >> 0x10;
	result &= 0x7fff;
	return result;
}

 

ソート関数

結果を得た後,パーセンテージでソートする必要がある.これがそのソート用の関数である.

    public void sort(Element[] elt) {
        for (int i = elt.length - 1; i > 0; i--) {
            int prev = 0;
            for (int j = 1; j <= i; j++) {
                if (!(elt[prev].Parcentage <= elt[j].Parcentage)) {
                    prev = j;
                }
            }
            /*iとprevについて入れ替える*/
            swap(elt, i, prev);
        }
    }

Javaで書くとこのような感じになる.基本的にバブルソートである.すいませんセレクションソートって言うらしいです.

 

感想

この解析に二時間以上かかってます.ダメっすよね,うん.

でもまあ,最後まで解析できたということで60点くらいはあげてもいいかなぁ.

ちなみに,

ψ(プサイ)の成分解析結果 : 
ψ(プサイ)の43%は食塩で出来ています。
ψ(プサイ)の36%は血で出来ています。
ψ(プサイ)の18%は厳しさで出来ています。
ψ(プサイ)の2%は真空で出来ています。
ψ(プサイ)の1%は鉄の意志で出来ています。

どうみてもしょっぱすぎです.本当にありがとうございました(何

 

品物リスト

0x00:下心
0x01:微妙さ
0x02:優雅さ
0x03:華麗さ
0x04:かわいさ
0x05:やさしさ
0x06:やましさ
0x07:やらしさ
0x08:むなしさ
0x09:ツンデレ
0x0a:厳しさ
0x0b:世の無常さ
0x0c:ハッタリ
0x0d:ビタミン
0x0e:努力
0x0f:気合
0x10:根性
0x11:砂糖
0x12:食塩
0x13:愛
0x14:電波
0x15:毒電波
0x16:元気玉
0x17:怨念
0x18:大阪のおいしい水
0x19:明太子
0x1a:勇気
0x1b:運
0x1c:電力
0x1d:小麦粉
0x1e:汗と涙(化合物)
0x1f:覚悟
0x20:大人の都合
0x21:見栄
0x22:欲望
0x23:嘘
0x24:真空
0x25:呪詛
0x26:信念
0x27:夢
0x28:記憶
0x29:鉄の意志
0x2a:カルシウム
0x2b:魔法
0x2c:希望
0x2d:不思議
0x2e:勢い
0x2f:度胸
0x30:乙女心
0x31:罠
0x32:花崗岩
0x33:宇宙の意思
0x34:犠牲
0x35:毒物
0x36:鉛
0x37:海水
0x38:蛇の抜け殻
0x39:波動
0x3a:純金
0x3b:情報
0x3c:知識
0x3e:知恵
0x3e:魂の炎
0x3f:媚び
0x40:保存料
0x41:着色料
0x42:税金
0x43:歌
0x44:苦労
0x45:柳の樹皮
0x46:睡眠薬
0x47:スライム
0x48:アルコール
0x49:時間
0x4a:果物
0x4b:玉露
0x4c:利益
0x4d:赤い何か
0x4e:白い何か
0x4f:鍛錬
0x50:月の光
0x51:回路
0x52:野望
0x53:陰謀
0x54:雪の結晶
0x55:株
0x56:黒インク
0x57:白インク
0x58:カテキン
0x59:祝福
0x5a:気の迷い
0x5b:マイナスイオン
0x5c:濃硫酸
0x5d:ミスリル
0x5e:お菓子
0x5f:言葉
0x60:心の壁
0x61:成功の鍵
0x62:理論
0x63:血

VBSに移植したい

という質問があったので,以下に回答を載せて起きます.  合ってるかどうかは分からないので,間違ってたら教えてください(最上位ビットのあたりとかアヤシス)

ψ(プサイ)さんすごいっす
実はうちの会社でも流行ってまして、ASP+VBSで実現
しようと思っています
ψ(プサイ)さんの解析Blogみてチャrネジしているのですがまったく実現できません。
「strを{(n and 3)*8}だけ左シフトする. 」を
VBでどう実現すればとか・・・・結構つまずいてます
何かよきアドバイスとかしてもらえるとうれしいです。

ありがとうございます.

VBSはよく分からないんですが,Cで書くと

code += str  << ((n & 3) << 3);

って感じです.VBSにはシフトが無いみたいなので,2の累乗を計算するルーチンは必須だと思います.

あと,VBSには符号なし整数の型が無いっぽいので,(Javaにも無いです^^;)基本的には数値は全部longで持っていて,計算を行うごとに0xffffffff(fが8コ)をandしてそれを使ってください.
符号アリでやってると掛け算の結果,最上位ビットが1になってマイナスになっちゃう時が(たぶん)あるので,それを防ぐためです.
が,Javaでやった時,なぜか9ケタ目が残っちゃったんで,32回左シフトして32回右シフトする事によって4バイト分取り出せたんですが,VBSで掛け算でシフトしたら結果がマイナスになる事もありそうな気がします.
あとstrを取得するときに,Byteをそのまま使っちゃダメです.0より小さいときは128を足して,long型に代入して使ってください.