« Pokenデザインコンテスト #5 - Kabuki(歌舞伎) | トップページ | DB2 で PL/SQL »

2009年5月21日 (木)

PL/SQL de ケンブリッジ関数

先日、ケンブリッジ関数ネタを取り上げたついでなのでPL/SQLで作ってみた。
こんな感じかな。他の言語に比べるとアウェイ感が強いけど。時間があったらほかのでもやるかも..w

ちなみに、OracleはOracle10g R2 10.2.0.4.0で、キャラクタセットはAL32UTF8

関連記事:
ケブンッリジ関数@ どう書く?org
確かに“読めてしまう”コピペに2ch住人が「人間すげー」と驚く@ITmedia
流行りのケブンリッジ関数 - JavaScript 編@IT戦記

ストアドファンクションにしてあります。

CREATE OR REPLACE FUNCTION Cambridge( iWords IN CLOB )
RETURN CLOB
IS
words CLOB := EMPTY_CLOB();
word CLOB := EMPTY_CLOB();
nonwords CLOB := EMPTY_CLOB();
TYPE t_char_table_type IS TABLE OF CHAR(1 CHAR);
chars t_char_table_type := t_char_table_type();
charsInit t_char_table_type := t_char_table_type();
startpos PLS_INTEGER := 1;
endpos PLS_INTEGER;
l PLS_INTEGER;
endpos_nonwords PLS_INTEGER;
tempwords CLOB := EMPTY_CLOB();
done BOOLEAN;
--
FUNCTION getShuffledWord RETURN CLOB
IS
workCLOB CLOB := EMPTY_CLOB();
BEGIN
IF chars.COUNT > 0 THEN
FOR j IN chars.FIRST..chars.LAST LOOP
workCLOB := workCLOB || chars(j);
END LOOP;
END IF;
RETURN workCLOB;
END;
--
BEGIN
words := iWords;
LOOP
endpos := REGEXP_INSTR(words, '(\s+|[[:punct:]]+|$)', startpos);
EXIT WHEN endpos = 0;
--
word := DBMS_LOB.SUBSTR(words, endpos - startpos, startpos);
chars := charsInit;
--
IF DBMS_LOB.getLength(word) > 3 THEN
FOR i IN 1..DBMS_LOB.getLength(word) LOOP
chars.EXTEND();
END LOOP;
chars(chars.FIRST) := DBMS_LOB.SUBSTR(word, 1, 1);
chars(chars.LAST) := DBMS_LOB.SUBSTR(word, 1, DBMS_LOB.getLength(word));
--
FOR k IN 2..DBMS_LOB.getLength(word) - 1 LOOP
done := FALSE;
WHILE NOT done LOOP
l := ROUND(DBMS_RANDOM.VALUE(2, DBMS_LOB.getLength(word) - 1));
IF chars(l) IS NULL THEN
chars(l) := DBMS_LOB.SUBSTR(word, 1, k);
done := TRUE;
END IF;
END LOOP;
END LOOP;
word := getShuffledWord();
END IF;
--
endpos_nonwords := REGEXP_INSTR(words, '(\s+|[[:punct:]]+|$)', startpos, 1, 1);
nonwords := DBMS_LOB.SUBSTR(words, endpos_nonwords - endpos, endpos);
startpos := endpos + 1;
tempwords := tempwords || word || nonwords;
END LOOP;
RETURN tempwords;
END;
/

あたえる文字列はテーブルに格納してあります。

SCOTT> 
SCOTT> set linesize 80
SCOTT> desc wordstable
名前 NULL? 型
----------------------------------------- -------- ----------------------------
ID NOT NULL NUMBER
WORDS CLOB

SCOTT> set long 4000
SCOTT> set longchunk 400
SCOTT> select words from wordstable where id = 1;

WORDS
---------------------------------------------------------------------------
こんにちは みなさん おげんき ですか? わたしは げんき です。
この ぶんしょう は いぎりす の ケンブリッジ だいがく の けんきゅう の けっか
にんげん は もじ を にんしき する とき その さしいょ と さいご の もじさえ あっていれば
じゅんばん は めちゃくちゃ でも ちゃんと よめる という けんきゅう に もとづいて
わざと もじの じゅんばん を いれかえて あります。
どうです? ちゃんと よめちゃう でしょ?
ちゃんと よめたら はんのう よろしく


じこっう けっか。 フツー に よまめす よね?
PL/SQLをNative compileすればもっと早くなるだろうけど...

SCOTT> select cambridge(words) from wordstable where id = 1;

CAMBRIDGE(WORDS)
---------------------------------------------------------------------------
こちにんは みさなん おんげき ですか? わたしは げんき です。
この ぶょんしう は いりぎす の ケブンリッジ だいがく の けゅんきう の けっか
にげんん は もじ を にしんき する とき その さしいょ と さいご の もさじえ あてっいれば
じゅんばん は めゃくちちゃ でも ちんゃと よめる という けゅんきう に もとづいて
わざと もじの じばんゅん を いかれえて あまりす。
どうです? ちゃんと よめちゃう でしょ?
ちゃんと よためら はのんう よろしく

経過: 00:00:00.07
SCOTT>


では、次回はLeoparde de Oracle10g R2ネタに戻るとしましょうか・・・

それにしても他の言語で書かれているの見ると随分短いよね。そういえば、Python ChallengeでもPythonなら数行なのにPL/SQL無理矢理で書いていたっけ。。そうだ誰か、PostgreSQLのPL/pgSQLとかMySQLのストアドで書くような人はいないか?なぁ〜。と呟いてみる。w (2009/5/22追記)

|

トラックバック


この記事へのトラックバック一覧です: PL/SQL de ケンブリッジ関数:

» 今流行のケブンリッジ関数・・・しってました!? トラックバック あにずむ
こんにちわ!知ってました?人間って文字を認識するときに、最初と最後の文字さえあっていれば他の文字の順番がめちゃくちゃでもちゃんと読めるそうですwケンブリッジ大学での研究だそうですよ^^百聞は一見に如かず!試してみてくださいwこんちには みさなん おんげき で...... [続きを読む]

受信: 2009年5月24日 (日) 14時29分

コメント

コメントを書く