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