Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Terse Code for Odd Numbers

by deep submerge (Scribe)
on May 13, 2005 at 19:42 UTC ( #456865=perlquestion: print w/ replies, xml ) Need Help??
deep submerge has asked for the wisdom of the Perl Monks concerning the following question:

My employer recently asked me to take a test to gauge my coding ability... And I was absolutely delighted to see a section in which I could choose the language to solve the problem. I chose Perl, of course. Now... The task was to print all of the odd numbers between 1 and 13. Here's what I tried:

for (1..13) { print if $_ % 2 }
and
print for (grep { $_ % 2 } (1..13))

Is there any more concise way to get the above output? Preferably keeping to its dynamic solution of N to M. (I realized while taking the test that some solutions could be written more literally, solving to the problem itself and not really being applicable elsewhere)

print 1, 3, 5, 7, 9, 11, 13

Update: I already took the test before posting. I'm just looking for a shorter, more concise answer. Golf away! =)

Comment on Terse Code for Odd Numbers
Select or Download Code
Re: Terse Code for Odd Numbers
by dragonchild (Archbishop) on May 13, 2005 at 19:45 UTC
    print grep $_%2, 1 .. 13; - you don't need the for().

    • In general, if you think something isn't in Perl, try it out, because it usually is. :-)
    • "What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against?"

      Arg!! So obvious! Printing the array itself!

      Hmmf. That's great. Could it get any better? =) I guess this could be considered golfing...

Re: Terse Code for Odd Numbers
by davidrw (Prior) on May 13, 2005 at 19:58 UTC
    Basically same thing, just slightly different construct (half the iterations)
    perl -le 'print map {$_*2+1} 1/2..13/2'
    Update: Can just use 'for' instead of 'map'..
    perl -le 'print 2*$_+1 for 1/2..13/2'
      wait a second...

      1/2 * 2 + 1
      = 2/2 + 1
      = 1 + 1
      = 2

      isn't that an even number?
      i think you meant:
      perl -le 'print map {$_*2+1} 0..12/2
      Update:
      Nope, i was wrong. i started thinking about how to do this given a low and a high, so i got about this far: int( $low/2 )..int( $high/2 ) when i realized, hey, the .. operator probably takes the int of the values already. so i tried it, and after running the code provided, i found out the .. operator already does take the int of the values, so your answer works. sorry.
      Perl6 version (doesn't work yet on current pugs):

      say (2 .. 13 :by(2))

Re: Terse Code for Odd Numbers
by Animator (Hermit) on May 13, 2005 at 20:06 UTC
    Another possibility: print grep { $_ & 1 } 1 .. 13

    Update For those who need the explenation: read the next node :)

      This is just for my or for future readers' reference... Please correct me if there's anything wrong or not explained properly. One reason I type this out is because I see code examples that use voodoo I'm not yet accustomed to. So maybe I can help someone else that reads this in the future. =)

      The expression $_ & 1 will evaluate to zero (false) for any even number $_. This uses the bitwise operator &...

      Translate both numbers ($_ and 1) to their binary formats and fill the lesser number with leading zeros (13 => 1101, 1 => 0001)... Perform the AND comparison between the numbers vertically and return that result. Since 1 is a number with many leading zeros, it cancels/falses out all higher order bits greater than 1 for the first number. The only way to make this expression true is to compare the two first bits as 1 AND 1. 1 is an active bit in binary when the first number is odd.

Re: Terse Code for Odd Numbers
by jhourcle (Prior) on May 13, 2005 at 20:20 UTC

    Not to be completely rude here, but...

    My employer recently asked me to take a test to gauge my coding ability... And I was absolutely delighted to see a section in which I could choose the language to solve the problem. I chose Perl, of course. Now... The task is to print all of the odd numbers between 1 and 13. Here's what I tried:

    If the test is to judge your coding ability, shouldn't you work on your own answers?

    (now, if it specifically states that it's an open reference test, and it's to judge your skill in overall ability to get the job done, and not just coding, it's okay, though)

    Update: Well, if it's already done, I'd use one of the following, depending on the rest of the scope of the problem, as 'better' is a subjective thing

    # better for speed print "1\n3\n5\n7\n9\n11\n13\n"; # better for clarity print "$_\n" foreach qw(1 3 5 7 9 11 13); # better if you like C for ( my $i = 1; $i < 14; $i += 2 ) { print "$i\n"; } # better if you like walking backwards for ( my $i = 13; $i > 0; $i-=2 ) { print "$i\n"; } # better if you like while loops my $i = 1; do { print "$i\n"; } while ( ($i+=2) < 14 ); # better if you like join print join("\n", qw(1 3 5 7 9 11 13), ''); # better if you like map print map { "$_\n" } qw(1 3 5 7 9 11 13); # better if you like printf printf ("%i\n", $_) foreach qw(1 3 5 7 9 11 13); # better if you don't like hard coding odd numbers print map { "$_\n" } grep { $_ % 2 } ( 1 .. 13); # better if you don't like white space. print(join':',grep{$_%2}(1..13)); # better if you don't assume things # (like 'don't print even numbers') print map { "$_\n" } (1..13); # better if you like strings print "@{[grep{$_%2}(1..13)]}\n";

    etc, etc, etc.

      i'm gonna guess that he already took the test, but it's over now. and now is just wondering about something that struck him while taking it.
      if not... whooooops!
      Uhh yeah I didn't mean to misleading but I took the test already and was just looking for a better answer. Sorry.
        Was said test asking for the shortest possible answer or simply testing your coding ability? Not to be pedantic, they aren't the same. Those of us who have to communicate with other programmers, write or maintain code, or teach, may disagree with your concept of 'better answer'.

        I'd prefer a three line solution above that used a foreach simply for readability.

        --
        jpg
Re: Terse Code for Odd Numbers
by sh1tn (Priest) on May 13, 2005 at 21:27 UTC
    print++$";print+$"+=2for+0..5 STDOUT: 135791113


Re: Terse Code for Odd Numbers
by TedPride (Priest) on May 13, 2005 at 22:39 UTC
    print$_++while++$_<14;
Re: Terse Code for Odd Numbers
by tlm (Prior) on May 14, 2005 at 04:34 UTC

    Must the keys be printed in numerical order? If not, then this also works:

    print keys%{{1..14}};

    the lowliest monk

      Beautiful. The parent is the first answer that revealed something interesting to me about how perl works. For those who want to try it out, the following would be more usable, but of course less elegant.

      print "$_\n" for sort {$a<=>$b} keys %{{1..14}};

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (7)
As of 2014-10-22 12:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (117 votes), past polls