Chemistry-Harmonia
view release on metacpan or search on metacpan
lib/Chemistry/Harmonia.pm view on Meta::CPAN
for( my $i = 0; $i <= $n; $i++ ){
$cf->[$i + $n + 1] = $cf->[$i].$oxi; # add oxigen to { C H N P } -> { CO HO NO PO }
$cf->[$i] .= $z; # add 'o' to { C H N P } -> { Co Ho No Po }
}
}
sub _in_gf{
my($s, $maU, $maUl, $cf) = @_;
# Unary symbols of fragment
my @i_maU = grep $s =~ /$_/i, @$maU;
if( length($s) == 1 ){ # Unary atom symbol
@i_maU || return;
$_ .= $i_maU[0] for @$cf;
return 1;
}
# Double symbols of fragment
( my @i_maUl = grep $s =~ /$_/i, @$maUl ) || @i_maU || return; # not present
# Strings of unary and double atom letters
my $saU = join '', @i_maU; # String of unary atom letters
my $saUl = join '|', @i_maUl; # 1th - CAPITAL, 2th - small
my @w; # Anchor symbols
# Unique unary symbols (is not present in double)
for( @i_maU ){
lib/Chemistry/Harmonia.pm view on Meta::CPAN
if( length $z ){
$_ .= $z for @$cf;
return 1 if length($z) == length; # The end
s/^$z//;
return &_in_gf($_, \@i_maU, \@i_maUl, $cf) if 3 > length;
}
}
if( @w ){ # Search by fragments of anchor symbols
my $m = join '|', @w;
for my $f (split /($m)/, $s){
&_in_gf($f, \@i_maU, \@i_maUl, $cf);
if( $#{$cf} ){ # For >1 formula
# To leave the longest fragments
for( my $i = $#$cf; $i > 0; $i-- ){
splice @$cf, $i, 1 if length( $cf->[$i] ) < length( $cf->[0] );
}
}
}
return 1;
}
# Difficult fragment
my $cf_copy = [ @$cf ];
$#{$cf} = -1; # Reset
_M_gf_1: # Letter by letter search
for( my $i = 1; $i < length($s); $i++ ){
my $cf_new = [ @$cf_copy ];
for( $s =~ /^(\w{$i})(\w+)/ ){
&_in_gf($_, \@i_maU, \@i_maUl, $cf_new) || next _M_gf_1;
}
# To accumulate only unique, big fragments
for my $k ( @$cf_new ){
scalar( grep length($_) > length($k) || $_ eq $k, @$cf ) || push @$cf, $k;
}
}
return 1;
}
# Tactico-technical characteristics of chemical reaction.
# Return quantity hash (SAR):
( run in 3.661 seconds using v1.01-cache-2.11-cpan-364913b4093 )