my @a = map ord, split //, ""; my @b; while(@a){ $#a or unshift @b, @a and last; my $c = shift @a; # ($_+$&)/2; my $d = shift @a; # ($_-$&)/2; unshift @b, $c - $d; # $& push @a, $c + $d; # $_ } unshift @b, undef; $_ = join "+",@b; s/\+-/-/g; s/[3-9][0-9]/($&>=32&&$&!=43&&$&!=45&&$&<48||$&>=58?chr $&:$&)/eg; s/1[0-2][0-9]/($&<127?chr $&:$&)/eg; print "$_\n";