recoder: (Default)
recoder ([personal profile] recoder) wrote2007-03-21 10:43 am
Entry tags:

Перловые экзерсисы

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

[identity profile] greshnik.livejournal.com 2007-03-21 09:39 am (UTC)(link)
Ну, алгоритм подбора всех возможных перестановок - не бином ньютона. Так что неудивительно, что заработало.

[identity profile] larubin.livejournal.com 2007-03-21 10:24 am (UTC)(link)
Т.е. бином Ньютона не заработал бы? ;)

[identity profile] russuv.livejournal.com 2007-03-21 10:52 am (UTC)(link)
помню дет так с десять назад, лежал в больнице и за неимение компа......
накатал на бумажке ;-) на ассмеблере пару листов....
при загнании в комп - на удивление все заработало.
че писал уже непомню.... но листинг был по длине достойный ;-)

цветной код

[identity profile] jerom.livejournal.com 2007-03-21 12:13 pm (UTC)(link)
#!/usr/bin/perl -l

$pattern = "Я [сразу|немедленно] [пошёл|поехал|пополз|попёрся] разбираться с [делами|братками].";

print "$_" for(@{mutate($pattern)});

sub mutate {
    my (@m, $s, $w);

    while($s = pop@_) {
        if($s =~ /\[(.*?)\]/) {

            for$w(split '\|',$1) {
                $_ = $s;

                s/\[(.*?)\]/$w/;
                push @_,$_;

            }
        } else {
            push @m, $s;

        }
    }
    return \@m;
}


[identity profile] greshnik.livejournal.com 2007-03-21 09:41 pm (UTC)(link)
Заработал бы. Но не сразу %)

Re: цветной код

[identity profile] larubin.livejournal.com 2007-03-22 09:05 am (UTC)(link)
Что скажешь, [livejournal.com profile] recoder?

меня уже поправили (с pre)

[identity profile] jerom.livejournal.com 2007-03-22 09:11 am (UTC)(link)
мне уже сказали, что надо быть проще и писать так:
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;
}

вот тут с моим кодом играли

[identity profile] jerom.livejournal.com 2007-03-22 09:20 am (UTC)(link)

угу

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

Re: угу

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

Re: меня уже поправили (с pre)

[identity profile] migmit.vox.com (from livejournal.com) 2008-02-27 08:33 am (UTC)(link)
quick and dirty:
> sequence_ $ map (putStrLn . concat) $ sequence $ either undefined id $ parse (many (liftM return (many1 $ noneOf "[")  <|> (between (char '[') (char ']') $ sepBy (many $ noneOf "]|") (char '|')))) "" "1[ab|c]2[qw|er|ty]"
1ab2qw
1ab2er
1ab2ty
1c2qw
1c2er
1c2ty