Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

reverse range (10..1)

2 views
Skip to first unread message

Paul Archer

unread,
Aug 26, 2003, 3:44:52 PM8/26/03
to begi...@perl.org
Is there any (quick and easy) way to get a reverse range, like (10..1),
rather than a standard (1..10)? The catch is to *not* use 'reverse'.
I'm teaching Sun's perl course this week (DTP-250), and we were talking
about working on arrays. The book had an exercise that had the student
reverse an array by using pop (or shift, I don't remember). That section is
before we talk about 'reverse', and I thought you'd be able to do it like:
@array[0 .. $#array] = @array[$#array .. 0]
...but of course, having the range count down doesn't work.

Paul

Ramprasad A Padmanabhan

unread,
Aug 27, 2003, 6:39:17 AM8/27/03
to begi...@perl.org, Paul Archer

IMHO this list is not for solving puzzles or doing school homework , It
is for people learning perl who are getting stuck due to pure perl problems
If I wanted a range (10..1) I will use reverse and why not. If you have
a better way tell me so that I can learn it

Ram

Todd W.

unread,
Aug 27, 2003, 7:26:01 AM8/27/03
to begi...@perl.org

"Paul Archer" <tig...@io.com> wrote in message
news:Pine.LNX.4.56.03...@hagbard.io.com...

Reverse an array without using reverse():

with an array slice and map():
[trwww@waveright trwww]$ perl
@array = ( 1 .. 5 );
@array = @array[ map abs(), -$#array .. 0 ];
print( join("\n", @array), "\n" );
Ctrl-D
5
4
3
2
1

using splice(), pop(), and for():
[trwww@waveright trwww]$ perl
@array = ( 1 .. 5 );
splice( @array, $_, 0, pop @array ) for ( 0 .. $#array );
print( join("\n", @array), "\n" );
Ctrl-D
5
4
3
2
1

or the C way (but skipping the temporary variable):
[trwww@waveright perl]$ perl
@array = ( 1 .. 5 );
for ( $a = 0, $z = $#array; $a < $z; $a++, $z-- ) {
( $array[$a], $array[$z] ) = ( $array[$z], $array[$a] );
# @array[ $a, $z ] = @array[ $z, $a ]; # works too
}
print( join("\n", @array), "\n" );
Ctrl-D
5
4
3
2
1

perl is soooo cool.

Todd W.


Eurospace Szarindar

unread,
Aug 27, 2003, 7:55:14 AM8/27/03
to Paul Archer, begi...@perl.org
Hi,

@normal = (0,1,2,3,4,5,6,7,8,9);
foreach (0..$#normal) { unshift @reverse, (shift @normal) };


this also works fine.

Michel

-----Message d'origine-----
De: Paul Archer [mailto:tig...@io.com]
Date: mardi 26 aoūt 2003 21:45
Ą: begi...@perl.org
Objet: reverse range (10..1)


Is there any (quick and easy) way to get a reverse range, like (10..1),
rather than a standard (1..10)? The catch is to *not* use 'reverse'.
I'm teaching Sun's perl course this week (DTP-250), and we were talking
about working on arrays. The book had an exercise that had the student
reverse an array by using pop (or shift, I don't remember). That section is
before we talk about 'reverse', and I thought you'd be able to do it like:
@array[0 .. $#array] = @array[$#array .. 0]
...but of course, having the range count down doesn't work.

Paul

--
To unsubscribe, e-mail: beginners-...@perl.org
For additional commands, e-mail: beginne...@perl.org

Paul Archer

unread,
Aug 27, 2003, 8:45:19 AM8/27/03
to begi...@perl.org, Ramprasad A Padmanabhan

Actually, the description for this mailing list says "A list for beginning
Perl programmers to ask questions in a *friendly atmosphere*." (emphasis
added) I don't see anything about "No schoolwork", or "No puzzles"...

And the problem is not simply a puzzle, nor is it homework. If you had read
my post more carefully, you would see that I am 1) *teaching* the class, and
2) want to be able to show off one concept (the range operator) before we
have talked about another concept (the 'reverse' statement).

IM"H"O, if you want to be on a list that is "...for people learning perl who
are getting stuck due to pure perl problems..." then start one. I, on the
other hand, am staying here.

Paul

Bob Showalter

unread,
Aug 27, 2003, 9:14:35 AM8/27/03
to Paul Archer, begi...@perl.org
Paul Archer wrote:
> Is there any (quick and easy) way to get a reverse range,
> like (10..1),
> rather than a standard (1..10)? The catch is to *not* use 'reverse'.
> I'm teaching Sun's perl course this week (DTP-250), and we
> were talking
> about working on arrays. The book had an exercise that had the student
> reverse an array by using pop (or shift, I don't remember).
> That section is
> before we talk about 'reverse', and I thought you'd be able
> to do it like:
> @array[0 .. $#array] = @array[$#array .. 0]
> ...but of course, having the range count down doesn't work.

This works:

@arr = map pop(@arr), @arr;

but seems overly tricky, IMO. The far more straightforward:

@arr = reverse @arr;

would be preferred.

If you're teaching a class, I think you want to avoid using trickery just to
steer clear of a concept you haven't introduced yet. I would either go ahead
and introduce reverse(), if your purpose is to reverse an array. Or, I would
stay away from reversing arrays if your purpose is to illustrate the range
opeator.

James Edward Gray II

unread,
Aug 27, 2003, 9:30:00 AM8/27/03
to begi...@perl.org
On Wednesday, August 27, 2003, at 05:39 AM, Ramprasad A Padmanabhan
wrote:

> IMHO this list is not for solving puzzles or doing school homework ,
> It is for people learning perl who are getting stuck due to pure perl
> problems

My, seldom humble, opinion does not agree with yours. My feeling is
that we are here to help people learn Perl. Generally, that means
we're answering beginner level questions, but I don't think there is
any harm in stretching our skills a little when we can.

Paul's question was pure Perl and he expressed exactly what he needed
well. The question is a little odd, as there's probably not too good a
reason not to use reverse() in normal code. What if there was though?
Say reverse() was known to be super slow and performance counted. Is
the question alright now? Probably, but the question hasn't changed at
all.

The answers to Paul's question also show exactly why it is fine, again
in my opinion. I don't know about you, but I learned something from
the responses and I'm no beginner. I think that's a sign that we're
doing the right things.

Finally, while I agree we should not be DOING homework, I think it
would be a great crime to say we should not be helping with homework.
I think this is one of the best, if not THE best, places to learn more
Perl on the Internet. To deny someone that resource because they are a
part of any demographic, especially students who hopefully want to
learn, is morally wrong, I think. Of course, this isn't too
significant as Paul's question was not homework.

While I'm quite certain I do not speak for everyone here, I just wanted
to make it clear, to Paul at least, that you do not speak for me either.

James

Alan Perry

unread,
Aug 27, 2003, 9:44:56 AM8/27/03
to James Edward Gray II, begi...@perl.org
On Wednesday, August 27, 2003 08:30, James Edward Gray II wrote:
>
>On Wednesday, August 27, 2003, at 05:39 AM, Ramprasad A Padmanabhan
>wrote:
>
>> IMHO this list is not for solving puzzles or doing school homework ,
>> It is for people learning perl who are getting stuck due to pure perl
>> problems
>
>My, seldom humble, opinion does not agree with yours. My feeling is
>that we are here to help people learn Perl. Generally, that means
>we're answering beginner level questions, but I don't think there is
>any harm in stretching our skills a little when we can.
>
> <*snip*>

>
>While I'm quite certain I do not speak for everyone here, I just wanted
>to make it clear, to Paul at least, that you do not speak for me either.

I agree wholeheartedly. I read this group because:

1. I learn something new almost every day
2. The people here are not (generally) hostile towards each other
3. I can actually answer some of the questions posed :-)

Thank you James for putting this out there, and long may begi...@perl.org
live!

Alan

Paul Archer

unread,
Aug 27, 2003, 9:49:37 AM8/27/03
to Todd W., begi...@perl.org
*Verrrry* cool examples--especially the 'map' in the first one.

Thanks!

Paul

--------------------------------------------------------------
"I'll say this about Linux: it's the first time I've seen Unix
on the right platform."--Steve Ballmer, president of Microsoft
(NB: Microsoft used to own SCO, which did, and still does,
produce a Unix for the Intel platform.)
--------------------------------------------------------------

Jenda Krynicky

unread,
Aug 27, 2003, 10:02:46 AM8/27/03
to begi...@perl.org
From: Paul Archer <tig...@io.com>

$array[-1] is the last item, $array[-scalar(@array)] is the first so:

@array[0 .. $#array] = @array[map -$_, (1 .. scalar(@array))];

Jenda
===== Je...@Krynicky.cz === http://Jenda.Krynicky.cz =====
When it comes to wine, women and song, wizards are allowed
to get drunk and croon as much as they like.
-- Terry Pratchett in Sourcery

Jenda Krynicky

unread,
Aug 27, 2003, 10:06:59 AM8/27/03
to begi...@perl.org
From: "Jenda Krynicky" <Je...@Krynicky.cz>

> From: Paul Archer <tig...@io.com>
> > Is there any (quick and easy) way to get a reverse range, like
> > (10..1), rather than a standard (1..10)? The catch is to *not* use
> > 'reverse'. I'm teaching Sun's perl course this week (DTP-250), and
> > we were talking about working on arrays. The book had an exercise
> > that had the student reverse an array by using pop (or shift, I
> > don't remember). That section is before we talk about 'reverse', and
> > I thought you'd be able to do it like: @array[0 .. $#array] =
> > @array[$#array .. 0] ...but of course, having the range count down
> > doesn't work.
>
> $array[-1] is the last item, $array[-scalar(@array)] is the first so:
>
> @array[0 .. $#array] = @array[map -$_, (1 .. scalar(@array))];

Actually
@array = @array[map -$_, (1 .. scalar(@array))];
is good enough.

Kevin Pfeiffer

unread,
Aug 31, 2003, 2:01:58 PM8/31/03
to begi...@perl.org
In article <Pine.LNX.4.56.03...@hagbard.io.com>, Paul Archer
wrote:
[top post moved into its chronological place]

[...]

> *Verrrry* cool examples--especially the 'map' in the first one.
>
> Thanks!
>
> Paul

Oh yeah, I'd really want to learn map before reverse... ;-)

-K

--
Kevin Pfeiffer
International University Bremen
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

R. Joseph Newton

unread,
Sep 5, 2003, 2:25:13 AM9/5/03
to Paul Archer, begi...@perl.org, Ramprasad A Padmanabhan
Paul Archer wrote:

> 4:09pm, Ramprasad A Padmanabhan wrote:
>
> And the problem is not simply a puzzle, nor is it homework. If you had read
> my post more carefully, you would see that I am 1) *teaching* the class, and
> 2) want to be able to show off one concept (the range operator) before we
> have talked about another concept (the 'reverse' statement).

Even more reason, if you are in the position of a teacher, not to use the range
operator for this purpose. It is simply inappropriate. Unless there is only a
certain subset of elements in the array for which you want to do magic, the foreach
(@array_name) format communicates intent much more clearly.

I'm a little surprised that no one has yet posted what seems to me the most direct
and transparent soltion: [note the sample does make use of the range operator in a
more appropriate context]

Greetings! E:\d_drive\perlStuff>perl -w
my @keeper = (1..15);
{
my @temp;
push @temp, pop @keeper while @keeper;
@keeper = @temp;
}
print "$_ " for @keeper;
^Z
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1

I like the above because:

1. It is transparent. You can "see" the data being moved.
2. It is process efficient. Each element is moved only once, and an array name is
redirected. It does what it takes--no more and no less.
3. It minimizes memory demands painlessly. The original storage for @keeper is
returned to the store when it is re-assigned, and @temp disappears entirely outside
the {...} closure, leaving @keeper pointing to the reversed array.

Hmmm...

On second thought, I'm not sure about process efficiency here, Perl may re-copy the
whole array in the assignment. In which case, the more efficient and elegant
solution would use references:

Greetings! E:\d_drive\perlStuff>perl -w
my $keeper = [1..15];
{
my $temp = []; # " = []" Not strictly neccesary. The first push() would
autovivify @$temp
push @$temp, pop @$keeper while @$keeper;
$keeper = $temp;
}
print "$_ " for @$keeper;
print "\n";
^Z
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1

As a side exercise, you might have your students add the implicit parens.

Joseph


0 new messages