Perl: Final Output Line in Foreach Loop Prints Twice










1















I'm trying to write a very simple script that takes two words from STDIN and outputs TRUE if they're anagrams and FALSE if not. My main issue is that if the two words aren't anagrams (this is the final "else" statement in the script), the output looks like:



Sorry, that's not an anagram pair
Sorry, that's not an anagram pair



where I just want:



Sorry, that's not an anagram pair



Other, more minor issues for the especially generous:



  • I know what the FALSE values are for Perl, but I can't get the script to print FALSE by, for example, setting a variable to '' or 0, etc. or saying "return ''". Ideally, I wouldn't have to put "print TRUE/FALSE" in the script at all.

  • I put in the last elsif statement in the script to see if it would affect the printing twice problem. It didn't, and now I'm curious why my m// expression doesn't work. It's supposed to find pairs that are identical except that one has more whitespace than the other.

Here's the script! I'm sorry it's so long - again, the problem is at the very end with the final "else" statement. Many thanks!!!



#To Run: Type start.pl on the command line.
#The script should prompt you to enter a word or phrase.
#Once you've done that, it'll prompt you for another one.
#Then you will be told if the two terms are anagrams or not.

#!/usr/bin/perl -w
use strict;

#I have to use this to make STDIN work. IDK why.

$|=1;

#variables

my $aWord;
my $bWord;
my $word;
my $sortWord;
my $sortWords;
my @words;
my %anaHash;

print "nReady to play the anagram game? Excellent.nnType your first word or phrase, then hit Enter.nn";

$aWord = <STDIN>;
chomp $aWord;

print "nnThanks! Now type your second word or phrase and hit Enter.nn";

$bWord = <STDIN>;
chomp $bWord;

#This foreach loop performs the following tasks:

#1. Pushes the two words from STDIN into an array (unsure if this is really necessary)
#2. lowercases everything and removes all characters except for letters & spaces
#3. splits both words into characters, sorts them alphabetically, then joins the sorted letters into a single "word"
#4.pushes the array into a hash

@words = ($bWord, $aWord);
foreach $word (@words)
$word =~ tr/A-Z/a-z/;
$word =~ s/[^a-z ]//ig;
$sortWord = join '', sort(split(//, $word));
push @$anaHash$sortWord, $word;


#This foreach loop tries to determine if the word pairs are anagrams or not.

foreach $sortWords (values %anaHash)









share|improve this question






















  • How many times does that last foreach loop run?

    – Shawn
    Nov 11 '18 at 7:54











  • When you supply different words your hash will have two keys (one for each $sortWord) and each key will have only one value in its arrayref. So both if and the first elsif are false; in the last elsif you end up matching that one word to itself but with spaces -- it fails. So you wind up in the else, for both words.

    – zdim
    Nov 11 '18 at 7:58











  • There is no "FALSE" or such value in Perl; if you want that you print it. (There are 0 and empty string '' and undef. If you attempt to print a variable which is undef you'll get a warning.) I don't see how a script would know what to print.

    – zdim
    Nov 11 '18 at 8:05












  • @zdim, thanks so much, that's exactly what I figured was happening. Any suggestions on how to get it to NOT happen? Like saying "else only look at one of the variables; print "blah blah";

    – ScarletRoxanne
    Nov 11 '18 at 8:13











  • Oh, right: If the words are same or anagrams your hash will have one key, if they aren't it will have more than one key -- in which case you don't need this analysis. So check that first.

    – zdim
    Nov 11 '18 at 8:15
















1















I'm trying to write a very simple script that takes two words from STDIN and outputs TRUE if they're anagrams and FALSE if not. My main issue is that if the two words aren't anagrams (this is the final "else" statement in the script), the output looks like:



Sorry, that's not an anagram pair
Sorry, that's not an anagram pair



where I just want:



Sorry, that's not an anagram pair



Other, more minor issues for the especially generous:



  • I know what the FALSE values are for Perl, but I can't get the script to print FALSE by, for example, setting a variable to '' or 0, etc. or saying "return ''". Ideally, I wouldn't have to put "print TRUE/FALSE" in the script at all.

  • I put in the last elsif statement in the script to see if it would affect the printing twice problem. It didn't, and now I'm curious why my m// expression doesn't work. It's supposed to find pairs that are identical except that one has more whitespace than the other.

Here's the script! I'm sorry it's so long - again, the problem is at the very end with the final "else" statement. Many thanks!!!



#To Run: Type start.pl on the command line.
#The script should prompt you to enter a word or phrase.
#Once you've done that, it'll prompt you for another one.
#Then you will be told if the two terms are anagrams or not.

#!/usr/bin/perl -w
use strict;

#I have to use this to make STDIN work. IDK why.

$|=1;

#variables

my $aWord;
my $bWord;
my $word;
my $sortWord;
my $sortWords;
my @words;
my %anaHash;

print "nReady to play the anagram game? Excellent.nnType your first word or phrase, then hit Enter.nn";

$aWord = <STDIN>;
chomp $aWord;

print "nnThanks! Now type your second word or phrase and hit Enter.nn";

$bWord = <STDIN>;
chomp $bWord;

#This foreach loop performs the following tasks:

#1. Pushes the two words from STDIN into an array (unsure if this is really necessary)
#2. lowercases everything and removes all characters except for letters & spaces
#3. splits both words into characters, sorts them alphabetically, then joins the sorted letters into a single "word"
#4.pushes the array into a hash

@words = ($bWord, $aWord);
foreach $word (@words)
$word =~ tr/A-Z/a-z/;
$word =~ s/[^a-z ]//ig;
$sortWord = join '', sort(split(//, $word));
push @$anaHash$sortWord, $word;


#This foreach loop tries to determine if the word pairs are anagrams or not.

foreach $sortWords (values %anaHash)









share|improve this question






















  • How many times does that last foreach loop run?

    – Shawn
    Nov 11 '18 at 7:54











  • When you supply different words your hash will have two keys (one for each $sortWord) and each key will have only one value in its arrayref. So both if and the first elsif are false; in the last elsif you end up matching that one word to itself but with spaces -- it fails. So you wind up in the else, for both words.

    – zdim
    Nov 11 '18 at 7:58











  • There is no "FALSE" or such value in Perl; if you want that you print it. (There are 0 and empty string '' and undef. If you attempt to print a variable which is undef you'll get a warning.) I don't see how a script would know what to print.

    – zdim
    Nov 11 '18 at 8:05












  • @zdim, thanks so much, that's exactly what I figured was happening. Any suggestions on how to get it to NOT happen? Like saying "else only look at one of the variables; print "blah blah";

    – ScarletRoxanne
    Nov 11 '18 at 8:13











  • Oh, right: If the words are same or anagrams your hash will have one key, if they aren't it will have more than one key -- in which case you don't need this analysis. So check that first.

    – zdim
    Nov 11 '18 at 8:15














1












1








1








I'm trying to write a very simple script that takes two words from STDIN and outputs TRUE if they're anagrams and FALSE if not. My main issue is that if the two words aren't anagrams (this is the final "else" statement in the script), the output looks like:



Sorry, that's not an anagram pair
Sorry, that's not an anagram pair



where I just want:



Sorry, that's not an anagram pair



Other, more minor issues for the especially generous:



  • I know what the FALSE values are for Perl, but I can't get the script to print FALSE by, for example, setting a variable to '' or 0, etc. or saying "return ''". Ideally, I wouldn't have to put "print TRUE/FALSE" in the script at all.

  • I put in the last elsif statement in the script to see if it would affect the printing twice problem. It didn't, and now I'm curious why my m// expression doesn't work. It's supposed to find pairs that are identical except that one has more whitespace than the other.

Here's the script! I'm sorry it's so long - again, the problem is at the very end with the final "else" statement. Many thanks!!!



#To Run: Type start.pl on the command line.
#The script should prompt you to enter a word or phrase.
#Once you've done that, it'll prompt you for another one.
#Then you will be told if the two terms are anagrams or not.

#!/usr/bin/perl -w
use strict;

#I have to use this to make STDIN work. IDK why.

$|=1;

#variables

my $aWord;
my $bWord;
my $word;
my $sortWord;
my $sortWords;
my @words;
my %anaHash;

print "nReady to play the anagram game? Excellent.nnType your first word or phrase, then hit Enter.nn";

$aWord = <STDIN>;
chomp $aWord;

print "nnThanks! Now type your second word or phrase and hit Enter.nn";

$bWord = <STDIN>;
chomp $bWord;

#This foreach loop performs the following tasks:

#1. Pushes the two words from STDIN into an array (unsure if this is really necessary)
#2. lowercases everything and removes all characters except for letters & spaces
#3. splits both words into characters, sorts them alphabetically, then joins the sorted letters into a single "word"
#4.pushes the array into a hash

@words = ($bWord, $aWord);
foreach $word (@words)
$word =~ tr/A-Z/a-z/;
$word =~ s/[^a-z ]//ig;
$sortWord = join '', sort(split(//, $word));
push @$anaHash$sortWord, $word;


#This foreach loop tries to determine if the word pairs are anagrams or not.

foreach $sortWords (values %anaHash)









share|improve this question














I'm trying to write a very simple script that takes two words from STDIN and outputs TRUE if they're anagrams and FALSE if not. My main issue is that if the two words aren't anagrams (this is the final "else" statement in the script), the output looks like:



Sorry, that's not an anagram pair
Sorry, that's not an anagram pair



where I just want:



Sorry, that's not an anagram pair



Other, more minor issues for the especially generous:



  • I know what the FALSE values are for Perl, but I can't get the script to print FALSE by, for example, setting a variable to '' or 0, etc. or saying "return ''". Ideally, I wouldn't have to put "print TRUE/FALSE" in the script at all.

  • I put in the last elsif statement in the script to see if it would affect the printing twice problem. It didn't, and now I'm curious why my m// expression doesn't work. It's supposed to find pairs that are identical except that one has more whitespace than the other.

Here's the script! I'm sorry it's so long - again, the problem is at the very end with the final "else" statement. Many thanks!!!



#To Run: Type start.pl on the command line.
#The script should prompt you to enter a word or phrase.
#Once you've done that, it'll prompt you for another one.
#Then you will be told if the two terms are anagrams or not.

#!/usr/bin/perl -w
use strict;

#I have to use this to make STDIN work. IDK why.

$|=1;

#variables

my $aWord;
my $bWord;
my $word;
my $sortWord;
my $sortWords;
my @words;
my %anaHash;

print "nReady to play the anagram game? Excellent.nnType your first word or phrase, then hit Enter.nn";

$aWord = <STDIN>;
chomp $aWord;

print "nnThanks! Now type your second word or phrase and hit Enter.nn";

$bWord = <STDIN>;
chomp $bWord;

#This foreach loop performs the following tasks:

#1. Pushes the two words from STDIN into an array (unsure if this is really necessary)
#2. lowercases everything and removes all characters except for letters & spaces
#3. splits both words into characters, sorts them alphabetically, then joins the sorted letters into a single "word"
#4.pushes the array into a hash

@words = ($bWord, $aWord);
foreach $word (@words)
$word =~ tr/A-Z/a-z/;
$word =~ s/[^a-z ]//ig;
$sortWord = join '', sort(split(//, $word));
push @$anaHash$sortWord, $word;


#This foreach loop tries to determine if the word pairs are anagrams or not.

foreach $sortWords (values %anaHash)






perl output repeating






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 11 '18 at 7:42









ScarletRoxanneScarletRoxanne

84




84












  • How many times does that last foreach loop run?

    – Shawn
    Nov 11 '18 at 7:54











  • When you supply different words your hash will have two keys (one for each $sortWord) and each key will have only one value in its arrayref. So both if and the first elsif are false; in the last elsif you end up matching that one word to itself but with spaces -- it fails. So you wind up in the else, for both words.

    – zdim
    Nov 11 '18 at 7:58











  • There is no "FALSE" or such value in Perl; if you want that you print it. (There are 0 and empty string '' and undef. If you attempt to print a variable which is undef you'll get a warning.) I don't see how a script would know what to print.

    – zdim
    Nov 11 '18 at 8:05












  • @zdim, thanks so much, that's exactly what I figured was happening. Any suggestions on how to get it to NOT happen? Like saying "else only look at one of the variables; print "blah blah";

    – ScarletRoxanne
    Nov 11 '18 at 8:13











  • Oh, right: If the words are same or anagrams your hash will have one key, if they aren't it will have more than one key -- in which case you don't need this analysis. So check that first.

    – zdim
    Nov 11 '18 at 8:15


















  • How many times does that last foreach loop run?

    – Shawn
    Nov 11 '18 at 7:54











  • When you supply different words your hash will have two keys (one for each $sortWord) and each key will have only one value in its arrayref. So both if and the first elsif are false; in the last elsif you end up matching that one word to itself but with spaces -- it fails. So you wind up in the else, for both words.

    – zdim
    Nov 11 '18 at 7:58











  • There is no "FALSE" or such value in Perl; if you want that you print it. (There are 0 and empty string '' and undef. If you attempt to print a variable which is undef you'll get a warning.) I don't see how a script would know what to print.

    – zdim
    Nov 11 '18 at 8:05












  • @zdim, thanks so much, that's exactly what I figured was happening. Any suggestions on how to get it to NOT happen? Like saying "else only look at one of the variables; print "blah blah";

    – ScarletRoxanne
    Nov 11 '18 at 8:13











  • Oh, right: If the words are same or anagrams your hash will have one key, if they aren't it will have more than one key -- in which case you don't need this analysis. So check that first.

    – zdim
    Nov 11 '18 at 8:15

















How many times does that last foreach loop run?

– Shawn
Nov 11 '18 at 7:54





How many times does that last foreach loop run?

– Shawn
Nov 11 '18 at 7:54













When you supply different words your hash will have two keys (one for each $sortWord) and each key will have only one value in its arrayref. So both if and the first elsif are false; in the last elsif you end up matching that one word to itself but with spaces -- it fails. So you wind up in the else, for both words.

– zdim
Nov 11 '18 at 7:58





When you supply different words your hash will have two keys (one for each $sortWord) and each key will have only one value in its arrayref. So both if and the first elsif are false; in the last elsif you end up matching that one word to itself but with spaces -- it fails. So you wind up in the else, for both words.

– zdim
Nov 11 '18 at 7:58













There is no "FALSE" or such value in Perl; if you want that you print it. (There are 0 and empty string '' and undef. If you attempt to print a variable which is undef you'll get a warning.) I don't see how a script would know what to print.

– zdim
Nov 11 '18 at 8:05






There is no "FALSE" or such value in Perl; if you want that you print it. (There are 0 and empty string '' and undef. If you attempt to print a variable which is undef you'll get a warning.) I don't see how a script would know what to print.

– zdim
Nov 11 '18 at 8:05














@zdim, thanks so much, that's exactly what I figured was happening. Any suggestions on how to get it to NOT happen? Like saying "else only look at one of the variables; print "blah blah";

– ScarletRoxanne
Nov 11 '18 at 8:13





@zdim, thanks so much, that's exactly what I figured was happening. Any suggestions on how to get it to NOT happen? Like saying "else only look at one of the variables; print "blah blah";

– ScarletRoxanne
Nov 11 '18 at 8:13













Oh, right: If the words are same or anagrams your hash will have one key, if they aren't it will have more than one key -- in which case you don't need this analysis. So check that first.

– zdim
Nov 11 '18 at 8:15






Oh, right: If the words are same or anagrams your hash will have one key, if they aren't it will have more than one key -- in which case you don't need this analysis. So check that first.

– zdim
Nov 11 '18 at 8:15













2 Answers
2






active

oldest

votes


















0














It's useful to print out the contents of %anaHash after you've finished building it, but before you start examining it. Using the words "foo" and "bar", I get this result using Data::Dumper.



$VAR1 = 
'abr' => [
'bar'
],
'foo' => [
'foo'
]
;


So the hash has two keys. And as you loop round all of the keys in the hash, you'll get the message twice (once for each key).



I'm not really sure what the hash is for here. I don't think it's necessary. I think that you need to:



  1. Read in the two words

  2. Convert the words to a canonical format

  3. Check if the two strings are the same

Simplified, your code would look like this:



print 'Give me a word: ';
chomp(my $word1 = <STDIN>);
print 'Give me another word: ';
chomp(my $word2 = <STDIN>);

# convert to lower case
$word1 = lc $word1;
$word2 = lc $word2;

# remove non-letters
$word1 =~ s/[^a-z]//g;
$word2 =~ s/[^a-z]//g;

# sort letters
$word1 = join '', sort split //, $word1;
$word2 = join '', sort split //, $word2;

if ($word1 eq $word2)
# you have an anagram
else
# you don't






share|improve this answer

























  • thank you so much; I think you're right. I do feel that "yes" and "yes" shouldn't be anagrams, but maybe I can check after the clean-up and before the split/join. I'll let you know how it went in the morning!

    – ScarletRoxanne
    Nov 11 '18 at 9:24











  • @Rebecca: Good point. I suggest checking for identical strings after converting to lower case.

    – Dave Cross
    Nov 11 '18 at 9:27











  • Dave, also, this will make "to, by" match "Toby" which I don't think is fair, either. :) Still though, I think you're correct.

    – ScarletRoxanne
    Nov 11 '18 at 9:28











  • Sorry, babbling. All I need to do is add spaces after the [a-z]'s.

    – ScarletRoxanne
    Nov 11 '18 at 9:30


















0














My final answer, thanks so much to Dave and @zdim! I'm so happy I could die.



#!/usr/bin/perl -w
use strict;
use feature qw(say);

#I have to use this to make STDIN work. IDK why.

$|=1;

#declare variables below

print "First word?n";

$aWord = <STDIN>;
chomp $aWord;

print "Second word?n";

$bWord = <STDIN>;
chomp $bWord;

#clean up input
$aWord =~ tr/A-Z/a-z/;
$bWord =~ tr/A-Z/a-z/;
$aWord =~ s/[^a-z ]//ig;
$bWord =~ s/[^a-z ]//ig;

#if the two inputs are identical, print FALSE and exit
if ($aWord eq $bWord)
say "nnFALSE: Your phrases are identical!n";
exit;


#split each word by character, sort characters alphabetically, join characters

$aSortWord = join '', sort(split(//, $aWord));
$bSortWord = join '', sort(split(//, $bWord));

#if the sorted characters match, you have an anagram
#if not, you don't

if ($aSortWord eq $bSortWord)
say "nnTRUE: Your two terms are anagrams!";

else
say "nnFALSE: Your two terms are not acronyms.";






share|improve this answer

























  • $aWord =~ tr/A-Z/a-z/ is a rather over-complicated way to write lc $aWord :-)

    – Dave Cross
    Nov 11 '18 at 16:06











  • I know. It's just a habit. :)

    – ScarletRoxanne
    Nov 12 '18 at 16:28











  • I usually have long lists of s// and m// and I like seeing them all together. If that makes sense.

    – ScarletRoxanne
    Nov 12 '18 at 16:30










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246765%2fperl-final-output-line-in-foreach-loop-prints-twice%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














It's useful to print out the contents of %anaHash after you've finished building it, but before you start examining it. Using the words "foo" and "bar", I get this result using Data::Dumper.



$VAR1 = 
'abr' => [
'bar'
],
'foo' => [
'foo'
]
;


So the hash has two keys. And as you loop round all of the keys in the hash, you'll get the message twice (once for each key).



I'm not really sure what the hash is for here. I don't think it's necessary. I think that you need to:



  1. Read in the two words

  2. Convert the words to a canonical format

  3. Check if the two strings are the same

Simplified, your code would look like this:



print 'Give me a word: ';
chomp(my $word1 = <STDIN>);
print 'Give me another word: ';
chomp(my $word2 = <STDIN>);

# convert to lower case
$word1 = lc $word1;
$word2 = lc $word2;

# remove non-letters
$word1 =~ s/[^a-z]//g;
$word2 =~ s/[^a-z]//g;

# sort letters
$word1 = join '', sort split //, $word1;
$word2 = join '', sort split //, $word2;

if ($word1 eq $word2)
# you have an anagram
else
# you don't






share|improve this answer

























  • thank you so much; I think you're right. I do feel that "yes" and "yes" shouldn't be anagrams, but maybe I can check after the clean-up and before the split/join. I'll let you know how it went in the morning!

    – ScarletRoxanne
    Nov 11 '18 at 9:24











  • @Rebecca: Good point. I suggest checking for identical strings after converting to lower case.

    – Dave Cross
    Nov 11 '18 at 9:27











  • Dave, also, this will make "to, by" match "Toby" which I don't think is fair, either. :) Still though, I think you're correct.

    – ScarletRoxanne
    Nov 11 '18 at 9:28











  • Sorry, babbling. All I need to do is add spaces after the [a-z]'s.

    – ScarletRoxanne
    Nov 11 '18 at 9:30















0














It's useful to print out the contents of %anaHash after you've finished building it, but before you start examining it. Using the words "foo" and "bar", I get this result using Data::Dumper.



$VAR1 = 
'abr' => [
'bar'
],
'foo' => [
'foo'
]
;


So the hash has two keys. And as you loop round all of the keys in the hash, you'll get the message twice (once for each key).



I'm not really sure what the hash is for here. I don't think it's necessary. I think that you need to:



  1. Read in the two words

  2. Convert the words to a canonical format

  3. Check if the two strings are the same

Simplified, your code would look like this:



print 'Give me a word: ';
chomp(my $word1 = <STDIN>);
print 'Give me another word: ';
chomp(my $word2 = <STDIN>);

# convert to lower case
$word1 = lc $word1;
$word2 = lc $word2;

# remove non-letters
$word1 =~ s/[^a-z]//g;
$word2 =~ s/[^a-z]//g;

# sort letters
$word1 = join '', sort split //, $word1;
$word2 = join '', sort split //, $word2;

if ($word1 eq $word2)
# you have an anagram
else
# you don't






share|improve this answer

























  • thank you so much; I think you're right. I do feel that "yes" and "yes" shouldn't be anagrams, but maybe I can check after the clean-up and before the split/join. I'll let you know how it went in the morning!

    – ScarletRoxanne
    Nov 11 '18 at 9:24











  • @Rebecca: Good point. I suggest checking for identical strings after converting to lower case.

    – Dave Cross
    Nov 11 '18 at 9:27











  • Dave, also, this will make "to, by" match "Toby" which I don't think is fair, either. :) Still though, I think you're correct.

    – ScarletRoxanne
    Nov 11 '18 at 9:28











  • Sorry, babbling. All I need to do is add spaces after the [a-z]'s.

    – ScarletRoxanne
    Nov 11 '18 at 9:30













0












0








0







It's useful to print out the contents of %anaHash after you've finished building it, but before you start examining it. Using the words "foo" and "bar", I get this result using Data::Dumper.



$VAR1 = 
'abr' => [
'bar'
],
'foo' => [
'foo'
]
;


So the hash has two keys. And as you loop round all of the keys in the hash, you'll get the message twice (once for each key).



I'm not really sure what the hash is for here. I don't think it's necessary. I think that you need to:



  1. Read in the two words

  2. Convert the words to a canonical format

  3. Check if the two strings are the same

Simplified, your code would look like this:



print 'Give me a word: ';
chomp(my $word1 = <STDIN>);
print 'Give me another word: ';
chomp(my $word2 = <STDIN>);

# convert to lower case
$word1 = lc $word1;
$word2 = lc $word2;

# remove non-letters
$word1 =~ s/[^a-z]//g;
$word2 =~ s/[^a-z]//g;

# sort letters
$word1 = join '', sort split //, $word1;
$word2 = join '', sort split //, $word2;

if ($word1 eq $word2)
# you have an anagram
else
# you don't






share|improve this answer















It's useful to print out the contents of %anaHash after you've finished building it, but before you start examining it. Using the words "foo" and "bar", I get this result using Data::Dumper.



$VAR1 = 
'abr' => [
'bar'
],
'foo' => [
'foo'
]
;


So the hash has two keys. And as you loop round all of the keys in the hash, you'll get the message twice (once for each key).



I'm not really sure what the hash is for here. I don't think it's necessary. I think that you need to:



  1. Read in the two words

  2. Convert the words to a canonical format

  3. Check if the two strings are the same

Simplified, your code would look like this:



print 'Give me a word: ';
chomp(my $word1 = <STDIN>);
print 'Give me another word: ';
chomp(my $word2 = <STDIN>);

# convert to lower case
$word1 = lc $word1;
$word2 = lc $word2;

# remove non-letters
$word1 =~ s/[^a-z]//g;
$word2 =~ s/[^a-z]//g;

# sort letters
$word1 = join '', sort split //, $word1;
$word2 = join '', sort split //, $word2;

if ($word1 eq $word2)
# you have an anagram
else
# you don't







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 11 '18 at 9:18

























answered Nov 11 '18 at 8:51









Dave CrossDave Cross

47.1k33978




47.1k33978












  • thank you so much; I think you're right. I do feel that "yes" and "yes" shouldn't be anagrams, but maybe I can check after the clean-up and before the split/join. I'll let you know how it went in the morning!

    – ScarletRoxanne
    Nov 11 '18 at 9:24











  • @Rebecca: Good point. I suggest checking for identical strings after converting to lower case.

    – Dave Cross
    Nov 11 '18 at 9:27











  • Dave, also, this will make "to, by" match "Toby" which I don't think is fair, either. :) Still though, I think you're correct.

    – ScarletRoxanne
    Nov 11 '18 at 9:28











  • Sorry, babbling. All I need to do is add spaces after the [a-z]'s.

    – ScarletRoxanne
    Nov 11 '18 at 9:30

















  • thank you so much; I think you're right. I do feel that "yes" and "yes" shouldn't be anagrams, but maybe I can check after the clean-up and before the split/join. I'll let you know how it went in the morning!

    – ScarletRoxanne
    Nov 11 '18 at 9:24











  • @Rebecca: Good point. I suggest checking for identical strings after converting to lower case.

    – Dave Cross
    Nov 11 '18 at 9:27











  • Dave, also, this will make "to, by" match "Toby" which I don't think is fair, either. :) Still though, I think you're correct.

    – ScarletRoxanne
    Nov 11 '18 at 9:28











  • Sorry, babbling. All I need to do is add spaces after the [a-z]'s.

    – ScarletRoxanne
    Nov 11 '18 at 9:30
















thank you so much; I think you're right. I do feel that "yes" and "yes" shouldn't be anagrams, but maybe I can check after the clean-up and before the split/join. I'll let you know how it went in the morning!

– ScarletRoxanne
Nov 11 '18 at 9:24





thank you so much; I think you're right. I do feel that "yes" and "yes" shouldn't be anagrams, but maybe I can check after the clean-up and before the split/join. I'll let you know how it went in the morning!

– ScarletRoxanne
Nov 11 '18 at 9:24













@Rebecca: Good point. I suggest checking for identical strings after converting to lower case.

– Dave Cross
Nov 11 '18 at 9:27





@Rebecca: Good point. I suggest checking for identical strings after converting to lower case.

– Dave Cross
Nov 11 '18 at 9:27













Dave, also, this will make "to, by" match "Toby" which I don't think is fair, either. :) Still though, I think you're correct.

– ScarletRoxanne
Nov 11 '18 at 9:28





Dave, also, this will make "to, by" match "Toby" which I don't think is fair, either. :) Still though, I think you're correct.

– ScarletRoxanne
Nov 11 '18 at 9:28













Sorry, babbling. All I need to do is add spaces after the [a-z]'s.

– ScarletRoxanne
Nov 11 '18 at 9:30





Sorry, babbling. All I need to do is add spaces after the [a-z]'s.

– ScarletRoxanne
Nov 11 '18 at 9:30













0














My final answer, thanks so much to Dave and @zdim! I'm so happy I could die.



#!/usr/bin/perl -w
use strict;
use feature qw(say);

#I have to use this to make STDIN work. IDK why.

$|=1;

#declare variables below

print "First word?n";

$aWord = <STDIN>;
chomp $aWord;

print "Second word?n";

$bWord = <STDIN>;
chomp $bWord;

#clean up input
$aWord =~ tr/A-Z/a-z/;
$bWord =~ tr/A-Z/a-z/;
$aWord =~ s/[^a-z ]//ig;
$bWord =~ s/[^a-z ]//ig;

#if the two inputs are identical, print FALSE and exit
if ($aWord eq $bWord)
say "nnFALSE: Your phrases are identical!n";
exit;


#split each word by character, sort characters alphabetically, join characters

$aSortWord = join '', sort(split(//, $aWord));
$bSortWord = join '', sort(split(//, $bWord));

#if the sorted characters match, you have an anagram
#if not, you don't

if ($aSortWord eq $bSortWord)
say "nnTRUE: Your two terms are anagrams!";

else
say "nnFALSE: Your two terms are not acronyms.";






share|improve this answer

























  • $aWord =~ tr/A-Z/a-z/ is a rather over-complicated way to write lc $aWord :-)

    – Dave Cross
    Nov 11 '18 at 16:06











  • I know. It's just a habit. :)

    – ScarletRoxanne
    Nov 12 '18 at 16:28











  • I usually have long lists of s// and m// and I like seeing them all together. If that makes sense.

    – ScarletRoxanne
    Nov 12 '18 at 16:30















0














My final answer, thanks so much to Dave and @zdim! I'm so happy I could die.



#!/usr/bin/perl -w
use strict;
use feature qw(say);

#I have to use this to make STDIN work. IDK why.

$|=1;

#declare variables below

print "First word?n";

$aWord = <STDIN>;
chomp $aWord;

print "Second word?n";

$bWord = <STDIN>;
chomp $bWord;

#clean up input
$aWord =~ tr/A-Z/a-z/;
$bWord =~ tr/A-Z/a-z/;
$aWord =~ s/[^a-z ]//ig;
$bWord =~ s/[^a-z ]//ig;

#if the two inputs are identical, print FALSE and exit
if ($aWord eq $bWord)
say "nnFALSE: Your phrases are identical!n";
exit;


#split each word by character, sort characters alphabetically, join characters

$aSortWord = join '', sort(split(//, $aWord));
$bSortWord = join '', sort(split(//, $bWord));

#if the sorted characters match, you have an anagram
#if not, you don't

if ($aSortWord eq $bSortWord)
say "nnTRUE: Your two terms are anagrams!";

else
say "nnFALSE: Your two terms are not acronyms.";






share|improve this answer

























  • $aWord =~ tr/A-Z/a-z/ is a rather over-complicated way to write lc $aWord :-)

    – Dave Cross
    Nov 11 '18 at 16:06











  • I know. It's just a habit. :)

    – ScarletRoxanne
    Nov 12 '18 at 16:28











  • I usually have long lists of s// and m// and I like seeing them all together. If that makes sense.

    – ScarletRoxanne
    Nov 12 '18 at 16:30













0












0








0







My final answer, thanks so much to Dave and @zdim! I'm so happy I could die.



#!/usr/bin/perl -w
use strict;
use feature qw(say);

#I have to use this to make STDIN work. IDK why.

$|=1;

#declare variables below

print "First word?n";

$aWord = <STDIN>;
chomp $aWord;

print "Second word?n";

$bWord = <STDIN>;
chomp $bWord;

#clean up input
$aWord =~ tr/A-Z/a-z/;
$bWord =~ tr/A-Z/a-z/;
$aWord =~ s/[^a-z ]//ig;
$bWord =~ s/[^a-z ]//ig;

#if the two inputs are identical, print FALSE and exit
if ($aWord eq $bWord)
say "nnFALSE: Your phrases are identical!n";
exit;


#split each word by character, sort characters alphabetically, join characters

$aSortWord = join '', sort(split(//, $aWord));
$bSortWord = join '', sort(split(//, $bWord));

#if the sorted characters match, you have an anagram
#if not, you don't

if ($aSortWord eq $bSortWord)
say "nnTRUE: Your two terms are anagrams!";

else
say "nnFALSE: Your two terms are not acronyms.";






share|improve this answer















My final answer, thanks so much to Dave and @zdim! I'm so happy I could die.



#!/usr/bin/perl -w
use strict;
use feature qw(say);

#I have to use this to make STDIN work. IDK why.

$|=1;

#declare variables below

print "First word?n";

$aWord = <STDIN>;
chomp $aWord;

print "Second word?n";

$bWord = <STDIN>;
chomp $bWord;

#clean up input
$aWord =~ tr/A-Z/a-z/;
$bWord =~ tr/A-Z/a-z/;
$aWord =~ s/[^a-z ]//ig;
$bWord =~ s/[^a-z ]//ig;

#if the two inputs are identical, print FALSE and exit
if ($aWord eq $bWord)
say "nnFALSE: Your phrases are identical!n";
exit;


#split each word by character, sort characters alphabetically, join characters

$aSortWord = join '', sort(split(//, $aWord));
$bSortWord = join '', sort(split(//, $bWord));

#if the sorted characters match, you have an anagram
#if not, you don't

if ($aSortWord eq $bSortWord)
say "nnTRUE: Your two terms are anagrams!";

else
say "nnFALSE: Your two terms are not acronyms.";







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 11 '18 at 14:59









Dave Cross

47.1k33978




47.1k33978










answered Nov 11 '18 at 10:13









ScarletRoxanneScarletRoxanne

84




84












  • $aWord =~ tr/A-Z/a-z/ is a rather over-complicated way to write lc $aWord :-)

    – Dave Cross
    Nov 11 '18 at 16:06











  • I know. It's just a habit. :)

    – ScarletRoxanne
    Nov 12 '18 at 16:28











  • I usually have long lists of s// and m// and I like seeing them all together. If that makes sense.

    – ScarletRoxanne
    Nov 12 '18 at 16:30

















  • $aWord =~ tr/A-Z/a-z/ is a rather over-complicated way to write lc $aWord :-)

    – Dave Cross
    Nov 11 '18 at 16:06











  • I know. It's just a habit. :)

    – ScarletRoxanne
    Nov 12 '18 at 16:28











  • I usually have long lists of s// and m// and I like seeing them all together. If that makes sense.

    – ScarletRoxanne
    Nov 12 '18 at 16:30
















$aWord =~ tr/A-Z/a-z/ is a rather over-complicated way to write lc $aWord :-)

– Dave Cross
Nov 11 '18 at 16:06





$aWord =~ tr/A-Z/a-z/ is a rather over-complicated way to write lc $aWord :-)

– Dave Cross
Nov 11 '18 at 16:06













I know. It's just a habit. :)

– ScarletRoxanne
Nov 12 '18 at 16:28





I know. It's just a habit. :)

– ScarletRoxanne
Nov 12 '18 at 16:28













I usually have long lists of s// and m// and I like seeing them all together. If that makes sense.

– ScarletRoxanne
Nov 12 '18 at 16:30





I usually have long lists of s// and m// and I like seeing them all together. If that makes sense.

– ScarletRoxanne
Nov 12 '18 at 16:30

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53246765%2fperl-final-output-line-in-foreach-loop-prints-twice%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)