*ズンドコキヨシ [#ua856f42]
ズンドコキヨシまとめ ~
http://qiita.com/shunsugai@github/items/971a15461de29563bf90

というわけで自分もPerlで書いてみた。

-アルゴリズムとしては、状態遷移グラフによる実装。~
多分[[この人の実装>http://qiita.com/shunsugai@github/items/971a15461de29563bf90]]とかとおなじような感じ。

-このPerlスクリプト自体はデータを標準入力から読み込むようになっているのでコード冒頭のコメントにもあるように、別のコマンドでランダムな文字列を生成し、パイプで食わせる。~
...この方法の方がデバッグがやりやすいため。

-とりあえず動くバージョンができあがった後で、オブジェクト指向にコーディングしなおした。

-せっかくオブジェクト指向に実装したので、インスタンスをもう一つ追加。~
「デンデケデケデケ」がくると「\タ・ケ・シ!/」と表示して終了。「\タ・ケ・シ!/」は、勿論エレキギター奏者の寺内タケシ氏。

-個々のオブジェクトは、自分と関係のない単語は無視するようになっている。~
例えば、$takeshiオブジェクトは、「デンデケデケデケ」の中に、自分とは関係のない「ズン」や「ドコ」が挟まっていてもそれらは無視され、例えば「デンデケズンデケドコデケ」となっていても「\タ・ケ・シ!/」と反応する。

以下コードと実行例

コード;
 #!/usr/bin/perl
 
 # Usage: jot -r 1000 1 4 | sed -e 's/1/ズン/; s/2/ドコ/; s/3/デン/; s/4/デケ/;' | ./zdk.pl
 
 { # 状態遷移グラフを実装するクラス StateGraph
   package StateGraph;
 
   # コンストラクタ
   #
   sub new {
     my $self = shift;
     bless {stat => 0,    # 現在の状態を保持
            stg  => [],   # 状態グラフ
            word => {}},  # 自分に関係のある単語
           $self;
   }
 
   # 状態を追加するメソッド
   #
   sub addstate {
     my $self = shift;
     my $from = shift;  # ノードの状態番号
     $self->{stg}[$from] = {tok  => shift,  # 比較する単語
                            eqto => shift,  # 単語が合致した場合に遷移する状態番号
                            neto => shift,  # 単語が合致しない場合に遷移する状態番号
                            proc => shift}; # 単語が合致した場合に実行されるコード
     $self->{word}{$self->{stg}[$from]{tok}}++; # 語彙を登録
   }
 
   # 状態を遷移するメソッド
   #
   sub transfer {
     my $self = shift;
     my $token = shift; # 与えられた単語
 
     # 知らない単語は無視 → 状態を遷移しない
     return unless $self->{word}{$token};
 
     # 次の状態への遷移先を決定し、遷移
     if ($self->{stg}[$self->{stat}]{tok} eq $token) {
       $self->{stg}[$self->{stat}]{proc}();
       $self->{stat} = $self->{stg}[$self->{stat}]{eqto};
     } else {
       $self->{stat} = $self->{stg}[$self->{stat}]{neto};
     }
   }
 }
 
 # kiyoshiオブジェクトの生成と
 # 状態遷移グラフの作成
 #
 my $kiyoshi = StateGraph->new();
 $kiyoshi->addstate(0, 'ズン', 1, 0, sub{});
 $kiyoshi->addstate(1, 'ズン', 2, 0, sub{});
 $kiyoshi->addstate(2, 'ズン', 3, 0, sub{});
 $kiyoshi->addstate(3, 'ズン', 4, 0, sub{});
 $kiyoshi->addstate(4, 'ドコ', 0, 0, sub{print "\キ・ヨ・シ!/\n"; exit 0;});
 
 # takeshiオブジェクトの生成と
 # 状態遷移グラフの作成
 #
 my $takeshi = StateGraph->new();
 $takeshi->addstate(0, 'デン', 1, 0, sub{});
 $takeshi->addstate(1, 'デケ', 2, 0, sub{});
 $takeshi->addstate(2, 'デケ', 3, 0, sub{});
 $takeshi->addstate(3, 'デケ', 0, 0, sub{print "\タ・ケ・シ!/\n"; exit 0;});
 
 # メインループ
 #
 while (<>) {
   foreach $token (/ズン|ドコ|デン|デケ/g) {
     print $token;
     $kiyoshi->transfer($token);
     $takeshi->transfer($token);
   }
 }
 print "\n";

実行例;
 $ cat ./zdk.sh
 #!/bin/sh
  
 jot -r 1000 1 4 | sed -e 's/1/ズン/; s/2/ドコ/; s/3/デン/; s/4/デケ/;' | ./zdk.pl
  
 $ ./zdk.sh
 デケドコドコズンズンズンドコデケデケデンズンドコデンデンデケデンデンドコデンドコズンドコドコデケデケ
 ドコドコデケデケデンズンズンデンデケデケデンドコドコズンドコデケドコデンズンデンデンデケドコドコデン
 デケデンデケズンズンズンデケデンズンドコ\キ・ヨ・シ!/
 
 $ ./zdk.sh
 ズンドコズンデンドコズンデンデンズンデンデンドコズンデンデケデンドコデケデケデンドコズンドコズンデケ
 デケデンドコデケデケドコデンデケデケデンデケデンドコデンズンデンドコデンズンズンデンドコドコドコデン
 ドコデンデンデケドコドコデンデケデケデンドコドコドコデンデンデンデケズンズンドコズンズンドコドコズン
 ドコデンデンズンドコドコドコデンドコドコデンズンドコデンドコデケズンドコズンズンデケデケ\タ・ケ・シ!/
  
 $

Top Index Search Recent Backups  Help  RSS