Skip to content

Instantly share code, notes, and snippets.

@tateisu
Created August 15, 2012 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tateisu/3360557 to your computer and use it in GitHub Desktop.
Save tateisu/3360557 to your computer and use it in GitHub Desktop.
数式を徐々に変化させるプログラム
#!perl
use utf8;
use warnings;
# ノードにランダムアクセスするための配列
my @list = ();
# 配列にノードを追加してそのインデクスを返す
sub add_node($){
my($node)=@_;
push @list,$node;
return $#list;
}
# 配列中のノードを入れ替える
sub replace_node($$){
my($idx,$node)=@_;
$list[$idx] = $node;
}
# 葉となるノードを生成する
sub gen_leaf{
my $mode = int rand 3;
if($mode==0){
return add_node { operate => "idx" };
}elsif($mode==1){
return add_node { operate => "inum", value=>( int rand 10) };
}else{
return add_node { operate => "past", value=>( int rand 3) };
}
}
# 初期のツリー
my $root = gen_leaf();
# 適当に式を変形する
for( 1.. 10 ){
# 既存のノードのどれかをランダムに選ぶ
my $node_idx = int rand @list;
# そのノードを複製する
my $node_idx_clone = add_node( $list[ $node_idx] );
# そのノードを置き換える
my $mode = int rand 3;
if( $mode == 0 ){
# 定数項の付与
$node = { operate =>"add", left=> $node_idx_clone , right =>gen_leaf(), apply=>sub{ my($l,$r)=@_; return $l + $r } };
}elsif($mode==1){
# 乗算
$node = { operate =>"mul_inum", left=> $node_idx_clone , right =>gen_leaf(), apply=>sub{ my($l,$r)=@_; return $l * $r } };
}elsif($mode==2){
# 数値の桁数
$node = { operate =>"length", left=> $node_idx_clone , right =>gen_leaf(), apply=>sub{ my($l,$r)=@_; return length("".$l) * $r } };
}
replace_node( $node_idx , $node );
}
##############################
# 実際に式を評価してみる
sub solve_tree{
my($env,$node_idx) = @_;
my $node = $list[ $node_idx ];
return $node->{value} if $node->{operate} eq "inum";
return $env->{n} if $node->{operate} eq "idx";
if($node->{operate} eq 'past' ){
my $offset = $node->{value};
my $size = 0+@{ $env->{past}};
return 0 if $offset >=$size;
return $env->{past}[ $size - 1 - $offset ];
}
return $node->{apply}->( solve_tree($env,$node->{left}) ,solve_tree($env,$node->{right}) );
}
my $env = { past=>[] };
for my $idx (1..10){
$env->{n} = $idx;
my $v = solve_tree($env,$root);
push @{$env->{past}},$v;
print $v,",";
}
print "\n";
__END__
実行例
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment