Home: Perl Programming Help: Beginner:
simple subroutine call

user4592357
New User

Sep 20, 2017, 11:56 AM

Views: 4364
 simple subroutine call
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

Views: 4352
 Re: [user4592357] simple subroutine call
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

Views: 4348
 Re: [user4592357] simple subroutine call
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.

Laurent_R
Veteran / Moderator

Sep 21, 2017, 2:28 AM

Views: 4342
 Re: [user4592357] simple subroutine call
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

Views: 4340
 Re: [Laurent_R] simple subroutine call

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

Views: 4330
 Re: [user4592357] simple subroutine call
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

Views: 4325
 Re: [Laurent_R] simple subroutine call
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

Views: 4322
 Re: [Laurent_R] simple subroutine call
 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

Views: 4313
 Re: [FishMonger] simple subroutine call
`my \$statues_ref = shift;`