Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Cube/digit script.

by Andrew_Levenson (Hermit)
on Mar 10, 2006 at 13:26 UTC ( [id://535691]=perlquestion: print w/replies, xml ) Need Help??

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

This script is supposed to find the four 3 digit numbers whose digits, when cubed and added together, equal the original number. Can anyone check this out and see why it won't work?
use strict; use warnings; my $i; my $j; my @num; my @numbers; for $i(100..999){ undef(@num); @num=split(//, $i); foreach $j(@num){ $j**3; } if(sum(@num)==$i){ push @numbers, $i; } } print @numbers;
Thanks in advance.

Replies are listed 'Best First'.
Re: Cube/digit script.
by japhy (Canon) on Mar 10, 2006 at 13:42 UTC
    You have warnings on! Why don't you read the warning you get? Useless use of exponentiation (**) in void context means that your $j**3 line isn't doing anything with its return value. Perhaps you meant $j **= 3 which would set $j to itself cubed.

    I assume you have a sum() function defined somewhere. And your variable scoping leaves something to be desired -- specifically, proper variable scoping. Rewriting only the scoping of your program, I'd do:

    my @numbers; for my $i (100 .. 999) { my @num = split(//, $i); foreach my $j (@num) { $j **= 3; } if (sum(@num) == $i) { push @numbers, $i; } }
    I have another comment. Why did you use 'for' in one loop and 'foreach' in another? They're not different things, and you're not using the C-style loop, so there's no reason one of them should have a different name from the other.

    All in all, I would rewrite this program to use far fewer temporary variables:

    my @numbers = grep { sum(map { $_ ** 3 } split //) == $_ } 100 .. 999;
    That might be a bit too succinct for you, but it does the same thing as yours.

    Jeff japhy Pinyan, P.L., P.M., P.O.D, X.S.: Perl, regex, and perl hacker
    How can we ever be the sold short or the cheated, we who for every service have long ago been overpaid? ~~ Meister Eckhart
Re: Cube/digit script.
by wfsp (Abbot) on Mar 10, 2006 at 14:02 UTC
    Hi Andrew_Levenson

    update:

    I misread the spec. The sum() threw me.

    The corrected output is

    153 370 371 407
    Here's my take on it :-)

    Do you have a sub called sum? I've taken the liberty of assuming you may not.

    I've also taken on board japhy's point about scoping and the for loop.

    You're not storing the cubes anywhere so I've added a var to hold it.

    There is, however, a slight snag. It only finds three!

    666 870 960
    With the code straigtened out a bit perhaps you can identify the error?

    #!/bin/perl5 use strict; use warnings; my @numbers; for my $i (100..999){ my @num = split(//, $i); my $cubed; for my $j (@num){ $cubed += $j**3; } #my $added; #$added += $_ for @num; #print "$i -> $cubed -> $added\n"; if( ($cubed) == $i ){ push @numbers, $i; } } print "$_\n" for @numbers;

    Hope this helps

      Ooh, not only does it only find 3, but the three it finds are wrong. O_O There must be an error in my math, i'll have to check that out.
      Here, I figured out what was wrong.
      The $added variable was unnecessary:
      use strict; use warnings; my $i; my $j; my $cubed; my @num; my @numbers; for $i(100..999){ undef($cubed); undef(@num); @num=split(//, $i); for $j(@num){ $cubed+=$j**3; } if($cubed==$i){ push @numbers, $i; } } print "$_\n" for @numbers;
      Thanks for the help!
Re: Cube/digit script.
by Limbic~Region (Chancellor) on Mar 10, 2006 at 14:18 UTC
    Andrew_Levenson,
    This sounds Project Eulerish.
    #!/usr/bin/perl use strict; use warnings; use List::Util 'sum'; for (100 .. 999) { print "$_\n" if sum(map {$_ ** 3} split //) == $_; }
    Grrrr - after I posted I finished reading japhy's post where he provided an even more succinct solution.

    Cheers - L~R

      To me, this one looks more succinct, if a bit too much on one line ;-) But, to take this a bit further, I look at postfix "if" as "grep" ...

      print map { "$_\n" } grep { $_ == sum map { $_ ** 3 } split // } 100 .. 999
      IMO, both better (more whitespace) and worse (hiding the loops, removal of parenthesis for the sum function). ;-) (I'm sure others have their own opinions of how they compare.)

      Just to make it a bit worse ...

      print "$_\n" for grep { $_ == sum map $_ ** 3, split // } 100 .. 999
      Or is that better? Hmmm...

Re: Cube/digit script.
by perlsen (Chaplain) on Mar 10, 2006 at 14:23 UTC
    Hi Andrew,
    I have rewritten your script(same as yours),
    I am not sure whether my output is correct or not,
    I just tried to get the output Result, What you are trying now
    I hope this might help
    use strict; use warnings; my ($i,$j,$l,$s); my (@num,@numbers); for $i(100..999) { undef(@num); @num=split(//, $i); foreach $j(@num){ $j=$j**3;} $s=0; for $l(@num) {$s = $s + $l;} if( $s == "$i") {push (@numbers, $i);} } print @numbers; #output is 153370371407

    Thanks,
    perlsen
    UPDATE:
    This script was written by me to produce the output for your program only.
    I am not clearly go through your script.
    Any way, This is waste of my precious time.
    and Thanks for some fellow monks good response.
Re: Cube/digit script.
by Yzzyx (Beadle) on Mar 10, 2006 at 14:28 UTC
    #!/usr/bin/perl use warnings; for my $a ( 1 .. 9 ) { for my $b ( 0 .. 9 ) { for my $c ( 0 .. 9 ) { my $num = $a.$b.$c; my $sum = ( $a ** 3 ) + ( $b ** 3 ) + ( $c ** 3 ); print "$num\n" if $num == $sum; } } }

      A minor quibble: I would avoid using $a and $b in this context, since they are global sort variables -- it has the potential to confuse a casual reader of your code. How 'bout $c, $d and $e instead? :)


      No good deed goes unpunished. -- (attributed to) Oscar Wilde

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (8)
As of 2024-04-18 10:39 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found