recoder: (Default)
[personal profile] recoder

Для домашнего проекта поставил себе задачку: по форматной строке вида "Я [сразу|немедленно] [пошёл|поехал|пополз|попёрся] разбираться с [делами|братками]." сгенерировать полный список всех возможных вариантов такой строки. Посидел с карандашиком минут 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.

perl coding

угу

Date: 2007-03-22 10:07 pm (UTC)
From: [identity profile] jerom.livejournal.com
[livejournal.com profile] gone_one:
sub mutate {{
    s/\[([^]|]*)\|?([^]]*)\]/$2 && push@_,$`."[$2]$'"; $1/e || return@_ for@_;
    redo
}}

Re: угу

Date: 2007-03-23 10:34 am (UTC)
From: [identity profile] mcsdwarken.livejournal.com
до свиданья!
всегда Ваша,
Крыша.

December 2024

S M T W T F S
1234567
891011121314
15161718192021
22232425 262728
293031    

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Feb. 2nd, 2026 11:07 am
Powered by Dreamwidth Studios