CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
simple subroutine call

 



user4592357
New User

Sep 20, 2017, 11:56 AM

Post #1 of 9 (308 views)
simple subroutine call Can't Post

hi everyone, i'm new to perl and this is my first post on here!

i'm solving exercises on this website: http://codefigths.com from arcade->intro section. also, i simultaneously execute my code online here: https://www.tutorialspoint.com/execute_perl_online.php.

my current exercise requirement is: Ratiorg got statues of different sizes as a present from CodeMaster for his birthday, each statue having an non-negative integer size. Since he likes to make things perfect, he wants to arrange them from smallest to largest so that each statue will be bigger than the previous one exactly by 1. He may need some additional statues to be able to accomplish that. Help him figure out the minimum number of additional statues needed.

it's really simple, and my code works in online execution website but not on codefights and i'm puzzled why this happens.

here's my code:

Code
sub makeArrayConsecutive2 { 
my (@statues) = @_;
my $size = scalar @statues;

my $max = $statues[0];
my $min = $max;
foreach my $i (1..$size - 1) {
if($statues[$i] > $max) {
$max = $statues[$i];
} elsif($statues[$i] < $min) {
$min = $statues[$i];
}
}

return ($max - $min + 1) - $size;
}

print makeArrayConsecutive2(6,2,3,8);


someone please shed a light here, i'm really lost :D

thanks!


(This post was edited by user4592357 on Sep 20, 2017, 11:57 AM)


FishMonger
Veteran / Moderator

Sep 20, 2017, 6:47 PM

Post #2 of 9 (296 views)
Re: [user4592357] simple subroutine call [In reply to] Can't Post

Why are you using an online site to run your script?

You should install perl on your own computer. I assume you're on Windows since nearly all other systems come with perl already installed.

Strawberry Perl is the preferred perl distro to install.
http://strawberryperl.com/

There are several approaches to solve this task. I'm about to burm my dinners, so I'll post one possible approach in a while.


FishMonger
Veteran / Moderator

Sep 20, 2017, 8:23 PM

Post #3 of 9 (292 views)
Re: [user4592357] simple subroutine call [In reply to] Can't Post

I don't wish to follow your link to codefits but based on your description you need to ouput the list of numbers between the lowest and highest numbers submitted.

There are modules which help to accomplish this but it's very easy to do it without them. Since this is a learning exercise for you, I won't provide the full solution, but I will give you some suggestions.

The sub should read-in the numbers into an array, like you're already doing. Instead of looping over those numbers, extract the lowest and highest numbers. Hint, read up on the sort function. Then use those to number to construct the loop that outputs the numbers.

If my reading of your requirements, please post the requirements instead of asking us to follow some unknown link.


Laurent_R
Veteran / Moderator

Sep 21, 2017, 2:28 AM

Post #4 of 9 (286 views)
Re: [user4592357] simple subroutine call [In reply to] Can't Post

Hi,
I tried to run your code (using an install of Perl on my computer), and it runs properly and also appear to print the desired result.

It is probably simply the codefights site which is not working properly.

One short comment on your code. This part:


Code
   foreach my $i (1..$size - 1) {  
if($statues[$i] > $max) {
$max = $statues[$i];
} elsif($statues[$i] < $min) {
$min = $statues[$i];
}
}


is better written as:

Code
foreach my $val (@statues) { 
if (my $val > $max {
$max = $val;
} elsif ($val < $min) {
$min = $val;
}
}

Looping directly over the content of the @statues array is simpler than using an index with the risk of making an off-by-one error.


user4592357
New User

Sep 21, 2017, 5:37 AM

Post #5 of 9 (284 views)
Re: [Laurent_R] simple subroutine call [In reply to] Can't Post

hi thanks for the reply

actually i do have perl installed on my computer and the code works fine. i was just asking what could be wrong with the codefights code.

i got it working after some modifications and using hints. what i don't understand is why we use @$statues? haven't seen such code when learning and practicing. what does it mean?

Code
sub makeArrayConsecutive2 { 
my ($statues) = @_;
my @statues = sort {$a <=> $b}(@$statues);

return $statues[-1] - $statues[0] - (scalar @statues) + 1;
}

p.s. i noticed that i could not use indices later, after i had posted the question. thanks for the notice though


(This post was edited by user4592357 on Sep 21, 2017, 5:38 AM)


Laurent_R
Veteran / Moderator

Sep 21, 2017, 9:39 AM

Post #6 of 9 (274 views)
Re: [user4592357] simple subroutine call [In reply to] Can't Post

Hi,
watch out, you have two different variables here, with the same name, this can be confusing. One is $statues, which is an array ref, and @statues, which is a new variable containing the array.

You don't show how the makeArrayConsecutive2 subroutine is called, but its parameter is presumably an array ref (i.e. a scalar variable containing only one item, which happens to be a reference to an array).

$statues is then populated with this array ref, and the syntax @$statues is a way to dereference this array ref, i.e. to access to the data in the array referenced by $statues, sort that data and store the resulting list into @statues.

I would advise you against using the same name (with a different sigil) to refer to two different things, as this can lead to confusion and errors.

For better comprehension and clarity, your code could be rewritten as follows:


Code
sub makeArrayConsecutive2 {  
my $statues_ref = $_[0];
my @statues = sort {$a <=> $b} @$statues_ref;

return $statues[-1] - $statues[0] - (scalar @statues) + 1;
}


Update: fixed a silly syntax error: $_[0] instead of @_[0]. Thanks to FishMonger for pointing it out.


(This post was edited by Laurent_R on Sep 22, 2017, 1:51 AM)


user4592357
New User

Sep 21, 2017, 12:15 PM

Post #7 of 9 (269 views)
Re: [Laurent_R] simple subroutine call [In reply to] Can't Post

the exercise doesn't show how it's called but i called it like this

Code
print &makeArrayConsecutive2(6,2,3,8);

on windows and it worked

so when you wrote my $statues = @_[0];, you're doing the same thing as in my code, right? but more explicitly.


FishMonger
Veteran / Moderator

Sep 21, 2017, 2:11 PM

Post #8 of 9 (266 views)
Re: [Laurent_R] simple subroutine call [In reply to] Can't Post


Quote
my $statues_ref = @_[0];

Produces this warning: "Scalar value @_[0] better written as $_[0]"

I'd write it as:

Code
my $statues_ref = shift;



(This post was edited by FishMonger on Sep 21, 2017, 2:17 PM)


Laurent_R
Veteran / Moderator

Sep 22, 2017, 1:54 AM

Post #9 of 9 (257 views)
Re: [FishMonger] simple subroutine call [In reply to] Can't Post


In Reply To

Quote
my $statues_ref = @_[0];

Produces this warning: "Scalar value @_[0] better written as $_[0]"

I'd write it as:

Code
my $statues_ref = shift;



Yes, it's a stupid syntax mistake, thanks for pointing it out. I fixed it in the original post. In fact, I would also usually use shift, but wanted here to avoid departing too much from the OP's code.

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives