semiprime_equationization.pl 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 09 July 2015
  5. # Website: https://github.com/trizen
  6. # Split a semiprime into a group of equations.
  7. use 5.016;
  8. use strict;
  9. use integer;
  10. use warnings;
  11. sub semiprime_equationization {
  12. my ($semiprime, $xlen, $ylen) = @_;
  13. $xlen -= 1;
  14. $ylen -= 1;
  15. my @map;
  16. my $mem = '0';
  17. my @result;
  18. my %vars;
  19. foreach my $j (0 .. $ylen) {
  20. foreach my $i (0 .. $xlen) {
  21. my $expr = '(' . join(' + ', "(x[$i] * y[$j])", grep { $_ ne '0' } $mem) . ')';
  22. $vars{"xy$i$j"} = $expr;
  23. my $n = "xy$i$j";
  24. if ($i == $xlen) {
  25. push @{$map[$j]}, "($n % 10)", "int($n / 10)";
  26. $mem = '0';
  27. }
  28. else {
  29. push @{$map[$j]}, "($n % 10)";
  30. $mem = "int($n / 10)";
  31. }
  32. }
  33. my $n = $ylen - $j;
  34. if ($n > 0) {
  35. push @{$map[$j]}, ((0) x $n);
  36. }
  37. my $m = $ylen - $n;
  38. if ($m > 0) {
  39. unshift @{$map[$j]}, ((0) x $m);
  40. }
  41. }
  42. my @number = reverse split //, $semiprime;
  43. my @mrange = (0 .. $#map);
  44. my %seen;
  45. my $initializer = sub {
  46. my ($str) = @_;
  47. while ($str =~ /\b(xy\d+)/g) {
  48. if (not $seen{$1}++) {
  49. my $init = "$1 = $vars{$1}";
  50. __SUB__->($init);
  51. push @result, $init;
  52. }
  53. }
  54. };
  55. foreach my $i (0 .. $#number) {
  56. my $expr = '(' . join(' + ', grep { $_ ne '0' } (map { $map[$_][$i] } @mrange), $mem) . ')';
  57. $initializer->($expr);
  58. push @result, "n$i = $expr";
  59. my $n = "n$i";
  60. if ($i == 0 or $i == $#number) {
  61. push @result, "$number[$i] = $n";
  62. $mem = '0';
  63. }
  64. else {
  65. push @result, "$number[$i] = ($n % 10)";
  66. $mem = "int($n / 10)";
  67. }
  68. }
  69. return @result;
  70. }
  71. # 71 * 43
  72. #say for semiprime_equationization('3053', 2, 2);
  73. # 251 * 197
  74. say for semiprime_equationization('49447', 3, 3);
  75. # 37975227936943673922808872755445627854565536638199 * 40094690950920881030683735292761468389214899724061
  76. #say for semiprime_equationization('1522605027922533360535618378132637429718068114961380688657908494580122963258952897654000350692006139', 50, 50);