Re: Perl 'Medium' Quiz-of-the-Whatever for 2009-08-11 : Plusified Equations

Jeff Yoak <[email protected]> Wed, 07 Oct 2009 10:50:52 -0700
Newsgroups gmane.comp.lang.perl.qotw.discuss
Message-ID <[email protected]>
Somehow I missed the original statement of the problem, but these  
solutions, perhaps with a slight mod in some cases, could be used to  
solve the current problem at http://mathfactor.uark.edu/ .  As the  
poster of that particular problem, I can say that anyone who wanted to  
share code with a solution would be welcome.

Cheers,
Jeff

On Oct 7, 2009, at 9:55 AM, Ronald J Kimball wrote:

> Yay, the list is back.  Here's my solution.  I generate the plusified
> expressions iteratively by doing repeated increments, treating the
> expression itself as a binary string with '+' and '' representing 1  
> and 0:
>
>  s/(.*\d)(\d.*)/my $x = $2; $x =~ tr!+!!d; "$1+$x"/e
>
> To be more efficient, I don't store both sets of results.  First, I
> calculate and store the results for the second expression only.   
> Then, I
> generate results one at a time for the first expression, print any  
> matches
> immediately, and throw away the result.  This gives the correct  
> order of
> output without any sorting.
>
> #!perl
>
> use strict;
> use warnings;
>
> @ARGV == 2
>  or die usage();
>
> foreach (@ARGV) {
>  /^\d+\z/
>    or die usage();
> }
>
> my %p2;
>
> my ($p1, $p2) = @ARGV;
>
> do {
>  push @{ $p2{do_eval($p2)} }, $p2;
> } while ($p2 = next_plusify($p2));
>
> do {
>  if (my $match = $p2{do_eval($p1)}) {
>    print "$p1 = $_\n" for @$match;
>  }
> } while ($p1 = next_plusify($p1));
>
> sub next_plusify {
>  my ($exp) = @_;
>  $exp =~ s/(.*\d)(\d.*)/my $x = $2; $x =~ tr!+!!d; "$1+$x"/e
>    or return;
>  return $exp;
> }
>
> sub do_eval {
>  my ($exp) = @_;
>  $exp =~ s/\+0+(?=\d)/\+/g;
>  eval $exp;
> }
>
> sub usage {
>  return "$0 <int> <int>\n";
> }
>
> __END__
>
> Ronald