Перловые экзерсисы
Mar. 21st, 2007 10:43 amДля домашнего проекта поставил себе задачку: по форматной строке вида "Я [сразу|немедленно] [пошёл|поехал|пополз|попёрся] разбираться с [делами|братками]." сгенерировать полный список всех возможных вариантов такой строки. Посидел с карандашиком минут 20, наваял примерно такой код:
package Xtras::Mutator;
sub new {
my ($class,$pattern) = @_;
my $self = bless {}, $class;
$self->parse( $pattern ) if $pattern;
return $self;
}
sub parse {
my( $self, $pattern ) = @_;
$pattern =~ s/\%/%%/g;
$self->{pattern} = $pattern;
$self->{words} = [];
while( $self->{pattern} =~ s/\[(.*?)\]/%s/ )
{
push @{$self->{words}}, [ split /\|/, $1 ];
}
return $self->{words};
}
sub permutations {
return make_mutes( $_[0]->{pattern}, $_[0]->{words}, [] );
}
sub make_mutes {
my( $pat, $dict, $dat ) = @_;
return [ sprintf( $pat, @$dat ) ] unless scalar @$dict;
my @mutes = ();
my $words = shift @$dict;
push @mutes, @{ make_mutes( $pat, $dict, [ @$dat, $_ ] ) } for @$words;
unshift @$dict, $words;
return [ @mutes ];
}
Добравшись до компа, втоптал. И - заработало всего после двух исправлений. Старею видать... Надо посидеть помедитировать - можно ли всё это проще или изящнее изобразить? Всё-таки люблю я perl.
меня уже поправили (с pre)
Date: 2007-03-22 09:11 am (UTC)sub mutate { my (@m, $s, $w); while($s = pop@_) { if($s =~ /\[(.*?)\]/) { push @_, map { ($w = $s) =~ s/\[.*?\]/$_/; $w } split '\|', $1; } else { push @m, $s; } } return \@m; }Re: меня уже поправили (с pre)
Date: 2007-03-22 09:14 am (UTC)Всегда знал, что нет предела перловому совершенству!
вот тут с моим кодом играли
Date: 2007-03-22 09:20 am (UTC)угу
Date: 2007-03-22 10:07 pm (UTC)sub mutate {{ s/\[([^]|]*)\|?([^]]*)\]/$2 && push@_,$`."[$2]$'"; $1/e || return@_ for@_; redo }}Groking... 17%
Date: 2007-03-23 09:55 am (UTC)Но всё-же - какая же мощь и сила в Перле! Круче наверное только lisp да smalltalk, но там уже надо мозг напильником затачивать под них.
Re: угу
Date: 2007-03-23 10:34 am (UTC)всегда Ваша,
Крыша.
Re: меня уже поправили (с pre)
Date: 2008-02-27 08:33 am (UTC)