inside-out range function

W

William Clifford

For some reason I thought I needed this code, but it turns out I
don't, really.
I need something weirder. Anyway, maybe someone else could use this.

def enrag(start, stop=None, step=1):
'''Yield a range of numbers from inside-out, evens on left.'''

if stop is None:
stop, start = start, 0

lstep = step * -2
rstep = step * 2
lstop = start - step

if stop % step > 0:
lstart = stop - (stop % rstep)
else:
lstart = stop - (rstep - (stop % rstep))

for left in xrange(lstart, lstop, lstep):
yield left

for right in xrange(step, stop, rstep):
yield right
 
S

Steven D'Aprano

For some reason I thought I needed this code, but it turns out I don't,
really.
I need something weirder. Anyway, maybe someone else could use this.

def enrag(start, stop=None, step=1):
'''Yield a range of numbers from inside-out, evens on left.'''
[snip code]

Interesting.

That's equivalent to a reverse followed by a Monge Shuffle.

http://mathworld.wolfram.com/MongesShuffle.html
http://en.wikipedia.org/wiki/Shuffling_playing_cards#Mongean_shuffle


I wrote a similar function to do this:

def monge_shuffle(deck):
if len(deck) % 2: # Odd number of items.
deck[:] = deck[0::2] + deck[1::2][::-1]
else: # Even number of items.
deck[:] = deck[1::2] + deck[0::2][::-1]
return deck
list(enrag(20)) [18, 16, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
monge_shuffle(range(20)[::-1]) [18, 16, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
list(enrag(203)) == monge_shuffle(range(203)[::-1])
True



I'm curious what your "something weirder" was.
 
W

William Clifford

For some reason I thought I needed this code, but it turns out I don't,
really.
I need something weirder. Anyway, maybe someone else could use this.
def enrag(start, stop=None, step=1):
    '''Yield a range of numbers from inside-out, evens on left.'''

[snip code]

Interesting.

That's equivalent to a reverse followed by a Monge Shuffle.

http://mathworld.wolfram.com/Monges.../wiki/Shuffling_playing_cards#Mongean_shuffle

I wrote a similar function to do this:

def monge_shuffle(deck):
    if len(deck) % 2: # Odd number of items.
        deck[:] = deck[0::2] + deck[1::2][::-1]
    else: # Even number of items.
        deck[:] = deck[1::2] + deck[0::2][::-1]
    return deck

[18, 16, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]>>> monge_shuffle(range(20)[::-1])

[18, 16, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]>>> list(enrag(203)) == monge_shuffle(range(203)[::-1])

True

I'm curious what your "something weirder" was.

Thanks for the links! Funny, while I worked on this I didn't think of
looking up card shuffling to see if there might be an algorithms for
it. I didn't think enrag (or her sister garne) would be unique, but I
didn't expect they could be useful either. Cool!

I weirder I needed was to generate an Ulam spiral sequence like this:

[4, 3, 2,
5, 0, 1,
7, 8, 9]

I found a couple of ways, one of which I'm a somewhat happier with.
 
M

Mensanator

[snip code]
Interesting.

That's equivalent to a reverse followed by a Monge Shuffle.

I wrote a similar function to do this:
def monge_shuffle(deck):
� � if len(deck) % 2: # Odd number of items.
� � � � deck[:] = deck[0::2] + deck[1::2][::-1]
� � else: # Even number of items.
� � � � deck[:] = deck[1::2] + deck[0::2][::-1]
� � return deck
[18, 16, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]>>> monge_shuffle(range(20)[::-1])
[18, 16, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]>>> list(enrag(203)) == monge_shuffle(range(203)[::-1])

I'm curious what your "something weirder" was.

Thanks for the links! Funny, while I worked on this I didn't think of
looking up card shuffling to see if there might be an algorithms for
it. I didn't think enrag (or her sister garne) would be unique, but I
didn't expect they could be useful either. Cool!

I weirder I needed was to generate an Ulam spiral sequence like this:

[4, 3, 2,
�5, 0, 1,
�7, 8, 9]

I found a couple of ways, one of which I'm a somewhat happier with.

What's your solution (I got a couple, also).
 
P

Paul Rubin

William Clifford said:
def enrag(start, stop=None, step=1):
'''Yield a range of numbers from inside-out, evens on left.'''
[8, 6, 4, 2, 0, 1, 3, 5, 7, 9]

ok, but:
[18, 16, 14, 12, 10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

is that really what you wanted?
[18, 16, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

For the 0...n-1 case, I think I'd write

from itertools import chain
def e(n):
max_even = (n-1) & ~1
return chain(xrange(max_even, -1, -2), xrange(1, n, 2))
 
W

William Clifford

William Clifford said:
def enrag(start, stop=None, step=1):
    '''Yield a range of numbers from inside-out, evens on left.'''

    >>> list(enrag(10))
    [8, 6, 4, 2, 0, 1, 3, 5, 7, 9]    

ok, but:

    >>> list(enrag(10,20))
    [18, 16, 14, 12, 10, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

is that really what you wanted?

    >>> list(enrag(20))
    [18, 16, 14, 12, 10, 8, 6, 4, 2, 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

Uh. No. Thank you. This was an easy fix. But now I've found other
problems with stepping I was trying to get it to do too. Yuck.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,169
Latest member
ArturoOlne
Top