LoginSignup
16
3

More than 3 years have passed since last update.

MATLABで湯婆婆を実装してみる

Last updated at Posted at 2020-12-01

はじめに

 遅ればせながらMATLABによる湯婆婆の実装です。湯婆婆のアドカレに書くか、MATLABのアドカレに書くか迷いました(両方ってできます?→とか書いていたらあっちは埋まってしまいました。さすが湯婆婆の本家)

1.湯婆婆コード(暫定)

とりあえず書いてみました。

%%% 湯婆婆
name=input('契約書だよ。そこに名前を書きな。\n','s');
disp(['フン。' name 'というのかい。贅沢な名だねぇ。']);
rng('shuffle');
r=randi([1 length(name)],1,1);
disp(['今からお前の名前は' name(r) 'だ。いいかい、' name(r) 'だよ。分かったら返事をするんだ、' name(r) '!!']);

解説が必要なほどのプログラムではないですが、rng('shuffle')がないと、毎回同じ乱数(!)が出ます(シードが同じになるため)。
あと、randi([a,b],c,d)は区間[a,b]の乱数をc行d列の配列で返します。

入力した名前のうちの一文字だけをランダムに表示される仕様です。
湯婆婆プログラムは、できるだけ短くというルールもあったような。
それでは実行させてみます。

>> yubaba
契約書だよ。そこに名前を書きな。
荻野千尋
フン。荻野千尋というのかい。贅沢な名だねぇ。
今からお前の名前は尋だ。いいかい、尋だよ。分かったら返事をするんだ、尋!!

よさそうですね。

2.𠮷田さん対応テスト

𠮷田さんの「𠮷」は、サロゲートペア(4バイト文字)なので、ちょっと手強いです。
やってみます。

>> yubaba
契約書だよ。そこに名前を書きな。
𠮷田さん
フン。𠮷田さんというのかい。贅沢な名だねぇ。
今からお前の名前は�だ。いいかい、�だよ。分かったら返事をするんだ、�!!

・・・・・・・・・𠮷田さんは契約書に署名はできますが、文字化けしてしまいます。
ちょっと工夫が必要なようです。

3.湯婆婆(𠮷田さん対応版)

改良してみました。

%%% 湯婆婆2
name=input('契約書だよ。そこに名前を書きな。\n','s');
disp(['フン。' name 'というのかい。贅沢な名だねぇ。']);
dum=unicode2native(name,'UTF-32BE');
namelen=length(dum)/4;
rng('shuffle');
R=randi([0 namelen-1],1,1);
noname=native2unicode(dum(4*R+1:4*(R+1)), 'UTF-32BE');
disp(['今からお前の名前は' noname 'だ。いいかい、' noname 'だよ。分かったら返事をするんだ、' noname '!!']);

名前を一度、UTF-32BE(UTF-32LEでも可)でデコードして4バイト文字コードに変換します。
文字数を数えて(namelen)、乱数で1文字分の4バイトを選択して表示します。
※UTF-32でも良いのですが、unicode2nativeで変換した出力の先頭にBOM(LE:リトルエンディアンか、BE:ビッグエンディアンかの識別コード)が付くので、若干煩雑になります。

まず、荻野千尋さんから。

>> yubaba2
契約書だよ。そこに名前を書きな。
荻野千尋
フン。荻野千尋というのかい。贅沢な名だねぇ。
今からお前の名前は千だ。いいかい、千だよ。分かったら返事をするんだ、千!!

つづいて𠮷田さん、

>> yubaba2
契約書だよ。そこに名前を書きな。
𠮷田さん
フン。𠮷田さんというのかい。贅沢な名だねぇ。
今からお前の名前は𠮷だ。いいかい、𠮷だよ。分かったら返事をするんだ、𠮷!!

めでたく𠮷田さんも契約できました。

4.クラッシュ

名前を入れないとクラッシュするのが湯婆婆プログラムのお約束でした。
やってみます。

>> yubaba2
契約書だよ。そこに名前を書きな。

フン。というのかい。贅沢な名だねぇ。
エラー: randi
最初の入力は正の整数のスカラー値 IMAX でなければなりません。または、IMAX 以下の IMIN をもつ 2 つの整数値 [IMIN IMAX] でなければなりません。

エラー: yubaba2 (行 7)
R=randi([1 namelen],1,1);

よさそうですね。クラッシュでなく、エラーだけど。

5.「𠮷田」さんを探せ!

数多い名字の中から「𠮷田」さんを探します。

fn1='佐藤鈴木高橋田中伊藤';%長いので省略します。
dum=(unicode2native(fn1,'UTF-32BE'));%
dlen=length(dum);%データ数を数える

%描画準備
f=figure(1);
f.MenuBar='none';
f.Color='k';
f.Units='characters';
axis([-2 22 -3 25]);
ax=gca;
ax.Color='k';
ax.InnerPosition=[0 0 1 1];

%描画
s=1;
for t=1:100:dlen
  t2=t+99;
  if t2>dlen
      t2=dlen;
  end
  txt=native2unicode(dum(t:t2), 'UTF-32BE');
  text(1,22-s,txt,'Color','w');
  s=s+1;
  pause(0.1);
end

pause(10);%タイムリミットは10秒

実行すると、表示されました。どこに「𠮷田」さんが?
ヨシダさん1.jpg
unicode2native('文字列','UTF-32BE')で数値データに変換した値を見てみますと、

>> dec2hex(unicode2native('一郎𠮷田','UTF-32BE'))
ans =

  16×2  char 配列

    '00' <--「一」
    '00' 
    '4E'
    '00'
    '00' <--「郎」
    '00' 
    '90'
    'CE'
    '00' <--「𠮷」
    '02' ★★
    '0B'
    'B7'
    '00' <--「田」
    '00' 
    '75'
    '30'

各文字の2バイトめ(★のところ)が、「𠮷」だけ2であることがわかります。
ここを抽出します。

%%%前のプログラムの続きです。

%𠮷田さんサーチ
dr=reshape(dum,[4,dlen/4]);%行列組み換え
yoshi=find((dr(2,:))>0);%2バイトめが0より大きいものを探す

%𠮷田さん表示
Xpos=(rem(yoshi-1,25)+1)*0.6875+0.3125;%位置調整
Ypos=22-ceil(yoshi/25);
text(Xpos,Ypos,'𠮷','Color','r');

実行します。
ヨシダさん2.jpg
見つかりました!

6.最後に

Simulink湯婆婆、とかもあるとよいですね。
チャレンジお願いします。
「やっぱSimulinkってすげーや。やりたいことがすぐ出来る」と思った方とか、ぜひ。

LTも、このくらいユルいのをやればよかったですね。楽だし。
当日、失敗作につき合わせてしまった運営の方々と参加者の皆さまにお詫び申し上げます。

では。

16
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
3