Given a list of N arbitrarily permutated integers from set {1..N}.
Need to find the ordering numbers of each integer in the LONGEST
increasing sequence to which this number belongs. Sample:
List:
[4, 5, 6, 1, 2, 7, 3]
Corresponding ordering numbers:
[1, 2, 3, 1, 2, 4, 3]
Details:
e.g. number 7 belongs to increasing sequence 1, 2, 7;
but this sequence is not the LONGEST sequence for "7".
The longest sequence for the 7 is 4, 5, 6, 7.
So, the 7's ordering number in this sequence is 4.
The salt of the thing is to do this with an O(n*log(n))
algorithm!
The straightforward O(n^2) algorithm is toooo slooow.
Any ideas?
Sep 7 '05
39 3121
[Tim Peters, on the problem at http://spoj.sphere.pl/problems/SUPPER/
] Oh, it's not that bad <wink>. I took a stab at a Python program for this, and it passed (3.44 seconds). ... I didn't make any effort to speed this, beyond picking a reasonable algorithm, so maybe someone else can slash the runtime
[Bryan Olson] Hmmm ... I used the Theta(n lg n) algorithm ... how the heck... Aha! The 'bisect' module changed since last I looked. It still has the Python implementation, but then the last few lines say:
# Overwrite above definitions with a fast C implementation try: from _bisect import bisect_right, bisect_left, insort_left, insort_right, insort, bisect except ImportError: pass Binary-search is the inner-loop in this algorithm. I wrote my own binary-search, so I was executing Theta(n lg n) Python statements. Tim's use of bisect means that his inner-loop is in C, so he does Theta(n) Python statements and Theta(n lg n) C statement.
That's part of it, but doesn't account for enough. If I disable the C
implementation of bisect (replace the "from ..." import above with a
"pass"), the program takes about 50% longer, which would still leave
it well under the 9-second SPOJ time limit. That's without psyco.
With psyco, it takes about the same time with the Python
implementation of bisect as with the C implementation.
Proably more important was my findall() routine. It does redundant
work, and its runtime seems hard to analyze, but it's conceptually
simple and actual timing showed it takes about a third of the time
consumed by my crack() on random 100,000-element permutations. In
fact, findall() takes very close to the amount of time needed just to
read a giant line of input and convert it to a list of ints (without
psyco; with psyco converting the input takes longer than findall()).
Possible surprise: there's a simple trick that allows rewriting
findall() to produce the result list in sorted order directly, instead
of building it in "random" order and sorting it at the end. That made
no measurable difference.
The key to fast Python: use a good algorithm,
Absolutely!
and keep the inner loop in C.
Usually ;-)
Add another: especially for long-term maintenance, readability,
stability and performance, use a library function instead of rolling
your own. The chance that Raymond Hettinger is going to recode _your_
functions in C is approximately 0 ;-)
Tim Peters wrote: The chance that Raymond Hettinger is going to recode _your_ functions in C is approximately 0 ;-)
Who is Raymond Hettinger?
n00m wrote: Tim Peters wrote: The chance that Raymond Hettinger is going to recode _your_ functions in C is approximately 0 ;-) Who is Raymond Hettinger?
See python-dev and, wrt this thread, http://docs.python.org/whatsnew/node12.html.
Reinhold
Got it! He is a kind of pythonic monsters.
Btw, why it's impossible to reply to old threads?
Namely, there're no more "Reply" link in them.
Only "Reply to author" etc.
"n00m" <n0**@narod.r u> wrote in message
news:11******** ************@f1 4g2000cwb.googl egroups.com... Who is Raymond Hettinger?
The Python developer who, in the last few years, has perhaps been the most
active in coding or recoding library modules, such as itertools and sets,
in C. He also partipates in development discussions, helps with
SourceForge tracker items (RFEs, bugs, and patches) and occasionally posts
here, especially about his modules, for which he is the expert.
Terry J. Reedy
n00m wrote: Got it! He is a kind of pythonic monsters.
Btw, why it's impossible to reply to old threads? Namely, there're no more "Reply" link in them. Only "Reply to author" etc.
Perhaps because you are not using a real Usenet client?
Reinhold
Thank you both for your replies.
And my personal "Thank you!" to Mr. Hettinger for
all his tremendous work! Perhaps because you are not using a real Usenet client?
Yes! And I don't even know what is the beast - Usenet client.
I just keep in Favorites of my browser (IE 6.0) this link: http://groups.google.com/group/comp.lang.python/
I hope nobody have posted similar solution (it's tested, but I didn't
submit it to contest):
from bisect import bisect_right as find
def supernumbers(ls ):
indices = [0]*len(ls)
for i, e in enumerate(ls):
indices[e - 1] = i
result = [None]*len(ls)
borders = []
for i in indices:
ind = find(borders, i)
result[i] = ind + 1
if ind == len(borders):
borders.append( i)
else:
borders[ind] = i
return result
At least, it looks shorter than other solutins.
Of course, it allows number of optimizations like
prefetching length and caching borders.append.
If I'm correct, it takes O(n*log (max sequence length)) time that can
be a win for huge datasets.
With the best regards,
anton.
Anton,
it simply does not work! Try supernumbers([2,1,4,5,3]).
Hellom n00m!
I beg your pardon for not having replied for such long time---I was
really busy.
Yes, the posted code doesn't solve the supernumbers problem, but solves
the problem you posted first as I understood it :) --- for each number
find a position of this number in the longest sequence it belongs to.
Ok, anyway, I hope that I can suggest a solution to the supernumbers
problem (see below).
Actually, as I find out today testing it against Tim Peters's solution,
they are of the same kind, but I use one additional optimimization.
And the last note: I didn't persue the maximal performace, rather
clarity of the algorithm.
With the best regards,
anton.
from bisect import bisect as find
def supernumbers(l) :
indices = [0]*len(l)
for i, e in enumerate(l):
indices[e - 1] = i
# Now we can find out index of each element in the longest ascending
sequence it belongs to
# I call this index 'generation'
# ess is an array indexed by generations and holding
# ascending list of generation's elements
# Note: suffix s stands for a list, therefore ess---list of lists
of elements
# Note: ess holds not the elements itself, but elements decreased
by 1
ess = []
# Borders i.e. positions that separate generations
borders = []
for e, i in enumerate(indic es):
ind = find(borders, i)
if ind < len(borders):
borders[ind] = i
ess[ind].append(e)
else:
borders.append( i)
ess.append([e])
# Now we should filter out those elements that don't
# belong to the longest sequences
gens = reversed(ess) # walk generations in reverse order
fes = gens.next() # fes stands for elements' filter
r = fes # r is a list of supernumbers; obvioulsy all the elements of
the latest generation belong to r
for es in gens:
new_fes = []
s = 0 # As elements are sorted ascendingly we can check lesser and
lesser lists
for e in es:
s = find(fes, e, s)
if s == len(fes):
# There is no more elements in filter that are greater
# than elements in the current generation
break
if indices[fes[s]] > indices[e]: # Nice---element e belongs to
the longest sequence
new_fes.append( e)
# Note: the following invariant holds: len(new_fes) > 0
fes = new_fes
r += new_fes
return [e + 1 for e in r] # As we used numbers from 0 internally This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: dam_fool_2003 |
last post by:
Hai,
I thank those who helped me to create a single linked list with int
type. Now I wanted to try out for a void* type. Below is the code:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<stddef.h>
struct node
|
by: aruna |
last post by:
Given a set of integers, how to write a program in C
to sort these set of integers using C, given the following conditions
a. Do not use arrays
b. Do not use any comparison function like if/then
or switch-case
c. you can use pointers only
d. you cannot use any of the loops either.
|
by: Girish Sahani |
last post by:
Hi,
Please check out the following loop,here indexList1 and indexList2 are a
list of numbers.
for index1 in indexList1:
for index2 in indexList2:
if ti1 == ti2 and not index1 != indexList1.pop():
index1+=1
index2+=1
continue
|
by: Steve |
last post by:
I'm trying to create a list range of floats and running into problems.
I've been trying something like:
a = 0.0
b = 10.0
flts = range(a, b)
fltlst.append(flts)
|
by: Amit Bhatia |
last post by:
Hi,
I am not sure if this belongs to this group. Anyway, my question is as
follows: I have a list (STL list) whose elements are pairs of integers (STL
pairs, say objects of class T). When I create a new object of class T, I
would like to check if this object already exists in the list: meaning one
having same integers. This can be done in linear time in a list, and
probably faster if I use STL Set instead of list. I am wondering however if...
| |
by: maruf.syfullah |
last post by:
Consider the following Class definitions:
class AClass
{
int ai1;
int ai2;
public:
CClass* c;
AClass(){}
|
by: python101 |
last post by:
I have a list of integers s= to be converted to s=
I tried
s=
for i in s:
str(a)
'2'
|
by: arnuld |
last post by:
It is quite an ugly hack but it is all I am able to come up with for
now :-( and it does the requires work. I want to improve the program, I
know you people have much better ideas ;-)
/* C++ Primer - 4/e
*
* exercise 9.20
* STATEMENT:
* Write a program to to compare whether a vector<intcontains the
|
by: antar2 |
last post by:
Hello,
I am a beginner in python.
following program prints the second element in list of lists 4 for the
first elements in list 4 that are common with the elements in list 5
list4 = ,,]
list5 =
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
| |
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own....
Now, this would greatly impact the work of software developers. The idea...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert into image.
Globals.ThisAddIn.Application.ActiveDocument.Select();...
|
by: TSSRALBI |
last post by:
Hello
I'm a network technician in training and I need your help.
I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs.
The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols.
I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |