Path: csiph.com!usenet.pasdenom.info!aioe.org!news.stack.nl!newsfeed.xs4all.nl!newsfeed2.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.005 X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; 'algorithm': 0.04; 'granted,': 0.07; 'indices': 0.07; 'though:': 0.07; 'assuming': 0.09; 'mentions': 0.09; 'storage.': 0.09; 'url:github': 0.09; 'cc:addr:python-list': 0.11; '(it': 0.16; 'ah,': 0.16; 'cc:name:python list': 0.16; 'enough.': 0.16; 'finds': 0.16; 'hard-code': 0.16; 'occurs.': 0.16; 'operation.': 0.16; 'subject:Sort': 0.16; 'top-level': 0.16; 'elements': 0.16; ':-)': 0.16; 'wrote:': 0.18; 'input': 0.22; 'memory': 0.22; 'cc:addr:python.org': 0.22; 'certainly': 0.24; 'exists': 0.24; "haven't": 0.24; 'cc:2**0': 0.24; 'sort': 0.25; '(for': 0.26; 'header:In-Reply-To:1': 0.27; 'tried': 0.27; 'chris': 0.29; 'subject:) ': 0.29; 'sets': 0.30; 'message-id:@mail.gmail.com': 0.30; "i'm": 0.30; 'code': 0.31; 'url:wiki': 0.31; 'existence': 0.31; 'url:wikipedia': 0.31; 'entirely': 0.33; 'subject:time': 0.33; 'problem': 0.35; 'something': 0.35; 'operations': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'really': 0.36; 'i.e.': 0.36; 'subject:one': 0.36; 'done': 0.36; "didn't": 0.36; 'possible': 0.36; 'url:org': 0.36; 'list': 0.37; 'clear': 0.37; 'sure': 0.39; 'even': 0.60; 'read': 0.60; 'algorithms': 0.60; 'new': 0.61; "you're": 0.61; 'skip:n 10': 0.64; 'zip': 0.64; 'different': 0.65; 'movement': 0.65; 'to:addr:gmail.com': 0.65; 'here': 0.66; 'yes': 0.68; 'carefully': 0.74; 'describes': 0.84; 'oscar': 0.84; 'subject:space': 0.84; 'url:master': 0.84 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=/otjEyBT+APZ2PsA8HiuWDkrTM7US6pLLW6gTn3U8vw=; b=anoSl4vrzjp4U0kQqW6vchUmI5L3ptIGwTetdeRabC64aeywlTtwu70FqBo10H7SOa oZyZ3T8PX8HfhuNCbC1xqfb7kchAWnE+/9z4t3ClWdxkQhXk1kgV5bzMWk/1Vxj6kLQ1 GkZul8mWDIM2Qt/jiJQQZ1nfi9G8UEIa3kVBbfiBlU3qrkeBvrkhg4KlkTcl4VaqF3aA GxbwvOJG9wv+vCobrr9uaypLO+HJFhO07lFyhg8VTtZrkcGNq9BnTlYBY26DMHDvTmZW AHDm+46NECF+6WubrrMIFKNm2jFfCX7M4UXFMdF33qLwJ8yINweJDW8C4Y1JzzGzx/fV h8lw== X-Received: by 10.52.110.201 with SMTP id ic9mr20546282vdb.22.1392047129188; Mon, 10 Feb 2014 07:45:29 -0800 (PST) MIME-Version: 1.0 In-Reply-To: <2079199387413737237.368296sturla.molden-gmail.com@news.gmane.org> References: <52f80bca$0$29972$c3e8da3$5496439d@news.astraweb.com> <9671c418-cde8-4857-85ec-52380f8390eb@googlegroups.com> <433934582413720306.205290sturla.molden-gmail.com@news.gmane.org> <2079199387413737237.368296sturla.molden-gmail.com@news.gmane.org> From: Oscar Benjamin Date: Mon, 10 Feb 2014 15:45:08 +0000 Subject: Re: Sort one sequence by O(n) in time and O(1) in space To: Sturla Molden Content-Type: text/plain; charset=ISO-8859-1 Cc: Python List X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 52 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1392047138 news.xs4all.nl 2898 [2001:888:2000:d::a6]:34392 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:65827 On 10 February 2014 15:03, Sturla Molden wrote: > Chris Angelico wrote: > >> That's assuming it really is a sort operation. The problem description >> isn't entirely clear on this point, but if it's actually a zip, then >> it can definitely be done in O(n). > > Ah, I didn't read it carefully enough. :-) > > Granted, a zip can be done in O(n) time and O(1) memory using a generator, > which by the way is what itertools.izip does. Yes but turning the generator into a list takes O(N) storage (for the new list!). The OP wants to rearrange a list in-place. Something like mylist[:] = reorder_generator(mylist) won't work because the generator would need to access the data non-sequentially (it would need to read elements after they were overwritten). The way to do this is to find the cycles of data movement i.e. the sets of indices for which a permutation occurs. If you know the size of the input then you can find these once and hard-code them. Otherwise you need an algorithm that finds each cycle exactly once using O(1) storage which is definitely not trivial. You can see the top-level code that fftw uses for this here (I think this code is very hard to follow without prior experience of their code base - I certainly don't understand it): https://github.com/FFTW/fftw3/blob/master/rdft/vrank3-transpose.c#L159 I'm not even sure if that really is O(1) storage though: it may be something like O(MN/gcd(M, N)). This page describes the general problem http://en.wikipedia.org/wiki/In-place_matrix_transposition and mentions the existence of "more complicated" algorithms that can use O(N+M) or O(log(MN)) storage. So I don't think an O(1) storage O(N) operations solution exists for the general M*N case although it may be possible for the specialisation to 2*M. (I haven't tried this but if you're interested see what cycles come up for different input sizes and whether there's a pattern that can be predicted using O(1) storage). Oscar