dankogaiさんの nested list comprehension のperl版に対抗(?)して、
eval() を使わない版を書いてみました。

# 2008-07-08 追記 コードが長いので続きに移動しました。

http://codepad.org/f2DsjilG

sub _comprehend_list_inner
{
  my @pairs = @_;
  my $dim = pop @pairs;
  my $cond_sub = pop @pairs;

  if (@pairs) {
    my ($start, $end) = splice @pairs, -2;
    my $next_sub = sub {
      my @list_ = @_;
      my $result_ = pop @list_;
      for my $i ( $start .. $end ) {
        my @next_list_ = @list_;
        push @next_list_, $i;
        push(@$result_, \@next_list_)
          if $cond_sub->(@next_list_, (@next_list_  $dim ? () : $result_)) &&
             @next_list_  $dim;
      }
      return @$result_;
    };
    return _comprehend_list_inner(@pairs, $next_sub, $dim);
  }

  # no pairs
  my $result_ = [];
  return $cond_sub->($result_);
}

sub comprehend_list
{
  my @pairs = @_;
  my $cond_sub = do {
    if ( ref($pairs[$#pairs]) =~ /^CODE/ ) {
      pop @pairs;
    }
    else {
      sub { 1 };
    }
  };
  die "ranges are not pairs" if (@pairs % 2);

  my $pairs_cnt = @pairs / 2;

  return _comprehend_list_inner(@pairs, $cond_sub, $pairs_cnt);
}

use Data::Dumper;
local $Data::Dumper::Terse = 1;
local $Data::Dumper::Indent = 0;

print Dumper(
  comprehend_list(
    0 => 9,
    0 => 9,
    sub { $_[0] + $_[1] == 5 && $_[0] > $_[1] }
  )
), "\n";
print Dumper(
  comprehend_list(
    0 => 4,
    0 => 4,
  )
);

普段curry化とか使わないから、若干頭がこんがらがってみたり..

トラックバック(0)

トラックバックURL: http://floralcompany.jp/mt/mt-tb.cgi/184

コメントする

AUTHOR

  • turugina (虎王 剱奈)
  • E-mail: turugina {at} floralcompany.jp
  • pixiv
  • PiXA

2011年4月

          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

アーカイブ

OpenID対応しています OpenIDについて
Powered by Movable Type 5.04

- 警 告 -

本サイトにはいわゆる「18禁画像」(イラスト)へのリンクが存在します。 未成年の方や、その手の画像に不快感を覚える方は、 該当記事(「えちぃの」及び「ちょっとえちぃの」カテゴリ) をご覧にならないようお願いいたします。

上記を理解した上で非表示のブログパーツを表示する
あわせて読みたいブログパーツ
ついった
drawr/pixiv/twitpic