sivaratna has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I am so sorry as its my first posting I was not aware of these things. Thank you so much for these many suggestions. I don't want you guys to bother much about my real coding but, I am posting sample code with same problem. If I will be able to solve problem with this sample code then I can be able to do the same for my original code as well.

Here is my code: and the problem is: I am trying to match the $string1 by using permutations of LHS and RHS and then joining LHS and RHS to be able to match with my string. So, I have to apply permute on LHS and RHS. My first while loop(@res) is for LHS and then inner loop(@res1) is for RHS. It is taking only first iteration value from outer loop and taking all values from inner loop.

#! /usr/bin/perl use warnings; use strict; use Algorithm::Permute; my $string1="acbd = 4213"; my $alp = new Algorithm::Permute(['a'..'d']); my $num = new Algorithm::Permute(['1'..'4']); my (@res,@res1,$alp1,$alp2,$fin); while (@res = $alp->next){ $alp1=join('',@res); while(@res1 = $num->next){ $alp2 = join('',@res1); $fin = join('',$alp1,' = ',$alp2); print"$fin\n"; if($fin eq $string1){ print"String exists"; } } }
OUTPUT:
dcba = 4321 dcba = 3421 dcba = 3241 dcba = 3214 dcba = 4231 dcba = 2431 dcba = 2341 dcba = 2314 dcba = 4213 dcba = 2413 dcba = 2143 dcba = 2134 dcba = 4312 dcba = 3412 dcba = 3142 dcba = 3124 dcba = 4132 dcba = 1432 dcba = 1342 dcba = 1324 dcba = 4123 dcba = 1423 dcba = 1243 dcba = 1234

As you can see its taking only one iteration from LHS i.e., outer loop and taking all values from inner loop. I want it to take all possible values for RHS i.e., outer while loop as well.

I think I am clear and my question is clear. Please let me know if you need any clarifications.

Thank you so much for all your invaluable suggestions. Please help he with this....awaiting for your awesome replies...

Replies are listed 'Best First'.
Re: nested while loops
by stevieb (Canon) on Jun 22, 2015 at 18:02 UTC

    You have a *lot* of syntax issues that you'd see if you put

    use warnings; use strict;

    at the top of your script. Also, when I do correct the errors, I'm not sure what to expect as output. Where are @prdct and @prdct1 defined?

    Please put your code in <code></code> tags as Laurent_R stated, use proper indentation, show us what the two arrays I mentioned above should have in them, and what exactly you expect as output.

    -stevieb

Re: nested while loops
by Laurent_R (Canon) on Jun 22, 2015 at 19:06 UTC
    Thank you, sivaratna, for having updated your post with code tags. This is now much more legible.

    We really need some information about the contents of the @prdct and @prdct1 arrays to figure out what you are trying to do and why, as you state, you're not entering the inner while loop.

    I agree with stevieb that you should have:

    use strict; use warnings;
    at the top of your program and declare all the variables that you are using (using the my built-in).

    Although this is not your main problem, please note that:

    for ( $i = 0 ; $i <= $#res ; $i++ ) {
    can be written in a more idiomatic way:
    for my $i (0..$#res) {
    or even better:
    for my $thing (@res) {
    but it is not clear to me if this latter version would work in you specific case.

    Also, you don't need:

    else { }
    If you don't need an else clause, just don't put it.

    But these are minor things, please let us know what data you have as input and want you want to do with it. We need that to better help you.

Re: nested while loops
by NetWallah (Canon) on Jun 22, 2015 at 19:05 UTC
    Here is what I think you are trying to do (Test data added, but code is untested).
    use strict; use warnings; use Algorithm::Permute; my @prdct = 55..66; my @prdct1 = 'a'..'f'; my $product = Algorithm::Permute->new( \@prdct ); my $product1 = Algorithm::Permute->new( \@prdct1 ); while ( my @res = $product->next ) { chomp @res; my $chk = join " + ", @res; print "chk:$chk\n"; $product1->reset; # Allow to iterate again while (my @res1 = $product1->next ) { chomp @res1; my $chk1 = join( ' + ', @res1); print "\tchk1:$chk1\n"; my $chk3 = "$chk <=> $chk1"; my $chk4 = "$chk1 <=> $chk"; } }

            "Despite my privileged upbringing, I'm actually quite well-balanced. I have a chip on both shoulders."         - John Nash

      Hey this " $product1->reset; # Allow to iterate again" suggested by NetWallah worked perfectly for my problem. Thanks a ton :) :)

      BTW how to close this or vote for this answer or mark as solved???

        I'm not sure you have enough XP to vote. You should be able to edit the title of the original question, though, adding a [SOLVED] notice - at least, that's what some people here do.
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: nested while loops
by 1nickt (Canon) on Jun 22, 2015 at 19:13 UTC

    Hi Sivaratna,

    1) ALWAYS "use strict;" and "use warnings;" These pragmas will reveal a lot of errors, and unexpected situations, like for example a variable being empty when you expected it to have a value, because you'll get a warning about it being "uninitialized" -- this will tip you off to where the problem is.

    2) Learn to use the Data::Dumper module as you develop your code. Then you can liberally use debugging statements that will show what is in the variables at each step of your program, rather than just waiting until the end to see whether or not it failed. Like this:

    #!perl use strict; use warnings; use feature qw/ say /; use Data::Dumper; use Algorithm::Permute; ## Some code here that produces @prdct ... my $product = Algorithm::Permute->new( \@prdct ); say Dumper( $product ); # did you get what you expected? while ( my @res = $product->next ) { say Dumper( @res ); # now did you get what you expected? # do something else ... }

    Remember, laziness is a virtue for a programmer, but laziness may not be what you think it is! Put in the work to make your code pass through strict, warnings, Perl::Critic, and so on, and put in the work to add debugging info and testing, and your life will be easier as you go forward!!

Re: nested while loops
by Laurent_R (Canon) on Jun 22, 2015 at 17:49 UTC
    Hi sivaratna

    Please put your code between <code> and </code> tags in order to preserve the formatting (especially code indentation which I hope that you are using). Right now, your code is very difficult to read, especially when it comes to nested loops.