Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

testing number of occurrences in a word

by jsmith
on Sep 19, 2006 at 13:23 UTC ( #573710=perlquestion: print w/replies, xml ) Need Help??

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

I can not find an algorithm to find out from user input of a word whether it is an isogram or not. How can I break a word and check letters for being an isograms or not?

Update: Can't seem to find a hash function to narrow it down.

20060919 Janitored by Corion: Restored original node text

2006-09-20 Retitled by planetscape, as per Monastery guidelines

( keep:0 edit:15 reap:0 )

Original title: 'testing number of occurances in a word'

  • Comment on testing number of occurrences in a word

Replies are listed 'Best First'.
Re: testing number of occurrences in a word
by jarich (Curate) on Sep 19, 2006 at 13:34 UTC

    It would help, in future, if you were to tell us what an "isogram" is; just in case we haven't seen this word since we were in school doing the same assignment you might be doing.

    According to a quick websearch:

    An isogram is a text that does not repeat a letter.

    It seems to me that all you need to do is to break your text up into letters and then check if they are all unique. You could do this latter part by sorting them and then walking the length of the sorted text testing to see if the current letter is the same as the previous; or you could take advantage of the fact that hash keys must be unique...

    The second option is faster, but both will be correct. Which ever way you choose, have a go at it and come back if you have any problems.

    all the best,

    jarich
Re: testing number of occurrences in a word
by Corion (Pope) on Sep 19, 2006 at 13:31 UTC

    This question and your previous question sound like homework problems. What code do you have for this, and where are you stuck? And what is an "isogram"? Do you mean the isogram? If so, you can restate the problem in easy steps which are translated easily into Perl.

Re: testing number of occurrences in a word
by talexb (Canon) on Sep 19, 2006 at 14:14 UTC

    Using the definition of an isogram from wikipedia, let's make it into a golf challenge. Anyone?

    (The reasoning being, if it's golfed, it won't be acceptable as a homework solution.)

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      49, but then again I suck at golf.

      sub isogram { #234567890#234567890#234567890#234567890#234567890 my%h=map{($_,1)}split//,$_[0];keys%h==length$_[0] } print "$_ is ", (isogram($_) ? '' : 'not '), "an isogram\n" for @ARGV;

      Duh, johngg had the right idea, except he wasn't greedy enough (nor was I. What's with the $_[0]? Sheesh.):

      sub isogram { #23456789 /(.).*\1/ } print "$_ is ", (isogram() ? '' : 'not '), "an isogram\n" for @ARGV;

      That makes for 9.

      • another intruder with the mooring in the heart of the Perl

        Very nice, but your logic is reversed.  Remember, an isogram does NOT have any letters duplicated.

        To keep it golfed, either change the caller of the subroutine:

        print "$_ is ", (isogram() ? 'not ' : ''), "an isogram\n" for @ARGV;

        or, better yet, the subroutine name:

        sub not_isogram { # ... } print "$_ is ", (not_isogram() ? '': 'not '), "an isogram\n" for @ARGV +;

        s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: testing number of occurrences in a word
by johngg (Canon) on Sep 19, 2006 at 15:01 UTC
    How about

    print qq{$word }, $word =~ m{(.).*?\1} ? q{is not } : q{is }, qq{an isogram\n};

    Cheers,

    JohnGG

    Update: Fixed wonky braces/parentheses, thanks tweetiepooh

      I like this one. I can actually read it. Some of the closing braces/parenthesis don't seem right though.
        Yes, well spotted. My excuse is I was rushing off early to play squash, hence the shonky typing. I'll fix it.

        Cheers,

        JohnGG

Re: testing number of occurrences in a word
by BrowserUk (Pope) on Sep 19, 2006 at 14:21 UTC

    Update: Added my %h to prevent false negatives. Thanks to Corion.

    This'll really impress teach :)

    perl -e"my %h;" -nle "++$h{$_}for split'';print'is ',(grep{1<$_}values%h)?'not ':'','an iso +gram'" fred is an isogram bill is not an isogram Terminating on signal SIGINT(2)

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: testing number of occurrences in a word
by jasonk (Parson) on Sep 19, 2006 at 14:46 UTC
    perl -F// -lane 'my(%x);@x{@F}=();print keys %x==@F?"yes":"no"';

    We're not surrounded, we're in a target-rich environment!
Re: testing number of occurrences in a word
by chargrill (Parson) on Sep 19, 2006 at 17:25 UTC

    I'm not sure how I'd count this, as it does the printing, also.

    #!/usr/bin/perl -l $_ = shift; print"$_ is",(grep$_>1,map++$c{$_},split//)?"n't":'',' an isogram';

    Output:

    $ perl isogram.pl greet greet isn't an isogram $ perl isogram.pl isogram isogram is an isogram $ perl isogram.pl discrete discrete isn't an isogram

    Update: I wouldn't count it, as /(.).*\1/ is much shorter.

    Update 2 I'd still count it as the shortest of the non-regex versions. And here it is as a sub for easier counting:

    sub is_iso { (grep$_>1,map++$c{$_},split//,shift)?1:0 } $_ = shift; print "$_ is", ( is_iso($_)? "n't" : '' ), ' an isogram';


    --chargrill
    s**lil*; $*=join'',sort split q**; s;.*;grr; &&s+(.(.)).+$2$1+; $; = qq-$_-;s,.*,ahc,;$,.=chop for split q,,,reverse;print for($,,$;,$*,$/)

      You can shorten that further:

      sub is_iso { grep$_>1,map++$c{$_},split// }
      12 fewer strokes :)
Re: testing number of occurrences in a word
by jwkrahn (Monsignor) on Sep 19, 2006 at 14:53 UTC
    if ( $word =~ /([\Q$word\E])(?=.*\1)/ ) { print "$word is NOT an isogram.\n"; } else { print "$word is an isogram.\n"; }
Re: testing number of occurrences in a word
by borisz (Canon) on Sep 19, 2006 at 14:11 UTC
    I do not know what a isogram is. But maybe this is what you search.
    $_ = <>; my %h; $h{$_}++ for ( split // ); my $not_isog = () = grep $_ > 1, values %h; print "$_ is ", $not_isog ? 'not ' : '', "isog\n";
    Boris

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://573710]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (2)
As of 2021-01-24 09:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?