![]() |
|< 1 2 >| | ![]() |
20 Einträge, 2 Seiten |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/perl
use strict;
use warnings;
my $operators = {
'+' => sub { my $i=shift @_; $i += $_ for @_; return $i },
'-' => sub { my $i=shift @_; $i -= $_ for @_; return $i },
'*' => sub { my $i=shift @_; $i *= $_ for @_; return $i },
'/' => sub { my $i=shift @_; $i /= $_ for @_; return $i },
};
my $task = "/ 12 2 2";
print solve($task), "\n";
exit;
sub solve {
my $to_solve = shift @_ || die "solve(): no parameter\n";
my ($op, @vals) = split /\s+/, $to_solve;
die "solve(): wrong operator or to less values"
unless (exists $operators->{$op} && $#vals >= 1);
return $operators->{$op}(@vals);
}
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#!/usr/bin/perl
use strict;
use warnings;
#use Data::Dumper;
my $operators = {
'+' => sub { my $i = shift @_; $i += $_ for @_; return $i },
'-' => sub { my $i = shift @_; $i -= $_ for @_; return $i },
'*' => sub { my $i = shift @_; $i *= $_ for @_; return $i },
'/' => sub { my $i = shift @_; $i /= $_ for @_; return $i },
};
my $task = "( + 3 4 ( * 2 7 ( + 1 1 ) ) ( / 6 2 ) )";
print calculate( split /\s+/, $task ), "\n";
exit;
sub solve {
my ( $op, @vals ) = @_;
die "solve(): wrong operator or to less values"
unless ( exists $operators->{$op} && $#vals >= 1 );
return $operators->{$op}(@vals);
}
sub calculate {
my @ops = @_;
@ops = @ops[ 1 .. $#ops - 1 ]
if $ops[0] eq '('
and $ops[-1] eq ')'; # remove leading and trailing brackets
my $marker = -1;
my $begin = undef;
my $end = undef;
my @marked = ();
for ( 0 .. $#ops ) {
$begin = $_ if $ops[$_] eq '(' && ++$marker == 0;
$end = $_ if $ops[$_] eq ')' && $marker-- == 0;
if ( defined $begin && defined $end ) {
push @marked, { begin => $begin,
end => $end }; # find balanced brackets on this level
$marker = -1;
$begin = undef;
$end = undef;
}
}
while (@marked) {
my $current = pop @marked;
splice @ops, $current->{begin}, # recursively solve inner brackets
$current->{end} - $current->{begin} + 1,
calculate( @ops[ $current->{begin} .. $current->{end} ] );
}
#print Dumper \@ops;
return solve(@ops);
}
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
#!/usr/bin/perl use strict; my $debug= 0; my $lisp= ""; # # S -> ( Op Opd* ) # Op -> + | * | - | / # Opd -> S | Number # my @tokens; my $pos= 0; sub lisp { print "lisp_eval [$pos] token [$tokens[$pos]]\n" if $debug; # throw away ( $pos ++; my $op= $tokens[$pos++]; my @operands= (); while( $pos < scalar( @tokens ) ) { last if( $tokens[$pos] eq ")" ); push @operands, operand(); } return [$op, @operands]; } sub operand { print "operand_eval [$pos] token [$tokens[$pos]]\n" if $debug; my $next= $tokens[$pos]; if( $next =~ m/\d+/ ) { $pos ++; return $next; } else { return lisp(); } } sub rewrite_perl { my @root= @{ shift() }; my $op= $root[0]; my @opds= (); foreach( 1 .. @root - 1 ) { if( ref $root[$_] eq "ARRAY" ) { push @opds, rewrite_perl( $root[$_] ); } else { push @opds, $root[$_]; } } my $code= $opds[0]; foreach( 1 .. @opds - 1 ) { $code= "( $code $op $opds[$_] )"; } return $code; } sub myread { $pos= 0; my $line= <STDIN>; @tokens= split /\s+/, $line; } LOOP: print eval ( rewrite_perl lisp( myread ) ), $/; goto LOOP;
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
#!/user/bin/perl
use strict;
use warnings;
use Parse::RecDescent;
my $parser = new Parse::RecDescent (q(
{
my $operators = {
'+' => sub { my $i = shift @_; $i += $_ for @_; return $i },
'-' => sub { my $i = shift @_; $i -= $_ for @_; return $i },
'*' => sub { my $i = shift @_; $i *= $_ for @_; return $i },
'/' => sub { my $i = shift @_; $i /= $_ for @_; return $i },
};
}
line: paren /^\Z/
{ $item[1] }
paren: '(' op arg arg(s) ')'
{ $operators->{$item[2]}->($item[3], @{$item[4]}) }
op: '+' | '-' | '*' | '/'
arg: paren | /^[+-]?(?:\d+|\d*\.\d+)/
));
my $task = "(+3 4(*2 7(+1 -1))(/6 2))";
my $calc = $parser->line($task) || die "Syntax error in $task\n";
print $calc, $/;
op: /[-+*\/](?!\d)/
Quote# S -> ( Op Opd* )
# Op -> + | * | - | /
# Opd -> S | Number
![]() |
|< 1 2 >| | ![]() |
20 Einträge, 2 Seiten |