f (0) = 1 f (n) = n * f (n-1)
factorial (0) ->
one;
factorial (N) ->
N * factorial (N-1). #! / usr / bin / perl -I./lib
use strict ;
use bigint ;
use recurrent ;
recurrent fac => {
arg ( 0 ) => lambda { my ( $ n ) = @_ ; return 1 } ,
arg ( n ) => lambda { my ( $ n ) = @_ ; return $ n * fac ( $ n - 1 ) } ,
} ;
print fac ( 100 ) ;
package recurrent;
our $ VERSION = '0.01';
use base qw (Exporter);
use strict;
use Carp qw (confess);
our @EXPORT = qw (arg n lambda recurrent);
sub arg {shift} # returns the first argument
sub n {''} # returns an empty string
sub lambda (&) {shift} # alias for sub {}
sub recurrent ($$) {
my ($ name, $ mapping) = @_;
confess '$ name should be a string'
if ref ($ name) ne '' || $ name! ~ / ^ \ p {XID_Start} \ p {XID_Continue} * $ /;
confess '$ mapping should be a hash reference'
if ref ($ mapping) ne 'HASH';
confess 'no parametric function in recurrent relation'
if ref ($ mapping -> {(n ())}) ne 'CODE';
{
no strict 'refs';
# create cache and $ name function
my $ mem = join ('::', (caller ()) [0], "RECURRENT_CACHE_ $ name");
my $ fun = join ('::', (caller ()) [0], "$ name");
* {$ mem} = {};
* {$ fun} = sub {
my ($ _ n, $ _mapping) = ($ # _? $ _ [1]: $ _ [0], $ mapping);
confess "argument is required for $ name (n)"
if! defined $ _n;
# look for the value in the cache, if not then we calculate
defined ($ {* {$ mem}} -> {$ _ n})
? ($ {* {$ mem}} -> {$ _ n})
: ($ {* {$ mem}} -> {$ _ n} =
defined ($ _ mapping -> {$ _ n})
? do {local $ _ = $ _n; $ _mapping -> {$ _ n} -> ($ _ n)}
: do {local $ _ = $ _n; $ _mapping -> {(n)} -> ($ _ n)});
};
}
}
one;
#! / usr / bin / perl -I./lib
use strict ;
use bigint ;
use recurrent ;
# | f (0) = 0
# | f (1) = 1
# | f (n) = f (n-1) + f (n-2)
recurrent fib => {
arg ( 0 ) => lambda { my ( $ n ) = @_ ; return 0 } ,
arg ( 1 ) => lambda { my ( $ n ) = @_ ; return 1 } ,
arg ( n ) => lambda { my ( $ n ) = @_ ; return fib ( $ n - 1 ) + fib ( $ n - 2 ) } ,
} ;
print fib ( 100 ) ;
sub reduce ( & @ ) {
my ( $ f , $ z , @x ) = @_ ;
map {
local ( $ a , $ b ) = ( $ _ , $ z ) ;
$ z = $ f -> ( $ a , $ b ) ;
} @x ;
$ z ;
}
print reduce {$ a + $ b} map {fib ($ _)} 1..100;
#! / usr / bin / perl -I./lib
use utf8 ;
use strict ;
use bigint ;
use recurrent ;
sub λ ( & ) { shift }
# | Ć’ (0) = 0
# | Ć’ (1) = 1
# | Ć’ (n) = Ć’ (n-1) + (n-2)
recurrent Ć’ => {
( 0 ) => λ { 0 } ,
( 1 ) => λ { 1 } ,
( n ) => λ { ƒ ( $ _ - 1 ) + ƒ ( $ _ - 2 ) } ,
} ;
print Ć’ ( 100 ) ;
Source: https://habr.com/ru/post/169469/
All Articles