For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > March 2006 > variables compare









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author variables compare
carlston88@gmail.com

2006-03-26, 9:57 pm

Hi, I'm quite new in PERL. There's this script I wanted to write to
compare the numbers to make sure there are no repetitions. It's
something like $a != $b != $c != $d.... Can you teach me how to do it
so that it can scale with any numbers of variables?

Thanks a lot!

MSG

2006-03-27, 3:57 am


carlston88@gmail.com wrote:
> Hi, I'm quite new in PERL. There's this script I wanted to write to
> compare the numbers to make sure there are no repetitions. It's
> something like $a != $b != $c != $d.... Can you teach me how to do it
> so that it can scale with any numbers of variables?
>
> Thanks a lot!


You can teach yourself by reading a book or the Perl documents.
To solve your problem, you need to have a basic understanding of
array and hash. To "scale with any numbers of variables", that is
what array is good at.

If you have written any code, please post it so people can help you.

Paul Lalli

2006-03-27, 7:57 am

carlston88@gmail.com wrote:
> Hi, I'm quite new in PERL. There's this script I wanted to write to
> compare the numbers to make sure there are no repetitions. It's
> something like $a != $b != $c != $d.... Can you teach me how to do it
> so that it can scale with any numbers of variables?


1) Declare a hash
2) begin a loop through all the numbers
2A) Check if the number exists as a key to the hash
2Aa) if so, you have a duplicate - handle this however you see fit
2Ab) otherwise, add the number to the hash, with an arbitrary value,
like 1
3) If you reach the end of the loop without ever getting 2Aa, you had
no duplicates.

Once you've written some code to implement this algorithm, let us know,
and we can help you debug it if it doesn't work.

If you need help even making an attempt, I suggest you start by reading
some documenation:
perldoc perlintro
perldoc perlsyn
perldoc perldata

Paul Lalli

carlston88@gmail.com

2006-03-27, 9:57 pm

Thanks a lot for your replies. Paul, you'd given me some ideas on how
to write it and this is the codes I wrote:

my %hash;
my @list = qw( good bad evil intelligent smart stupid good foolish
genius);
foreach my $i (@list) {
$hash{$i}++;
}
foreach my $key (%hash) {
$i = $hash{$key};
print $key if $i >= 2;
}

Please correct me if I'm not writing it in a correct manner. Thanks!

carlston88@gmail.com

2006-03-27, 9:57 pm

Sorry, I'd missed out something... I couldnt edit the post, so I would
have to repost. Please bear with my careless mistake.

my %hash;
my @list = qw( good bad evil intelligent smart stupid good foolish
genius);
foreach my $i (@list) {
$hash{$i}++;
}
foreach my $key (keys %hash) {
$i = $hash{$key};
print $key if ($i >= 2);
}

Paul Lalli

2006-03-28, 3:57 am

carlston88@gmail.com wrote:
> Sorry, I'd missed out something... I couldnt edit the post, so I would
> have to repost. Please bear with my careless mistake.
>
> my %hash;
> my @list = qw( good bad evil intelligent smart stupid good foolish
> genius);
> foreach my $i (@list) {
> $hash{$i}++;
> }
> foreach my $key (keys %hash) {
> $i = $hash{$key};
> print $key if ($i >= 2);
> }


Good first attempt. But there's really no reason for two separate
loops.

my %hash;
my @list = qw/good bad evil intelligent smart stupid good foolish
genius/;

#The following assumes you only want each duplicate printed once:
for my $elem (@list) {
$hash{$elem}++;
print $elem if $hash{$elem} == 2;
}

#Alternatively, the following prints each duplicate each time it's
duplicated:
for my $elem (@list) {
print $elem if $hash{$elem}++;
}

(Note that I changed your $i to $elem. $i is generally used for
integer indices, which you don't get with a foreach loop. Using that
mnemonic decreases readability of your code)

Paul Lalli

carlston88@gmail.com

2006-03-28, 3:58 am

Thanks a lot! Here's the program I'd written just for fun. Well, it was
a fun idea until I have to repeat the codes... Can you help me simplify
it? Basically it's a program that compares rows and columns of the
matrix. The matrices with no redundant values in rows and columns are
printed out. Here are the codes:

use strict;

my ($a1,$a2,$a3,$b1,$b2,$b3,$c1,$c2,$c3);

sub compare {
print "comparing $a1 $a2 $a3 $b1 $b2 $b3 $c1 $c2 $c3\n";
my @listA = ($a1,$a2,$a3);
my @listB = ($b1,$b2,$b3);
my @listC = ($c1,$c2,$c3);
my @list1 = ($a1,$b1,$c1);
my @list2 = ($a2,$b2,$c2);
my @list3 = ($a3,$b3,$c3);
my %hash = ();
my $trigger = 1;
for my $i (@listA) {
$hash{$i}++;
$trigger = 0 if $hash{$i} == 2;
}
%hash = ();
for my $i (@listB) {
$hash{$i}++;
$trigger = 0 if $hash{$i} == 2;
}
%hash = ();
for my $i (@listC) {
$hash{$i}++;
$trigger = 0 if $hash{$i} == 2;
}
%hash = ();
for my $i (@list2) {
$hash{$i}++;
$trigger = 0 if $hash{$i} == 2;
}
%hash = ();
for my $i (@list3) {
$hash{$i}++;
$trigger = 0 if $hash{$i} == 2;
}
write ANSWER if $trigger == 1;
}

format ANSWER =
@> @> @>
$a1,$a2,$a3
@> @> @>
$b1,$b2,$b3
@> @> @>
$c1,$c2,$c3
========
..

sub iterations {
for ($a1 = 1; $a1 <= 3; $a1++) {
for ($a2 = 1; $a2 <= 3; $a2++) {
for ($a3 = 1; $a3 <= 3; $a3++) {
for ($b1 = 1; $b1 <= 3; $b1++) {
for ($b2 = 1; $b2 <= 3; $b2++) {
for ($b3 = 1; $b3 <= 3; $b3++) {
for ($c1 = 1; $c1 <= 3; $c1++) {
for ($c2 = 1; $c2 <= 3; $c2++) {
for ($c3 = 1; $c3 <= 3; $c3++) {
&compare;
}
}
}
}
}
}
}
}
}
}

##--Main--#
open(ANSWER,">answer.txt");
&iterations;
print "Finished.\n"

I'm really very sorry that it's so long. I can't help it. I don't know
how to simplify it. Help me please!

Paul Lalli

2006-03-28, 6:57 pm

carlston88@gmail.com wrote:
> Thanks a lot! Here's the program I'd written just for fun. Well, it was
> a fun idea until I have to repeat the codes... Can you help me simplify
> it? Basically it's a program that compares rows and columns of the
> matrix. The matrices with no redundant values in rows and columns are
> printed out.


One of the things you should learn about Perl is that a *lot* of it has
already been written for you. You just have to find it and use it. In
this case, you should be looking at the Math::Combinatorics module on
CPAN (http://search.cpan.org). This module does the work of finding
all those permutations for you.

Using that module, here's a simplified solution to your stated problem.
Note that the three-by-three size of the matrices is hardcoded in. I'm
still working on generalizing the solution to arbitrary sizes....

#!/usr/bin/perl
use strict;
use warnings;

use Math::Combinatorics;

my @one = my @two = my @three = qw/a b c/;

#Loop through all possible permutations of the arrays
for my $one (permute(@one)){
for my $two (permute(@two)){
for my $three (permute(@three)){
print "@$one\n@$two\n@$three\n\n" if
compare_arrays($one, $two, $three);
}
}
}


#return true if all values passed in are unique
sub unique {
my %vals = map {$_ => 1 } @_;
return keys %vals == @_;
}

#return true if all "rows" and "columns" are unique
sub compare_arrays {
my ($x, $y, $z) = @_;
#compare rows
for my $ref ($x, $y, $z) {
return unless unique(@{$ref});
}
#compare columns
for my $i (0..$#{$x}){
return unless unique($x->[$i], $y->[$i], $z->[$i]);
}
return 1;
}

__END__

Paul Lalli

carlston88@gmail.com

2006-03-29, 3:57 am

Thank you very much, Paul. I'd spent the whole morning trying to
understand modules. It's really worth it. I can't really thank you
enough for guiding me.

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com